Подтвердить что ты не робот

Событие после изменения полигона в google maps api v3

Я сделал приложение сопоставления, которое использует диспетчер чертежей (и реализует выбираемые формы); Программа работает следующим образом: при завершении рисования полигона после нажатия кнопки путь отображается на многоугольник.

Когда полигон отредактирован после этого процесса, я хочу снова вызвать функцию сопоставления. Однако я не могу заставить эту часть работать,

Я попытался использовать следующий код, но всегда получаю сообщение об ошибке, потому что при добавлении этого слушателя не будет выбрана никакая фигура. Что я могу сделать?

google.maps.event.addListener(selectedShape, 'set_at', function() {
  console.log("test");
});

google.maps.event.addListener(selectedShape, 'insert_at', function() {
   console.log("test");
});

важные фрагменты кода:

function showDrawingManager(){
    var managerOptions = {
        drawingControl: true,
        drawingControlOptions: {
            position: google.maps.ControlPosition.TOP_CENTER,
            drawingModes: [google.maps.drawing.OverlayType.MARKER,google.maps.drawing.OverlayType.POLYLINE,google.maps.drawing.OverlayType.POLYGON]
        },
        markerOptions: {
            editable: true,
            icon : '/largeTDGreenIcons/blank.png'
        },
        polygonOptions: {
            fillColor:"#1E90FF",
            strokeColor:"#1E90FF",
        },
        polylineOptions: {
            strokeColor:"#FF273A"
        }
    }

    var drawingManager = new google.maps.drawing.DrawingManager(managerOptions);
    drawingManager.setMap(map); 
    return drawingManager;
}

    function clearSelection() {
        if (selectedShape) {
          console.log("clearSelection");

          selectedShape.setEditable(false);
          selectedShape = null;
          numberOfShapes--;
        }
 }

 function setSelection(shape) {
        console.log("setSelection");

    clearSelection();
    selectedShape = shape;
    shape.setEditable(true);
        numberOfShapes++;
        //getInformation(shape);
 }

function initialize(){
//....
var drawingManager = showDrawingManager();
        google.maps.event.addListener(drawingManager, 'overlaycomplete', function(e) {
            if (e.type != google.maps.drawing.OverlayType.MARKER) {
            // Switch back to non-drawing mode after drawing a shape.
            drawingManager.setDrawingMode(null);

            // Add an event listener that selects the newly-drawn shape when the user
            // mouses down on it.
            var newShape = e.overlay;
            newShape.type = e.type;
            google.maps.event.addListener(newShape, 'click', function() {
              setSelection(newShape);
            });
            setSelection(newShape);
          }
        });
4b9b3361

Ответ 1

Я решил это, вызвав .getPath() и положив слушателя внутри слушателя, который вызывается каждый раз, когда нажимается фигура. Я думаю, что документация google api не очень понятна, как использовать set_at, поэтому она может быть полезна и для других людей.

// Add an event listener that selects the newly-drawn shape when the user
    // mouses down on it.
    var newShape = e.overlay;
    newShape.type = e.type;
    google.maps.event.addListener(newShape, 'click', function() {
        google.maps.event.addListener(newShape.getPath(), 'set_at', function() {
            console.log("test");
        });

        google.maps.event.addListener(newShape.getPath(), 'insert_at', function() {
            console.log("test");
        });
      setSelection(newShape);
    });

Ответ 2

    google.maps.event.addListener(yourPolygon.getPath(), 'insert_at', function(index, obj) {
           //polygon object: yourPolygon
    });
    google.maps.event.addListener(yourPolygon.getPath(), 'set_at', function(index, obj) {
           //polygon object: yourPolygon
    });

Этот код работает для меня. Если set_at запускается, когда мы изменяем область многоугольника из выделенной точки (краев) и insert_at запускается, когда мы перетаскиваем точку, расположенную между выделенными краями. Я использовал их в событии polygoncomplete и после загрузки многоугольника из базы данных. Работать хорошо для них

Ответ 3

Чтобы избежать проблем, связанных с set_at и перетаскиванием, я добавил следующее, которое отключает трансляцию событий для set_at при перетаскивании чертежа. Я создал класс, который расширяет класс многоугольника, и добавил этот метод:

 ExtDrawingPolygon.prototype.enableCoordinatesChangedEvent = function(){
  var me = this,
      superClass = me.superClass,
      isBeingDragged = false,
      triggerCoordinatesChanged = function(){
         //broadcast normalized event
         google.maps.event.trigger(superClass,'coordinates_changed');
      };

  //if  the overlay is being dragged, set_at gets called repeatedly, so either we can debounce that or igore while dragging, ignoring is more efficient
  google.maps.event.addListener(superClass,'dragstart',function(){
    isBeingDragged = true;
  });

  //if the overlay is dragged
  google.maps.event.addListener(superClass,'dragend',function(){
    triggerCoordinatesChanged();
    isBeingDragged = false;
  });

  //or vertices are added to any of the possible paths, or deleted 
  var paths = superClass.getPaths();
  paths.forEach(function(path,i){
    google.maps.event.addListener(path,"insert_at",function(){
      triggerCoordinatesChanged();
    });
    google.maps.event.addListener(path,"set_at",function(){
      if(!isBeingDragged){
        triggerCoordinatesChanged();
      }
    });
    google.maps.event.addListener(path,"remove_at",function(){
      triggerCoordinatesChanged();
    });
  });

};

Он добавил событие "codes_changed" к самому полигону, поэтому другой код может просто прослушать приятное одно единственное упрощенное событие -

Ответ 4

chrismarx в соответствии с вашим сообщением ниже - пример использования нового события на typescript. Я сделал небольшую замену удаления суперкласса и изменения ссылок на "меня", потому что возникла проблема с ссылкой undefined.

В верхней части файла или глобального файла конфигурации и т.д. используйте:

declare global {
    module google.maps {
        interface Polygon {
            enableCoordinatesChangedEvent();
        }
    }
}

Затем определите расширение:

    google.maps.Polygon.prototype.enableCoordinatesChangedEvent = function () {
            var me = this,
            isBeingDragged = false,
            triggerCoordinatesChanged = function () {
                //broadcast normalized event
                google.maps.event.trigger(me, 'coordinates_changed');
            };

        //if  the overlay is being dragged, set_at gets called repeatedly, so either we can debounce that or igore while dragging, ignoring is more efficient
        google.maps.event.addListener(me, 'dragstart', function () {
            isBeingDragged = true;
        });

        //if the overlay is dragged
        google.maps.event.addListener(me, 'dragend', function () {
            triggerCoordinatesChanged();
            isBeingDragged = false;
        });

        //or vertices are added to any of the possible paths, or deleted 
        var paths = me.getPaths();
        paths.forEach(function (path, i) {
            google.maps.event.addListener(path, "insert_at", function () {
                triggerCoordinatesChanged();
            });
            google.maps.event.addListener(path, "set_at", function () {
                if (!isBeingDragged) {
                    triggerCoordinatesChanged();
                }
            });
            google.maps.event.addListener(path, "remove_at", function () {
                triggerCoordinatesChanged();
            });
        });

    };

Наконец, добавьте расширение и добавьте прослушиватель:

  google.maps.event.addListener(drawingManager, 'overlaycomplete', function (event) {
        event.overlay.enableCoordinatesChangedEvent();

        google.maps.event.addListener(event.overlay, 'coordinates_changed', function (index, obj) {
            //polygon object: yourPolygon
            console.log('coordinates_changed');
        });

    });