From 6dc06aac3c050e658a15ab3d3bcb6e87d1667290 Mon Sep 17 00:00:00 2001 From: Carsten Piepel Date: Fri, 30 Aug 2024 18:18:21 -0400 Subject: [PATCH] Resolves felt/geo#193 (#194) * Resolves felt/geo#193 * Apply suggestions from code review * Fix formatting * One more attempt to fix formatting (sigh) --------- Co-authored-by: Tyler A. Young --- lib/geo/json/decoder.ex | 11 ++++++++- test/geo/json_test.exs | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/geo/json/decoder.ex b/lib/geo/json/decoder.ex index 978d35a..b42999d 100644 --- a/lib/geo/json/decoder.ex +++ b/lib/geo/json/decoder.ex @@ -197,7 +197,16 @@ defmodule Geo.JSON.Decoder do 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) + if geometry["type"] == "GeometryCollection" do + geometry_collection = decode!(geometry) + + %GeometryCollection{ + geometries: geometry_collection.geometries, + properties: properties + } + else + do_decode(Map.get(geometry, "type"), Map.get(geometry, "coordinates"), properties, nil) + end end defp do_decode(type, [x, y, _z], properties, crs) do diff --git a/test/geo/json_test.exs b/test/geo/json_test.exs index 526b033..a8c5b4e 100644 --- a/test/geo/json_test.exs +++ b/test/geo/json_test.exs @@ -473,4 +473,58 @@ defmodule Geo.JSON.Test do assert(Geo.JSON.encode!(gc, feature: true) == expected) end + + test "Decode Feature with GeometryCollection geometry" do + # Similar to response from https://api.weather.gov/zones/county/FLC017 + json = """ + { + "@context": { + "@version": "1.1" + }, + "id": "https://api.weather.gov/zones/county/FLC017", + "type": "Feature", + "geometry": { + "type": "GeometryCollection", + "geometries": [ + { + "type": "MultiPolygon", + "coordinates": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]] + }, + { + "type": "MultiPolygon", + "coordinates": [[[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],[[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],[[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]] + } + ] + }, + "properties": { + "@id": "https://api.weather.gov/zones/county/FLC017", + "@type": "wx:Zone", + "id": "FLC017", + "type": "county", + "name": "Citrus", + "effectiveDate": "2023-09-19T18:00:00+00:00", + "expirationDate": "2200-01-01T00:00:00+00:00", + "state": "FL", + "cwa": [ + "TBW" + ], + "forecastOffices": [ + "https://api.weather.gov/offices/TBW" + ], + "timeZone": [ + "America/New_York" + ], + "observationStations": [], + "radarStation": null + } + } + """ + + geom = Jason.decode!(json) |> Geo.JSON.decode!() + + assert %GeometryCollection{} = geom + assert length(geom.geometries) == 2 + assert Enum.all?(geom.geometries, &match?(%Geo.MultiPolygon{}, &1)) + assert geom.properties["id"] == "FLC017" + end end