opendatalab-de / geojson-jackson

GeoJson POJOs for Jackson - serialize and deserialize objects with ease
http://blog.opendatalab.de
Apache License 2.0
263 stars 94 forks source link

Make parsing of `crs` more lenient #62

Open vpavic opened 1 year ago

vpavic commented 1 year ago

At present, type property of crs is mapped to org.geojson.jackson.CrsType enum. This makes it challenging to parse GeoJSON containing crs.type value outside of those outlined by the spec (and present in the enum).

One such example is government WFS service that provides cadastral data here in Croatia. The crs property of GeoJSON returned by this service contains the following:

"crs": {
    "type": "EPSG",
    "properties": {
        "code": "3765"
    }
}

Attempting to parse such GeoJSON using something like:

JsonMapper.builder().build().readValue("""
        {
            "type": "FeatureCollection",
            "totalFeatures": 0,
            "features": [],
            "crs": {
                "type": "EPSG",
                "properties": {
                    "code": "3765"
                }
            }
        }
        """, FeatureCollection.class);

Fails with InvalidFormatException:

Cannot deserialize value of type `org.geojson.jackson.CrsType` from String "EPSG": not one of the values accepted for Enum class: [link, name]

Additionally, GeoJSON spec linked in introduction is obsoleted by RFC 7946 which actually removes crs from the spec. See Appendix B of the RFC:

Appendix B.  Changes from the Pre-IETF GeoJSON Format Specification

   This appendix briefly summarizes non-editorial changes from the 2008
   specification [GJ2008].

B.1.  Normative Changes

   o  Specification of coordinate reference systems has been removed,
      i.e., the "crs" member of [GJ2008] is no longer used.

All of this IMO supports the case for a more lenient parsing of crs in geojson-jackson.

vpavic commented 1 year ago

Forgot to mention, I'm working around the issue by providing something like this as a replacement for org.geojson.FeatureCollection:

@JsonIgnoreProperties(ignoreUnknown = true)
record FeatureCollection(List<Feature> features) {

    @JsonCreator
    FeatureCollection(@JsonProperty("features") List<Feature> features) {
        this.features = features;
    }

}
vpavic commented 1 year ago

Another, perhaps more elegant, workaround is to provide a mix-in that ignores Crs altogether:

@JsonIgnoreType
class IgnoreTypeMixin {
}
JsonMapper jsonMapper = JsonMapper.builder()
        .addMixIn(Crs.class, IgnoreTypeMixin.class)
        .build();