Ich bin neu in d3 - werde versuchen zu erklären, wie ich es verstehe, aber ich bin nicht sicher, ob ich alles richtig gemacht habe.
Das Geheimnis ist zu wissen, dass einige Methoden im kartografischen Raum (Breite, Länge) und andere im kartesischen Raum (x, y auf dem Bildschirm) funktionieren. Der kartografische Raum (unser Planet) ist (fast) sphärisch, der kartesische Raum (Bildschirm) ist flach - um einen übereinander abzubilden, benötigen Sie einen Algorithmus, der als Projektion bezeichnet wird . Dieser Raum ist zu kurz, um tief in das faszinierende Thema der Projektionen einzudringen und wie sie geografische Merkmale verzerren, um sphärisch in eben zu verwandeln. Einige sind so konzipiert, dass Winkel erhalten bleiben, andere Entfernungen usw. - es gibt immer einen Kompromiss (Mike Bostock hat eine riesige Sammlung von Beispielen ).
In d3 hat das Projektionsobjekt eine Center-Eigenschaft / einen Setter, die in Karteneinheiten angegeben ist:
projection.center ([Ort])
Wenn Mitte angegeben ist, wird die Mitte der Projektion auf die angegebene Position festgelegt, ein Array mit zwei Elementen aus Längen- und Breitengrad in Grad, und die Projektion wird zurückgegeben. Wenn Mitte nicht angegeben ist, wird die aktuelle Mitte zurückgegeben, die standardmäßig ⟨0 °, 0 °⟩ ist.
Es gibt auch die Übersetzung in Pixel - wobei das Projektionszentrum relativ zur Leinwand steht:
projection.translate ([point])
Wenn point angegeben ist, wird der Translationsversatz der Projektion auf das angegebene Array mit zwei Elementen [x, y] festgelegt und die Projektion zurückgegeben. Wenn point nicht angegeben ist, wird der aktuelle Übersetzungsoffset zurückgegeben, der standardmäßig [480, 250] ist. Der Translationsversatz bestimmt die Pixelkoordinaten des Projektionszentrums. Der Standard-Translationsversatz platziert ⟨0 °, 0 °⟩ in der Mitte eines 960 × 500-Bereichs.
Wenn ich ein Feature auf der Leinwand zentrieren möchte, möchte ich das Projektionszentrum auf die Mitte des Feature-Begrenzungsrahmens setzen. Dies funktioniert bei Verwendung von mercator (WGS 84, in Google Maps verwendet) für mein Land (Brasilien). nie mit anderen Vorsprüngen und Halbkugeln getestet. Möglicherweise müssen Sie Anpassungen für andere Situationen vornehmen, aber wenn Sie diese Grundprinzipien festlegen, wird es Ihnen gut gehen.
Beispiel: Projektion und Pfad:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
Die bounds
Methode von path
gibt den Begrenzungsrahmen in Pixel zurück . Verwenden Sie diese Option, um den richtigen Maßstab zu finden, indem Sie die Größe in Pixel mit der Größe in Karteneinheiten vergleichen (0,95 ergibt einen Rand von 5% gegenüber der besten Anpassung für Breite oder Höhe). Grundlegende Geometrie hier, Berechnung der Rechteckbreite / -höhe bei diagonal gegenüberliegenden Ecken:
var b = path.bounds(feature),
s = 0.9 / Math.max(
(b[1][0] - b[0][0]) / width,
(b[1][1] - b[0][1]) / height
);
projection.scale(s);
Verwenden Sie die d3.geo.bounds
Methode, um den Begrenzungsrahmen in Karteneinheiten zu finden:
b = d3.geo.bounds(feature);
Stellen Sie die Mitte der Projektion auf die Mitte des Begrenzungsrahmens ein:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
Verwenden Sie die translate
Methode, um die Mitte der Karte in die Mitte der Leinwand zu verschieben:
projection.translate([width/2, height/2]);
Inzwischen sollte die Funktion in der Mitte der Karte mit einem Rand von 5% gezoomt sein.