package com.bedatadriven.jackson.datatype.jts.serialization; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.vividsolutions.jts.geom.*; import java.io.IOException; import java.util.Arrays; import static com.bedatadriven.jackson.datatype.jts.GeoJson.*; public class GeometrySerializer extends JsonSerializer<Geometry> { @Override public void serialize(Geometry value, JsonGenerator jgen, SerializerProvider provider) throws IOException { writeGeometry(jgen, value); } public void writeGeometry(JsonGenerator jgen, Geometry value) throws IOException { if (value instanceof Polygon) { writePolygon(jgen, (Polygon) value); } else if(value instanceof Point) { writePoint(jgen, (Point) value); } else if (value instanceof MultiPoint) { writeMultiPoint(jgen, (MultiPoint) value); } else if (value instanceof MultiPolygon) { writeMultiPolygon(jgen, (MultiPolygon) value); } else if (value instanceof LineString) { writeLineString(jgen, (LineString) value); } else if (value instanceof MultiLineString) { writeMultiLineString(jgen, (MultiLineString) value); } else if (value instanceof GeometryCollection) { writeGeometryCollection(jgen, (GeometryCollection) value); } else { throw new JsonMappingException("Geometry type " + value.getClass().getName() + " cannot be serialized as GeoJSON." + "Supported types are: " + Arrays.asList( Point.class.getName(), LineString.class.getName(), Polygon.class.getName(), MultiPoint.class.getName(), MultiLineString.class.getName(), MultiPolygon.class.getName(), GeometryCollection.class.getName())); } } private void writeGeometryCollection(JsonGenerator jgen, GeometryCollection value) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, GEOMETRY_COLLECTION); jgen.writeArrayFieldStart(GEOMETRIES); for (int i = 0; i != value.getNumGeometries(); ++i) { writeGeometry(jgen, value.getGeometryN(i)); } jgen.writeEndArray(); jgen.writeEndObject(); } private void writeMultiPoint(JsonGenerator jgen, MultiPoint value) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, MULTI_POINT); jgen.writeArrayFieldStart(COORDINATES); for (int i = 0; i != value.getNumGeometries(); ++i) { writePointCoords(jgen, (Point) value.getGeometryN(i)); } jgen.writeEndArray(); jgen.writeEndObject(); } private void writeMultiLineString(JsonGenerator jgen, MultiLineString value) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, MULTI_LINE_STRING); jgen.writeArrayFieldStart(COORDINATES); for (int i = 0; i != value.getNumGeometries(); ++i) { writeLineStringCoords(jgen, (LineString) value.getGeometryN(i)); } jgen.writeEndArray(); jgen.writeEndObject(); } @Override public Class<Geometry> handledType() { return Geometry.class; } private void writeMultiPolygon(JsonGenerator jgen, MultiPolygon value) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, MULTI_POLYGON); jgen.writeArrayFieldStart(COORDINATES); for (int i = 0; i != value.getNumGeometries(); ++i) { writePolygonCoordinates(jgen, (Polygon) value.getGeometryN(i)); } jgen.writeEndArray(); jgen.writeEndObject(); } private void writePolygon(JsonGenerator jgen, Polygon value) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, POLYGON); jgen.writeFieldName(COORDINATES); writePolygonCoordinates(jgen, value); jgen.writeEndObject(); } private void writePolygonCoordinates(JsonGenerator jgen, Polygon value) throws IOException { jgen.writeStartArray(); writeLineStringCoords(jgen, value.getExteriorRing()); for (int i = 0; i < value.getNumInteriorRing(); ++i) { writeLineStringCoords(jgen, value.getInteriorRingN(i)); } jgen.writeEndArray(); } private void writeLineStringCoords(JsonGenerator jgen, LineString ring) throws IOException { jgen.writeStartArray(); for (int i = 0; i != ring.getNumPoints(); ++i) { Point p = ring.getPointN(i); writePointCoords(jgen, p); } jgen.writeEndArray(); } private void writeLineString(JsonGenerator jgen, LineString lineString) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, LINE_STRING); jgen.writeFieldName(COORDINATES); writeLineStringCoords(jgen, lineString); jgen.writeEndObject(); } private void writePoint(JsonGenerator jgen, Point p) throws IOException { jgen.writeStartObject(); jgen.writeStringField(TYPE, POINT); jgen.writeFieldName(COORDINATES); writePointCoords(jgen, p); jgen.writeEndObject(); } private void writePointCoords(JsonGenerator jgen, Point p) throws IOException { jgen.writeStartArray(); jgen.writeNumber(p.getCoordinate().x); jgen.writeNumber(p.getCoordinate().y); if(!Double.isNaN(p.getCoordinate().z)) { jgen.writeNumber(p.getCoordinate().z); } jgen.writeEndArray(); } }