OpenLayers Markers – Adding, Removing and Modifying Markers

markersopenlayers

I am making a web page with a map which requires some operations with markers/waypoints. I need to add markers to a map, one of them should move to a given point which would be updated each second/half a second, one will be static and the others should be added on click and remove when a button is pressed.

Right now I have this:

map.on("click", function (evt) {
    if(dibujo == true){
        coordinates.push(new ol.Feature({type: 'geoMarker', geometry: new ol.geom.Point(evt.coordinate)}))
        old_coordinates = []
        point = new ol.geom.Point(evt.coordinate)
        const marker = new ol.Feature({
            type: 'icon',
            geometry: point,
        });
        const vectorLayer = new ol.layer.Vector({
            source: new ol.source.Vector({
            features: [marker],
            }),
            style: function (feature) {
            return style[feature.get('type')];
            },
        });
        map.addLayer(vectorLayer);
    }
});

What this does is to place a marker where you click, the problem is that I think I am creating a new layer each time I add a marker so I would like to know how to add them to a given layer instead of adding them on creation and how to remove them. Just removing the last one would be ok but it would be nice to know how to remove any waypoint, as you can see I save the Features in an array so I know where are all the waypoints.

Best Answer

Ok, I've managed to add waypoints to a map and also to remove them, right now it just allows to remove the last one but I suppose it should work for any waypoint

Global variables:

let draw;
let save;
let dibujo;
let coordinates = [];
let old_coordinates = [];
let map;

const drawVector = new ol.layer.Vector({
    source: new ol.source.Vector({ wrapX: false }),
    style: function (feature) {
        return style[feature.get("type")] || style.line;
    },
});

Init function:

draw = new ol.interaction.Draw({
    source: drawVector.getSource(),
    type: 'LineString',
    freehandCondition: ol.events.condition.never,
    finishCondition: ol.events.condition.never,
});
const raster = new ol.layer.Tile({
    source: new ol.source.XYZ({
        url: 'imgs/sat_tiles/{z}/{x}/{y}.png' // Ruta donde se encuentran los archivos tiles descargados
      }),
});

    map = new ol.Map({
        layers: [raster, drawVector],
        keyboardEventTarget: document,
        target: "mapa",
        view: new ol.View({
            projection: "EPSG:4326",
            center: [-1.790436, 43.356794],
            zoom: 16,
            extent: [-9.844, 35.747, 4.878, 43.993],
        }),
    });
    map.addLayer(vectorLayer);
    map.on("click", function (evt) {
        if(dibujo == true){
            point = new ol.geom.Point(evt.coordinate);
            marker = new ol.Feature({
                type: "marker",
                geometry: point,
            });
            coordinates.push(marker);       
            old_coordinates = [];
            drawVector.getSource().addFeature(marker);
        }
    });

With that code you can add markers to the layer drawVector and with the next function you should be able to remove them.

function waypointsUndo() {
    if(save == false){
        draw.removeLastPoint();
        const lastCoord = coordinates.pop();
        drawVector.getSource().removeFeature(lastCoord);
        old_coordinates.push(lastCoord);
        drawVector.getSource().changed();
    }
}

You also need a function or somewhere in your code where you add the draw object to the map. Something like this:

function waypoints() {
    save = false;
    dibujo = true;
    map.addInteraction(draw)
    // If you want to clear the map of the previous drawing
    drawVector.getSource().clear();
    drawVector.getSource().clear();
    coordinates = [];
    old_coordinates = [];    
}

Finally it would be possible to make a redo method, limit where you want to allow drawing and some other tings but this is the answer to what I was asking.

Related Question