mgold / elm-geojson / GeoJson

Decode GeoJson into an Elm data structure where you can operate on it further. Most of this module defines types that collectively define that data structure.

After using GeoJson.decoder you can either traverse the data structure directly or use Json.Decode.andThen to transform it into a more convenient representation specific to your use case. It is recommended that you try the first approach first, and switch to the second if you encounter difficulty.

An encode function is also provided, mostly for completeness and testing. Neither encoding nor decoding attempt to enforce minimum array lengths.

Decoder

decoder : Json.Decode.Decoder GeoJson

Decode GeoJSON into Elm. The decoded value is expressed in the types defined by this module.

Elm Representation of GeoJSON

All union types are fully exposed so you can inspect them as necessary.


type alias GeoJson =
( GeoJsonObject
, Maybe Bbox 
)

The root representation of GeoJSON in Elm. It consists of a GeoJsonObject and an optional Bbox.


type GeoJsonObject
    = Geometry Geometry
    | Feature FeatureObject
    | FeatureCollection (List FeatureObject)

A GeoJsonObject contains the primary data, and is either a Geometry, a FeatureObject, or a list of FeatureObjects.

Note that the tag for FeatureObject is just Feature, to avoid a name collision.


type alias FeatureObject =
{ geometry : Maybe Geometry
, properties : Json.Encode.Value
, id : Maybe String 
}

A FeatureObject represents a geographic feature. The geometry field is allowed to have null instead of actual geometry, which is represented as Nothing. The properties may be any JSON object but no attempt is made to inspect it. The id is an optional "commonly used identifier". It is permitted by the RFC to be either a string or a number; if the latter this implementation converts it to a string.


type Geometry
    = Point Position
    | MultiPoint (List Position)
    | LineString (List Position)
    | MultiLineString (List (List Position))
    | Polygon (List (List Position))
    | MultiPolygon (List (List (List Position)))
    | GeometryCollection (List Geometry)

The heart of GeoJSON: geometry objects. The union tags reflect the type field of the JSON, and carries the value of the coordinates field (or geometries for GeometryCollection).

The specification imposes minimum lengths for some of the arrays (lists in Elm). This representation does not express those guarantees, on the theory that you will likely be working with a valid GeoJson file rather than generating one of your own.


type alias Position =
( Basics.Float
, Basics.Float
, Basics.Float 
)

A Position is the fundamental geometry construct, and are represented in JSON as an array of numbers. RFC 7946 states that "[t]he first two elements are longitude and latitude, or easting and northing, precisely in that order". The third element is the altitude. If omitted in the JSON, it will be set to zero.

As recommended by the RFC, position arrays with more than three elements are rejected.


type alias Bbox =
List Basics.Float

A Bounding Box is represented as a simple list of floats. No attempt is made to validate that its length is twice the length of the geometrys' positions, or that low values are preceded by high values.

Encoding

encode : GeoJson -> Json.Encode.Value

Encode GeoJSON into Elm. This is mostly for completeness and roundtrip testing.

Positions with an altitude of zero will be encoded as two-element arrays.