Created
June 24, 2011 07:19
-
-
Save eungju/1044372 to your computer and use it in GitHub Desktop.
GeoJSON Encoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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