When you draw in OpenLayers, you draw in local projections' features. Then, if you need, for example, to exchange data source with a third party, sometimes you need to make reprojections. It's useful to know how to consume data and reproject them or on the contrary, export them. It's what we will see here:
sandbox directory.var projection declaration, add a new GeoJSON source, a vector source:var countriesSource = new ol.source.GeoJSON({
projection: 'EPSG:2154',
url: '../assets/data/nutsv9_lea.geojson'
});console.log statements:countriesSource.once('change', function(evt) {
if (this.getState() == 'ready') {
console.log(this.getFeatures()[0].getGeometry().getCoordinates());
console.log(this.getFeatures()[0].getGeometry().clone().transform('EPSG:2154','EPSG:4326').getCoordinates());
}
});countriesSource as the source. You will normally write something like the following:var layers = [
new ol.layer.Image({
}),
new ol.layer.Vector({
source: countriesSource
})
];var bbox = new ol.layer.Vector({
source: new ol.source.GeoJSON()
})
map.addLayer(bbox);featureCollection inline. It's recommended by the GeoJSON specifications to have coordinates using EPSG:4326:var geojson = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [
[[-0.944824, 46.134170], [-0.944824, 48.312428],
[4.438477, 48.312428], [4.438477, 46.134170],
[-0.944824, 46.134170]
]
]
}
}
]
}ol.format.GeoJSON with defaultDataProjection:var format = new ol.format.GeoJSON({
defaultDataProjection: 'EPSG:4326'
})bbox layer:var features = format.readFeatures(geojson, {
dataProjection : 'EPSG:4326',
featureProjection: 'EPSG:2154'
});
bbox.getSource().addFeatures(features);console.log statements to help inspect the result, but also see how you can use writeFeatures and reproject.console.log(features);
console.log(
format.writeFeatures(features, {
dataProjection : 'EPSG:4326',
featureProjection: 'EPSG:2154'
})
);
We first set a source by defining its target projection. You might not remember but when you consume GeoJSON, the data default projection is supposed to be EPSG:4326, but our previous map example relies on EPSG:2154, a local projection. By setting this parameter, we are able to tell our application to make a reprojection from EPSG:4326 to EPSG:2154.
How can we be sure it works? You just need to inspect your GeoJSON file and see the coordinates. For EPSG:4326, the approximate values are mostly less than a hundred degrees, whereas with EPSG, the units are meters and expressed with thousands of meters.
For this purpose, we already set a listener with countriesSource.once('change', function(evt) { to inspect the features values. We checked before firing the console.log statements that the GeoJSON was ready to use getState. Then, we tried to inspect the coordinates that the layer vector source contained. As you can see, we chained methods to write a shorter code. We requested all the features with the getFeatures method; the 0 index is to select only the first feature in the array. By reusing this feature, we got geometry with getGeometry, and on this geometry, we retrieved the coordinates.
With a second console.log, we started like the previous statement, but we cloned the geometry. It's because we wanted to keep the values in the original feature intact. The API documentation mentions about the ol.geom.Geometry transform method that it transforms a geometry from one coordinate reference system to another, modifies the geometry in place. If you do not want the geometry modified in place, first clone() it and then use this function on the clone.
If you extend both returned arrays in the console, you will see that the transformation to EPSG:2154 was already stored in the features, and by transforming again, we were able to get the EPSG:4326 original values.
For the rectangle box in the new layer, we choose another way to manipulate projections with vector. We choose to use an empty source within a new vector layer.
The goal was to show you that when you need to add features using the addFeatures method from the ol.source.GeoJSON vector source, you need to reproject features using an object ol.format. Here, we used ol.format.GeoJSON, but it could have been ol.format.WKT. As long as the type of format accepts dataProjection and featureProjection as options in the readFeatures, you can make reprojections.
The important part to keep in mind is the role of the ol.format.GeoJSON methods, readFeatures and writeFeatures and their options.
When you use readFeatures, you reproject from EPSG:4326 to EPSG:2154, and when you use writeFeatures, you reproject from EPSG:2154 to EPSG:4326.
At the code level, when you use readFeatures, you need to provide a string or a GeoJSON object with options and when you write them, it must be Array.<ol.Feature> with options. An excerpt from the document will help to understand those options (common to readFeatures and writeFeatures), as follows:
We also need to mention that for simplicity, we used readFeatures and writeFeatures, but for only one feature (when outside a GeoJSON FeatureCollection), you have to use the readFeature and writeFeature methods (note the singular in the methods' names). Refer to the complete API documentation for more at http://openlayers.org/en/v3.0.0/apidoc/ol.format.GeoJSON.html.
After this review, it's up to you to imagine how you can play with features from the source and also how to manage projections in other formats in various use cases, as we mainly focus for demonstration on GeoJSON.
Q1. Give some reasons why you might want to use a projection other than EPSG:3857?
Q2. Which areas will not be best suited for displaying the EPSG:3857 projection?
Q3. You need to get your local country EPSG code, where do you need to go to be efficient?