Let's see the first test case. In this map, the US has taken on a journey to discover some terra incognita.
The map was produced with this simple code:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://demo.opengeo.org/geoserver/wms',
params: {
layers: 'bluemarble',
format: 'image/png'
}
})
}),
new ol.layer.Vector({
source: new ol.source.Vector({
loader: function (extent, res, proj) {
var source = this;
var wfsParser = new ol.format.WFS();
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
source.addFeatures(wfsParser.readFeatures(request.responseText));
}
};
request.open('GET', 'http://demo.opengeo.org/geoserver/wfs?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=topp:states&VERSION=1.1.0&SRSNAME=' + proj.getCode() + '&BBOX=' + extent.join(','));
request.send();
}
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 2,
projection: 'EPSG:4326'
})
});
So what is the problem with the request? We should use WFS 2.0.0 instead? No luck there. WFS 1.0.0? No luck, either (which is quite disturbing, as it has a reverse coordinate order in the specification). I couldn't find out the reason behind this capricious behaviour of GeoServer. If you know the answer, don't hesitate to leave a comment.Now, let's see the good news. With a little JavaScript magic, we can quite easily swap the coordinates in the parsed features.
Now the US is safe and sound again, in the bounds of the Earth. How can you achieve the same effect? With the following modified code:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://demo.opengeo.org/geoserver/wms',
params: {
layers: 'bluemarble',
format: 'image/png'
}
})
}),
new ol.layer.Vector({
source: new ol.source.Vector({
loader: function (extent, res, proj) {
var source = this;
var wfsParser = new ol.format.WFS();
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
var features = wfsParser.readFeatures(request.responseText);
for (var i=0;i<features.length;i++) {
features[i].getGeometry().applyTransform(function (coords, coords2, stride) {
for (var j=0;j<coords.length;j+=stride) {
var y = coords[j];
var x = coords[j+1];
coords[j] = x;
coords[j+1] = y;
}
});
}
source.addFeatures(features);
}
};
request.open('GET', 'http://demo.opengeo.org/geoserver/wfs?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=topp:states&VERSION=1.1.0&SRSNAME=' + proj.getCode() + '&BBOX=' + extent.join(','));
request.send();
}
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 2,
projection: 'EPSG:4326'
})
});
The applyTransform method to the rescue
This method is listed in the API, however it lacks the required documentation. If you look at the source code, fortunately, you can see how it works. It gives out the internal coordinate array of a feature, which is a simple array. We can modify it in place with the function given to the method as an argument. The method gives three arguments to our function. The first two are the same coordinate array (don't ask why), while the third is called the stride. It is a numerical representation of the layout used in the feature:
- XY - 2
- XYZ - 3
- XYZM - 4
tnx, very useful the best i found on net
ReplyDeleteThanks!!!!
ReplyDelete