0

How does draw.appendCoordinates method from OpenLayer work? I can´t make it work. I have a web page where the idea is that the user can create a path by drawing points in the map and then save it and reopen it later. Right know I have this:

Global variables:

let draw;
let coordinates = [];
let old_coordinates = [];
const source = new ol.source.Vector({ wrapX: false });
const raster = new ol.layer.Tile({
    source: new ol.source.OSM(),
});
let map;

In the init function i create the map and start a listener for the click event:

const vector = new ol.layer.Vector({
    source: source,
});
map = new ol.Map({
    layers: [raster, vector],
    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.on("click", function (evt) {
    coordinates.push(new ol.Feature({type: 'geoMarker', geometry: new ol.geom.Point(evt.coordinate)}));
});

And then this functions:

function addInteraction() {
    draw = new ol.interaction.Draw({
        source: source,
        type: "LineString",
    });
    map.addInteraction(draw);
}

function waypoints() {
    document.getElementById("leftNavigation").style.width = "0%";
    document.getElementById("waypoints").style.width = "5%";
    switchNavB();
    switchMap();
    addInteraction();
}
function waypointsOut() {
    draw.abortDrawing()
    draw.finishDrawing()
    switchNavB();
    switchMap();
    document.getElementById("waypoints").style.width = "0%";
    document.getElementById("leftNavigation").style.width = "5%";
}

function waypointsSave() {
    draw.finishDrawing()
}

function waypointsUndo(){
    draw.removeLastPoint()
    let last = coordinates.slice(-1).pop();
    old_coordinates.push(last);
    coordinates.pop();
}

function waypointsRedo(){
    if(old_coordinates.length > 0){
        let last = old_coordinates.pop();
        coordenadas = last.getGeometry().getCoordinates()
        draw.appendCoordinates(coordenadas)
        coordinates.push(last)
    }
}
function waypointsClear(){
    draw.abortDrawing()
}

As you can see I save the coordinates in the click event and when I do an undo I save them to another array in case the user wants to redo. First I tried saving them with evt.coordinates but since it didnt work I tried with features but it also doesn´t work so I think there´s a problem with how I use draw.appendCoordinates, in the browser console i get this error: "Uncaught TypeError: t.slice is not a function", i thought it may be because the coordinates I give it are not an array but I´ve confirmed they are. Here´s an image of the web in case it helps: Waypoints webpage

Also, how can I remove the drawing once finishDrawing is called?

6
  • It expects an array of vertices as used in a LineString. Your coordenadas is a single coordinate pair from a Point feature, so you will need draw.appendCoordinates([coordenadas]) to add a single vertex.
    – Mike
    May 26, 2023 at 11:01
  • Thank you so much, it worked perfectly, how you hapen to know how can I remove the drawing once finishDrawing is called?
    – Alejandro
    May 26, 2023 at 11:27
  • If you do not want to save the drawing you do not need to specify source in the interaction options.
    – Mike
    May 26, 2023 at 11:55
  • I want to save it, but I also want an option where the user can remove this drawing and start again but not like the option of waypointsClear() which clears the waypoints while doing the drawing, start again after having called finishDrawing
    – Alejandro
    May 26, 2023 at 12:07
  • finishDrawing adds the feature to the source, to remove it after that you would need source.clear() or you could remove individual features with source.removeFeature(feature) if you can identify which feature you need removing (maybe keep a record of the last feature from the drawend event)
    – Mike
    May 26, 2023 at 12:28

1 Answer 1

0

Thanks to Mike I´ve managed to do what I wanted, so, in case someone is trying to do the same, here´s my solution:

Global variables:

let draw;
let dibujo;
let coordinates = [];
let old_coordinates = [];
const source = new ol.source.Vector({ wrapX: false });
const raster = new ol.layer.Tile({
    source: new ol.source.OSM(),
});
let map;

Init function:

const vector = new ol.layer.Vector({
    source: source,
});
map = new ol.Map({
    layers: [raster, vector],
    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.on("click", function (evt) {
    //Too avoid saving coordinates when clicking but not drawing
    if(dibujo == true){
        coordinates.push(new ol.Feature({type: 'geoMarker', geometry: new ol.geom.Point(evt.coordinate)}))
        old_coordinates = []
    }
        
});

Waypoints functions:

function addInteraction() {
    draw = new ol.interaction.Draw({
        source: source,
        type: "LineString",
    });

    map.addInteraction(draw);
}

function waypoints() {
    dibujo = true;
    source.clear() //Remove what was drawn before
    //This two lines are just shows the waypoints menu and hides another menu which was in the same position
    document.getElementById("leftNavigation").style.width = "0%";
    document.getElementById("waypoints").style.width = "5%";
    //This two do similar things to the upper ones
    switchNavB();
    switchMap();
    //Start drawing
    addInteraction();
}
function waypointsOut() {
    dibujo = false;
    map.removeInteraction(draw);
    switchNavB();
    switchMap();
    document.getElementById("waypoints").style.width = "0%";
    document.getElementById("leftNavigation").style.width = "5%";
}

function waypointsSave() {
    //Save the drawing and stop drawing
    dibujo = false;
    draw.finishDrawing()
    map.removeInteraction(draw);
}
    
function waypointsUndo(){
    draw.removeLastPoint()
    old_coordinates.push(coordinates.slice(-1).pop());
    coordinates.pop();
}
    
function waypointsRedo(){
    if(old_coordinates.length > 0){
        let last = old_coordinates.pop();
        draw.appendCoordinates([last.getGeometry().getCoordinates()])
        coordinates.push(last)
    }
}

function waypointsClear(){
    draw.abortDrawing()
    source.clear()
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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