3

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?

Emissary
  • 9,954
  • 8
  • 54
  • 65
Kamzz
  • 119
  • 4
  • 10
  • 1
    5e6 stands for 5 x 10^6 - or 5000000. See https://en.wikipedia.org/wiki/Scientific_notation – Sander Mar 20 '16 at 15:04
  • Sure, good idea must be this. I'll update my first post – Kamzz Mar 20 '16 at 15:19
  • The second area is about 2.000.000 x 2.000.000 units - the first one 4 x 8 units. If both features are displayed on the same map the first one will appear as very tiny at best (and possibly hidden by the big one). What happens if you remove the big area from the code? – Sander Mar 20 '16 at 15:58
  • If i remove the first one, the second one is displayed, but if i remove the second one, the first one is not displayed neither. Thank you for the idea however – Kamzz Mar 20 '16 at 16:00
  • The question is confusing. It is not clear whether the OP asks about handling invalid GeoJSON with geometries in different projections, or if they want help getting data from GeoJSON displayed properly, taking into account different data and view projections. – ahocevar Mar 23 '16 at 16:03

1 Answers1

4

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.

ahocevar
  • 5,448
  • 15
  • 29
Emissary
  • 9,954
  • 8
  • 54
  • 65
  • Thank you very much for this detailed answer. – Kamzz Mar 20 '16 at 17:59
  • While there is nothing wrong with the code above, it is way more complicated than it needs to be. See my answer for a simpler solution. – ahocevar Mar 21 '16 at 16:03
  • @ahocevar did you even test your alternative before down voting me? The parser doesn't work consistently when the same *GeoJSON* data set like the one stipulated in the OP contains features defined in different projections / formats. – Emissary Mar 21 '16 at 17:43
  • Sorry, I misunderstood the question. I should downvote the question, not your answer. Once the answer is unlocked/edited, I'll upvote again. – ahocevar Mar 23 '16 at 14:59
  • @ahocevar : Can't we have a configuration while defining map for transforming coordinates? – Aniruddha Shevle Nov 10 '18 at 07:11