Перетащите (переместите) многоугольник с помощью Google Maps v3 - PullRequest
7 голосов
/ 25 июня 2010

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

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

Спасибо!

Ответы [ 5 ]

6 голосов
/ 02 сентября 2010

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

По сути, идея такова:

  1. Создание пользовательского наложения
  2. Заполните его своими собственными SVG / VML-полигонами и присоедините событие перетаскивания к этому пользовательскому объекту-полигону

Пользовательские оверлеи:

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

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


Создание собственного«Перетаскиваемый» объект многоугольника:

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

http://raphaeljs.com/

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

http://raphaeljs.com/graffle.html

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

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

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

4 голосов
/ 15 февраля 2013

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

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

3 голосов
/ 08 июня 2012

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

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;
}

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

1 голос
/ 02 сентября 2010

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

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

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

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

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

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

По существу мы делаем следующее

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

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

1 голос
/ 25 июня 2010

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

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

...