Fix lat/lon vs. lon/lat issues
authorMathieu Baudier <mbaudier@argeo.org>
Thu, 26 Oct 2023 06:44:33 +0000 (08:44 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Thu, 26 Oct 2023 06:44:33 +0000 (08:44 +0200)
js/src/geo/BboxVectorSource.js
js/src/geo/OpenLayersMapPart.js
js/src/geo/OpenLayersUtils.js
org.argeo.app.geo/src/org/argeo/app/api/geo/FeatureAdapter.java
org.argeo.app.geo/src/org/argeo/app/geo/GeoJson.java
org.argeo.app.geo/src/org/argeo/app/geo/GpxUtils.java
org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java

index f0721ff001ac3412abc765f051dca1288544fe1f..e1051b08394418a7b684b9fb36e349e1ab353ac2 100644 (file)
@@ -1,7 +1,7 @@
 
 import VectorSource from 'ol/source/Vector.js';
 import { bbox } from 'ol/loadingstrategy';
-import { transformToLatLonExtent } from './OpenLayersUtils.js';
+import { transformToEpsg4326LatLonExtent } from './OpenLayersUtils.js';
 
 export default class BboxVectorSource extends VectorSource {
        constructor(options) {
@@ -11,7 +11,7 @@ export default class BboxVectorSource extends VectorSource {
        static processOptions(options) {
                options.strategy = bbox;
                options.url = function(extent, resolution, projection) {
-                       var bbox = transformToLatLonExtent(extent, projection);
+                       var bbox = transformToEpsg4326LatLonExtent(extent, projection);
 
                        const baseUrl = options.baseUrl;
                        // invert bbox order in order to have minLat,minLon,maxLat,maxLon as required by WFS 2.0.0
index a31bc214c0b521bfb68219b47051ab4bc80c5c75..d033e303df5583b96850d2f714b116bde8c2857e 100644 (file)
@@ -3,7 +3,6 @@
  */
 
 import { fromLonLat, getPointResolution } from 'ol/proj.js';
-import { transformExtent } from 'ol/proj.js';
 
 import TileLayer from 'ol/layer/Tile.js';
 
@@ -21,6 +20,7 @@ import { easeOut } from 'ol/easing';
 import * as SLDReader from '@nieuwlandgeo/sldreader';
 
 import MapPart from './MapPart.js';
+import { transformToOlLonLatExtent } from './OpenLayersUtils.js';
 
 /** OpenLayers implementation of MapPart. */
 export default class OpenLayersMapPart extends MapPart {
@@ -81,7 +81,7 @@ export default class OpenLayersMapPart extends MapPart {
        }
 
        fit(extent, options) {
-               var transformed = transformExtent(extent, 'EPSG:4326', this.#map.getView().getProjection());
+               var transformed = transformToOlLonLatExtent(extent, this.#map.getView().getProjection());
                this.#map.getView().fit(transformed, options);
        }
 
index d223463133f2925d74a91cccdeb4b8e0bd9e7595..b85ad7d3ab46d290433c92c2cbaccfd5c000d0ba 100644 (file)
@@ -1,7 +1,7 @@
 import { transformExtent } from 'ol/proj.js';
 
 
-export function transformToLatLonExtent(extent, projection) {
+export function transformToEpsg4326LatLonExtent(extent, projection) {
        const proj = projection.getCode();
        if (proj === 'EPSG:4326')
                return toLatLonExtent(extent);
@@ -9,6 +9,23 @@ export function transformToLatLonExtent(extent, projection) {
        return toLatLonExtent(transformed);
 }
 
+/** From EPSG:4326 lat/lon to a proj lon/lat */
+export function transformToOlLonLatExtent(extent, projection) {
+       const proj = projection.getCode();
+       if (proj === 'EPSG:4326')
+               return toLonLatExtent(extent);
+       const reordered = toLonLatExtent(extent);
+       var transformed = transformExtent(reordered, 'EPSG:4326', proj);
+       return transformed;
+}
+
+/** Converts from an extent in OpenLayers order (lon/lat) to WFS 2.0 order (lat/lon). */
 export function toLatLonExtent(extent) {
        return [extent[1], extent[0], extent[3], extent[2]];
-}
\ No newline at end of file
+}
+
+/** Converts from an extent in WFS 2.0 order (lat/lon) to OpenLayers order (lon/lat) . */
+export function toLonLatExtent(extent) {
+       return [extent[1], extent[0], extent[3], extent[2]];
+}
+
index 03ca1ce4bd8fd5a0b670e410fd962453a7172270..69689a95b07f1e54ca015184534b5112e43f0293 100644 (file)
@@ -5,11 +5,8 @@ import javax.xml.namespace.QName;
 import org.argeo.api.acr.Content;
 import org.argeo.api.acr.search.AndFilter;
 import org.argeo.app.api.EntityType;
-import org.argeo.app.api.WGS84PosName;
-import org.argeo.app.geo.JTS;
-import org.locationtech.jts.geom.Coordinate;
+import org.argeo.app.geo.acr.GeoEntityUtils;
 import org.locationtech.jts.geom.Geometry;
-import org.locationtech.jts.geom.Point;
 
 import jakarta.json.stream.JsonGenerator;
 
@@ -29,12 +26,13 @@ public interface FeatureAdapter {
 
        static Geometry getGeoPointGeometry(Content c) {
                if (c.hasContentClass(EntityType.geopoint)) {
-                       double latitude = c.get(WGS84PosName.lat, Double.class).get();
-                       double longitude = c.get(WGS84PosName.lon, Double.class).get();
-
-                       Coordinate coordinate = new Coordinate(longitude, latitude);
-                       Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
-                       return the_geom;
+                       return GeoEntityUtils.toPoint(c);
+//                     double latitude = c.get(WGS84PosName.lat, Double.class).get();
+//                     double longitude = c.get(WGS84PosName.lon, Double.class).get();
+//
+//                     Coordinate coordinate = new Coordinate(longitude, latitude);
+//                     Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
+//                     return the_geom;
                }
                return null;
        }
index c1ba1d393b71627ce70632e50253344da273d779..8c4c7b23259054d4d784451ad4533ac68aa35d99 100644 (file)
@@ -93,8 +93,9 @@ public class GeoJson {
 
        /** Writes a pair of coordinates [lat,lon]. */
        public static void writeCoordinate(JsonGenerator g, Coordinate coordinate) {
-               g.write(coordinate.getX());
+               // !! longitude is first in GeoJSON
                g.write(coordinate.getY());
+               g.write(coordinate.getX());
                double z = coordinate.getZ();
                if (!Double.isNaN(z)) {
                        g.write(z);
@@ -149,13 +150,14 @@ public class GeoJson {
                return (T) res;
        }
 
-       /** Reads a coordinate sequence [[lat,lon],[lat,lon]]. */
+       /** Reads a coordinate pair [lon,lat]. */
        public static Coordinate readCoordinate(JsonArray arr) {
                assert arr.size() >= 2;
-               return new Coordinate(arr.getJsonNumber(0).doubleValue(), arr.getJsonNumber(1).doubleValue());
+               // !! longitude is first in GeoJSon
+               return new Coordinate(arr.getJsonNumber(1).doubleValue(), arr.getJsonNumber(0).doubleValue());
        }
 
-       /** Reads a coordinate pair [lat,lon]. */
+       /** Reads a coordinate sequence [[lon,lat],[lon,lat]]. */
        public static Coordinate[] readCoordinates(JsonArray arr) {
                Coordinate[] coords = new Coordinate[arr.size()];
                for (int i = 0; i < arr.size(); i++)
index dcd205ab39ab33d5f990f860db245e5407b55631..44afa2c01f0a9341700aa644a4324ef207407d8b 100644 (file)
@@ -68,7 +68,7 @@ public class GpxUtils {
                                                Double latitude = Double.parseDouble(attributes.getValue("lat"));
                                                Double longitude = Double.parseDouble(attributes.getValue("lon"));
                                                // TODO elevation in 3D context
-                                               Coordinate coordinate = new Coordinate(longitude, latitude);
+                                               Coordinate coordinate = new Coordinate(latitude, longitude);
                                                coordinates.add(coordinate);
                                        }
                                }
@@ -107,7 +107,7 @@ public class GpxUtils {
                        throw new IllegalArgumentException("Unsupported format " + clss);
                }
        }
-       
+
        /** @deprecated Use {@link #parseGpxTrackTo(InputStream, Class)} instead. */
        @Deprecated
        public static SimpleFeature parseGpxToPolygon(InputStream in) throws IOException {
index 94c3c01220711e154f998c89a084e96daacf3c27..8c143dbf01510d7eb10a56b588ec50b82ac819ea 100644 (file)
@@ -34,6 +34,7 @@ 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.app.geo.acr.GeoEntityUtils;
 import org.argeo.cms.acr.json.AcrJsonUtils;
 import org.argeo.cms.auth.RemoteAuthUtils;
 import org.argeo.cms.http.HttpHeader;
@@ -59,7 +60,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.Point;
 import org.locationtech.jts.geom.Polygon;
 
 import com.sun.net.httpserver.HttpExchange;
@@ -361,12 +361,7 @@ public class WfsHttpHandler implements HttpHandler {
 
        protected Geometry getDefaultGeometry(Content content) {
                if (content.hasContentClass(EntityType.geopoint)) {
-                       double latitude = content.get(WGS84PosName.lat, Double.class).get();
-                       double longitude = content.get(WGS84PosName.lon, Double.class).get();
-
-                       Coordinate coordinate = new Coordinate(longitude, latitude);
-                       Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
-                       return the_geom;
+                       return GeoEntityUtils.toPoint(content);
                }
                return null;
        }