Created
April 29, 2020 16:14
-
-
Save SLAVONchick/fd967ab1c9a611d0d6ca47a5e3777cde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System | |
open System.Text | |
open Utf8Json | |
[<JsonFormatter(typeof<PointFormatter>)>] | |
type Point = | |
{ Longitude: float | |
Latitude: float } | |
//type Feature = | |
// { geometry: GeoJson | |
// properties: Dictionary<string, obj> } | |
// | |
//and GeoJson = | |
// | Point of coordinates: Point | |
// | Polygon of coordinates: Point [] [] | |
// | MultiPolygon of coordinates: Point [] [] [] | |
// | Feature of feature: Feature | |
// | FeatureCollection of features: Feature [] | |
and Feature<'T> = | |
{ geometry: GeoJson<'T> | |
properties: 'T } | |
and [<JsonFormatter(typedefof<GeoJsonFormatter<_>>)>] GeoJson<'T> = | |
| Point of coordinates: Point | |
| Polygon of coordinates: Point [] [] | |
| MultiPolygon of coordinates: Point [] [] [] | |
| Feature of feature: Feature<'T> | |
| FeatureCollection of features: Feature<'T> [] | |
and [<CLIMutable>] private TmpGeoJson = | |
{ ``type``: string | |
coordinates: string | |
feature: string | |
features: string } | |
and PointFormatter() = | |
interface IJsonFormatter<Point> with | |
member self.Deserialize(reader: byref<JsonReader>, formatterResolver: IJsonFormatterResolver) = | |
let points = formatterResolver.GetFormatterWithVerify<float []>().Deserialize(&reader, formatterResolver) | |
{ Longitude = points.[0]; Latitude = points.[1] } | |
member self.Serialize(writer: byref<JsonWriter>, value: Point, formatterResolver: IJsonFormatterResolver) = | |
writer.WriteBeginArray() | |
writer.WriteDouble(value.Longitude) | |
writer.WriteDouble(value.Latitude) | |
writer.WriteEndArray() | |
and GeoJsonFormatter<'T>() = | |
interface IJsonFormatter<GeoJson<'T>> with | |
member self.Deserialize(reader: byref<JsonReader>, formatterResolver: IJsonFormatterResolver) = | |
let tmp = formatterResolver.GetFormatterWithVerify<TmpGeoJson>().Deserialize(&reader, formatterResolver) | |
let pointArrayToPoint (points: float []) = { Longitude = points.[0]; Latitude = points.[1] } | |
match tmp.``type``.ToUpperInvariant() with | |
| "POINT" -> | |
let mutable reader' = JsonReader(Encoding.UTF8.GetBytes(tmp.coordinates)) | |
formatterResolver.GetFormatterWithVerify<Point>().Deserialize(&reader', formatterResolver) |> Point | |
| "POLYGON" -> | |
let mutable reader' = JsonReader(Encoding.UTF8.GetBytes(tmp.coordinates)) | |
formatterResolver.GetFormatterWithVerify<Point [] []>().Deserialize(&reader', formatterResolver) |> Polygon | |
| "MULTIPOLYGON" -> | |
let mutable reader' = JsonReader(Encoding.UTF8.GetBytes(tmp.coordinates)) | |
formatterResolver.GetFormatterWithVerify<Point [] [] []>().Deserialize(&reader', formatterResolver) |> MultiPolygon | |
| "FEATURE" -> | |
let mutable reader' = JsonReader(Encoding.UTF8.GetBytes(tmp.feature)) | |
let feature = formatterResolver.GetFormatterWithVerify<Feature<'T>>().Deserialize(&reader', formatterResolver) | |
Feature feature | |
| "FEATURECOLLECTION" -> | |
let mutable reader' = JsonReader(Encoding.UTF8.GetBytes(tmp.feature)) | |
let feature = formatterResolver.GetFormatterWithVerify<Feature<'T> []>().Deserialize(&reader', formatterResolver) | |
FeatureCollection feature | |
| _ -> failwith (sprintf "Incorrect type (%s)" tmp.``type``) | |
member self.Serialize(writer: byref<JsonWriter>, value: GeoJson<'T>, formatterResolver: IJsonFormatterResolver) = | |
match value with | |
| Point coords -> | |
formatterResolver | |
.GetFormatterWithVerify<{|``type``:string; coordinates: Point|}>() | |
.Serialize(&writer, {|``type``="Point";coordinates=coords|}, formatterResolver) | |
| Polygon coords -> | |
formatterResolver | |
.GetFormatterWithVerify<{|``type``:string; coordinates: Point [] []|}>() | |
.Serialize(&writer, {|``type``="Polygon";coordinates=coords|}, formatterResolver) | |
| MultiPolygon coords -> | |
formatterResolver | |
.GetFormatterWithVerify<{|``type``:string; coordinates: Point [] [] []|}>() | |
.Serialize(&writer, {|``type``="MultiPolygon";coordinates=coords|}, formatterResolver) | |
| Feature feature -> | |
formatterResolver | |
.GetFormatterWithVerify<{|``type``:string; geometry: GeoJson<'T>; properties: 'T|}>() | |
.Serialize(&writer, {|``type``="Feature";geometry=feature.geometry;properties=feature.properties|}, formatterResolver) | |
| FeatureCollection features -> | |
formatterResolver | |
.GetFormatterWithVerify<{|``type``:string; features: {|``type``:string; geometry: GeoJson<'T>; properties: 'T|} [] |}>() | |
.Serialize(&writer, | |
{| ``type``="FeatureCollection" | |
features=features |> Array.map (fun feature -> | |
{|``type``="Feature" | |
geometry=feature.geometry | |
properties=feature.properties |}) |}, | |
formatterResolver) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment