Skip to content

Instantly share code, notes, and snippets.

@eungju
Created June 24, 2011 07:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eungju/1044372 to your computer and use it in GitHub Desktop.
Save eungju/1044372 to your computer and use it in GitHub Desktop.
GeoJSON Encoder
package geojson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Feature;
import java.lang.reflect.Type;
public class FeatureCollectionJsonSerializer implements JsonSerializer<FeatureCollection> {
public JsonElement serialize(FeatureCollection featureCollection, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject json = new JsonObject();
json.addProperty("type", "FeatureCollection");
JsonArray features = new JsonArray();
FeatureIterator i = featureCollection.features();
try {
while (i.hasNext()) {
Feature feature = i.next();
features.add(jsonSerializationContext.serialize(feature));
}
} finally {
i.close();
}
json.add("features", features);
return json;
}
}
package geojson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import org.opengis.feature.Feature;
import org.opengis.feature.Property;
import java.lang.reflect.Type;
public class FeatureJsonSerializer implements JsonSerializer<Feature> {
public JsonElement serialize(Feature feature, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject json = new JsonObject();
json.addProperty("type", "Feature");
json.add("geometry", jsonSerializationContext.serialize(feature.getDefaultGeometryProperty().getValue()));
JsonObject properties = new JsonObject();
for (Property property : feature.getProperties()) {
String name = property.getName().getURI();
Object value = property.getValue();
if (feature.getType().getGeometryDescriptor().getName().getURI().equals(name)) {
continue;
}
properties.add(name, jsonSerializationContext.serialize(value, property.getType().getBinding()));
}
json.add("properties", properties);
if (feature.getType().isIdentified()) {
json.addProperty("id", feature.getIdentifier().getID());
}
return json;
}
}
package geojson;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.vividsolutions.jts.geom.Geometry;
import org.geotools.feature.FeatureCollection;
import org.opengis.feature.Feature;
public class GeoJson {
private final Gson gson;
public GeoJson() {
gson = new GsonBuilder()
//.serializeNulls()
.disableHtmlEscaping()
.registerTypeHierarchyAdapter(Geometry.class, new GeometryJsonSerializer())
.registerTypeHierarchyAdapter(Feature.class, new FeatureJsonSerializer())
.registerTypeHierarchyAdapter(FeatureCollection.class, new FeatureCollectionJsonSerializer())
.create();
}
public String toJson(Object src) {
return gson.toJson(src);
}
public void toJson(Object src, Appendable writer) {
gson.toJson(src, writer);
}
}
package geojson;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class GeoJsonTest {
private GeoJson dut;
private GeometryFactory gf = new GeometryFactory();
@Before public void beforeEach() {
dut = new GeoJson();
}
@Test public void
point() {
assertThat(dut.toJson(gf.createPoint(new Coordinate(1.2345678, 2.3456789))),
is("{\"type\":\"Point\",\"coordinates\":[1.2345678,2.3456789]}"));
}
@Test public void
multiPoint() {
assertThat(dut.toJson(gf.createMultiPoint(new Point[] { gf.createPoint(new Coordinate(1.2345678,2.3456789)) })),
is("{\"type\":\"MultiPoint\",\"coordinates\":[[1.2345678,2.3456789]]}"));
}
@Test public void
lineString() {
assertThat(dut.toJson(gf.createLineString(new Coordinate[] {
new Coordinate(100.0, 0.0),
new Coordinate(101.0, 1.0)})),
is("{\"type\":\"LineString\",\"coordinates\":[[100.0,0.0],[101.0,1.0]]}"));
}
@Test public void
multiLineString() {
assertThat(dut.toJson(gf.createMultiLineString(new LineString[] {
gf.createLineString(new Coordinate[]{
new Coordinate(100.0, 0.0),
new Coordinate(101.0, 1.0)}),
gf.createLineString(new Coordinate[]{
new Coordinate(102.0, 2.0),
new Coordinate(103.0, 3.0)})})),
is("{\"type\":\"MultiLineString\",\"coordinates\":[[[100.0,0.0],[101.0,1.0]],[[102.0,2.0],[103.0,3.0]]]}"));
}
@Test public void
polygon() {
LinearRing shell = gf.createLinearRing(new Coordinate[] {
new Coordinate(102.0, 2.0),
new Coordinate(103.0, 2.0),
new Coordinate(103.0, 3.0),
new Coordinate(102.0, 3.0),
new Coordinate(102.0, 2.0)});
LinearRing[] holes = new LinearRing[] {
gf.createLinearRing(new Coordinate[] {
new Coordinate(100.2, 0.2),
new Coordinate(100.8, 0.2),
new Coordinate(100.8, 0.8),
new Coordinate(100.2, 0.8),
new Coordinate(100.2, 0.2)})};
assertThat(dut.toJson(gf.createPolygon(shell, holes)),
is("{\"type\":\"Polygon\",\"coordinates\":[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]}"));
}
@Test public void
multiPolygon() {
LinearRing shell = gf.createLinearRing(new Coordinate[] {
new Coordinate(102.0, 2.0),
new Coordinate(103.0, 2.0),
new Coordinate(103.0, 3.0),
new Coordinate(102.0, 3.0),
new Coordinate(102.0, 2.0)});
assertThat(dut.toJson(gf.createMultiPolygon(new Polygon[]{gf.createPolygon(shell, null)})),
is("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]]]]}"));
}
@Test public void
geometryCollection() {
GeometryCollection collection = gf.createGeometryCollection(new Geometry[] { gf.createPoint(new Coordinate(1.2345678, 2.3456789)) });
assertThat(dut.toJson(collection),
is("{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Point\",\"coordinates\":[1.2345678,2.3456789]}]}"));
}
@Test public void
feature() {
SimpleFeature feature = buildFeature();
assertThat(dut.toJson(feature),
is("{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":[102.0,2.0]},\"properties\":{\"name\":\"Hello, World\"},\"id\":\"fid-1\"}"));
}
@Test public void
featureCollection() {
SimpleFeatureCollection collection = FeatureCollections.newCollection();
assertThat(dut.toJson(collection),
is("{\"type\":\"FeatureCollection\",\"features\":[]}"));
}
SimpleFeature buildFeature() {
SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
typeBuilder.setName("poi");
typeBuilder.setDefaultGeometry("location");
typeBuilder.add("location", Point.class);
typeBuilder.add("name", String.class);
typeBuilder.nillable(true).add("etc", String.class);
SimpleFeatureType featureType = typeBuilder.buildFeatureType();
SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
featureBuilder.add(gf.createPoint(new Coordinate(102.0, 2.0)));
featureBuilder.add("Hello, World");
featureBuilder.add(null);
SimpleFeature feature = featureBuilder.buildFeature("fid-1");
return feature;
}
}
package geojson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import java.lang.reflect.Type;
public class GeometryJsonSerializer implements JsonSerializer<Geometry> {
public JsonElement serialize(Geometry geometry, Type type, JsonSerializationContext jsonSerializationContext) {
JsonObject json = new JsonObject();
json.addProperty("type", geometry.getGeometryType());
String geometryType = geometry.getGeometryType();
if (geometryType.equals("Point")) {
JsonArray coordinates = pointCoordinates((Point) geometry);
json.add("coordinates", coordinates);
} else if (geometryType.equals("MultiPoint")) {
JsonArray coordinates = new JsonArray();
for (int i = 0; i < geometry.getNumGeometries(); i++) {
Point child = (Point) geometry.getGeometryN(i);
coordinates.add(pointCoordinates(child));
}
json.add("coordinates", coordinates);
} else if (geometryType.equals("LineString")) {
JsonArray coordinates = lineStringCoordinates((LineString) geometry);
json.add("coordinates", coordinates);
} else if (geometryType.equals("MultiLineString")) {
JsonArray coordinates = new JsonArray();
for (int i = 0; i < geometry.getNumGeometries(); i++) {
LineString child = (LineString) geometry.getGeometryN(i);
coordinates.add(lineStringCoordinates(child));
}
json.add("coordinates", coordinates);
} else if (geometryType.equals("Polygon")) {
JsonArray coordinates = polygonCoordinates((Polygon) geometry);
json.add("coordinates", coordinates);
} else if (geometryType.equals("MultiPolygon")) {
JsonArray coordinates = new JsonArray();
for (int i = 0; i < geometry.getNumGeometries(); i++) {
Polygon child = (Polygon) geometry.getGeometryN(i);
coordinates.add(polygonCoordinates(child));
}
json.add("coordinates", coordinates);
} else if (geometryType.equals("GeometryCollection")) {
JsonArray geometries = new JsonArray();
for (int i = 0; i < geometry.getNumGeometries(); i++) {
Geometry child = geometry.getGeometryN(i);
geometries.add(jsonSerializationContext.serialize(child));
}
json.add("geometries", geometries);
} else {
throw new IllegalArgumentException("Unknown geometry type " + geometry.getGeometryType());
}
return json;
}
JsonArray pointCoordinates(Point geometry) {
return toJson(geometry.getCoordinate());
}
JsonArray lineStringCoordinates(LineString geometry) {
return toJson(geometry.getCoordinates());
}
JsonArray polygonCoordinates(Polygon polygon) {
JsonArray result = new JsonArray();
result.add(toJson(polygon.getExteriorRing().getCoordinates()));
for (int i = 0; i < polygon.getNumInteriorRing(); i++) {
result.add(toJson(polygon.getInteriorRingN(i).getCoordinates()));
}
return result;
}
JsonArray toJson(Coordinate[] coordinates) {
JsonArray result = new JsonArray();
for (Coordinate coordinate : coordinates) {
result.add(toJson(coordinate));
}
return result;
}
JsonArray toJson(Coordinate coordinate) {
JsonArray result = new JsonArray();
result.add(new JsonPrimitive(coordinate.x));
result.add(new JsonPrimitive(coordinate.y));
if (!Double.isNaN(coordinate.z)) {
result.add(new JsonPrimitive(coordinate.z));
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment