1 package org
.argeo
.app
.geo
.acr
;
3 import java
.io
.IOException
;
4 import java
.io
.InputStream
;
5 import java
.io
.InputStreamReader
;
6 import java
.io
.OutputStream
;
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
;
14 import javax
.xml
.namespace
.QName
;
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
;
31 import jakarta
.json
.Json
;
32 import jakarta
.json
.JsonObject
;
33 import jakarta
.json
.JsonReader
;
34 import jakarta
.json
.stream
.JsonGenerator
;
36 /** Utilities around entity types related to geography. */
37 public class GeoEntityUtils
{
38 public static final String _GEOM_JSON
= ".geom.json";
40 public static void putGeometry(Content c
, QNamed name
, Geometry geometry
) {
41 putGeometry(c
, name
.qName(), geometry
);
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
);
51 GeoJson
.writeGeometry(g
, geometry
);
54 } catch (IOException e
) {
55 throw new UncheckedIOException("Cannot add geometry " + name
+ " to " + c
, e
);
58 // try (BufferedReader in = new BufferedReader(
59 // new InputStreamReader(geom.open(InputStream.class), StandardCharsets.UTF_8))) {
60 // System.out.println(in.readLine());
61 // } catch (IOException e) {
62 // throw new UncheckedIOException("Cannot parse " + c, e);
67 public static boolean hasGeometry(Content c
, QNamed name
) {
68 return hasGeometry(c
, name
.qName());
71 public static boolean hasGeometry(Content c
, QName name
) {
72 QName jsonFileName
= getJsonFileName(name
);
73 return c
.hasChild(jsonFileName
);
76 public static <T
extends Geometry
> T
getGeometry(Content c
, QNamed name
, Class
<T
> clss
) {
77 return getGeometry(c
, name
.qName(), clss
);
80 public static <T
extends Geometry
> T
getGeometry(Content c
, QName name
, Class
<T
> clss
) {
81 QName jsonFileName
= getJsonFileName(name
);
82 Content geom
= c
.soleChild(jsonFileName
).orElse(null);
85 try (Reader in
= new InputStreamReader(geom
.open(InputStream
.class), StandardCharsets
.UTF_8
)) {
86 JsonReader jsonReader
= Json
.createReader(in
);
87 JsonObject jsonObject
= jsonReader
.readObject();
88 T readGeom
= GeoJson
.readGeometry(jsonObject
, clss
);
90 } catch (IOException e
) {
91 throw new UncheckedIOException("Cannot parse " + c
, e
);
95 private static QName
getJsonFileName(QName name
) {
96 QName jsonFileName
= new ContentName(name
.getNamespaceURI(), name
.getLocalPart() + _GEOM_JSON
);
100 public static Point
toPoint(Content c
) {
101 if (c
.containsKey(WGS84PosName
.lon
) && c
.containsKey(WGS84PosName
.lat
)) {
102 Double lat
= c
.get(WGS84PosName
.lat
, Double
.class).orElseThrow();
103 Double lon
= c
.get(WGS84PosName
.lon
, Double
.class).orElseThrow();
104 return JTS
.GEOMETRY_FACTORY_WGS84
.createPoint(new Coordinate(lat
, lon
));
105 // Double alt = c.get(WGS84PosName.alt, Double.class).orElse(null);
106 // return JTS.GEOMETRY_FACTORY_WGS84
107 // .createPoint(alt != null ? new Coordinate(lat, lon, alt) : new Coordinate(lat, lon));
112 public static GeometryCollection
getGeometries(Content entity
) {
113 List
<Geometry
> geoms
= new ArrayList
<>();
114 Point geoPoint
= toPoint(entity
);
115 if (geoPoint
!= null)
118 Geometry place
= getGeometry(entity
, EntityName
.place
.qName(), Geometry
.class);
124 GeometryCollection geometryCollection
= JTS
.GEOMETRY_FACTORY_WGS84
125 .createGeometryCollection(geoms
.toArray(new Geometry
[geoms
.size()]));
126 return geometryCollection
;
129 public static void updateBoundingBox(Content entity
) {
130 GeometryCollection geometryCollection
= getGeometries(entity
);
131 if (geometryCollection
== null)
133 entity
.addContentClasses(EntityType
.geobounded
.qName());
135 Envelope bbox
= geometryCollection
.getEnvelopeInternal();
136 entity
.put(EntityName
.minLat
, bbox
.getMinX());
137 entity
.put(EntityName
.minLon
, bbox
.getMinY());
138 entity
.put(EntityName
.maxLat
, bbox
.getMaxX());
139 entity
.put(EntityName
.maxLon
, bbox
.getMaxY());
142 public static void updateBoundingBox(Content entity
, QName prop
) {
143 Geometry geom
= getGeometry(entity
, prop
, Geometry
.class);
146 entity
.addContentClasses(EntityType
.geobounded
.qName());
148 Envelope bbox
= geom
.getEnvelopeInternal();
149 entity
.put(EntityName
.minLat
, bbox
.getMinX());
150 entity
.put(EntityName
.minLon
, bbox
.getMinY());
151 entity
.put(EntityName
.maxLat
, bbox
.getMaxX());
152 entity
.put(EntityName
.maxLon
, bbox
.getMaxY());
156 private GeoEntityUtils() {