Fix order of coordinates in BBOX
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 5 Oct 2023 07:03:55 +0000 (09:03 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 5 Oct 2023 07:03:55 +0000 (09:03 +0200)
js/src/geo/BboxVectorSource.js
js/src/geo/OpenLayersMapPart.js
js/src/geo/OpenLayersUtils.js [new file with mode: 0644]
org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java
org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java
org.argeo.app.geo/src/org/argeo/app/geo/ux/OpenLayersMapPart.java

index 49606b182e1f36ae27d768948e4801195c48b225..f0721ff001ac3412abc765f051dca1288544fe1f 100644 (file)
@@ -1,7 +1,7 @@
 
 import VectorSource from 'ol/source/Vector.js';
 import { bbox } from 'ol/loadingstrategy';
-import { transformExtent } from 'ol/proj.js';
+import { transformToLatLonExtent } from './OpenLayersUtils.js';
 
 export default class BboxVectorSource extends VectorSource {
        constructor(options) {
@@ -11,13 +11,15 @@ export default class BboxVectorSource extends VectorSource {
        static processOptions(options) {
                options.strategy = bbox;
                options.url = function(extent, resolution, projection) {
-                       const proj = projection.getCode();
-                       var bbox = transformExtent(extent, proj, 'EPSG:4326');
+                       var bbox = transformToLatLonExtent(extent, projection);
 
                        const baseUrl = options.baseUrl;
-                       const url = baseUrl + '&bbox=' + bbox.join(',');
+                       // invert bbox order in order to have minLat,minLon,maxLat,maxLon as required by WFS 2.0.0
+                       const url = baseUrl + '&bbox=' + bbox.join(',') + ',EPSG:4326';
                        return url;
                }
                return options;
        }
+
+
 }
\ No newline at end of file
index a1fc2b852f1e9a298f9bf07a2615664f31cc3f6d..293b6995c8f086b278bc0f8846da4c8c047ba5e2 100644 (file)
@@ -52,8 +52,8 @@ export default class OpenLayersMapPart extends MapPart {
                this.#map.getView().setZoom(zoom);
        }
 
-       setCenter(lng, lat) {
-               this.#map.getView().setCenter(fromLonLat([lng, lat]));
+       setCenter(lat, lon) {
+               this.#map.getView().setCenter(fromLonLat([lon, lat]));
        }
 
        addPoint(lng, lat, style) {
@@ -274,5 +274,4 @@ export default class OpenLayersMapPart extends MapPart {
                });
                vectorLayer.setStyle(olStyleFunction);
        }
-
 }
diff --git a/js/src/geo/OpenLayersUtils.js b/js/src/geo/OpenLayersUtils.js
new file mode 100644 (file)
index 0000000..d223463
--- /dev/null
@@ -0,0 +1,14 @@
+import { transformExtent } from 'ol/proj.js';
+
+
+export function transformToLatLonExtent(extent, projection) {
+       const proj = projection.getCode();
+       if (proj === 'EPSG:4326')
+               return toLatLonExtent(extent);
+       var transformed = transformExtent(extent, proj, 'EPSG:4326');
+       return toLatLonExtent(transformed);
+}
+
+export function toLatLonExtent(extent) {
+       return [extent[1], extent[0], extent[3], extent[2]];
+}
\ No newline at end of file
index 2c0bb39a76e29d641f7d9bf8939e69a4d216be1f..6f50c086796b30d2e7989c27607d2c1ce2670fa9 100644 (file)
@@ -69,6 +69,7 @@ import tech.units.indriya.quantity.Quantities;
 
 /** Utilities around geographical format, mostly wrapping GeoTools patterns. */
 public class GeoUtils {
+       public final static String EPSG_4326 = "EPSG:4326";
 
        /** In square meters. */
        public static Quantity<Area> calcArea(SimpleFeature feature) {
index 580866dec4c5c13577d7aa34f908b17ad8f0184c..5897d567095865c4ac87019b9c7a775ec4f8a1c7 100644 (file)
@@ -29,19 +29,16 @@ import org.argeo.app.api.WGS84PosName;
 import org.argeo.app.api.geo.FeatureAdapter;
 import org.argeo.app.geo.CqlUtils;
 import org.argeo.app.geo.GeoJson;
+import org.argeo.app.geo.GeoUtils;
 import org.argeo.app.geo.GpxUtils;
 import org.argeo.app.geo.JTS;
 import org.argeo.cms.acr.json.AcrJsonUtils;
 import org.argeo.cms.http.HttpHeader;
 import org.argeo.cms.http.server.HttpServerUtils;
 import org.argeo.cms.util.LangUtils;
-import org.geotools.data.DataUtilities;
-import org.geotools.data.geojson.GeoJSONWriter;
 import org.geotools.feature.DefaultFeatureCollection;
 import org.geotools.feature.NameImpl;
-import org.geotools.feature.SchemaException;
 import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.geometry.jts.JTSFactoryFinder;
 import org.geotools.referencing.CRS;
 import org.geotools.referencing.crs.DefaultGeographicCRS;
 import org.geotools.wfs.GML;
@@ -49,7 +46,6 @@ import org.geotools.wfs.GML.Version;
 import org.locationtech.jts.geom.Coordinate;
 import org.locationtech.jts.geom.Envelope;
 import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.GeometryFactory;
 import org.locationtech.jts.geom.Point;
 import org.locationtech.jts.geom.Polygon;
 import org.opengis.feature.GeometryAttribute;
@@ -112,10 +108,11 @@ public class WfsHttpHandler implements HttpHandler {
                                srs = null;
                        }
 
-                       if (srs != null) {
+                       if (srs != null && !srs.equals(GeoUtils.EPSG_4326)) {
                                try {
+                                       // TODO optimise
                                        CoordinateReferenceSystem sourceCRS = CRS.decode(srs);
-                                       CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
+                                       CoordinateReferenceSystem targetCRS = CRS.decode(GeoUtils.EPSG_4326);
                                        MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
                                        bbox = org.geotools.geometry.jts.JTS.transform(
                                                        new Envelope(new Coordinate(minLat, minLon), new Coordinate(maxLat, maxLon)), transform);
@@ -171,10 +168,20 @@ public class WfsHttpHandler implements HttpHandler {
                        }
 
                        if (bbox != null) {
-                               search.getWhere().gte(EntityName.minLat, bbox.getMinX());
-                               search.getWhere().gte(EntityName.minLon, bbox.getMinY());
-                               search.getWhere().lte(EntityName.maxLat, bbox.getMaxX());
-                               search.getWhere().lte(EntityName.maxLon, bbox.getMaxY());
+                               search.getWhere().any((or) -> {
+                                       or.all((and) -> {
+                                               and.gte(EntityName.minLat, bbox.getMinX());
+                                               and.gte(EntityName.minLon, bbox.getMinY());
+                                               and.lte(EntityName.maxLat, bbox.getMaxX());
+                                               and.lte(EntityName.maxLon, bbox.getMaxY());
+                                       });
+                                       or.all((and) -> {
+                                               and.gte(WGS84PosName.lat, bbox.getMinX());
+                                               and.gte(WGS84PosName.lon, bbox.getMinY());
+                                               and.lte(WGS84PosName.lat, bbox.getMaxX());
+                                               and.lte(WGS84PosName.lon, bbox.getMaxY());
+                                       });
+                               });
                        }
                });
 
@@ -337,78 +344,6 @@ public class WfsHttpHandler implements HttpHandler {
 
        }
 
-       protected void encodeCollectionAsGeoJSonOld(Stream<Content> features, OutputStream out) throws IOException {
-
-               // BODY PROCESSING
-               try (GeoJSONWriter geoJSONWriter = new GeoJSONWriter(out)) {
-                       geoJSONWriter.setPrettyPrinting(true);
-                       geoJSONWriter.setEncodeFeatureBounds(true);
-
-                       boolean gpx = true;
-                       SimpleFeatureType TYPE;
-                       try {
-                               if (gpx)
-                                       TYPE = DataUtilities.createType("Content",
-                                                       "the_geom:Polygon:srid=4326,path:String,type:String,name:String");
-                               else
-                                       TYPE = DataUtilities.createType("Content",
-                                                       "the_geom:Point:srid=4326,path:String,type:String,name:String");
-                       } catch (SchemaException e) {
-                               throw new RuntimeException(e);
-                       }
-                       SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
-                       GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
-
-                       features.forEach((c) -> {
-                               Geometry the_geom;
-                               if (gpx) {// experimental
-                                       Content area = c.getContent("gpx/area.gpx").orElse(null);
-                                       if (area == null)
-                                               return;
-                                       try (InputStream in = area.open(InputStream.class)) {
-                                               SimpleFeature feature = GpxUtils.parseGpxToPolygon(in);
-                                               the_geom = (Geometry) feature.getDefaultGeometry();
-                                       } catch (IOException e) {
-                                               throw new UncheckedIOException("Cannot parse " + c, e);
-                                       }
-                               } else {
-                                       if (!c.hasContentClass(EntityType.geopoint))
-                                               return;
-
-                                       double latitude = c.get(WGS84PosName.lat, Double.class).get();
-                                       double longitude = c.get(WGS84PosName.lon, Double.class).get();
-
-                                       Coordinate coordinate = new Coordinate(longitude, latitude);
-                                       the_geom = geometryFactory.createPoint(coordinate);
-
-                               }
-
-                               featureBuilder.add(the_geom);
-                               String pth = c.getPath();
-                               featureBuilder.add(pth);
-                               if (c.hasContentClass(EntityType.local)) {
-                                       String type = c.attr(EntityName.type);
-                                       featureBuilder.add(type);
-                               } else {
-                                       List<QName> contentClasses = c.getContentClasses();
-                                       if (!contentClasses.isEmpty()) {
-                                               featureBuilder.add(NamespaceUtils.toPrefixedName(contentClasses.get(0)));
-                                       }
-                               }
-                               featureBuilder.add(NamespaceUtils.toPrefixedName(c.getName()));
-
-                               String uuid = c.attr(LdapAttr.entryUUID);
-
-                               SimpleFeature feature = featureBuilder.buildFeature(uuid);
-                               try {
-                                       geoJSONWriter.write(feature);
-                               } catch (IOException e) {
-                                       throw new UncheckedIOException(e);
-                               }
-                       });
-               }
-       }
-
        protected void encodeCollectionAsGML(Stream<Content> features, OutputStream out) throws IOException {
                String entityType = "entity";
                URL schemaLocation = getClass().getResource("/org/argeo/app/api/entity.xsd");
index 6a9f3625b378587fe956cf4a1f10697d57bff6c9..e6edbf6e2861cb556fc1fb7cc9b35e3c13d19c06 100644 (file)
@@ -28,6 +28,10 @@ public class OpenLayersMapPart extends AbstractGeoJsObject {
                executeMethod(getMethodName(), JsClient.escapeQuotes(xml));
        }
 
+       public void setCenter(Double lat, Double lon) {
+               executeMethod(getMethodName(), lat, lon);
+       }
+
        public void applyStyle(String layerName, String styledLayerName) {
                executeMethod(getMethodName(), layerName, styledLayerName);
        }