TransWikia.com

Show GML on map (using an example GML file)

Geographic Information Systems Asked by tm1701 on January 5, 2021

How can I show features (from an example file)? I tried many, many ways. This is a different route using a standard GML example file from OpenLayers.

Problem : With the shown code example, I don’t see any features. There are no error messages.

In an Angular / typescript environment I tried also:

  let polygonStyle = new Style({
  fill: new Fill({
    color: "rgba(255, 0, 0, 0.8)"
  }),
  stroke: new Stroke({
    color: "#ffcc33",
    width: 10
  })
});
let vectorSource = new VectorSource({
  format: new WFS({gmlFormat: new GML3() }),
  url: 'http://osgis.terragis.net/openlayers/examples/gml/polygon.xml',
});
this.vectorLayer = new Vector({
  source: vectorSource,
  style: [polygonStyle]
});

this.map = new Map({
  layers: [
    new TileLayer({
      source: new XYZ({
        url: "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png"
      })
    }),
    this.vectorLayer
  ],
  view: new View({
    center: transform([0.532597, 47.428810], 'EPSG:4326', 'EPSG:3857'),
    zoom: 12
  }),
  target: "map"
});

2 Answers

The first problem with the above code is that GML example is in WFS 1.0.0 format, which means you have to use OL GML2 format (for GML3 it has to be 1.1.0).

But then comes the next problem: displayed features have flipped coordinates. I couldn't find solution for that within OL (probably could use rotate by 90 degrees), so I used turf.js library and turf.flip function to flip feature coordinates.

Not very elegant, but it works. Here is the code:

var map = new ol.Map({
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    })
  ],
  target: 'map',
  view: new ol.View({
    center: [0, 0],
    zoom: 2
  })
});

function featureLoader(extent, resolution, projection) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'http://osgis.terragis.net/openlayers/examples/gml/polygon.xml');
  var onError = function() {
    console.log('error');
  }
  xhr.onerror = onError;
  xhr.onload = function() {
    if (xhr.status == 200) {
      var wfsFormat = new ol.format.WFS({
        gmlFormat: new ol.format.GML2()
      });
      var features = wfsFormat.readFeatures(xhr.response, {
        featureProjection: 'EPSG:4326',
        dataProjection: 'EPSG:4326'
      });
      var geoJSON = new ol.format.GeoJSON().writeFeaturesObject(features);
      var flippedGeoJSON = turf.flip(geoJSON);
      var flippedFeatures = new ol.format.GeoJSON().readFeatures(flippedGeoJSON, {
        featureProjection: 'EPSG:3857',
        dataProjection: 'EPSG:4326'
      });
      vectorSource.addFeatures(flippedFeatures);
      map.getView().fit(vectorSource.getExtent());
      }
    else {
      onError();
    }
  }
  xhr.send();
}

var vectorSource = new ol.source.Vector({
  format: new ol.format.WFS(),
  loader: featureLoader
});

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

Correct answer by TomazicM on January 5, 2021

A more direct way of dealing with flipped EPSG:4326 coordinates would be to define a flipped projection and coordinate transforms to EPSG:3857

  ol.proj.addProjection(new ol.proj.Projection({code: 'EPSG:4326YX'}));
  ol.proj.addCoordinateTransforms(
    'EPSG:4326YX',
    'EPSG:3857',
    function(yx) {
      var xy = [yx[1], [yx[0]];
      return ol.proj.transform(xy, 'EPSG:4326', 'EPSG:3857');
    },
    function(coordinate) {
      var xy = ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326')
      return [xy[1], [xy[0]];
    }
  );

Then you should be able to read and transform the features directly

  var features = wfsFormat.readFeatures(xhr.response, {
    featureProjection: 'EPSG:4326YX',
    dataProjection: 'EPSG:3857'
  });
  vectorSource.addFeatures(features);

Answered by Mike on January 5, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP