Library
Module
Module type
Parameter
Class
Class type
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.
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.
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 = Result.map 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
end
Feel free to copy and paste any of the parsers without attribution :)
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
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 @@ G.Feature.properties f
| Ok (FeatureCollection fc) ->
let fs = G.Feature.Collection.features fc in
List.filter_map G.Feature.properties fs
| _ -> []