OpenLayers 3 – Accessing Features by ID

featuresopenlayers

I want to create a map with openlayers, add feature points, let people move the points and retrieve the new coordinates later. I have searched the net for two days but all I found was an example where you get the new coordinates while the move is in progress capturing the data of the event. But I want to access the feature later (on another event).

Everything works fine beside accessing the feature object afterwards to retrieve the coordinates.

Here is my working code:

    <script src="path/to/jquery.js"></script>
    <link rel="stylesheet" href="path/to/bootstrap.css">
    <script src="path/to/bootstrap.js"></script>    
    <script src="path/to/ol.js"></script>
    <div id="mapdiv" style="width: 900px; height: 600px"></div><div id="mappopup"></div>

    <script>
    var iconFeatures=[];

    function makeMovable(feature) {
       var modify = new ol.interaction.Modify({
        features: new ol.Collection([feature])
        });

        feature.on('change',function() {
        // here you could easily get the geometry, but I need it later
        //console.log('Feature Moved To:' + this.getGeometry().getCoordinates());

        }, feature);
        return modify;
    }

    var openStreetMapLayer = new ol.layer.Tile({
      source: new ol.source.OSM({
        attributions: [
        new ol.Attribution({
        html: 'All maps &copy; ' +
        '<a href="http://www.openstreetmap.org/">OpenstreetMap</a>'
        }),
        ol.source.OSM.ATTRIBUTION
        ],
        url: 'http://mytilesserver.test&z={z}&x={x}&y={y}&r=mapnik'
    })
    });

    var map = new ol.Map({
      layers: [
        openStreetMapLayer,
      ],
        target: 'mapdiv',
         controls: ol.control.defaults({
            attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
            collapsible: false
        })
        }),
        view: new ol.View({
        maxZoom: 18,
        center: ol.proj.transform([18.3261549, 50.2499405], 'EPSG:4326', 'EPSG:3857'),
        zoom: 14
    })
    });


        var iconFeature = new ol.Feature({
            id: 'addressfeature',
            geometry: new ol.geom.Point(ol.proj.transform([18.3261549, 50.2499405], 'EPSG:4326',    'EPSG:3857')),
                    popuptext: 'This would be my moveable feature ',
        });

        var iconStyle = new ol.style.Style({
        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({
        opacity: 1,
        rotation: 0 * Math.PI / 180,
        src: '/path/to/icon.png'
        }))
        });

        iconFeature.setStyle(iconStyle);
        var modifyInteraction = makeMovable(iconFeature);
            map.addInteraction(modifyInteraction);iconFeatures.push(iconFeature);

    vectorSource = new ol.source.Vector({
    features: iconFeatures
    });

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

    map.addLayer(vectorLayer);

    </script>

And now I would like to retrieve the coordinates of the object with this function:

function getFeaturecoordinates(featureID) {
console.log('Feature Moved To:' + vectorSource.getFeatureById(featureID).getGeometry().getCoordinates());               
    }

But obviously it does not work. I also tried a lot of other possibilities to access the feature, e.g.

vectorLayer.getSource().getFeatureById(featureID).getGeometry().getCoordinates());

But they all do not work.

What is the right way to access the feature by featureID?

Best Answer

Your way of getting features out of a source by ID is correct, but you way of setting the ID is not.

In OpenLayers 3, you set the ID of a feature with the setId method. Including id in the constructor is valid, but only adds the id as a feature property (not as the feature's identifier).

var iconFeature = new ol.Feature({
        id: 'addressfeature',
        geometry: new ol.geom.Point(ol.proj.transform([18.3261549, 50.2499405], 'EPSG:4326', 'EPSG:3857')),
        popuptext: 'This would be my moveable feature ',
 });
 // this is what set's the ID:
 iconFeature.setId('addressfeature');
Related Question