Skip to content

Commit

Permalink
Geocode source improvements (#47)
Browse files Browse the repository at this point in the history
* Geocode source improvements

* Fix - geocode source options

* Fix - geocode source for postal codes

* Update lib/kino_maplibre/map_cell.ex

Co-authored-by: Jonatan Kłosko <[email protected]>

Co-authored-by: Jonatan Kłosko <[email protected]>
  • Loading branch information
Cristine Guadelupe and jonatanklosko authored Nov 25, 2022
1 parent 3421fb6 commit c356f78
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 29 deletions.
3 changes: 2 additions & 1 deletion lib/assets/map_cell/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ export function init(ctx, payload) {
label="Type"
:index="index"
v-model="layer.layer_type"
:options="typeOptions"
:options="layer.source_type === 'query' ? geocodeOptions : typeOptions"
:disabled="noSourceVariable"
:required
/>
Expand Down Expand Up @@ -262,6 +262,7 @@ export function init(ctx, payload) {
dataOptions: payload.source_variables,
missingDep: payload.missing_dep,
typeOptions: ["circle", "fill", "line", "heatmap", "cluster"],
geocodeOptions: ["fill", "line", "circle"],
styles: [
"default",
"street (non-commercial)",
Expand Down
49 changes: 33 additions & 16 deletions lib/kino_maplibre/map_cell.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ defmodule KinoMapLibre.MapCell do
@as_float ["layer_opacity"]
@geometries [Geo.Point, Geo.LineString, Geo.Polygon, Geo.GeometryCollection]
@styles %{"street (non-commercial)" => :street, "terrain (non-commercial)" => :terrain}
@geocode_options ["fill", "line", "circle"]

@query_source %{columns: nil, type: "query", variable: "🌎 Geocoding"}
@query_base "https://nominatim.openstreetmap.org/search?format=geojson&limit=1&polygon_geojson=1"

@impl true
def init(attrs, ctx) do
Expand Down Expand Up @@ -110,8 +110,16 @@ defmodule KinoMapLibre.MapCell do

updated_source = prefill_source_options(ctx.assigns.layers, value)

layer_type =
if source_type == "query" and layer["layer_type"] not in @geocode_options,
do: "fill",
else: layer["layer_type"]

updated_fields =
Map.merge(%{"layer_source" => value, "source_type" => source_type}, updated_source)
Map.merge(
%{"layer_source" => value, "source_type" => source_type, "layer_type" => layer_type},
updated_source
)

updated_layer = Map.merge(layer, updated_fields)
updated_layers = List.replace_at(ctx.assigns.layers, idx, updated_layer)
Expand Down Expand Up @@ -334,19 +342,18 @@ defmodule KinoMapLibre.MapCell do
defp build_arg_source(id, data, :table, coordinates, opts),
do: [id, Macro.var(String.to_atom(data), nil), coordinates, opts]

defp build_arg_source(id, data, :query, _, opts) do
args = [type: :geojson, data: data]
args = if opts, do: Keyword.merge(args, opts), else: args
[id, args]
end
defp build_arg_source(id, {data, nil}, :query, _, _),
do: [id, data]

defp build_arg_source(id, {data, strict}, :query, _, _),
do: [id, data, String.to_atom(strict)]

defp build_arg_source(id, data, _, _, opts) do
args = [type: :geojson, data: Macro.var(String.to_atom(data), nil)]
args = if opts, do: Keyword.merge(args, opts), else: args
[id, args]
end

defp build_arg_layer(nil, _, _, _, _), do: nil
defp build_arg_layer(_, nil, _, _, _), do: nil

defp build_arg_layer(id, source, :cluster, _, cluster_options) do
Expand Down Expand Up @@ -414,22 +421,23 @@ defmodule KinoMapLibre.MapCell do
defp build_layer_source(%{source_type: :query, layer_source_query: nil}), do: nil

defp build_layer_source(%{source_type: :query} = layer) do
query = String.replace(layer.layer_source_query, ~r/\W+/, "_")
query = normalize_geocode_id(layer.layer_source_query)
strict = layer.layer_source_query_strict
if strict, do: "#{query}_#{strict}", else: query
end

defp build_layer_source(layer), do: layer.layer_source

defp source_id(%{"layer_type" => "cluster"} = layer), do: "#{layer["layer_source"]}_clustered"
defp source_id(%{"source_type" => "query", "layer_source_query" => nil}), do: nil

defp source_id(%{"source_type" => "query"} = layer) do
query = String.replace(layer["layer_source_query"], ~r/\W+/, "_")
query = normalize_geocode_id(layer["layer_source_query"])
strict = layer["layer_source_query_strict"]
if strict, do: "#{query}_#{strict}", else: query
end

defp source_id(%{"layer_type" => "cluster"} = layer), do: "#{layer["layer_source"]}_clustered"

defp source_id(layer), do: layer["layer_source"]

defp source_coordinates(%{"source_type" => "table", "coordinates_format" => "columns"} = layer) do
Expand All @@ -446,17 +454,14 @@ defmodule KinoMapLibre.MapCell do
defp source_options(_), do: []

defp source_data(%{"source_type" => "query"} = layer) do
build_source_query(layer["layer_source_query"], layer["layer_source_query_strict"])
{layer["layer_source_query"], layer["layer_source_query_strict"]}
end

defp source_data(layer), do: layer["layer_source"]

defp build_source_query(nil, _), do: nil
defp build_source_query(query, nil), do: "#{@query_base}&q=#{query}"
defp build_source_query(query, strict), do: "#{@query_base}&#{strict}=#{query}"

defp add_source_function(:geo), do: :add_geo_source
defp add_source_function(:table), do: :add_table_source
defp add_source_function(:query), do: :add_geocode_source
defp add_source_function(_), do: :add_source

defp missing_dep() do
Expand Down Expand Up @@ -511,4 +516,16 @@ defmodule KinoMapLibre.MapCell do
valid_lat? = lat >= -90 and lat <= 90
if valid_lng? and valid_lat?, do: {lng, lat}
end

defp normalize_geocode_id(query) do
if Regex.match?(~r/^[\d-]*$/, query) do
"postalcode_#{String.replace(query, ~r/\D+/, "")}"
else
query
|> String.downcase()
|> String.normalize(:nfd)
|> String.replace(~r/[^a-zA-Z\s]/u, "")
|> String.replace(~r/\W+/, "_")
end
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule KinoMapLibre.MixProject do
[
{:kino, "~> 0.6.1 or ~> 0.7.0"},
{:table, "~> 0.1.0"},
{:maplibre, "~> 0.1.2"},
{:maplibre, "~> 0.1.3"},
{:ex_doc, "~> 0.28", only: :dev, runtime: false}
]
end
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"maplibre": {:hex, :maplibre, "0.1.2", "63fe5a071a0d2d167fded093e0958b1247890024e7a04b9429f714463a0ba4dd", [:mix], [{:geo, "~> 3.4", [hex: :geo, repo: "hexpm", optional: false]}, {:req, "~> 0.3.0", [hex: :req, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "8db58a5d302125249b479397e0475d0308275b6e45dff86ceb4a01f4810c6587"},
"maplibre": {:hex, :maplibre, "0.1.3", "510476c23ac9958d3adddc5d349f40907309718639a9b1a93eebd586a39ef2f3", [:mix], [{:geo, "~> 3.4", [hex: :geo, repo: "hexpm", optional: false]}, {:req, "~> 0.3.0", [hex: :req, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "8439795a90365c4363e26a8b66676d88ef44fda8db0060279451343d2259d640"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"table": {:hex, :table, "0.1.2", "87ad1125f5b70c5dea0307aa633194083eb5182ec537efc94e96af08937e14a8", [:mix], [], "hexpm", "7e99bc7efef806315c7e65640724bf165c3061cdc5d854060f74468367065029"},
}
33 changes: 23 additions & 10 deletions test/kino_maplibre/map_cell_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,7 @@ defmodule KinoMapLibre.MapCellTest do

assert MapCell.to_source(attrs) == """
MapLibre.new()
|> MapLibre.add_source("brazil",
type: :geojson,
data:
"https://nominatim.openstreetmap.org/search?format=geojson&limit=1&polygon_geojson=1&q=brazil"
)
|> MapLibre.add_geocode_source("brazil", "brazil")
|> MapLibre.add_layer(
id: "brazil_fill_1",
source: "brazil",
Expand All @@ -311,6 +307,27 @@ defmodule KinoMapLibre.MapCellTest do
"""
end

test "source for a map with one postal code geocode source" do
layer = %{
"layer_source_query" => "95819",
"source_type" => "query",
"layer_type" => "circle"
}

attrs = build_attrs(layer)

assert MapCell.to_source(attrs) == """
MapLibre.new()
|> MapLibre.add_geocode_source("postalcode_95819", "95819")
|> MapLibre.add_layer(
id: "postalcode_95819_circle_1",
source: "postalcode_95819",
type: :circle,
paint: [circle_color: "#000000", circle_radius: 5, circle_opacity: 1]
)\
"""
end

test "source for a map with one strict geocode source" do
layer = %{
"layer_source_query" => "sao paulo",
Expand All @@ -325,11 +342,7 @@ defmodule KinoMapLibre.MapCellTest do

assert MapCell.to_source(attrs) == """
MapLibre.new()
|> MapLibre.add_source("sao_paulo_state",
type: :geojson,
data:
"https://nominatim.openstreetmap.org/search?format=geojson&limit=1&polygon_geojson=1&state=sao paulo"
)
|> MapLibre.add_geocode_source("sao_paulo_state", "sao paulo", :state)
|> MapLibre.add_layer(
id: "sao_paulo_state_fill_1",
source: "sao_paulo_state",
Expand Down

0 comments on commit c356f78

Please sign in to comment.