GeoShape to Geometry
[gpl/argeo-suite.git] / org.argeo.app.geo / src / org / argeo / app / geo / GeoShapeUtils.java
index 1db099bb8a4a03d56eee96e011fed968e4c8d7b1..d35492ad68d881b673b37e6a28b872f97003d440 100644 (file)
@@ -1,14 +1,63 @@
 package org.argeo.app.geo;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.StringTokenizer;
+
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.LineString;
+import org.locationtech.jts.geom.MultiPoint;
 import org.locationtech.jts.geom.Point;
 import org.locationtech.jts.geom.Polygon;
 
 /** Utilities around ODK's GeoShape format */
 public class GeoShapeUtils {
 
+       @SuppressWarnings("unchecked")
+       public static <T> T geoShapeToGeometry(String geoShape, Class<T> clss) {
+               Objects.requireNonNull(geoShape);
+               GeometryFactory geometryFactory = JTS.GEOMETRY_FACTORY_WGS84;
+               List<Coordinate> coordinates = new ArrayList<>();
+               StringTokenizer stSeg = new StringTokenizer(geoShape.trim(), ";");
+               while (stSeg.hasMoreTokens()) {
+                       StringTokenizer stPt = new StringTokenizer(stSeg.nextToken().trim(), " ");
+                       String lat = stPt.nextToken();
+                       String lng = stPt.nextToken();
+                       String alt = stPt.nextToken();
+                       // String precision = stPt.nextToken();
+                       Coordinate coord;
+                       if (!alt.equals("0.0")) {
+                               coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(alt));
+                       } else {
+                               coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng));
+                       }
+                       coordinates.add(coord);
+               }
+               if (LineString.class.isAssignableFrom(clss)) {
+                       LineString lineString = geometryFactory
+                                       .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
+                       return (T) lineString;
+               } else if (MultiPoint.class.isAssignableFrom(clss)) {
+                       MultiPoint multiPoint = geometryFactory
+                                       .createMultiPointFromCoords(coordinates.toArray(new Coordinate[coordinates.size()]));
+                       return (T) multiPoint;
+               } else if (Polygon.class.isAssignableFrom(clss)) {
+                       Coordinate first = coordinates.get(0);
+                       Coordinate last = coordinates.get(coordinates.size() - 1);
+                       if (!(first.getX() == last.getX() && first.getY() == last.getY())) {
+                               // close the line string
+                               coordinates.add(first);
+                       }
+                       Polygon polygon = geometryFactory.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
+                       return (T) polygon;
+               } else {
+                       throw new IllegalArgumentException("Unsupported format " + clss);
+               }
+       }
+
        /** Converts a {@link Geometry} with WGS84 coordinates to a GeoShape. */
        public static String geometryToGeoShape(Geometry geometry) {
                if (geometry instanceof Point point) {