geojson 0.1.0


The GeoJson library provides a functor Make for building a GeoJson parsing and manipulating module. You just need to provide a Json parser using tools like Ezjsone or Yojson.

Before diving in, it is important to note that if you are dealing with gigabytes of data in GeoJson format you would be better served by the Geojsonm library which provides functions using the Jsonm streaming parser to avoid loading everything in memory.

Providing a Json Parser

Before getting a Geojson library you first must provide a parser implementation. Geojson doesn't depend on a particular Json parsing library (there are quite a few in the OCaml universe). This modularity comes with a small cost, you must provide a simple parsing module to the Geojson.Make functor.

Ezjsone Parser

The following is an example of such a parser. If you can you would be better checking the tests and benchmarks of this library for an up to date, type-checked and building version.

module Ezjsone_parser = struct
  type t = Ezjsone.value

  let catch_err f v =
    try Ok (f v) with Ezjsone.Parse_error (_, s) -> Error (`Msg s)

  let find = Ezjsone.find_opt
  let to_string t = catch_err Ezjsone.get_string t
  let string = Ezjsone.string
  let to_float t = catch_err Ezjsone.get_float t
  let float = Ezjsone.float
  let to_list f t = catch_err (Ezjsone.get_list f) t
  let list f t = Ezjsone.list f t
  let to_array f t = Array.of_list @@ to_list f t
  let array f t = list f (Array.to_list t)
  let obj = Ezjsone.dict
  let null = `Null
  let is_null = function `Null -> true | _ -> false

Feel free to copy and paste any of the parsers without attribution :)

Using the Library

Reading Geojson

Once you have provided the Json parser, you can then start using the library properly. The simplest way to get started is first reading Json into your choosen parsers internal representation and calling Geojson.S.of_json.

Sticking with the Ezjsone example we can do

module G = Geojson.Make(Ezjsone_parser)

let geojson_of_string s = 
  let json = Ezjsone.value_from_string s in
    match G.of_json json with 
      | Ok v -> v
      | Error (`Msg m) -> failwith m

Manipulating and Accessing Geojson

Imagine you wished to access all the properties fields in your GeoJson document. There are two ways they can appear -- either as part of a single, toplevel Geojson.S.Feature object or as a list of features inside Geojson.S.Feature.Collection. Here's one way you could go about this:

let get_all_props s = 
  let json = Ezjsone.value_from_string s in
  let geo = G.of_json json in
  match geo with 
    | Ok (Feature f) -> Option.to_list @@ f 
    | Ok (FeatureCollection fc) -> 
      let fs = G.Feature.Collection.features fc in
      List.filter_map fs 
    | _ -> []