1 package org
.argeo
.app
.geo
;
3 import java
.util
.ArrayList
;
5 import java
.util
.Objects
;
6 import java
.util
.StringTokenizer
;
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
;
16 /** Utilities around ODK's GeoShape format */
17 public class GeoShapeUtils
{
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();
32 if (!alt
.equals("0.0")) {
33 coord
= new Coordinate(Double
.parseDouble(lat
), Double
.parseDouble(lng
), Double
.parseDouble(alt
));
35 coord
= new Coordinate(Double
.parseDouble(lat
), Double
.parseDouble(lng
));
37 coordinates
.add(coord
);
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
);
54 Polygon polygon
= geometryFactory
.createPolygon(coordinates
.toArray(new Coordinate
[coordinates
.size()]));
57 throw new IllegalArgumentException("Unsupported format " + clss
);
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());
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());
76 throw new IllegalArgumentException("Unsupported geometry " + geometry
.getClass());
80 public static String
geoPointToGeoShape(double lon
, double lat
, double alt
) {
81 StringBuilder sb
= new StringBuilder();
82 appendToGeoShape(sb
, lon
, lat
, alt
);
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(' ');
97 private GeoShapeUtils() {