Перетаскивание (перемещение) полигона с помощью Google Maps v3

на Google Maps API для полигона не предлагает метод перетаскивания.

каким будет эффективный способ реализации такой функции (т. е. достаточно оптимизированной, чтобы она не убивала четырехлетний ноутбук)?

спасибо!

5 ответов


Я обнаружил, что реализация Google Maps V2 Polygon очень ограничивает потребности, которые у меня были, и решил ее, создав пользовательский оверлей. Моя группа в настоящее время застряла на IE6, поэтому мне еще предстоит перейти на Google Maps V3, но быстрый взгляд на API показывает, что вы, вероятно, могли бы сделать аналогичную вещь, которую я сделал в V2 с V3.

по существу идея такова:

  1. создать пользовательский оверлей
  2. заполните его своими собственными полигонами SVG/VML и прикрепите событие drag к этому настраиваемому объекту polygon

Пользовательские Надписи:

вот некоторая информация, чтобы вы начали создавать свой собственный оверлей:

http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays


создание собственного" перетаскиваемого " полигонального объекта:

Как только вы это сделаете, вы захотите добавить свои собственные полигоны в пользовательский оверлей вместо использования GPolygons. Я прошел через болезненный процесс изучения SVG/VML и написания библиотеки для объединения SVG / VML вместе - вы могли бы это сделать, но я бы рекомендовал начать с попытки использовать другую библиотеку, такую как Raphaël.

http://raphaeljs.com/

использование Raphaël сэкономит вам много времени, пытаясь выяснить, как получить функциональность кросс-браузерной векторной графики (полигона) - и лучше всего он поддерживает события перетаскивания уже здесь пример из их библиотеки:

http://raphaeljs.com/graffle.html

Как только у вас есть пользовательский оверлей, и вы можете бросить на него некоторые объекты Raphaël, последний шаг-перевести нужные координаты из значения Lat/Lng в значение пикселя. Это доступно в MapCanvasProjection V3:

http://code.google.com/apis/maps/documentation/javascript/reference.html#MapCanvasProjection

вы можете использовать fromLatLngToDivPixel, чтобы выяснить, каковы фактические значения пикселей для точек на вашем многоугольнике Рафаэля, нарисовать его, а затем добавить его в оверлей с событием перетаскивания.


начиная с версии 3.11 (от 22 января 2013 года) можно просто установить draggable собственности на google.maps.Polygon экземпляра; см. .

Если вы хотите программно переместить многоугольник, вам понадобится пользовательское расширение Google Maps, которое я написал, поскольку API не предоставляет такой метод.


вот как я это делаю. Найдите приблизительный центр полигона и добавьте маркер, затем добавьте прослушиватель перетаскивания к маркеру. При изменении lat/lng вычитайте разницу из исходного маркера lat/lng, вычитайте разницу для каждого из путей, затем установите исходное положение в новое положение. Убедитесь,что в вызове javascript api у вас есть library=geometry, drawing

google.maps.event.addListener(draw, 'overlaycomplete', function(shape) {
// POLYGON
      if (shape.type == 'polygon') {
        var bounds = new google.maps.LatLngBounds(); var i;  
        var path = shape.overlay.getPath();
        for (i = 0; i < path.length; i++) { bounds.extend(path.getAt(i)); }
        shape.latLng = bounds.getCenter();
        marker = getMarker(map,shape);
        shape.overlay.marker = marker;
        markers.push(marker); 
      }
      google.maps.event.addListener(marker, 'drag', function(event) {
         shape.overlay.move(event.latLng, shape, path);
      });

          google.maps.event.addListener(shape.overlay, 'rightclick', function() {
            this.setMap(null);
            this.marker.setMap(null);
            draw.setDrawingMode('polygon');
          });

  });
}
google.maps.Polygon.prototype.move = function(latLng, shape, p) {
    var lat = latLng.lat();
    var lng = latLng.lng();

    latDiff = shape.latLng.lat()-lat;
    lngDiff = shape.latLng.lng()-lng;

   for (i = 0; i < p.length; i++) {
    pLat = p.getAt(i).lat();
    pLng = p.getAt(i).lng();
    p.setAt(i,new google.maps.LatLng(pLat-latDiff,pLng-lngDiff));
   }
   shape.latLng = latLng; 
}
function getMarker(map,shape){
  var infowindow = new google.maps.InfoWindow();
  if(shape.type=='polygon'){ latLng = shape.latLng; }
  marker = new google.maps.Marker({
              position: latLng,
              map:map,
              draggable:true,
              clickable: true,
              animation: google.maps.Animation.DROP
            });
           shape.overlay.marker = marker;
           shape.overlay.bindTo('center',marker,'position');
           google.maps.event.addListener(marker, 'click', (function(marker) {
            return function() {
              infowindow.setContent('polygon');
              infowindow.open(map, marker);
              toggleBounce(marker);
            }
          })(marker));
          google.maps.event.addListener(infowindow,'closeclick', (function(marker) {      
            return function() {
            marker.setAnimation(null);
            }
          })(marker));
 return marker;
}

Если у вас есть какие-либо вопросы, не стесняйтесь связаться со мной.


У вас могут быть маркеры для каждой точки На многоугольнике, эти маркеры могут иметь перетаскивание, и в конце каждого перетаскивания многоугольник может быть перерисован.

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


хорошо-Итак, увидев веб - сайт, который вы пытаетесь реализовать, я начал чувствовать, что Рафаэль может не понадобиться, потому что это довольно тяжелая библиотека JS-и если вы только пытаетесь нарисовать прямоугольник многоугольника, я подумал, почему бы просто не сделать это с одним легким DIV вместо этого?

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

вот рабочий пример, который я бросил вместе:

http://www.johnmick.net/drag-div-v3/

Не стесняйтесь взглянуть на источник:

http://www.johnmick.net/drag-div-v3/js/main.js

по сути, мы делаем следующее:

  1. создать пользовательский оверлей
  2. создайте перетаскиваемый многоугольник div и, используя jQuery UI, сделайте его перетаскиваемым
  3. свяжите событие, которое слушает, когда перетаскивание остановило это обновляет положение LatLng прямоугольника
  4. Добавить объект в пользовательское наложение
  5. реализуйте функцию draw для перерисовки прямоугольника во время масштабирования и панорамирования

В настоящее время я храню только одно значение LatLng для прямоугольника (являющегося верхним левым углом) - вы можете легко расширить этот пример, чтобы сохранить все 4 точки прямоугольника и динамически изменять размер фигуры на масштабах. Вы можете сделать это, в противном случае, как пользователи уменьшить масштаб они получат доклад климат на большую площадь.