2121import static de .fraunhofer .iosb .ilt .frostserver .util .ParserUtils .idFromObject ;
2222
2323import com .fasterxml .jackson .core .JsonProcessingException ;
24+ import com .fasterxml .jackson .databind .JsonNode ;
2425import com .fasterxml .jackson .databind .ObjectMapper ;
25- import de .fraunhofer .iosb .ilt .frostserver .json .deserialize .custom .GeoJsonDeserializier ;
2626import de .fraunhofer .iosb .ilt .frostserver .json .serialize .GeoJsonSerializer ;
2727import de .fraunhofer .iosb .ilt .frostserver .model .DefaultEntity ;
2828import de .fraunhofer .iosb .ilt .frostserver .model .EntityType ;
@@ -120,6 +120,7 @@ public void insertUserDefinedId(JooqPersistenceManager pm, Map<Field, Object> cl
120120 *
121121 * @param pm the persistenceManager
122122 * @param e The Entity to check.
123+ * @param updateMode The update mode to use.
123124 * @throws NoSuchEntityException If the entity has an id, but does not
124125 * exist.
125126 * @throws IncompleteEntityException If the entity has no id, but is not
@@ -216,105 +217,72 @@ public static void insertTimeInterval(Map<Field, Object> clause, Field<Moment> s
216217 }
217218
218219 /**
219- * Sets both the geometry and location in the clause.
220+ * Sets both the geometry and location in the clause. The geometry will be
221+ * flattened to 2D.
220222 *
221223 * @param clause The insert or update clause to add to.
222224 * @param locationPath The path to the location column.
223225 * @param geomPath The path to the geometry column.
224226 * @param encodingType The encoding type.
225227 * @param location The location.
226228 */
227- public static void insertGeometry (Map <Field , Object > clause , Field <String > locationPath , Field <? extends Object > geomPath , String encodingType , final Object location ) {
228- if (encodingType == null && location instanceof GeoJsonObject ) {
229- encodingType = GeoJsonDeserializier .APPLICATION_GEOJSON ;
230- }
231- if (encodingType != null && GeoJsonDeserializier .ENCODINGS .contains (encodingType .toLowerCase ())) {
232- insertGeometryKnownEncoding (location , clause , geomPath , locationPath );
229+ public static void insertGeometry (Map <Field , Object > clause , Field <String > locationPath , Field <? extends Object > geomPath , String encodingType , Object location ) {
230+ if (location instanceof JsonNode jn ) {
231+ insertGeometry (clause , locationPath , geomPath , encodingType , jn , true );
233232 } else {
234- String json ;
235- json = objectToJson (location );
236- clause .put (geomPath , NULL_FIELD );
237- if (locationPath != null ) {
238- clause .put (locationPath , json );
239- }
233+ throw new IllegalArgumentException ("Unknown location object type" );
240234 }
241235 }
242236
243- public static void insertGeometryNoTransform (Map <Field , Object > clause , Field <String > locationPath , Field <? extends Object > geomPath , String encodingType , final Object location ) {
244- if (encodingType == null && location instanceof GeoJsonObject ) {
245- encodingType = GeoJsonDeserializier .APPLICATION_GEOJSON ;
246- }
247- if (encodingType != null && GeoJsonDeserializier .ENCODINGS .contains (encodingType .toLowerCase ())) {
248- insertGeometryKnownEncodingNoTransform (location , clause , geomPath , locationPath );
237+ /**
238+ * Sets both the geometry and location in the clause.
239+ *
240+ * @param clause The insert or update clause to add to.
241+ * @param locationPath The path to the location column.
242+ * @param geomPath The path to the geometry column.
243+ * @param encodingType The encoding type.
244+ * @param location The location.
245+ * @param flatten If the GEOM column should be transformed and flattened.
246+ */
247+ public static void insertGeometry (Map <Field , Object > clause , Field <String > locationPath , Field <? extends Object > geomPath , String encodingType , Object location , boolean flatten ) {
248+ if (location instanceof JsonNode jn ) {
249+ insertGeometry (clause , locationPath , geomPath , encodingType , jn , flatten );
249250 } else {
250- String json ;
251- json = objectToJson (location );
252- clause .put (geomPath , NULL_FIELD );
253- if (locationPath != null ) {
254- clause .put (locationPath , json );
255- }
251+ throw new IllegalArgumentException ("Unknown location object type" );
256252 }
257253 }
258254
259- private static void insertGeometryKnownEncoding (final Object location , Map <Field , Object > clause , Field <? extends Object > geomPath , Field <String > locationPath ) {
260- String locJson ;
261- try {
262- locJson = new GeoJsonSerializer ().serialize (location );
263- } catch (JsonProcessingException ex ) {
264- LOGGER .error ("Failed to store." , ex );
265- throw new IllegalArgumentException ("encoding specifies geoJson, but location not parsable as such." );
266- }
255+ /**
256+ * Sets both the geometry and location in the clause.
257+ *
258+ * @param clause The insert or update clause to add to.
259+ * @param locationPath The path to the location column.
260+ * @param geomPath The path to the geometry column.
261+ * @param encodingType The encoding type.
262+ * @param location The location.
263+ * @param flatten If the GEOM column should be transformed and flattened.
264+ */
265+ public static void insertGeometry (Map <Field , Object > clause , Field <String > locationPath , Field <? extends Object > geomPath , String encodingType , JsonNode location , boolean flatten ) {
266+ Object locationParsed = Utils .locationFromEncoding (encodingType , location );
267267
268- // Postgres does not support Feature.
269- Object geoLocation = location ;
270- if (location instanceof Feature ) {
271- geoLocation = ((Feature ) location ).getGeometry ();
272- }
273- // Ensure the geoJson has a crs, otherwise Postgres complains.
274- if (geoLocation instanceof GeoJsonObject ) {
275- GeoJsonObject geoJsonObject = (GeoJsonObject ) geoLocation ;
276- Crs crs = geoJsonObject .getCrs ();
277- if (crs == null ) {
278- crs = new Crs ();
279- crs .setType (CrsType .name );
280- crs .getProperties ().put ("name" , "EPSG:4326" );
281- geoJsonObject .setCrs (crs );
282- }
283- }
284- String geoJson ;
285- try {
286- geoJson = new GeoJsonSerializer ().serialize (geoLocation );
287- } catch (JsonProcessingException ex ) {
288- LOGGER .error ("Failed to store." , ex );
289- throw new IllegalArgumentException ("encoding specifies geoJson, but location not parsable as such." );
268+ if (locationParsed instanceof GeoJsonObject locationGeoJson ) {
269+ insertGeoJson (clause , geomPath , locationPath , location , locationGeoJson , flatten );
270+ return ;
290271 }
291272
292- try {
293- // geojson.jackson allows invalid polygons, geolatte catches those.
294- Utils .getGeoJsonMapper ().fromJson (geoJson , Geometry .class );
295- } catch (JsonException ex ) {
296- throw new IllegalArgumentException ("Invalid geoJson: " + ex .getMessage ());
297- }
298- final String template = "ST_Force2D(ST_Transform(ST_GeomFromGeoJSON({0}), 4326))" ;
299- clause .put (geomPath , DSL .field (template , Object .class , geoJson ));
273+ String json ;
274+ json = objectToJson (location );
275+ clause .put (geomPath , NULL_FIELD );
300276 if (locationPath != null ) {
301- clause .put (locationPath , locJson );
277+ clause .put (locationPath , json );
302278 }
303279 }
304280
305- private static void insertGeometryKnownEncodingNoTransform (final Object location , Map <Field , Object > clause , Field <? extends Object > geomPath , Field <String > locationPath ) {
306- String locJson ;
307- try {
308- locJson = new GeoJsonSerializer ().serialize (location );
309- } catch (JsonProcessingException ex ) {
310- LOGGER .error ("Failed to store." , ex );
311- throw new IllegalArgumentException ("encoding specifies geoJson, but location not parsable as such." );
312- }
313-
281+ private static void insertGeoJson (Map <Field , Object > clause , Field <? extends Object > geomPath , Field <String > locationPath , JsonNode locationSource , GeoJsonObject locationParsed , boolean flatten ) {
314282 // Postgres does not support Feature.
315- Object geoLocation = location ;
316- if (location instanceof Feature ) {
317- geoLocation = (( Feature ) location ) .getGeometry ();
283+ Object geoLocation = locationParsed ;
284+ if (locationParsed instanceof Feature feature ) {
285+ geoLocation = feature .getGeometry ();
318286 }
319287 // Ensure the geoJson has a crs, otherwise Postgres complains.
320288 if (geoLocation instanceof GeoJsonObject ) {
@@ -327,6 +295,7 @@ private static void insertGeometryKnownEncodingNoTransform(final Object location
327295 geoJsonObject .setCrs (crs );
328296 }
329297 }
298+
330299 String geoJson ;
331300 try {
332301 geoJson = new GeoJsonSerializer ().serialize (geoLocation );
@@ -341,18 +310,19 @@ private static void insertGeometryKnownEncodingNoTransform(final Object location
341310 } catch (JsonException ex ) {
342311 throw new IllegalArgumentException ("Invalid geoJson: " + ex .getMessage ());
343312 }
344- final String template = "ST_GeomFromGeoJSON({0})" ;
313+
314+ final String template ;
315+ if (flatten ) {
316+ template = "ST_Force2D(ST_Transform(ST_GeomFromGeoJSON({0}), 4326))" ;
317+ } else {
318+ template = "ST_GeomFromGeoJSON({0})" ;
319+ }
345320 clause .put (geomPath , DSL .field (template , Object .class , geoJson ));
346321 if (locationPath != null ) {
347- clause .put (locationPath , locJson );
322+ clause .put (locationPath , objectToJson ( locationSource ) );
348323 }
349324 }
350325
351- public static Object reParseGeometry (String encodingType , Object object ) {
352- String json = objectToJson (object );
353- return Utils .locationFromEncoding (encodingType , json );
354- }
355-
356326 public static String objectToJson (JsonValue jsonValue ) {
357327 return objectToJson (jsonValue .getValue ());
358328 }
0 commit comments