2013-08-23 4 views
9

Ich versuche, ein Infofenster in Google Maps anzuzeigen. Es zeigt perfekt an, wenn Sie über einen Marker fahren, wird ein Infofenster geladen, aber die Karte springt in das Fenster. Ich möchte nicht, dass sich die Karte bewegt, sondern vielmehr ihre Position entsprechend der Karte einstellt. Booking.com hat so etwas.Verhindern, dass Google Maps nach der Anzeige von Infowindow verschoben wird

EDIT: Hinzugefügt meinen Code

Hier ist die abgespeckte Version von meinem Code. Ich bekomme alle Informationen von einem AJAX Service und dieser Service gibt response zurück (was auch weitere Informationen enthält).

$.ajax({ 
    url: 'URL', 
    dataType: "json", 
    type: "GET", 
    success: function(response) { 
     // delete all markers 
     clearOverlays(); 

     var infowindow = new google.maps.InfoWindow(); 

     for (var i = 0; i < response.length; i++) { 
      item = response[i]; 

      var marker = new google.maps.Marker({ 
       position: new google.maps.LatLng(item.lat, item.lng), 
       map: map, 
       url: item.detail_url 
      }); 

      markersArray.push(marker); 

      // display infowindow 
      google.maps.event.addListener(marker, "mouseover", (function(marker, item) { 
       return function() { 
        infowindow.setOptions({ 
         content: 'SOME CONTENT HERE FOR INFOWINDOW' 
        }); 

        infowindow.open(map, marker); 
       } 
      })(marker, item)); 

      // remove infowindow 
      google.maps.event.addListener(marker, 'mouseout', function() { 
       infowindow.close(); 
      }); 

      // marker click 
      google.maps.event.addListener(marker, 'click', function() { 
       window.location.href = marker.url; 
      }); 
     } 
    } 
}); 

Wie Sie unten sehen können, zeigt das erste Bild das Infofenster am unteren Rand des Marker angezeigt, während zweite das Infofenster auf der Markierung angezeigt wird, zeigt. Die Karte bewegt sich nicht, sondern Infowindow setzt ihre Position innerhalb der Grenzen der Karte.

Infowindow bottom of marker Infowindow on top of marker

+0

Was macht Ihr Code wie diese Funktionalität Blick zu implementieren? – geocodezip

+0

Mein Javascript-Code hinzugefügt. –

Antwort

30

In Ihrer Erklärung die Infofenster Optionen zur Einstellung infowindow.setOptions, fügen Sie die folgende Option, um das Schwenken der Karte zu deaktivieren, wenn das Infofenster angezeigt wird, disableAutoPan : true.

Dies bedeutet jedoch auch, dass Sie die verfügbaren Immobilien berechnen müssen, um das Infowindow auf Ihrer Karte anzuzeigen, und geben Sie eine Position mit der Option position ein. Andernfalls wird nicht garantiert, dass Ihr Infofenster auf der Karte vollständig sichtbar ist.

https://developers.google.com/maps/documentation/javascript/reference#InfoWindowOptions

EDIT: Wie Bildschirm Immobilien

Ich weiß, ich war ziemlich vage mit meinem Vorschlag zur Berechnung der Bildschirm Immobilien die Position Ihrer Infofenster gesetzt zur Verfügung zu berechnen, wenn Teil Ihrer Frage war, die Position des Infowindows tatsächlich festzulegen. Also habe ich ein Update für meine Antwort zur Verfügung gestellt, wie Sie die Bildschirm-Immobilien berechnen und die Position Ihres Infofensters anpassen können.

Der Schlüssel besteht darin, zuerst Ihre Punkte von LatLng in Pixel zu konvertieren und die Pixelkoordinate des Markers auf der Karte in Bezug auf die Pixelkoordinate des Kartenmittelpunkts herauszufinden. Der folgende Ausschnitt zeigt, wie dies durchgeführt werden kann.

getPixelFromLatLng: function (latLng) { 
    var projection = this.map.getProjection(); 
    //refer to the google.maps.Projection object in the Maps API reference 
    var point = projection.fromLatLngToPoint(latLng); 
    return point; 
} 

Sobald Sie Ihre Pixelkoordinaten haben, müssen Sie herausfinden, welche Quadranten der Karte Leinwand Marker zur Zeit in residiert. Dies wird durch den Vergleich des X erreicht wird und Y-Koordinaten des Markers die Karte, etwa so:

quadrant += (point.y > center.y) ? "b" : "t"; 
quadrant += (point.x < center.x) ? "l" : "r"; 

Hier bin ich zu bestimmen, ob der Punkt in der rechten unteren Ecke, unten links, oben rechts oder oben links Quadranten der Karte basiert auf sie relative Position auf der Karte Zentrum ist. Denken Sie daran, dass wir Pixel im Gegensatz zu LatLng-Werten verwenden, da LatLng-Werte immer das gleiche Ergebnis liefern - aber die Realität ist, dass der Marker abhängig vom Panning in jedem Quadranten des Kartenbereichs sein kann.

Sobald Sie wissen, in welchem ​​Quadranten der Marker in ist, können Sie Offset-Werte zu dem Infofenster geben sie zu positionieren, so dass es auf der Karte sichtbar ist - wie so:

if (quadrant == "tr") { 
    offset = new google.maps.Size(-70, 185); 
} else if (quadrant == "tl") { 
    offset = new google.maps.Size(70, 185); 
} else if (quadrant == "br") { 
    offset = new google.maps.Size(-70, 20); 
} else if (quadrant == "bl") { 
    offset = new google.maps.Size(70, 20); 
} 
//these values are subject to change based on map canvas size, infowindow size 

Sobald der Offset-Wert bestimmt wird, können Sie passen Sie einfach den pixelOffset Ihres Infofensters auf den Listener an, den Sie mit der Methode infoWindow.open() aufgerufen haben. Dies wird durch die Verwendung der setOptions() Methode für Infofenster getan:

infowindow.setOptions({pixelOffset : self.getInfowindowOffset(self.map, marker)}); 

Hier ist ein funktionierendes JSFiddle example der oben beschriebenen Lösung.

Hinweis: Sie den lästigen „Pfeil“ auf dem Infofenster bemerken desbite die Position Ihrer Infofenster angezeigt wird, ist dieser Teil des Standard für Infofenster Google-Karte Einstellung und ich konnte nicht eine richtige Art und Weise loszuwerden finden es. Es gab einen Vorschlag here, aber ich konnte es nicht zur Arbeit bringen. Alternativ können Sie die infobox library oder die infobubble library verwenden, die Ihnen mehr Styling-Optionen bietet.

+0

Danke Suvi Vignarajah. Ich kenne "disableAutoPan", aber das Problem ist, dass es mir nicht gelungen ist, die Immobilien auf der Karte zu berechnen und dem Infofenster eine Position mit der Option "Position" zu geben. –

+0

@BurakErdem Ich habe einen Ansatz zur Verfügung gestellt, den Sie verwenden können, um den Bildschirm Immobilien zu berechnen, um Ihre Infowindow entsprechend in meiner bearbeiteten Antwort zu positionieren. Hoffentlich gibt dir das etwas zum arbeiten. –

+1

Ihre Implementierung funktioniert großartig. Ich habe gerade Ihren Code aktualisiert (http://jsfiddle.net/SJCNp/2/), um den unteren Pfeil zu entfernen. Ich weiß, es ist nicht die beste Lösung, aber es funktioniert. Möglicherweise möchte jemand zusätzliches CSS hinzufügen, um die Google Maps-Infofensterfunktionen nachzuahmen. Vielen Dank. –

1

Suvi Vignarajahs Antwort ist großartig, was ich nicht mochte, war, wie unberechenbar die Position des Fensters in der Nähe der Ränder ist.

Ich zwickte es so, dass die Blase klebt an der Wand, wie es zu erwarten ist: http://jsfiddle.net/z5NaG/5/ ist

Die einzige Bedingung, dass Sie die width & height des Infowindow wissen müssen, können Sie es ganz gut positionieren kann. Du würdest es durch die Pixel der Karten herausfinden. Wenn Sie es nicht wissen, können Sie das InfoWindow auch außerhalb des Bildschirms initialisieren, seine Größe ermitteln und es an der richtigen Stelle wieder öffnen. Hässlich aber würde funktionieren.

Zuerst zum Zeitpunkt der Karten Initialisierung auf Overlay initialisieren, indem diese Funktion ausgeführt wird:

ourOverlay:null, 
    createOverlay:function(){ 
     this.ourOverlay = new google.maps.OverlayView(); 
     this.ourOverlay.draw = function() {}; 
     this.ourOverlay.setMap(this.map); 
    }, 

dann bei open Ereignisse an den Offset wie folgt:

getInfowindowOffset: function (map, marker) { 
    // Settings 
    var iwWidth = 240; // InfoWindow width 
    var iwHeight = 190; // InfoWindow Height 
    var xOffset = 0; 
    var yOffset = 0; 

    // Our point of interest 
    var location = this.ourOverlay.getProjection().fromLatLngToContainerPixel(marker.getPosition()); 

    // Get Edges of map in pixels: Sout West corner and North East corner 
    var swp = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getSouthWest()); 
    var nep = this.ourOverlay.getProjection().fromLatLngToContainerPixel(map.getBounds().getNorthEast()); 

    // Horizontal Adjustment 
    if(location.x<iwWidth/2){ 
     xOffset= iwWidth/2-location.x; 
    }else if(location.x>nep.x-iwWidth/2){ 
     xOffset = (nep.x-iwWidth/2)-location.x ; 
    } 

    // Vertical Adjustment 
    if(location.y<iwHeight){ 
     yOffset = location.y + iwHeight-(location.y-nep.y); 
    } 

    // Return it 
    return new google.maps.Size(xOffset, yOffset); 

}, 

Und das Ergebnis ist recht nett, aber Dieses Dreieck scheint jetzt fehl am Platz.

können Sie InfoBox verwenden Sie den spitzen Pfeil auf der Unterseite zu entfernen:

  GmapsManager.infowindow = new InfoBox({ 
      content:'', 
      alignBottom: true, 
      closeBoxURL: "", 
     }); 

und Stil der Blase mit dem folgenden Code:

.infobox-popup{ 
    background: #fff; 
    -webkit-border-radius: 3px; 
    border-radius: 3px; 
    padding: 5px; 
    margin-left: -100px; 
    margin-bottom: 30px; 
    width: 200px; 
    -webkit-box-shadow: 0 0 1px 0 #595959; 
    box-shadow: 0 0 1px 0 #595959; 
} 
+1

Kumpel hast du meinen Tag gerettet, wenn du die kaputten Links reparieren kannst wird das super (habe ich schon Infobox fixiert) –