X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.app.geo%2Fsrc%2Forg%2Fargeo%2Fapp%2Fgeo%2Fhttp%2FWfsHttpHandler.java;h=580866dec4c5c13577d7aa34f908b17ad8f0184c;hb=b384a9cbe93b83b3aa94fe46cf2ff0a929f0332c;hp=84b9893082f3f324c9e2952fd8afaf82ef81cdcd;hpb=b96d17f3eb275a97109cc160db1cfd3731a01d31;p=gpl%2Fargeo-suite.git 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 84b9893..580866d 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 @@ -42,10 +42,12 @@ 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; 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; @@ -55,6 +57,10 @@ import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.Name; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.crs.CoordinateReferenceSystem; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; @@ -71,6 +77,7 @@ public class WfsHttpHandler implements HttpHandler { final static String OUTPUT_FORMAT = "outputFormat"; final static String TYPE_NAMES = "typeNames"; final static String CQL_FILTER = "cql_filter"; + final static String BBOX = "bbox"; private final Map featureAdapters = new HashMap<>(); @@ -80,6 +87,7 @@ public class WfsHttpHandler implements HttpHandler { ContentSession session = HttpServerUtils.getContentSession(contentRepository, exchange); // Content content = session.get(path); + // PARAMETERS Map> parameters = HttpServerUtils.parseParameters(exchange); String cql = getKvpParameter(parameters, CQL_FILTER); String typeNamesStr = getKvpParameter(parameters, TYPE_NAMES); @@ -87,6 +95,40 @@ public class WfsHttpHandler implements HttpHandler { if (outputFormat == null) { outputFormat = "application/json"; } + String bboxStr = getKvpParameter(parameters, BBOX); + log.debug(bboxStr); + final Envelope bbox; + if (bboxStr != null) { + String srs; + String[] arr = bboxStr.split(","); + // TODO check SRS and convert to WGS84 + double minLat = Double.parseDouble(arr[0]); + double minLon = Double.parseDouble(arr[1]); + double maxLat = Double.parseDouble(arr[2]); + double maxLon = Double.parseDouble(arr[3]); + if (arr.length == 5) { + srs = arr[4]; + } else { + srs = null; + } + + if (srs != null) { + try { + CoordinateReferenceSystem sourceCRS = CRS.decode(srs); + CoordinateReferenceSystem targetCRS = CRS.decode("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); + } catch (FactoryException | TransformException e) { + throw new IllegalArgumentException("Cannot convert bounding box", e); + // bbox = null; + } + } else { + bbox = new Envelope(new Coordinate(minLat, minLon), new Coordinate(maxLat, maxLon)); + } + } else { + bbox = null; + } switch (outputFormat) { case "application/json" -> { @@ -113,13 +155,13 @@ public class WfsHttpHandler implements HttpHandler { if (typeNames.size() > 1) throw new UnsupportedOperationException("Only one type name is currently supported"); + // QUERY Stream res = session.search((search) -> { if (cql != null) { CqlUtils.filter(search.from(path), cql); } else { search.from(path); } -// search.getWhere().any((f) -> { for (QName typeName : typeNames) { FeatureAdapter featureAdapter = featureAdapters.get(typeName); if (featureAdapter == null) @@ -127,7 +169,13 @@ public class WfsHttpHandler implements HttpHandler { // f.isContentClass(typeName); featureAdapter.addConstraintsForFeature((AndFilter) search.getWhere(), typeName); } -// }); + + 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()); + } }); exchange.sendResponseHeaders(200, 0); @@ -192,20 +240,48 @@ public class WfsHttpHandler implements HttpHandler { featureAdapter = featureAdapters.get(typeName); } - Geometry defaultGeometry = featureAdapter != null ? featureAdapter.getDefaultGeometry(c, typeName) - : getDefaultGeometry(c); - if (defaultGeometry == null) - return; - generator.writeStartObject(); - generator.write("type", "Feature"); - String featureId = getFeatureId(c); - if (featureId != null) - generator.write("id", featureId); -// GeoJson.writeBBox(generator, defaultGeometry); - generator.writeStartObject(GeoJson.GEOMETRY); - GeoJson.writeGeometry(generator, defaultGeometry); - generator.writeEnd();// geometry object + boolean geometryWritten = false; +// if (typeName.getLocalPart().equals("fieldSimpleFeature")) { +// Content area = c.getContent("place.geom.json").orElse(null); +// if (area != null) { +// generator.writeStartObject(); +// generator.write("type", "Feature"); +// String featureId = getFeatureId(c); +// if (featureId != null) +// generator.write("id", featureId); +// +// generator.flush(); +// try (InputStream in = area.open(InputStream.class)) { +// out.write(",\"geometry\":".getBytes()); +// StreamUtils.copy(in, out); +// //out.flush(); +// } catch (Exception e) { +// log.error(c.getPath() + " : " + e.getMessage()); +// } finally { +// } +// geometryWritten = true; +// }else { +// return; +// } +// } + if (!geometryWritten) { + + Geometry defaultGeometry = featureAdapter != null ? featureAdapter.getDefaultGeometry(c, typeName) + : getDefaultGeometry(c); + if (defaultGeometry == null) + return; + generator.writeStartObject(); + generator.write("type", "Feature"); + String featureId = getFeatureId(c); + if (featureId != null) + generator.write("id", featureId); + + GeoJson.writeBBox(generator, defaultGeometry); + generator.writeStartObject(GeoJson.GEOMETRY); + GeoJson.writeGeometry(generator, defaultGeometry); + generator.writeEnd();// geometry object + } generator.writeStartObject(GeoJson.PROPERTIES); AcrJsonUtils.writeTimeProperties(generator, c); if (featureAdapter != null)