]> git.argeo.org Git - gpl/argeo-suite.git/blob - geo/acr/GeoEntityUtils.java
Prepare next development cycle
[gpl/argeo-suite.git] / geo / acr / GeoEntityUtils.java
1 package org.argeo.app.geo.acr;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
6 import java.io.OutputStream;
7 import java.io.Reader;
8 import java.io.UncheckedIOException;
9 import java.nio.charset.StandardCharsets;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
13
14 import javax.xml.namespace.QName;
15
16 import org.argeo.api.acr.Content;
17 import org.argeo.api.acr.ContentName;
18 import org.argeo.api.acr.DName;
19 import org.argeo.api.acr.QNamed;
20 import org.argeo.app.api.EntityName;
21 import org.argeo.app.api.EntityType;
22 import org.argeo.app.api.WGS84PosName;
23 import org.argeo.app.geo.GeoJson;
24 import org.argeo.app.geo.JTS;
25 import org.locationtech.jts.geom.Coordinate;
26 import org.locationtech.jts.geom.Envelope;
27 import org.locationtech.jts.geom.Geometry;
28 import org.locationtech.jts.geom.GeometryCollection;
29 import org.locationtech.jts.geom.Point;
30
31 import jakarta.json.Json;
32 import jakarta.json.JsonObject;
33 import jakarta.json.JsonReader;
34 import jakarta.json.stream.JsonGenerator;
35
36 /** Utilities around entity types related to geography. */
37 public class GeoEntityUtils {
38 public static final String _GEOM_JSON = ".geom.json";
39
40 public static void putGeometry(Content c, QNamed name, Geometry geometry) {
41 putGeometry(c, name.qName(), geometry);
42 }
43
44 public static void putGeometry(Content c, QName name, Geometry geometry) {
45 QName jsonFileName = getJsonFileName(name);
46 Content geom = c.soleChild(jsonFileName).orElseGet(
47 () -> c.add(jsonFileName, Collections.singletonMap(DName.getcontenttype.qName(), "application/json")));
48 try (OutputStream out = geom.open(OutputStream.class)) {
49 JsonGenerator g = Json.createGenerator(out);
50 g.writeStartObject();
51 GeoJson.writeGeometry(g, geometry);
52 g.writeEnd();
53 g.close();
54 } catch (IOException e) {
55 throw new UncheckedIOException("Cannot add geometry " + name + " to " + c, e);
56 }
57 updateBoundingBox(c);
58 }
59
60 public static boolean hasGeometry(Content c, QNamed name) {
61 return hasGeometry(c, name.qName());
62 }
63
64 public static boolean hasGeometry(Content c, QName name) {
65 QName jsonFileName = getJsonFileName(name);
66 return c.hasChild(jsonFileName);
67 }
68
69 public static <T extends Geometry> T getGeometry(Content c, QNamed name, Class<T> clss) {
70 return getGeometry(c, name.qName(), clss);
71 }
72
73 public static <T extends Geometry> T getGeometry(Content c, QName name, Class<T> clss) {
74 QName jsonFileName = getJsonFileName(name);
75 Content geom = c.soleChild(jsonFileName).orElse(null);
76 if (geom == null)
77 return null;
78 try (Reader in = new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8)) {
79 JsonReader jsonReader = Json.createReader(in);
80 JsonObject jsonObject = jsonReader.readObject();
81 T readGeom = GeoJson.readGeometry(jsonObject, clss);
82 return readGeom;
83 } catch (IOException e) {
84 throw new UncheckedIOException("Cannot parse " + c, e);
85 }
86 }
87
88 private static QName getJsonFileName(QName name) {
89 QName jsonFileName = new ContentName(name.getNamespaceURI(), name.getLocalPart() + _GEOM_JSON);
90 return jsonFileName;
91 }
92
93 public static Point toPoint(Content c) {
94 if (c.hasContentClass(EntityType.geopoint)) {
95 Double lat = c.get(WGS84PosName.lat, Double.class).orElseThrow();
96 Double lon = c.get(WGS84PosName.lon, Double.class).orElseThrow();
97 return JTS.GEOMETRY_FACTORY_WGS84.createPoint(new Coordinate(lat, lon));
98 // Double alt = c.get(WGS84PosName.alt, Double.class).orElse(null);
99 // return JTS.GEOMETRY_FACTORY_WGS84
100 // .createPoint(alt != null ? new Coordinate(lat, lon, alt) : new Coordinate(lat, lon));
101 }
102 return null;
103 }
104
105 public static GeometryCollection getGeometries(Content entity) {
106 List<Geometry> geoms = new ArrayList<>();
107 Point geoPoint = toPoint(entity);
108 if (geoPoint != null)
109 geoms.add(geoPoint);
110
111 Geometry place = getGeometry(entity, EntityName.place.qName(), Geometry.class);
112 if (place != null)
113 geoms.add(place);
114
115 if (geoms.isEmpty())
116 return null;
117 GeometryCollection geometryCollection = JTS.GEOMETRY_FACTORY_WGS84
118 .createGeometryCollection(geoms.toArray(new Geometry[geoms.size()]));
119 return geometryCollection;
120 }
121
122 public static void updateBoundingBox(Content entity) {
123 GeometryCollection geometryCollection = getGeometries(entity);
124 if (geometryCollection == null)
125 return;
126 entity.addContentClasses(EntityType.geobounded.qName());
127
128 Envelope bbox = geometryCollection.getEnvelopeInternal();
129 entity.put(EntityName.minLat, bbox.getMinX());
130 entity.put(EntityName.minLon, bbox.getMinY());
131 entity.put(EntityName.maxLat, bbox.getMaxX());
132 entity.put(EntityName.maxLon, bbox.getMaxY());
133 }
134
135 public static void updateBoundingBox(Content entity, QName prop) {
136 Geometry geom = getGeometry(entity, prop, Geometry.class);
137 if (geom == null)
138 return;
139 entity.addContentClasses(EntityType.geobounded.qName());
140
141 Envelope bbox = geom.getEnvelopeInternal();
142 entity.put(EntityName.minLat, bbox.getMinX());
143 entity.put(EntityName.minLon, bbox.getMinY());
144 entity.put(EntityName.maxLat, bbox.getMaxX());
145 entity.put(EntityName.maxLon, bbox.getMaxY());
146 }
147
148 /** singleton */
149 private GeoEntityUtils() {
150 }
151
152 }