Antwort

6

Ich fand die Google Maps V2-Polygon-Implementierung sehr einschränkend für die Bedürfnisse, die ich hatte und löste sie, indem ich ein benutzerdefiniertes Overlay erstellte. Meine Gruppe ist derzeit auf IE6 festgefahren, so dass ich noch auf Google Maps V3 umstellen muss - aber ein kurzer Blick auf die API zeigt, dass Sie wahrscheinlich eine ähnliche Sache wie in V2 mit V3 machen könnten.

Im Grunde ist die Idee:

  1. Erstellen eine benutzerdefinierte Overlay
  2. Bestücken Sie es mit Ihrem eigenen SVG/VML Polygonen und ein Drag-Event zu diesem Objekt benutzerdefinierten Polygon

befestigen Benutzerdefinierte Überlagerungen:

Hier sind einige Informationen, die Sie bei der Erstellung Ihrer Daten unterstützen r eigene benutzerdefinierte Overlay:

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


Erstellen eines eigenen „Dragable“ Polygon Objekt:

Sobald Sie, dass Sie möchten, erhalten nach unten werden Ihre eigene Polygone dem benutzerdefinierten Overlay hinzufügen statt Verwenden von GPolygons. Ich habe den schmerzhaften Prozess des Erlernens von SVG/VML und des Schreibens einer Bibliothek zum gemeinsamen Überbrücken von SVG/VML durchgesehen - Sie könnten das tun, aber ich würde Ihnen empfehlen, zunächst eine andere Bibliothek wie Raphaël zu verwenden.

http://raphaeljs.com/

Raphaël Verwendung finden Sie eine ganze Menge Zeit zu sparen, um herauszufinden, wie Cross-Browser-Vektor-Grafik (Polygon) Funktionalität zu erhalten - und am besten von allen unterstützt Drag Ereignisse schon, hier ist ein Beispiel aus ihrer Bibliothek:

http://raphaeljs.com/graffle.html

Sobald Sie eine benutzerdefinierte Overlay haben, und Sie sind in der Lage einige Raphaël Objekte auf es der letzte Schritt zu übersetzen ist, die Koordinaten, die Sie wollen von einem Lat/Lng Wert auf einen Pixelwert zu werfen . Dies ist in der MapCanvasProjection von V3 zur Verfügung:

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

Sie fromLatLngToDivPixel können die tatsächlichen Pixelwerte für die Punkte auf Ihrem Raphael Polygon um herauszufinden, was es zeichnen, dann ist es mit einem zu dem Overlay hinzufügen Ereignis ziehen

+0

Im Nachhinein - ich habe festgestellt, dass meine Polygon-Objekte viel schneller als GPolygon-Objekte in V2 durchgeführt - ich weiß nicht, wie sie in V3 ausführen, aber ich habe festgestellt, dass das Erstellen eigener Polygone direkt mit SVG/VML zu einem viel leichteren Objekt Sie haben mehr Kontrolle direkt. Ich bin nicht sicher, ob Google jetzt SVG/VML oder Canvas verwendet, um ihre Polygone zu zeichnen - es hat sich mehrmals in den Versionen geändert. – John

1

Sie könnten Marker für jeden Punkt auf dem Polygon haben, diese Marker könnten ziehen und am Ende jedes Ziehens könnte das Polygon neu gezeichnet werden.

Sie könnten auch einen Marker in der Mitte des Polygons haben, der das Polygon als Ganzes darstellt. Wenn Sie diesen Marker verschieben, kann jeder Marker um den gleichen Betrag verschoben werden, um die Form beizubehalten.

+0

Können Sie Click/Drag-Listener usw. auf dem GMap selbst hinzufügen und die Berechnung durchführen, wenn der Klick innerhalb des Polyons war oder nicht? – paullb

1

Okay - nachdem ich die Website gesehen habe, die Sie zu implementieren versuchen, habe ich das Gefühl, dass Raphael nicht notwendig ist, weil es eine ziemlich schwere JS Library ist - und wenn Sie nur ein Rechteck Polygon zeichnen wollen, dachte ich, warum nicht nur mit einem einzigen leichten DIV?

Allerdings denke ich, die Raphael-Lösung würde noch Wasser für viele andere Fälle halten - so denke ich, werde ich nur eine andere mögliche Antwort posten. Hier

ist ein funktionierendes Beispiel, das ich zusammen warf:

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

Fühlen Sie sich frei einen Blick auf die Quelle zu nehmen:

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

Im Wesentlichen haben wir die folgende

  1. Erstellen Sie das benutzerdefinierte Overlay
  2. Erstellen Sie die ziehbar div Polygon und jQuery UI verwenden, stellen Sie es ziehbar
  3. Tie ein Ereignis, das hört, wenn das Ziehen aufgehört hat, die die LatLng Position des Rechtecks ​​aktualisiert
  4. Fügen Sie das Objekt den benutzerdefinierten Overlay
  5. Implementieren Sie die Zeichenfunktion das Rechteck während zoomt neu zu zeichnen und Pfannen

derzeit nur für das Rechteck eines LatLng Wert ich bin Speicher (die linke obere Ecke ist) - Sie dieses Beispiel leicht erweitern könnte alle 4 Punkte zu speichern des Rechtecks ​​und haben die Form dynamica Stellen Sie die Größe auf Zooms ein. Vielleicht möchten Sie das tun, denn wenn die Benutzer auszoomen, erhalten sie einen Klimareport für ein größeres und größeres Gebiet.

+0

@Dave: Ah, das hört sich jetzt nach einer interessanten Sache an - für komplexe Polygonformen ist es vielleicht am besten, SVG/VML zu lernen - es ist wirklich nicht so schlimm, wenn nicht ein bisschen mühsam - so könnte man es jedoch im Auge behalten viele Punkte und zeichne jede beliebige Form in beliebiger Größe. Oh, und Sie sind herzlich willkommen! Meine eigenen verbesserten GPolygon-Objekte zu machen, war vor ein paar Jahren ein großes Dilemma für mich, und ich bin wirklich glücklich, alles weiterzugeben, was ich gelernt habe, um jemandem anderen zu helfen. – John

+0

Ab heute 12.04.2015 habe ich sowohl auf IE als auch auf Chrome versucht, das Polygon ist nicht ziehbar. – user2618844

2

Hier ist, wie ich es mache. Suchen Sie nach der ungefähren Mitte des Polygons, fügen Sie einen Marker hinzu und fügen Sie dem Marker einen Zieh-Listener hinzu. Bei Änderung lat/lng subtrahiere die Differenz vom ursprünglichen Marker lat/lng, subtrahiere die Differenz zu jedem der Pfade und setze dann die ursprüngliche Position auf die neue Position. Stellen Sie sicher, dass in Ihrem Javascript-API-Aufruf, die Sie Bibliothek = Geometrie haben, zeichnen

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

Wenn Sie Fragen haben, zögern Sie nicht mich zu kontaktieren.

4

Seit der Version 3.11 (vom 22. Januar 2013) ist es möglich, die draggable-Eigenschaft einfach auf die google.maps.Polygon Instanz zu setzen; siehe this example. Wenn Sie ein Polygon programmgesteuert verschieben möchten, benötigen Sie a custom Google Maps Extension which I wrote, da die API keine solche Methode bereitstellt.