]> git.argeo.org Git - gpl/argeo-suite.git/blob - acr/GeoEntityUtils.java
Prepare next development cycle
[gpl/argeo-suite.git] / 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.api.cms.CmsLog;
21 import org.argeo.app.api.EntityName;
22 import org.argeo.app.api.EntityType;
23 import org.argeo.app.api.WGS84PosName;
24 import org.argeo.app.geo.GeoJson;
25 import org.argeo.app.geo.JTS;
26 import org.locationtech.jts.geom.Coordinate;
27 import org.locationtech.jts.geom.Envelope;
28 import org.locationtech.jts.geom.Geometry;
29 import org.locationtech.jts.geom.GeometryCollection;
30 import org.locationtech.jts.geom.Point;
31
32 import jakarta.json.Json;
33 import jakarta.json.JsonObject;
34 import jakarta.json.JsonReader;
35 import jakarta.json.stream.JsonGenerator;
36 import jakarta.json.stream.JsonParsingException;
37
38 /** Utilities around entity types related to geography. */
39 public class GeoEntityUtils {
40 private final static CmsLog log = CmsLog.getLog(GeoEntityUtils.class);
41
42 public static final String _GEOM_JSON = ".geom.json";
43
44 public static void putGeometry(Content c, QNamed name, Geometry geometry) {
45 putGeometry(c, name.qName(), geometry);
46 }
47
48 public static void putGeometry(Content c, QName name, Geometry geometry) {
49 QName jsonFileName = getJsonFileName(name);
50 Content geom = c.soleChild(jsonFileName).orElseGet(
51 () -> c.add(jsonFileName, Collections.singletonMap(DName.getcontenttype.qName(), "application/json")));
52 try (OutputStream out = geom.open(OutputStream.class)) {
53 JsonGenerator g = Json.createGenerator(out);
54 g.writeStartObject();
55 GeoJson.writeGeometry(g, geometry);
56 g.writeEnd();
57 g.close();
58 } catch (IOException e) {
59 throw new UncheckedIOException("Cannot add geometry " + name + " to " + c, e);
60 }
61
62 // try (BufferedReader in = new BufferedReader(
63 // new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8))) {
64 // System.out.println(in.readLine());
65 // } catch (IOException e) {
66 // throw new UncheckedIOException("Cannot parse " + c, e);
67 // }
68 updateBoundingBox(c);
69 }
70
71 public static boolean hasGeometry(Content c, QNamed name) {
72 return hasGeometry(c, name.qName());
73 }
74
75 public static boolean hasGeometry(Content c, QName name) {
76 QName jsonFileName = getJsonFileName(name);
77 return c.hasChild(jsonFileName);
78 }
79
80 public static <T extends Geometry> T getGeometry(Content c, QNamed name, Class<T> clss) {
81 return getGeometry(c, name.qName(), clss);
82 }
83
84 public static <T extends Geometry> T getGeometry(Content c, QName name, Class<T> clss) {
85 QName jsonFileName = getJsonFileName(name);
86 Content geom = c.soleChild(jsonFileName).orElse(null);
87 if (geom == null)
88 return null;
89 // try (Reader in = new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8)) {
90 // String json = StreamUtils.toString(new BufferedReader(in));
91 // System.out.println("JSON:\n" + json);
92 // } catch (IOException e1) {
93 // // TODO Auto-generated catch block
94 // e1.printStackTrace();
95 // }
96 try (Reader in = new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8)) {
97 JsonReader jsonReader = Json.createReader(in);
98 JsonObject jsonObject = jsonReader.readObject();
99 T readGeom = GeoJson.readGeometry(jsonObject, clss);
100 return readGeom;
101 } catch (IOException e) {
102 throw new UncheckedIOException("Cannot parse " + c, e);
103 } catch (JsonParsingException e) {
104 if (log.isTraceEnabled())
105 log.warn("Invalid GeoJson for " + geom);
106 // json is invalid, returning null
107 return null;
108 }
109 }
110
111 private static QName getJsonFileName(QName name) {
112 QName jsonFileName = new ContentName(name.getNamespaceURI(), name.getLocalPart() + _GEOM_JSON);
113 return jsonFileName;
114 }
115
116 public static Point toPoint(Content c) {
117 if (c.containsKey(WGS84PosName.lon) && c.containsKey(WGS84PosName.lat)) {
118 Double lat = c.get(WGS84PosName.lat, Double.class).orElseThrow();
119 Double lon = c.get(WGS84PosName.lon, Double.class).orElseThrow();
120 return JTS.GEOMETRY_FACTORY_WGS84.createPoint(new Coordinate(lat, lon));
121 // Double alt = c.get(WGS84PosName.alt, Double.class).orElse(null);
122 // return JTS.GEOMETRY_FACTORY_WGS84
123 // .createPoint(alt != null ? new Coordinate(lat, lon, alt) : new Coordinate(lat, lon));
124 }
125 return null;
126 }
127
128 public static GeometryCollection getGeometries(Content entity) {
129 List<Geometry> geoms = new ArrayList<>();
130 Point geoPoint = toPoint(entity);
131 if (geoPoint != null)
132 geoms.add(geoPoint);
133
134 Geometry place = getGeometry(entity, EntityName.place.qName(), Geometry.class);
135 if (place != null)
136 geoms.add(place);
137
138 if (geoms.isEmpty())
139 return null;
140 GeometryCollection geometryCollection = JTS.GEOMETRY_FACTORY_WGS84
141 .createGeometryCollection(geoms.toArray(new Geometry[geoms.size()]));
142 return geometryCollection;
143 }
144
145 public static void updateBoundingBox(Content entity) {
146 GeometryCollection geometryCollection = getGeometries(entity);
147 if (geometryCollection == null)
148 return;
149 entity.addContentClasses(EntityType.geobounded.qName());
150
151 Envelope bbox = geometryCollection.getEnvelopeInternal();
152 entity.put(EntityName.minLat, bbox.getMinX());
153 entity.put(EntityName.minLon, bbox.getMinY());
154 entity.put(EntityName.maxLat, bbox.getMaxX());
155 entity.put(EntityName.maxLon, bbox.getMaxY());
156 }
157
158 public static void updateBoundingBox(Content entity, QName prop) {
159 Geometry geom = getGeometry(entity, prop, Geometry.class);
160 if (geom == null)
161 return;
162 entity.addContentClasses(EntityType.geobounded.qName());
163
164 Envelope bbox = geom.getEnvelopeInternal();
165 entity.put(EntityName.minLat, bbox.getMinX());
166 entity.put(EntityName.minLon, bbox.getMinY());
167 entity.put(EntityName.maxLat, bbox.getMaxX());
168 entity.put(EntityName.maxLon, bbox.getMaxY());
169 }
170
171 /** singleton */
172 private GeoEntityUtils() {
173 }
174
175 }