Search code examples
geojsonopenlayers-5

How to add a GeoJSON polygon feature to a vector source in OpenLayers 5


I am embarrassed by how elementary this problem seems, but I can't seem to work out how to simply add a GeoJSON polygon feature to a vector source.

I'm using OpenLayers 5, and up until now I've been creating a separate source and layer for every feature I'm adding to the map. The reason being I needed to be able to turn the visibility of individual polygons on and off, and this seemed like the best way to do that at the time. This worked at first, but I'm sure it's not the best practice - in effect I'm creating 200 layers and 200 sources for 200 polygons. I'd prefer to be creating one layer which uses one source which contains those 200 polygons.

This is what I currently have:

window["srcCells"] = new ol.source.Vector({});
window["ftr1"] = new ol.Feature({
    geometry: new ol.geom.Polygon({ // <--- this is where I'm getting an error
        coordinates: geometry.coordinates[0]
    })
});
window["srcCells"].addFeature(window["ftr1"]);
window["lyrCells"] = new ol.layer.Vector({
    name: "lyrCells",
    source: window["srcCells"],
    visible: true,
    style: new ol.style.Style({
        stroke: new ol.style.Stroke({
        color: 'rgba(255, 255, 255, 1)',
        width: 0.5
    }),
    fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0)'
    }),
    text: new ol.style.Text({
        font: '11px Roboto',
        overflow: false,
        fill: new ol.style.Fill({
            color: '#fff'
        }),
        stroke: new ol.style.Stroke({
            color: '#333',
            width: 2
        })
    })
    })
});
map.addLayer(window["lyrCells"]);

console.dir(geometry.coordinates[0]); gives the following:

0: (3) [140.9528856796365, -37.00284635019008, 111.304]
1: (3) [140.9536707180603, -37.00304972058393, 113.03]
2: (3) [140.9537622719694, -37.00307250872015, 110.607]
3: (3) [140.95383548835147, -37.003105295678026, 110.64]
4: (3) [140.95393795398604, -37.003149857783384, 110.26276070403628]
5: (3) [140.95586925648476, -37.00401679761869, 111.192]
6: (3) [140.95644098404094, -37.00388629902322, 110.38710718081241]
7: (3) [140.95644582710668, -37.0051300157363, 111.17174176388276]
8: (3) [140.9528945167084, -37.00514320603378, 110.9445749409575]
9: (3) [140.95289318042316, -37.004769323489825, 113.688]

At the third line of the code above (where I've indicated), I'm getting this error:

SimpleGeometry.js:187 Uncaught TypeError: Cannot read property 'length' of undefined
    at e.setLayout (SimpleGeometry.js:187)
    at e.setCoordinates (Polygon.js:313)
    at new e (Polygon.js:80)

Solution

  • geometry.coordinates[0] looks like an open linestring. To use it as a polygon you would need to close the ring and, as a polygon is an array of linear rings, enclose with []. Also the coordinates are the first parameter of the constructor, not an option:

    geometry: new ol.geom.Polygon(
         [ geometry.coordinates[0].concat([geometry.coordinates[0][0]]) ]
    )
    

    Alternatively you may need check that your data is polygon or linestring and use new ol.geom.LineString where appropriate