From: Mathieu Baudier Date: Mon, 11 Sep 2023 12:17:24 +0000 (+0200) Subject: Support geometry field in CSV X-Git-Tag: v2.3.16~35 X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=commitdiff_plain;h=10ada90446095744f4ed73798936de9d0ed415bd Support geometry field in CSV --- diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/GeoShapeUtils.java b/org.argeo.app.geo/src/org/argeo/app/geo/GeoShapeUtils.java new file mode 100644 index 0000000..1db099b --- /dev/null +++ b/org.argeo.app.geo/src/org/argeo/app/geo/GeoShapeUtils.java @@ -0,0 +1,51 @@ +package org.argeo.app.geo; + +import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +/** Utilities around ODK's GeoShape format */ +public class GeoShapeUtils { + + /** Converts a {@link Geometry} with WGS84 coordinates to a GeoShape. */ + public static String geometryToGeoShape(Geometry geometry) { + if (geometry instanceof Point point) { + Coordinate coordinate = point.getCoordinate(); + StringBuilder sb = new StringBuilder(); + appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ()); + return sb.toString(); + } else if (geometry instanceof Polygon || geometry instanceof LineString) { + StringBuilder sb = new StringBuilder(); + for (Coordinate coordinate : geometry.getCoordinates()) { + appendToGeoShape(sb, coordinate.getX(), coordinate.getY(), coordinate.getZ()); + sb.append(';'); + } + return sb.toString(); + } else { + throw new IllegalArgumentException("Unsupported geometry " + geometry.getClass()); + } + } + + public static String geoPointToGeoShape(double lon, double lat, double alt) { + StringBuilder sb = new StringBuilder(); + appendToGeoShape(sb, lon, lat, alt); + return sb.toString(); + } + + private static void appendToGeoShape(StringBuilder sb, double lon, double lat, double alt) { + sb.append(lat).append(' '); + sb.append(lon).append(' '); + if (alt != Double.NaN) + sb.append(alt).append(' '); + else + sb.append("0 "); + sb.append('0'); + } + + /** singleton */ + private GeoShapeUtils() { + } + +} diff --git a/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkManifestServlet.java b/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkManifestServlet.java index 6e145c2..6cc71d6 100644 --- a/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkManifestServlet.java +++ b/org.argeo.app.servlet.odk/src/org/argeo/app/servlet/odk/OdkManifestServlet.java @@ -30,6 +30,9 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.output.NullOutputStream; import org.argeo.app.api.EntityMimeType; +import org.argeo.app.api.EntityType; +import org.argeo.app.api.WGS84PosName; +import org.argeo.app.geo.GeoShapeUtils; import org.argeo.app.odk.OrxManifestName; import org.argeo.cms.auth.RemoteAuthUtils; import org.argeo.cms.servlet.ServletHttpRequest; @@ -142,6 +145,7 @@ public class OdkManifestServlet extends HttpServlet { } // TODO make it more configurable columnNames.add("display"); + columnNames.add("geometry"); if (EntityMimeType.XML.equals(mimeType)) { } else if (EntityMimeType.CSV.equals(mimeType)) { @@ -158,6 +162,16 @@ public class OdkManifestServlet extends HttpServlet { } // display lst.add(row.getValue("name").getString() + " (" + row.getValue("label").getString() + ")"); + Node field = row.getNode("geopoint"); + if (field != null && field.isNodeType(EntityType.geopoint.get())) { + double lat = field.getProperty(WGS84PosName.lat.get()).getDouble(); + double lon = field.getProperty(WGS84PosName.lng.get()).getDouble(); + double alt = field.hasProperty(WGS84PosName.alt.get()) + ? field.getProperty(WGS84PosName.alt.get()).getDouble() + : Double.NaN; + String geoshape = GeoShapeUtils.geoPointToGeoShape(lon, lat, alt); + lst.add(geoshape); + } csvWriter.writeLine(lst); } } else {