risposta

6

Ho trovato che l'implementazione di Google Maps V2 Polygon è molto limitante per i bisogni che ho avuto e l'ho risolta creando una sovrapposizione personalizzata. Il mio gruppo è attualmente bloccato su IE6, quindi devo ancora eseguire la migrazione su Google Maps V3, ma dare un'occhiata all'API dimostra che probabilmente si potrebbe fare una cosa simile che ho fatto in V2 con V3.

In sostanza l'idea è:

  1. Creare un modulo elettronico personalizzato
  2. popolarlo con i propri SVG/VML poligoni e allegare un evento di trascinamento a questo oggetto poligonale personalizzato

Sovrapposizioni personalizzate:

Ecco alcune informazioni per iniziare a farti r proprio modulo elettronico personalizzato:

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


Creare il proprio "Dragable" Poligono Oggetto:

volta che si ottiene che verso il basso si vorrà aggiungere i propri poligoni al modulo elettronico personalizzato al posto di usando GPolygons. Sono passato attraverso il doloroso processo di apprendimento di SVG/VML e la scrittura di una libreria per collegare insieme SVG/VML - potreste farlo, ma raccomanderei di iniziare provando ad usare un'altra libreria come Raphaël.

http://raphaeljs.com/

Utilizzando Raphaël vi farà risparmiare un sacco di tempo a cercare di capire come ottenere cross-browser grafica vettoriale (Poligono) funzionalità - e meglio di tutti Supporta eventi di trascinamento già, ecco un esempio dalla loro biblioteca:

http://raphaeljs.com/graffle.html

volta che hai un modulo elettronico personalizzato e si è in grado di gettare un po Raphaël oggetti su di esso l'ultimo passo è quello di tradurre le coordinate che si desidera da un valore di Lat/Lng a un valore di pixel . Questo è disponibile nel MapCanvasProjection di V3:

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

È possibile utilizzare fromLatLngToDivPixel per capire quali sono i valori dei pixel effettivi sono per i punti sulla poligono Raphael, disegnarlo, quindi aggiungerlo alla sovrapposizione con un trascinare l'evento.

+0

Come ripensamento: ho scoperto che i miei oggetti Polygon venivano eseguiti molto più velocemente degli oggetti GPolygon in V2 - Non so come si comportano in V3, ma ho scoperto che creare i propri poligoni direttamente con SVG/VML si traduce in un oggetto molto più leggero che hai più controllo direttamente. Non sono sicuro che Google stia utilizzando SVG/VML o Canvas per disegnare i loro poligoni: è cambiato un paio di volte in tutte le versioni. – John

1

Potresti avere marcatori per ogni punto del poligono, questi marcatori avrebbero potuto trascinare e alla fine di ogni trascinamento, il poligono potrebbe essere ridisegnato.

Si potrebbe anche avere un marcatore al centro del poligono che rappresenta il poligono nel suo insieme, quando si sposta quel marcatore, ogni marker può essere spostato della stessa quantità per mantenere la forma.

+0

È possibile aggiungere click/trascina listener ecc. Sul GMap stesso e fare il calcolo se il clic era all'interno del poligono oppure no? – paullb

1

Ok, quindi dopo aver visto il sito Web che stai cercando di implementare ho iniziato a pensare che Raphael potrebbe non essere necessario perché è una libreria JS piuttosto pesante, e se stai solo provando a disegnare un rettangolo di poligono ho pensato, perché non farlo semplicemente con un solo DIV leggero?

Comunque penso che la soluzione di Raffaello possa ancora contenere l'acqua per molti altri casi - quindi penso che pubblicherò solo un'altra possibile risposta.

Ecco un esempio di lavoro ho buttato insieme:

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

Sentitevi liberi di dare un'occhiata alla fonte:

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

In sostanza facciamo il seguente

  1. Creare la sovrapposizione personalizzata
  2. Creare il poligono div trascinabile e, utilizzando jQuery UI, lo rendono trascinabile
  3. Tie un evento che ascolta quando il trascinamento si è fermato che aggiorna la posizione LatLng del rettangolo
  4. Aggiungere l'oggetto al modulo elettronico personalizzato
  5. implementare la funzione draw per ridisegnare il rettangolo durante zoom e panoramica

Attualmente sto solo la memorizzazione di un valore LatLng del rettangolo (essendo l'angolo in alto a sinistra) - si potrebbe facilmente estendere questo esempio per memorizzare tutti i 4 punti del rettangolo e avere la forma dynamica ridimensionare se stesso sugli zoom. Potresti volerlo fare, altrimenti quando gli utenti ridurranno lo zoom riceveranno un rapporto sul clima per un'area sempre più grande.

+0

@Dave: Ah ora sembra una cosa interessante da risolvere - per fare forme poligonali complesse potresti imparare meglio SVG/VML - non è poi così male, se non un po 'noioso - in questo modo puoi comunque tenere traccia di molti punti e disegna qualsiasi forma in qualsiasi dimensione tu voglia. Oh e tu sei il benvenuto! Costruire i miei oggetti GPolygon migliorati è stato un grande dilemma per me un paio di anni fa, quindi sono davvero felice di trasmettere tutto ciò che ho imparato per aiutare qualcun altro. – John

+0

A partire da oggi il 12/4/2015, ho provato sia su IE che su Chrome, il poligono non è trascinabile. – user2618844

2

Ecco come lo faccio. Trova il centro approssimativo del poligono e aggiungi un marcatore, quindi aggiungi un indicatore di trascinamento all'indicatore. Al cambio lat/lng, sottrarre la differenza dal marcatore originale lat/lng, sottrarre la differenza a ciascuno dei percorsi, quindi impostare la posizione originale nella nuova posizione. Assicurarsi che nella chiamata API JavaScript che avete biblioteca = geometria, disegno

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

Se avete domande, non esitate a contattarmi.

4

Dalla versione 3.11 (datata 22 gennaio 2013) è possibile impostare la proprietà draggable sull'istanza google.maps.Polygon; vedi this example.

Se si desidera spostare un poligono a livello di codice, è necessario a custom Google Maps Extension which I wrote poiché l'API non fornisce tale metodo.