Kamzz
Kamzz

Reputation: 119

GeoJSON feature coordinates not displaying on OpenLayers map

I'm trying to display a GeoJSON polygon on a map. I've used the example provided by OpenLayers with the following data, but only the second polygon is displayed:

var geojsonObject = {
    "type": "FeatureCollection",
    "crs": {
        "type": "name",
    },
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [[[103.92240800000013,21.69931],[100.93664,21.66959500000013],[108.031899,18.67076]]]                
            }
        },
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [[[-5e6, -1e6], [-4e6, 1e6], [-3e6, -1e6]]]                  
            }
        }
    ]
};

The code I'm using to parse and add the GeoJSON to the map is as follows:

var vectorSource = new ol.source.Vector({
    features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
});

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

I noticed different kinds of coordinates. In the second set the coordinates are represented like [-5e6, -1e6] with the e which I don't understand and in the first set - that don't work - they look like [103.92240800000013, 21.69931].

Is this a possible reason why my polygon is not displayed?

Upvotes: 3

Views: 3142

Answers (1)

Emissary
Emissary

Reputation: 10138

The problem is your two polygons are specified using different coordinate spaces and you need to determine which map projection you are going to use. By default OpenLayers uses something they call a "spherical mercator" and without delving into the detail the geometry coordinates are represented by pixels on a 2D plane.

Ideally, you would fix your GeoJSON to provide all coordinates in the same projection. If you can't do that, here is a working solution:

The set that you say aren't working look like longitude and latitude (GIS) coordinates and need to be transformed if they are to be displayed on the same layer - in the following example I've tagged the features that require transform using the GeoJSON properties like so:

var geojsonObject = {
    type: 'FeatureCollection',
    // ...
    features: [
        {
            type: 'Feature',
            geometry: {
                type: 'Polygon',
                coordinates: [/* ... */],
                properties: {
                    requiresTransform: true  // <- custom property
                }
            }
        },
        // ...
    ]
};

Before adding features to the layer source you could then do something like the following:

var features = (new ol.format.GeoJSON()).readFeatures(geojsonObject);

features.forEach(function(feature){
    if(!feature.get('requiresTransform')) 
        return; // ignore

    var geometry = feature.getGeometry(),
        coords = geometry.getCoordinates();

    if(geometry instanceof ol.geom.Polygon)
        geometry.setCoordinates(transformPolyCoords(coords));
});

function transformPolyCoords(/* Array */ a){
    return a.map(function(aa){
        return aa.map(function(coords){
            return ol.proj.transform(coords, 'EPSG:4326', 'EPSG:3857');  
        });
    });
}

There may be a cleaner way of managing this and I'd imagine it involves keeping the separate formats in separate GeoJSON objects and I don't know how close it is to what you were expecting, but this is what I came up with using what you provided » working example.

Upvotes: 4

Related Questions