From: Mathieu Baudier Date: Thu, 5 Oct 2023 07:03:55 +0000 (+0200) Subject: Fix order of coordinates in BBOX X-Git-Tag: v2.3.16~10 X-Git-Url: http://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=commitdiff_plain;h=efda92d76cd7ccce3925763bf95f68d7927ac5c7 Fix order of coordinates in BBOX --- diff --git a/js/src/geo/BboxVectorSource.js b/js/src/geo/BboxVectorSource.js index 49606b1..f0721ff 100644 --- a/js/src/geo/BboxVectorSource.js +++ b/js/src/geo/BboxVectorSource.js @@ -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 diff --git a/js/src/geo/OpenLayersMapPart.js b/js/src/geo/OpenLayersMapPart.js index a1fc2b8..293b699 100644 --- a/js/src/geo/OpenLayersMapPart.js +++ b/js/src/geo/OpenLayersMapPart.js @@ -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 index 0000000..d223463 --- /dev/null +++ b/js/src/geo/OpenLayersUtils.js @@ -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 diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java b/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java index 2c0bb39..6f50c08 100644 --- a/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java +++ b/org.argeo.app.geo/src/org/argeo/app/geo/GeoUtils.java @@ -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 calcArea(SimpleFeature feature) { diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java b/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java index 580866d..5897d56 100644 --- a/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java +++ b/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java @@ -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 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 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 features, OutputStream out) throws IOException { String entityType = "entity"; URL schemaLocation = getClass().getResource("/org/argeo/app/api/entity.xsd"); diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/ux/OpenLayersMapPart.java b/org.argeo.app.geo/src/org/argeo/app/geo/ux/OpenLayersMapPart.java index 6a9f362..e6edbf6 100644 --- a/org.argeo.app.geo/src/org/argeo/app/geo/ux/OpenLayersMapPart.java +++ b/org.argeo.app.geo/src/org/argeo/app/geo/ux/OpenLayersMapPart.java @@ -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); }