[GIS] Adding a feature to Openlayers Vector source

openlayers

I want to;

  1. get the features from a vector source and
  2. for some features, use their coordinates to construct new features, e.g. ol.geom.Circle buffers.

My sample vector source (epsg:3857 projection), with two features (points) that I would like to read their coordinates from:

var sampleSource = new ol.source.Vector({
    url: (basePath + '/data/scanner_locations.json'),
    format: new ol.format.GeoJSON()
    "EPSG:3857"})).readFeatures(basePath + '/data/scanner_locations.json')
});

This layer renders two points on my map.

For 1, to retrieve the source features, if I understand correctly you need to monitor the change event like this:

sampleSource.on('change', function(evt){
var source = evt.target;
if (source.getState() === 'ready') {

If it is 'ready' you have asynchronously retrieved the source, correct?

Following I try to add something to the source like so:

sampleSource.on('change', function(evt){
var source = evt.target;
if (source.getState() === 'ready') {
    var numFeatures = source.getFeatures().length; // if 0, quit ?
    var features = source.getFeatures();
    console.log(features); // gives me the two features
    features.forEach((feature) => {
        if (feature.values_.id === 1){ // if the id property of the feature is 1
            // feature.getGeometry().flatCoordinates should be the center of the circle
            source.addFeature(new ol.Feature({
            // coordinates for the circle center are hardcoded here, radius is 500 meter 
                geometry: new ol.geom.Circle([486524.0550283753, 6801035.6531745335], 500),
                name: 'the buffer'
                // id: 500
            }));
        } // end if
    }) // end forEach
}});

This creates a huge stack size, so something is clearly going wrong.

Best Answer

Try to add features outside of forEach. Because features of the source are increasing every loop in your code. Try to code like this:

sampleSource.on('change', function(evt){
var source = evt.target;
if (source.getState() === 'ready') {
    var features = source.getFeatures();
    var featuresToAdd = [];
    features.forEach((feature) => {
        if (feature.values_.id === 1){ 
            featuresToAdd.push(new ol.Feature({
                geometry: new ol.geom.Circle([486524.0550283753, 6801035.6531745335], 500),
                name: 'the buffer'
            }));
        } // end if
    }) // end forEach

    source.addFeatures(featuresToAdd);
}});
Related Question