Skip to content

Commit

Permalink
Merge pull request #176 from felt/support-null-feature-geometry
Browse files Browse the repository at this point in the history
Support null feature geometries
  • Loading branch information
bryanjos authored Jun 5, 2023
2 parents c74a7b4 + e36d74f commit 5ffa5be
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
13 changes: 10 additions & 3 deletions lib/geo/json/decoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ defmodule Geo.JSON.Decoder do

@doc """
Takes a map representing GeoJSON and returns a Geometry.
Feature objects with null geometries will be stripped from a FeatureCollection,
and a standalone Feature object with null geometry will be decoded to nil.
"""
@spec decode!(map()) :: Geo.geometry()
@spec decode!(map()) :: Geo.geometry() | nil
def decode!(geo_json) do
cond do
Map.has_key?(geo_json, "geometries") ->
Expand Down Expand Up @@ -72,14 +75,16 @@ defmodule Geo.JSON.Decoder do

Map.get(geo_json, "type") == "FeatureCollection" ->
geometries =
Enum.map(Map.get(geo_json, "features"), fn x ->
Map.get(geo_json, "features")
|> Enum.map(fn x ->
do_decode(
Map.get(x, "type"),
Map.get(x, "geometry"),
Map.get(x, "properties", %{}),
Map.get(x, "id", "")
)
end)
|> Enum.reject(&is_nil/1)

%GeometryCollection{
geometries: geometries,
Expand All @@ -94,7 +99,7 @@ defmodule Geo.JSON.Decoder do
@doc """
Takes a map representing GeoJSON and returns a Geometry.
"""
@spec decode(map()) :: {:ok, Geo.geometry()} | {:error, DecodeError.t()}
@spec decode(map()) :: {:ok, Geo.geometry() | nil} | {:error, DecodeError.t()}
def decode(geo_json) do
{:ok, decode!(geo_json)}
rescue
Expand Down Expand Up @@ -168,6 +173,8 @@ defmodule Geo.JSON.Decoder do
%MultiPolygonZ{coordinates: coordinates, srid: get_srid(crs), properties: properties}
end

defp do_decode("Feature", nil, _properties, _id), do: nil

defp do_decode("Feature", geometry, properties, _id) do
do_decode(Map.get(geometry, "type"), Map.get(geometry, "coordinates"), properties, nil)
end
Expand Down
37 changes: 37 additions & 0 deletions test/geo/json_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,43 @@ defmodule Geo.JSON.Test do
assert geom1.properties["label"] == "8 Boulevard du Port 80000 Amiens"
end

test "Decode feature with null geometry" do
json = """
{
"properties": {
"context": "80, Somme, Picardie",
"housenumber": "8"
},
"geometry": null,
"type": "Feature"
}
"""

geom = Jason.decode!(json) |> Geo.JSON.decode!()
assert is_nil(geom)
end

test "Decode feature in a feature collection with null geometry" do
json = """
{
"type": "FeatureCollection",
"features": [
{
"properties": {
"context": "80, Somme, Picardie",
"housenumber": "8"
},
"geometry": null,
"type": "Feature"
}
]
}
"""

geom = Jason.decode!(json) |> Geo.JSON.decode!()
assert geom.geometries == []
end

property "encodes and decodes back to the correct Point struct" do
check all x <- float(),
y <- float() do
Expand Down

0 comments on commit 5ffa5be

Please sign in to comment.