2

I am trying to work with the French IGN geoportal which provides a WFS source of data.

I have worked out how to use OpenLayers' Vector source with

const ignPkUrl = (extent: Extent, projection: string = 'EPSG:3857') => {
  return `https://wxs.ign.fr/topographie/geoportail/wfs?version=2.0.0&service=WFS&request=GetFeature&typename=BDTOPO_V3:point_de_repere&outputformat=application/json&srsname=${projection}&bbox=${extent.join(',')},${projection}`;
};
const ignPKWFSSource = new VectorSource({
  format: new GeoJSON(),
  url: e => ignPkUrl(e),
  strategy: bbox,
});

but the BBox strategy returns too much features that I don't need.

I tried to figure out how to use the filter parameter (which is incompatible with the bbox parameter) and came up with the following XML filter:

<?xml version="1.0"?>
<Filter xmlns="http://www.opengis.net/ogc">
  <And>
    <And>
      <PropertyIsLike wildCard="*" escape="\" singleChar=".">
        <PropertyName>route</PropertyName>
        <Literal>A*</Literal>
      </PropertyIsLike>
      <PropertyIsLike wildCard="*" escape="\" singleChar=".">
        <PropertyName>cote</PropertyName>
        <Literal>D</Literal>
      </PropertyIsLike>
    </And>
    <BBOX xmlns:gml="http://www.opengis.net/gml">
      <PropertyName>geometrie</PropertyName>
      <gml:Box srsName="EPSG:3857">
        <gml:coordinates>432026.55,5401138.14,436574.55,5405657.47</gml:coordinates>
      </gml:Box>
    </BBOX>
  </And>
</Filter>

what this is supposed to do is get the features that have A* in their route and D in their cote and within the given BBox.

With this, the request is sent without error but no matter where I set my BBox, I get a grand total of 0 features.

Is there any other way to use a filter and a Bbox with a WFS source or should I try something different?

Note: The PropertyName is correct despite not being the usual the_geom


Edit:

Taking into account what nmtoken said about the server only working with EPSG:4326, my query is now like the following: https://wxs.ign.fr/topographie/geoportail/wfs?version=2.0.0&service=WFS&request=GetFeature&typename=BDTOPO_V3:point_de_repere&outputformat=application/json&srsname=EPSG:4326&filter=(...)

with the filter XML being

<?xml version="1.0"?>
<Filter xmlns="http://www.opengis.net/ogc">
  <And>
    <BBOX xmlns:gml="http://www.opengis.net/gml"> 
      <PropertyName>geometrie</PropertyName>
      <gml:Box srsName="EPSG:4326"> 
        <gml:coordinates>
3.692779541015625,43.542637937898604,4.056701660156251,43.68519110738575
        </gml:coordinates>
      </gml:Box>
    </BBOX>
    <PropertyIsLike wildCard="*" singleChar="." escape="\"> 
      <PropertyName>route</PropertyName>
      <Literal>A*</Literal>
    </PropertyIsLike>
    <PropertyIsLike wildCard="*" singleChar="." escape="\"> 
      <PropertyName>cote</PropertyName>
      <Literal>D</Literal>
    </PropertyIsLike>
  </And>
</Filter>

Still no features in sight...


Edit #2: Since gml:Envelope, gml:lowerCorner, gml:upperCorner and gml:boundBy aren't recognized by the server, I tried to use the following (within the "ogc" root namespace):

<BBOX xmlns:gml="http://www.opengis.net/gml">
  <PropertyName>geometrie</PropertyName>
  <Literal>3.69 43.54 4.056 43.68</Literal>
</BBOX>

and the server stopped screaming at me, which is good.

The bbox still seems to have no effect.

12
  • try changing your escape char to something that isn't \ or use two \\
    – Ian Turton
    May 15, 2023 at 9:52
  • The <PropertyIsLike> are working as intended, it's the <BBOX> that causes problem.
    – Askirkela
    May 15, 2023 at 10:00
  • 1
    I am not sure how lenient the IGN server might be, but WFS 2.0 is based on GML 3.x and "Box + Coordinates" belong to GML 2 schemas.liquid-technologies.com/OpenGis/gml/3.0.1/…. I would still try Envelope with lowerCorner and upperCorner.
    – user30184
    May 15, 2023 at 10:45
  • I'll try that, thanks for the input.
    – Askirkela
    May 15, 2023 at 11:56
  • Ok, I tried but the server responds with org.xml.sax.SAXException: Attempted to construct illegal filter - I dont understand the tag: gml:Envelope... while gml:Envelope is listed in the GetCapabilites of the server
    – Askirkela
    May 15, 2023 at 12:27

1 Answer 1

1

I managed to make it work with CQL filter. When using CQL filter, BBOX has to be specified as a part of filter, not as a request parameter. To be on the safe side, I used EPSG:4326 for WFS request.

Relevant part of the code could then look something like this:

function url(extent, resolution, projection, success, failure) {
  var reprojExtent = ol.proj.transformExtent(extent, projection, 'EPSG:4326');
  var cqlFilter = "cql_filter=route LIKE 'A%' AND cote = 'D'";
  cqlFilter += ' AND BBOX(geometrie,' + reprojExtent.join(',') + ",'EPSG:4326'" + ')';
  cqlFilter = encodeURI(cqlFilter);
  return 'https://wxs.ign.fr/topographie/geoportail/wfs?version=2.0.0&service=WFS&request=GetFeature&' + 
         'typename=BDTOPO_V3:point_de_repere&outputformat=application/json&' + 
         'srsname=EPSG:4326&' + cqlFilter;
}

var vectorSource = new ol.source.Vector({
  format: new ol.format.GeoJSON({featureProjection: 'EPSG:3857', dataProjection: 'EPSG:4326'}),
  url: url,
  strategy: ol.loadingstrategy.bbox
});

This is how the result looks like then for a part of the map:

enter image description here

1
  • Thanks, that works like a charm (and cleaner than wonky XML). Still have to figure out what to do when the bbox is large enough to hit the feature limit, it does not seem to reload features when the bbox changes to a smaller area that already has been processed. But many thanks.
    – Askirkela
    May 17, 2023 at 7:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.