Skip to content

Commit

Permalink
One GeoJson type to rule them all
Browse files Browse the repository at this point in the history
  • Loading branch information
taig committed Jul 21, 2023
1 parent 657320d commit cf490b7
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 21 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# GeoJSON

> Plain GeoJSON data structures
```scala
libraryDependencies ++=
"io.taig" %%% "geojson-core" % "x.y.z" ::
"io.taig" %%% "geojson-circe" % "x.y.z" ::
Nil
```
25 changes: 20 additions & 5 deletions modules/circe/src/main/scala/io/taig/geojson/circe.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,21 @@ import io.circe.JsonObject
import io.circe.DecodingFailure

trait circe:
implicit val decodeGeoJson: Decoder[GeoJson] = cursor =>
cursor
.get[String]("type")
.flatMap:
case FeatureCollection.Type => cursor.as[FeatureCollection]
case Feature.Type => cursor.as[Feature]
case _ => cursor.as[Geometry]

implicit val encodeGeoJson: Encoder.AsObject[GeoJson] =
case geoJson: FeatureCollection => geoJson.asJsonObject
case geoJson: Feature => geoJson.asJsonObject
case geoJson: Geometry => geoJson.asJsonObject

implicit final val decodeFeatureCollection: Decoder[FeatureCollection] = cursor =>
for
_ <- cursor.get["FeatureCollection"]("type")
features <- cursor.get[List[Feature]]("features")
yield FeatureCollection(features)
cursor.get[List[Feature]]("features").map(FeatureCollection.apply)

implicit final val encodeFeatureCollection: Encoder.AsObject[FeatureCollection] = feature =>
JsonObject(
Expand All @@ -21,7 +31,6 @@ trait circe:

implicit final val decodeFeature: Decoder[Feature] = cursor =>
for
_ <- cursor.get["Feature"]("type")
id <- cursor.get[Option[String]]("id")
geometry <- cursor.get[Option[Geometry]]("geometry")
properties <- cursor.get[Option[Map[String, String]]]("properties")
Expand All @@ -40,6 +49,12 @@ trait circe:
.get[String]("type")
.flatMap:
case GeometryCollection.Type => cursor.as[GeometryCollection]
case LineString.Type => cursor.as[LineString]
case MultiLineString.Type => cursor.as[MultiLineString]
case MultiPoint.Type => cursor.as[MultiPoint]
case MultiPolygon.Type => cursor.as[MultiPolygon]
case Point.Type => cursor.as[Point]
case Polygon.Type => cursor.as[Polygon]
case tpe => DecodingFailure(s"Unknown type: $tpe", cursor.downField("type").history).asLeft

implicit final val encodeGeometry: Encoder.AsObject[Geometry] =
Expand Down
5 changes: 0 additions & 5 deletions modules/core/src/main/scala/io/taig/geojson/Feature.scala

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
package io.taig.geojson

sealed abstract class Geometry extends Product with Serializable:
sealed abstract class GeoJson extends Product with Serializable

final case class FeatureCollection(features: List[Feature]) extends GeoJson:
def combine(featureCollection: FeatureCollection): FeatureCollection = FeatureCollection(
this.features ++ featureCollection.features
)

object FeatureCollection:
val Type: String = "FeatureCollection"

final case class Feature(id: Option[String], geometry: Option[Geometry], properties: Option[Map[String, String]])
extends GeoJson:
def combine(feature: Feature): FeatureCollection = FeatureCollection(List(this, feature))
def toFeatureCollection: FeatureCollection = FeatureCollection(List(this))

object Feature:
val Type: String = "Feature"

sealed abstract class Geometry extends GeoJson:
def combine(geometry: Geometry): Geometry

final def toGeometryCollection: GeometryCollection = this match
Expand Down

0 comments on commit cf490b7

Please sign in to comment.