X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.app.geo%2Fsrc%2Forg%2Fargeo%2Fapp%2Fgeo%2FGeoJSon.java;h=5d5b99fdeb32efd6a29b84d665455e5170cc38e0;hb=8b7dc8398a17d09c5e20857b4e1e5f82ad28e769;hp=b590814ee2961113799111297ad60839691ac87f;hpb=8a490e540ac623b3545b1bd3da65ecbf2e4b6436;p=gpl%2Fargeo-suite.git diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/GeoJSon.java b/org.argeo.app.geo/src/org/argeo/app/geo/GeoJSon.java index b590814..5d5b99f 100644 --- a/org.argeo.app.geo/src/org/argeo/app/geo/GeoJSon.java +++ b/org.argeo.app.geo/src/org/argeo/app/geo/GeoJSon.java @@ -8,6 +8,8 @@ import org.locationtech.jts.geom.LinearRing; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; +import jakarta.json.JsonArray; +import jakarta.json.JsonObject; import jakarta.json.stream.JsonGenerator; /** @@ -16,31 +18,34 @@ import jakarta.json.stream.JsonGenerator; * @see https://datatracker.ietf.org/doc/html/rfc7946 */ public class GeoJSon { - public static void writeBBox(JsonGenerator generator, Geometry geometry) { - generator.writeStartArray("bbox"); - Envelope envelope = geometry.getEnvelopeInternal(); - generator.write(envelope.getMinX()); - generator.write(envelope.getMinY()); - generator.write(envelope.getMaxX()); - generator.write(envelope.getMaxY()); - generator.writeEnd(); - } + public final static String POINT_TYPE = "Point"; + public final static String LINE_STRING_TYPE = "LineString"; + public final static String POLYGON_TYPE = "Polygon"; + + public final static String TYPE = "type"; + public final static String GEOMETRY = "geometry"; + public final static String COORDINATES = "coordinates"; + public final static String BBOX = "bbox"; + public final static String PROPERTIES = "properties"; + /* + * WRITE + */ + /** Writes a {@link Geometry} as GeoJSON. */ public static void writeGeometry(JsonGenerator generator, Geometry geometry) { - generator.writeStartObject("geometry"); if (geometry instanceof Point point) { - generator.write("type", "Point"); - generator.writeStartArray("coordinates"); + generator.write(TYPE, POINT_TYPE); + generator.writeStartArray(COORDINATES); writeCoordinate(generator, point.getCoordinate()); generator.writeEnd();// coordinates array } else if (geometry instanceof LineString lineString) { - generator.write("type", "LineString"); - generator.writeStartArray("coordinates"); + generator.write(TYPE, LINE_STRING_TYPE); + generator.writeStartArray(COORDINATES); writeCoordinates(generator, lineString.getCoordinates()); generator.writeEnd();// coordinates array } else if (geometry instanceof Polygon polygon) { - generator.write("type", "Polygon"); - generator.writeStartArray("coordinates"); + generator.write(TYPE, POLYGON_TYPE); + generator.writeStartArray(COORDINATES); LinearRing exteriorRing = polygon.getExteriorRing(); generator.writeStartArray(); writeCoordinates(generator, exteriorRing.getCoordinates()); @@ -54,9 +59,9 @@ public class GeoJSon { } generator.writeEnd();// coordinates array } - generator.writeEnd();// geometry object } + /** Writes a sequence of coordinates [[lat,lon],[lat,lon]] */ public static void writeCoordinates(JsonGenerator generator, Coordinate[] coordinates) { for (Coordinate coordinate : coordinates) { generator.writeStartArray(); @@ -65,6 +70,7 @@ public class GeoJSon { } } + /** Writes a pair of coordinates [lat,lon]. */ public static void writeCoordinate(JsonGenerator generator, Coordinate coordinate) { generator.write(coordinate.getX()); generator.write(coordinate.getY()); @@ -74,6 +80,68 @@ public class GeoJSon { } } + /** + * Writes the {@link Envelope} of a {@link Geometry} as a bbox GeoJSON object. + */ + public static void writeBBox(JsonGenerator generator, Geometry geometry) { + generator.writeStartArray(BBOX); + Envelope envelope = geometry.getEnvelopeInternal(); + generator.write(envelope.getMinX()); + generator.write(envelope.getMinY()); + generator.write(envelope.getMaxX()); + generator.write(envelope.getMaxY()); + generator.writeEnd(); + } + + /* + * READ + */ + /** Reads a geometry from the geometry object of a GEoJSON feature. */ + @SuppressWarnings("unchecked") + public static T readGeometry(JsonObject geom, Class clss) { + String type = geom.getString(TYPE); + JsonArray coordinates = geom.getJsonArray(COORDINATES); + Geometry res = switch (type) { + case POINT_TYPE: { + Coordinate coord = readCoordinate(coordinates); + yield JTS.GEOMETRY_FACTORY_WGS84.createPoint(coord); + } + case LINE_STRING_TYPE: { + Coordinate[] coords = readCoordinates(coordinates); + yield JTS.GEOMETRY_FACTORY_WGS84.createLineString(coords); + } + case POLYGON_TYPE: { + assert coordinates.size() > 0; + LinearRing exterior = JTS.GEOMETRY_FACTORY_WGS84 + .createLinearRing(readCoordinates(coordinates.getJsonArray(0))); + LinearRing[] holes = new LinearRing[coordinates.size() - 1]; + for (int i = 0; i < coordinates.size() - 1; i++) { + holes[i] = JTS.GEOMETRY_FACTORY_WGS84 + .createLinearRing(readCoordinates(coordinates.getJsonArray(i + 1))); + } + yield JTS.GEOMETRY_FACTORY_WGS84.createPolygon(exterior, holes); + } + default: + throw new IllegalArgumentException("Unexpected value: " + type); + }; +// res.normalize(); + return (T)res; + } + + /** Reads a coordinate sequence [[lat,lon],[lat,lon]]. */ + public static Coordinate readCoordinate(JsonArray arr) { + assert arr.size() >= 2; + return new Coordinate(arr.getJsonNumber(0).doubleValue(), arr.getJsonNumber(1).doubleValue()); + } + + /** Reads a coordinate pair [lat,lon]. */ + public static Coordinate[] readCoordinates(JsonArray arr) { + Coordinate[] coords = new Coordinate[arr.size()]; + for (int i = 0; i < arr.size(); i++) + coords[i] = readCoordinate(arr.getJsonArray(i)); + return coords; + } + /** singleton */ private GeoJSon() { }