1

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.

1

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);
}});
  • Great, thanks a lot! To make things more complicated, how could I wrap this (getting features and creating buffers from certain geometries) somehow in a function that I can combine with setInterval(createBuffers, 1000*5) for example? Is there some way of storing the features outside of this event callback? Or what could I do to repeat this process over time? – Robin Braggaar Aug 10 '17 at 18:18
  • May you accept the answer if it solve your problem? – himyata Aug 13 '17 at 11:45
  • Accepted the answer. However, would be very grateful if you could comment on my last comment. I.e. how can I get these features on a timed interval? – Robin Braggaar Aug 14 '17 at 14:49
  • setInterval(createBuffers, 1000 * 5); function createBuffers() { var features = vectorLayer.getSource().getFeatures(); 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' })); } }); } – himyata Aug 15 '17 at 6:42
  • If the interval is really short and the source has not yet been (fully) loaded getFeatures() does not return all features. Perhaps I should monitor the load process and then fire off my interval'd functions? – Robin Braggaar Aug 23 '17 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.