Search code examples
javamongodbrestspring-bootgeojson

How to change marshalling of geojson (GeoJsonPolygon) from mongodb in Spring Boot?


I've never used Spring Boot before and I'd like to create a small REST service with using mongodb. I am storing some spatial data in the database and want to make them accessible via the rest interface. This works and was quite simple but I am struggling with the Geojson representation I get using the default mappig/marshalling.

So here is what I have so far:

POJO:

@Document(collection = "geofences")
public class Geofence {
    @Id
    private String id;
    private String topic;
    private Date expiresOn;
    private GeoJsonPolygon geo;

    // getters and setters 
}

Document in mongodb:

{ "_id" : ObjectId("5816b03b71e2e892bd7846f3"), "topic" : "ok", "expiresOn" : ISODate("2017-01-01T00:00:00Z"), "geo" : { "type" : "Polygon", "coordinates" : [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ] } }

Method in REST controller:

public ResponseEntity<Collection<Geofence>> getAll() {
    return new ResponseEntity<>(repository.findAll(), HttpStatus.OK);
}

By calling the rest service I would like to receive the geojson part like it is in my document, but I get this instead:

[
  {
    "id": "5816b03b71e2e892bd7846f3",
    "topic": "ok",
    "expiresOn": 1483228800000,
    "geo": {
      "points": [
        {
          "x": 0,
          "y": 0,
          "type": "Point",
          "coordinates": [
            0,
            0
          ]
        },
        {
          "x": 3,
          "y": 6,
          "type": "Point",
          "coordinates": [
            3,
            6
          ]
        },
        {
          "x": 6,
          "y": 1,
          "type": "Point",
          "coordinates": [
            6,
            1
          ]
        },
        {
          "x": 0,
          "y": 0,
          "type": "Point",
          "coordinates": [
            0,
            0
          ]
        }
      ],
      "coordinates": [
        {
          "type": "LineString",
          "coordinates": [
            {
              "x": 0,
              "y": 0,
              "type": "Point",
              "coordinates": [
                0,
                0
              ]
            },
            {
              "x": 3,
              "y": 6,
              "type": "Point",
              "coordinates": [
                3,
                6
              ]
            },
            {
              "x": 6,
              "y": 1,
              "type": "Point",
              "coordinates": [
                6,
                1
              ]
            },
            {
              "x": 0,
              "y": 0,
              "type": "Point",
              "coordinates": [
                0,
                0
              ]
            }
          ]
        }
      ],
      "type": "Polygon"
    }
  }
]

Any suggestions? How can I change this behavior?


Solution

  • I wrote a custom serializer

    public static class GeoJsonPolygonSerializer extends JsonSerializer<GeoJsonPolygon> {
    
        @Override
        public void serialize(GeoJsonPolygon value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
            gen.writeStartObject();
            gen.writeStringField("type", value.getType());
            gen.writeArrayFieldStart("coordinates");
            for (GeoJsonLineString ls : value.getCoordinates()) {
                gen.writeStartArray();
                for (Point p : ls.getCoordinates()) {
                    gen.writeObject(new double[]{p.getX(), p.getY()});
                }
                gen.writeEndArray();
            }
            gen.writeEndArray();
            gen.writeEndObject();
        }
    }
    

    but there has to be a out-of-the-box solution I don't know of?