]> git.argeo.org Git - gpl/argeo-suite.git/blob - geo/GeoShapeUtils.java
Prepare next development cycle
[gpl/argeo-suite.git] / geo / GeoShapeUtils.java
1 package org.argeo.app.geo;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Objects;
6 import java.util.StringTokenizer;
7
8 import org.locationtech.jts.geom.Coordinate;
9 import org.locationtech.jts.geom.Geometry;
10 import org.locationtech.jts.geom.GeometryFactory;
11 import org.locationtech.jts.geom.LineString;
12 import org.locationtech.jts.geom.MultiPoint;
13 import org.locationtech.jts.geom.Point;
14 import org.locationtech.jts.geom.Polygon;
15
16 /** Utilities around ODK's GeoShape format */
17 public class GeoShapeUtils {
18
19 @SuppressWarnings("unchecked")
20 public static <T> T geoShapeToGeometry(String geoShape, Class<T> clss) {
21 Objects.requireNonNull(geoShape);
22 GeometryFactory geometryFactory = JTS.GEOMETRY_FACTORY_WGS84;
23 List<Coordinate> coordinates = new ArrayList<>();
24 StringTokenizer stSeg = new StringTokenizer(geoShape.trim(), ";");
25 while (stSeg.hasMoreTokens()) {
26 StringTokenizer stPt = new StringTokenizer(stSeg.nextToken().trim(), " ");
27 String lat = stPt.nextToken();
28 String lng = stPt.nextToken();
29 String alt = stPt.nextToken();
30 // String precision = stPt.nextToken();
31 Coordinate coord;
32 if (!alt.equals("0.0")) {
33 coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng), Double.parseDouble(alt));
34 } else {
35 coord = new Coordinate(Double.parseDouble(lat), Double.parseDouble(lng));
36 }
37 coordinates.add(coord);
38 }
39 if (LineString.class.isAssignableFrom(clss)) {
40 LineString lineString = geometryFactory
41 .createLineString(coordinates.toArray(new Coordinate[coordinates.size()]));
42 return (T) lineString;
43 } else if (MultiPoint.class.isAssignableFrom(clss)) {
44 MultiPoint multiPoint = geometryFactory
45 .createMultiPointFromCoords(coordinates.toArray(new Coordinate[coordinates.size()]));
46 return (T) multiPoint;
47 } else if (Polygon.class.isAssignableFrom(clss)) {
48 Coordinate first = coordinates.get(0);
49 Coordinate last = coordinates.get(coordinates.size() - 1);
50 if (!(first.getX() == last.getX() && first.getY() == last.getY())) {
51 // close the line string
52 coordinates.add(first);
53 }
54 Polygon polygon = geometryFactory.createPolygon(coordinates.toArray(new Coordinate[coordinates.size()]));
55 return (T) polygon;
56 } else {
57 throw new IllegalArgumentException("Unsupported format " + clss);
58 }
59 }
60
61 /** Converts a {@link Geometry} with WGS84 coordinates to a GeoShape. */
62 public static String geometryToGeoShape(Geometry geometry) {
63 if (geometry instanceof Point point) {
64 Coordinate coordinate = point.getCoordinate();
65 StringBuilder sb = new StringBuilder();
66 appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ());
67 return sb.toString();
68 } else if (geometry instanceof Polygon || geometry instanceof LineString) {
69 StringBuilder sb = new StringBuilder();
70 for (Coordinate coordinate : geometry.getCoordinates()) {
71 appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ());
72 sb.append(';');
73 }
74 return sb.toString();
75 } else {
76 throw new IllegalArgumentException("Unsupported geometry " + geometry.getClass());
77 }
78 }
79
80 public static String geoPointToGeoShape(double lon, double lat, double alt) {
81 StringBuilder sb = new StringBuilder();
82 appendToGeoShape(sb, lon, lat, alt);
83 return sb.toString();
84 }
85
86 private static void appendToGeoShape(StringBuilder sb, double lon, double lat, double alt) {
87 sb.append(lat).append(' ');
88 sb.append(lon).append(' ');
89 if (alt != Double.NaN)
90 sb.append(alt).append(' ');
91 else
92 sb.append("0 ");
93 sb.append('0');
94 }
95
96 /** singleton */
97 private GeoShapeUtils() {
98 }
99
100 }