0

I'm writing a web app that uses WFS data on top of OpenLayers with OpenStreetMap. The entire project works in EPSG:2180 projection and uses multiple versions of WFS (depending on server). OL doesn't draw polygons on the map when srsName="http://www.opengis.net/gml/srs/epsg.xml#2180" instead of srsName="EPSG:2180".

I tried adding EquivalentProjections as in documentation and it even returns true on check. However, still, no geometries are drawn.

Code:

import proj4 from 'proj4';
import * as ol_proj4 from 'ol/proj/proj4.js';
import * as olProj from 'ol/proj';

[...]

proj4.defs("EPSG:2180","+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs +axis=neu");
ol_proj4.register(proj4);

var epsg_nazwa_xml = new olProj.Projection ({
  code: 'http://www.opengis.net/gml/srs/epsg.xml#2180',
  units: 'm',
  axisOrientation: 'neu',
  global: false,
  metersPerUnit: 1,
}) 
olProj.addProjection(epsg_nazwa_xml);

olProj.addEquivalentProjections([epsg_nazwa_xml, olProj.get('EPSG:2180')]);

console.log(olProj.equivalent(olProj.get('EPSG:2180'), olProj.get('http://www.opengis.net/gml/srs/epsg.xml#2180')))

[...]

/**
 * MAPA init
 */
var map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      source: new OSM(),
      projection: 'EPSG:2180'
    })
  ],
  view: new View({
    projection: 'EPSG:2180',
    center: miejsce,
    zoom: 14,
  })
});

[...]

WFSvectorSource = new VectorSource({
        format: new WFS({
          version: '1.1.0',
        }),
        url: function(extent) {
            return compURL+"&bbox="+extent.join(',')+",EPSG:2180";
        },
        strategy: bbox
      });
WFSvectorLayer = new VectorLayer({
      source: WFSvectorSource,
      projection: 'EPSG:2180',

      style: new Style({
          stroke: new Stroke({
              color: '#000000',
              width: 1
          }),
          fill: new Fill({
              color: 'rgba(255, 255, 255, 0.01)'
          })
      }),
    });
map.addLayer(WFSvectorLayer);

Example of working WFS link: https://corsproxy.io/?https://trzebnicki-wms.webewid.pl/iip/ows?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki&bbox=357783.463892855,391038.4860643449,358805.47125767067,391700.3901630342

and not working WFS link: https://corsproxy.io/?https://geoportal.powiat.klodzko.pl/ggp?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki&bbox=332468.6208316547,272386.1313619815,333179.64381146623,272819.1873043835

The only difference being in only in srsName in <gml:Polygon srsName="EPSG:2180"> vs <gml:Polygon srsDimension="2" srsName="http://www.opengis.net/gml/srs/epsg.xml#2180">

5
  • The trzebnicki-wms.webewid.pl service GetCapabilities suggests you should be using the urn:ogc:def:crs:EPSG::2180 form to reference the SRS, vs the geoportal.powiat.klodzko.pl servers EPSG:2180 form.
    – nmtoken
    Commented Jun 1, 2023 at 12:42
  • I tried your suggestion and it doesn't make a difference. I still think that it is the matter of making 'EPSG:2180' and 'opengis.net/gml/srs/epsg.xml#2180' equal to the XMLparser, but I don't know how to make it work Commented Jun 1, 2023 at 12:53
  • Your geoportal.powiat.klodzko.pl/ggp? example request doesn't return any data for me, but a request without that bounding box does with EPSG:2180, (geoportal.powiat.klodzko.pl/…). Both servers return the expected ` text/xml; subtype=gml/3.1.1` output format. So it looks like a BBOX issue
    – nmtoken
    Commented Jun 1, 2023 at 13:22
  • GML will work but the assumption that EPSG:2180 and http://www.opengis.net/gml/srs/epsg.xml#2180 are equivalent is not correct. Only EPSG:2180 uses axis order neu, so they must be defined as separate projections codesandbox.io/s/vector-wfs-forked-qpk1dr?file=/main.js
    – Mike
    Commented Jun 2, 2023 at 14:06
  • It worked! Thank you very much Mike, this is what I was looking for. Cheers! Commented Jun 3, 2023 at 7:07

2 Answers 2

1

The issue is with the BBOX. The BBOX should include the crsuri unless the coordinates are specified in WGS 84 decimal degrees (according to the WFS 1.1.0 specification).

So the request should be:

https://corsproxy.io/?https://geoportal.powiat.klodzko.pl/ggp?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki&bbox=332468.6208316547,272386.1313619815,333179.64381146623,272819.1873043835,EPSG:2180

So the working WFS example using MapServer software is non-compliant to the standard (or lax) whereas the non-working example is conforming to the standard and not returning data.

1

I played with a little with outputFormat and managed to show both layers with EPSG:2180 projection. Since there is a huge number of features, I limited returned number with the maxFeatures parameter.

For the first URL https://corsproxy.io/?https://trzebnicki-wms.webewid.pl/iip/ows?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki I left default output format, which is GML 3.1.1.

This is the complete code:

proj4.defs("EPSG:2180","+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs +axis=neu");
ol.proj.proj4.register(proj4);

function url(extent, resolution, projection, success, failure) {
  var url = 'https://corsproxy.io/?https://trzebnicki-wms.webewid.pl/iip/ows?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki' 
            + '&maxFeatures=5000&bbox=' + extent.join(',') + ',EPSG:2180';
  return url;
}

var vectorSource = new ol.source.Vector({
  format: new ol.format.GML(),
  url: url,
  strategy: ol.loadingstrategy.bbox
});


var vector = new ol.layer.Vector({
  source: vectorSource,
});

var raster = new ol.layer.Tile({
  source: new ol.source.OSM()
});

var map = new ol.Map({
  layers: [raster, vector],
  target: document.getElementById('map'),
  view: new ol.View({
    projection: 'EPSG:2180',
    center: ol.proj.fromLonLat([17.059, 51.36], 'EPSG:2180'),
    maxZoom: 19,
    zoom: 11
  })
});

And this is the result of the above code:

enter image description here

For the second URL https://corsproxy.io/?https://geoportal.powiat.klodzko.pl/ggp?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki I couldn't make it work with GML output format, so I took simpler GeoJSON.

This is the complete code:

proj4.defs("EPSG:2180","+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs +axis=neu");
ol.proj.proj4.register(proj4);

function url(extent, resolution, projection, success, failure) {
  var url = 'https://corsproxy.io/?https://geoportal.powiat.klodzko.pl/ggp?service=WFS&request=GetFeature&version=1.1.0&srsname=EPSG:2180&typename=dzialki' 
            + '&maxFeatures=1000&outputFormat=json&bbox=' + extent.join(',') + ',EPSG:2180';
  return url;
}

var vectorSource = new ol.source.Vector({
  format: new ol.format.GeoJSON({dataFormat: 'EPSG:2180', featureFormat: 'EPSG:2180'}),
  url: url,
  strategy: ol.loadingstrategy.bbox
});


var vector = new ol.layer.Vector({
  source: vectorSource,
});

var raster = new ol.layer.Tile({
  source: new ol.source.OSM()
});

var map = new ol.Map({
  layers: [raster, vector],
  target: document.getElementById('map'),
  view: new ol.View({
    projection: 'EPSG:2180',
    center: ol.proj.fromLonLat([16.649, 50.6], 'EPSG:2180'),
    maxZoom: 19,
    zoom: 13
  })
});

And this is the result of the above code:

enter image description here

1
  • Thank you for your answer. I am using over 300 different WFS servers in this project and GML3 is the only format that all of them support. Your way works, but I have to use gml. Is there a way to do it? I think GML3 doesnt render because geoportal.powiat.klodzko.pl returns srsName="opengis.net/gml/srs/epsg.xml#2180" instead of srsName="EPSG:2180" . Is it possible to make it work? Thanks Commented Jun 2, 2023 at 10:03

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