AshNeo4j.GeoJson (AshNeo4j v0.8.0)

Copy Markdown View Source

RFC 7946 GeoJSON encoder/decoder over the :geo library.

Geo.JSON.encode!/1 produces the obsolete 2008-spec GeoJSON shape when srid is set on a geometry struct — it adds a "crs" member that RFC 7946 explicitly removed. AshNeo4j wants RFC 7946 strictly on disk (GIS-tool interop is half the motivation), so this module wraps Geo.JSON to:

  • Strip the crs member on encode by nilling srid before handing the struct to Geo.JSON.encode!/1.
  • Add the optional RFC bbox member to every encoded geometry, derived from the coordinates. Makes the JSON self-describing for any consumer that doesn't want to recompute the bounding box.
  • Set srid: 4326 on decoded structs. AshNeo4j is WGS-84 2D throughout; the struct should carry that explicitly even though the on-disk JSON omits the CRS.

Round-trip: encode!(geom) |> decode!() == geom (with srid: 4326 set on the decoded side).

The encode workaround is a candidate for an upstream fix in :geo itself (an option like Geo.JSON.encode!(geom, rfc7946: true)); to be filed once this local workaround is exercised in production.

Summary

Functions

Derives the RFC 7946 §5 bbox for a geometry as [west, south, east, north] (2D, WGS-84). Walks the coordinate structure recursively, so works for any geometry shape — Point, LineString, Polygon (incl. holes), MultiPoint, MultiLineString, MultiPolygon.

Decodes an RFC 7946 GeoJSON string to a %Geo.*{} struct with srid: 4326 set. The bbox member, if present, is ignored — it's metadata derivable from coordinates and the struct doesn't carry it.

Encodes a %Geo.*{} struct to an RFC 7946-compliant GeoJSON string with the bbox member included. Keys are sorted alphabetically via AshNeo4j.Util.json_encode/1 for stable on-disk ordering.

Encodes a %Geo.*{} struct to an RFC 7946 GeoJSON map (without JSON-stringifying). Used when the GeoJSON needs to be nested inside another structure that will itself be JSON-encoded — e.g. a Geo struct living inside a TypedStruct attribute, where the parent's JSON blob contains the nested GeoJSON inline.

Functions

bbox(map)

@spec bbox(Geo.geometry()) :: [float()]

Derives the RFC 7946 §5 bbox for a geometry as [west, south, east, north] (2D, WGS-84). Walks the coordinate structure recursively, so works for any geometry shape — Point, LineString, Polygon (incl. holes), MultiPoint, MultiLineString, MultiPolygon.

decode!(json)

@spec decode!(String.t()) :: Geo.geometry()

Decodes an RFC 7946 GeoJSON string to a %Geo.*{} struct with srid: 4326 set. The bbox member, if present, is ignored — it's metadata derivable from coordinates and the struct doesn't carry it.

encode!(geom)

@spec encode!(Geo.geometry()) :: String.t()

Encodes a %Geo.*{} struct to an RFC 7946-compliant GeoJSON string with the bbox member included. Keys are sorted alphabetically via AshNeo4j.Util.json_encode/1 for stable on-disk ordering.

encode_map(geom)

@spec encode_map(Geo.geometry()) :: map()

Encodes a %Geo.*{} struct to an RFC 7946 GeoJSON map (without JSON-stringifying). Used when the GeoJSON needs to be nested inside another structure that will itself be JSON-encoded — e.g. a Geo struct living inside a TypedStruct attribute, where the parent's JSON blob contains the nested GeoJSON inline.