¿Cómo agregar un punto en una polilínea en algún lugar entre dos vértices?

3 minutos de lectura

Avatar de usuario de Alexey
alexey

El objetivo es tener una polilínea editable con marcadores personalizados en cada vértice.

Como veo Map API V3 no permite eso. Entonces hice una polilínea editable como esta:

let polyline = new self.google.maps.Polyline({
    strokeColor: '#000000',
    strokeOpacity: 0.3,
    strokeWeight: 3,
    editable: false,
    path: path,
    map: self.map
});

polyline.binder = new MVCArrayBinder(polyline.getPath());

let markers = [];
for (let i = 0; i < path.length; i++) {
    let marker = this.getBasicMarker(path[i]);
    marker.bindTo('position', polyline.binder, i.toString());
    markers.push(marker);
}
getBasicMarker(position){
    return new this.google.maps.Marker({
        position: position,
        map: this.map,
        icon: {
            url: "https://maps.gstatic.com/intl/en_us/mapfiles/markers2/measle.png",
            size: new google.maps.Size(7, 7),
            anchor: new google.maps.Point(3.5, 3.5)
        },
        draggable: true,
        visible: false
    });
}
function MVCArrayBinder(mvcArray) {
    this.array_ = mvcArray;
}

MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function (key) {
    if (!isNaN(parseInt(key))) {
        return this.array_.getAt(parseInt(key));
    } else {
        this.array_.get(key);
    }
};

MVCArrayBinder.prototype.set = function (key, val) {
    if (!isNaN(parseInt(key))) {
        this.array_.setAt(parseInt(key), val);
    } else {
        this.array_.set(key, val);
    }
};

La polilínea final ahora se ve así: http://sandbox.rubera.ru/img/2019-05-28_17-04-25.jpg. Puedo arrastrar cualquier punto existente. La polilínea se actualiza mientras se arrastra el punto.

Ahora tengo que agregar un nuevo vértice en algún lugar entre dos existentes.

Aquí es donde estoy atascado.

Puede haber otra solución, ¿cómo resolver la tarea?

  • ¿Por qué no simplemente establece su polilínea en editable: true para que se pueda agregar cualquier punto en cualquier lugar de la polilínea usando la GUI?

    – Señor Upsidown

    28 de mayo de 2019 a las 15:26

  • Porque necesito personalizar cada marcador de vértice.

    – Alexei

    29 de mayo de 2019 a las 8:37

  • ¿Y? ¿Cuál es el problema con eso? Edite su pregunta con un ejemplo mínimo, completo y verificable que demuestre el problema y explique lo que está tratando de lograr. Tal como está, su pregunta es demasiado amplia e incompleta.

    – Señor Upsidown

    29 de mayo de 2019 a las 9:03

  • Pregunta actualizada.

    – Alexei

    29 de mayo de 2019 a las 9:45

  • Pregunta relacionada: Google Maps: seleccione el marcador anterior en la polilínea

    – geocodezip

    29 de mayo de 2019 a las 9:51

En caso de que alguien se enfrente a una tarea similar, aquí hay algunas modificaciones a mi código publicado anteriormente. Eso me ayudó finalmente a resolver el problema.

MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function (key) {
    if (!isNaN(parseInt(key))) {
        return this.array_.getAt(parseInt(key));
    } else {
        this.array_.get(key);
    }
};

MVCArrayBinder.prototype.set = function (key, val) {
    if (!isNaN(parseInt(key))) {
        this.array_.setAt(parseInt(key), val);
    } else {
        this.array_.set(key, val);
    }
};

MVCArrayBinder.prototype.insertAt = function (key, val) {
    this.array_.insertAt(key, val);
};
google.maps.event.addListener(this.activePoly, 'click', function (e) {
    let path = $this.activePoly.getPath(),
        inserted = false;

    // find line segment
    for (let i = 0; i < path.getLength() - 1, !inserted; i++) {
        let tempPoly = new google.maps.Polyline({
            path: [path.getAt(i), path.getAt(i + 1)]
        });

        if (google.maps.geometry.poly.isLocationOnEdge(e.latLng, tempPoly, 10e-2)) {
            $this.activeRoute.binder.insertAt(i + 1, e.latLng);
            inserted = true;

            let marker = $this.getBasicMarker(e.latLng);
            marker.setVisible(true);

            // Add new marker to array
            $this.activeRoute.markers.splice(i + 1, 0, marker);

            // Have to rebind all markers
            $this.activeRoute.markers.forEach((marker, index) => {
                marker.bindTo('position', $this.activeRoute.binder, index.toString());
            });
        }
    }
});

Mi activeRoute es un objeto con la siguiente estructura:

{polyline: polyline, markers: markers, binder: polyline.binder}

¿Ha sido útil esta solución?