5 Stimmen

JavaScript: beste Methode zur Aufrechterhaltung von Grenzen (Google Maps)?

Ich verwende die Google Maps v3 API . Ich stelle derzeit eine Anfrage, um jedes Mal, wenn eine Person das Ansichtsfenster ändert (entweder durch Zoomen oder Verschieben der Karte), neue Daten abzurufen, und werfe die alten Daten weg, die ich habe. Das funktioniert prima, aber jetzt möchte ich die Daten zwischenspeichern, damit ich sie nicht jedes Mal abrufen muss, wenn sich das Ansichtsfenster ändert. Die Google Maps API definiert ein Ansichtsfenster durch seine nordöstlichen und südwestlichen Koordinaten, die aus einem Breitengrad und einem Längengrad bestehen. Sie werden in Objekten namens LatLngBounds .

Ich habe mir 2 Möglichkeiten ausgedacht, wie ich dies tun kann:

  1. Speichern Sie die Grenzen jedes neuen Ansichtsfensters, das der Benutzer besucht, und prüfen Sie, ob das neue Ansichtsfenster in einem alten Ansichtsfenster liegt, und holen Sie neue Daten nur für den Teil des neuen Ansichtsfensters, der nicht in einem alten Ansichtsfenster liegt. Im Wesentlichen,
  2. Unterteilen Sie jedes neue Ansichtsfenster in rechteckige Abschnitte mit Daten, die bereits vorhanden sind, und Daten, die abgerufen werden müssen. Speichern Sie die Grenzen der einzelnen rechteckigen Abschnitte.

Falls jemandem eine bessere Lösung einfällt, kann er gerne neue Ansätze vorschlagen.

Meine Frage ist, welche Lösung in Bezug auf Leistung/Speichernutzung und Gesamtgeschwindigkeit besser ist? Sie sind beide ähnliche Algorithmen so ist es wirklich wichtig?

Außerdem basieren beide Algorithmen derzeit auf der Aufteilung des neuen Ansichtsfensters auf der Grundlage der alten Ansichtsfenster. Wie würde der Algorithmus zur Aufteilung neuer Ansichtsfenster aussehen? (Angenommen, ich habe meinen 2. Algorithmus implementiert)

var prevBounds = [ /* Array of previously seen bounds */ ];
var newViewport = map.getBounds(); // New Viewport to divide up
var sw = newViewport.getSouthWest();
var swlat = sw.lat();
var swlng = sw.lng();
var ne = newViewport.getNorthEast();
var nelat = ne.lat();
var nelng = ne.lng();
// newViewport.intersects(bounds) 
// Returns true if this bounds shares any points with this bounds.

1voto

nrabinowitz Punkte 54138

Ich könnte in Erwägung ziehen, dies mehr oder weniger genau so zu machen, wie Google Kartenkacheln serviert - anstatt Daten für das gesamte Ansichtsfenster auf einmal zu laden, zerlegen Sie die gesamte Karte in quadratische Bereiche (obwohl wahrscheinlich größere Bereiche als Googles 256x256 Kacheln), bestimmen, welche Bereiche im aktuellen Ansichtsfenster sind, und laden Sie Daten für diese Bereiche. Wenn der Benutzer die Karte schwenkt und zoomt, überprüfen Sie die Grenzen des Ansichtsfensters, um zu sehen, ob neue Bereiche in den Rahmen gekommen sind, und laden Sie sie bei Bedarf. Grober Pseudocode:

var cache = {}

function onViewportChange() {
    // get new bounds
    var bounds = map.getBounds();
    // identify all the areas in the bounds
    var areas = getAreas(bounds);
    areas.forEach(function(area) {
        if (area.key in cache) {
            // do nothing, or load items from cache
        } else {
            // load new data, storing the key (and maybe the data) 
            // to the cache
        }
    })
}

function getAreas(bounds) {
    /* given a set of bounds, return an array of objects like:
    [
        {
           x: 1,
           y: 2,
           zoom: 4,
           key: "4-1,2",
           bounds: b // lat/lon bounds of this area
        },
        ...
    ]
    */
}

(Siehe die Google Erklärung der Kartenkoordinaten y dieses Beispiel für eine Idee, wie man die getAreas .)

Der Reiz daran ist, dass die Bereiche, die Sie abrufen, viel einfacher sind, und es wird sehr einfach zu überprüfen, ob Sie bereits Daten für einen bestimmten Bereich geladen haben - jeder Bereich kann einen einfachen eindeutigen Schlüssel haben, wahrscheinlich eine Zeichenkette, die aus den x/y/zoom-Koordinaten besteht, und wenn jeder neue Bereich geladen wird, speichern Sie den Schlüssel (oder vielleicht den Schlüssel und die Daten - es hängt davon ab, ob Sie alte Daten aus der Karte entfernen oder sie einfach dort lassen) in einem Cache-Objekt. Wenn sich das Ansichtsfenster dann in einen neuen Bereich bewegt, müssen Sie nur noch prüfen, ob dieser Schlüssel im Cache vorhanden ist.

Der Nachteil ist, dass Sie möglicherweise oft Daten außerhalb des aktuellen Ansichtsfensters laden und wahrscheinlich mehr Anfragen an den Server senden, als Sie es mit den von Ihnen vorgeschlagenen Implementierungen tun würden. Diese Methode könnte am besten funktionieren, wenn Sie verschiedene Daten in verschiedenen Zoomstufen bereitstellen - andernfalls könnten Sie feststecken, wenn Sie versuchen, einen Cache-Bereich mit einer einzigen Größe zu wählen, der bei verschiedenen Zooms gut funktioniert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X