Centre d'une carte en d3 donné un geoJSON objet
Actuellement en d3 si vous avez un geoJSON objet que vous allez vous attirer de mettre à l'échelle et de le traduire afin de le rendre à la taille que l'on veut et de le traduire afin de le centrer. C'est un très fastidieuse tâche d'essais et d'erreurs, et je me demandais si quelqu'un connaissait une meilleure façon d'obtenir ces valeurs?
Si, par exemple, j'ai ce code
var path, vis, xy;
xy = d3.geo.mercator().scale(8500).translate([0, -1200]);
path = d3.geo.path().projection(xy);
vis = d3.select("#vis").append("svg:svg").attr("width", 960).attr("height", 600);
d3.json("../../data/ireland2.geojson", function(json) {
return vis.append("svg:g")
.attr("class", "tracts")
.selectAll("path")
.data(json.features).enter()
.append("svg:path")
.attr("d", path)
.attr("fill", "#85C3C0")
.attr("stroke", "#222");
});
Comment diable puis-je obtenir .échelle(8500) et .traduire([0, -1200]) sans aller petit à petit?
Vous devez vous connecter pour publier un commentaire.
La suite semble faire environ ce que vous voulez. La mise à l'échelle semble être ok. Lors de l'application à ma carte il y a un petit décalage. Ce petit décalage est probablement causée parce que je utiliser la traduire de commande au centre de la carte, alors que je devrais utiliser le centre de commande.
Dans le code:
projection.fitSize([width, height], geojson)
(API docs) - voir @dnltsk 's réponse ci-dessous.Ma réponse est proche de Jan van der Laan, mais vous pouvez simplifier un peu les choses parce que vous n'avez pas besoin de calculer le centre de gravité géographique; vous avez seulement besoin de la boîte englobante. Et, à l'aide d'un non mis à l'échelle, non traduite de l'unité de projection, vous pouvez simplifier les calculs.
L'importante partie du code est: est-ce
Après la composition de la fonction de boîte englobante dans l'appareil de projection, vous pouvez calculer l'appropriées échelle en comparant le ratio d'aspect de la boîte englobante (
b[1][0] - b[0][0]
etb[1][1] - b[0][1]
) pour le ratio d'aspect de la toile (width
etheight
). Dans ce cas, j'ai également mis à l'échelle de la boîte englobante de 95% de la toile, au lieu de 100%, donc il y a un peu d'espace supplémentaire sur les bords pour les contours et les caractéristiques environnantes ou de rembourrage.Ensuite, vous pouvez calculer la traduire en utilisant le centre de la boîte englobante (
(b[1][0] + b[0][0]) /2
et(b[1][1] + b[0][1]) /2
) et le centre de la toile (width /2
etheight /2
). À noter que depuis la boîte englobante est dans l'unité de projection de coordonnées, il doit être multiplié par l'échelle (s
).Par exemple, bl.ocks.org/4707858:
Il y a une question connexe, qui est de savoir comment zoomer sur une fonction spécifique dans une collection sans réglage de la projection, c'est à dire, combinant la projection avec une transformation géométrique pour zoomer et dézoomer. Qui utilise les mêmes principes que ci-dessus, mais le calcul est légèrement différent, car la transformation géométrique (le SVG "transformer" attribut) est combiné avec la projection géographique.
Par exemple, bl.ocks.org/4699541:
* 500
est étranger ici... aussi,b[1][1] - b[0][0]
devrait êtreb[1][1] - b[0][1]
dans le barème de calcul.b[x][y]
. Le tableau de tableaux de notation[x][y]
correspond à la syntaxe pour les liens et les images, probablement Mikes réponse est ici, mais l'analyseur foiré avec elle quand un lien/image a été ajoutée.b.s = b[0][1]; b.n = b[1][1]; b.w = b[0][0]; b.e = b[1][0]; b.height = Math.abs(b.n - b.s); b.width = Math.abs(b.e - b.w); s = .9 / Math.max(b.width / width, (b.height / height));
Je suis nouveau sur d3 - allons essayer d'expliquer comment je le comprends mais je ne suis pas sûr que je suis tout à droite.
Le secret est de savoir que certaines méthodes fonctionnent sur la cartographique de l'espace (latitude,longitude) et d'autres sur l'espace cartésien (x,y sur l'écran). La cartographique de l'espace (notre planète) est (presque) de forme sphérique, l'espace cartésien (écran) est plat afin de cartographier l'un sur l'autre vous avez besoin d'un algorithme, qui est appelé projection. Cet espace est trop court pour en profondeur dans le sujet fascinant de projections et comment ils déforment les caractéristiques géographiques dans le but de transformer sphérique dans un avion; certains sont conçus pour assurer la conservation des angles, d'autres de conserver les distances et ainsi de suite - il y a toujours un compromis (Mike Bostock a un énorme collection d'exemples).
En d3, la projection de l'objet dispose d'un centre de propriété/définition, donnée dans les unités de la carte:
Il y a aussi la traduction, donnée en pixels - où le centre de projection des stands par rapport à la toile:
Quand je veux le centre d'une fonction dans la toile, j'aime le centre de projection du centre de la fonctionnalité de la boîte englobante - ce qui fonctionne pour moi lors de l'utilisation de mercator (WGS 84, utilisé dans google maps) pour mon pays (Brésil), jamais testé à l'aide d'autres projections et les hémisphères. Vous pourriez avoir à faire des ajustements pour d'autres situations, mais si vous le clou de ces principes de base, vous serez bien.
Par exemple, étant donné une projection et le chemin d'accès:
La
bounds
méthode depath
retourne la boîte englobante en pixels. L'utiliser pour trouver la bonne échelle, la comparaison de la taille en pixels de la taille dans les unités de la carte (0.95 vous donne une marge de 5% sur le meilleur ajustement de la largeur ou de la hauteur). Géométrie de base ici, le calcul du rectangle de la largeur/hauteur compte tenu de la diagonale opposée coins:Utiliser le
d3.geo.bounds
méthode pour trouver la boîte englobante dans les unités de la carte:Définir le centre de la projection du centre de la boîte englobante:
Utiliser le
translate
méthode pour déplacer le centre de la carte au centre de la toile:Maintenant vous devriez avoir la caractéristique dans le centre de la carte agrandie avec une marge de 5%.
Avec d3 v4 son obtention plus facile!
et enfin
Profiter, Des Acclamations
d3v4
pendant un certain temps et viens de découvrir cette méthode.g
viennent? Est ce que le conteneur svg?g
devrait être<g></g>
tagIl y a un (centre) méthode que vous pouvez utiliser qui accepte un lat/lon paire.
De ce que je comprends, translate() est utilisée uniquement pour l'littéralement déplacer les pixels de la carte. Je ne suis pas sûr de la façon de déterminer quelle est l'échelle.
Je regardais autour de moi sur l'Internet pour un tracas de façon libre au centre de ma carte, et j'ai eu envie de Jan van der Laan et mbostock de réponse. Voici un moyen plus facile à l'aide de jQuery si vous utilisez un récipient pour le svg. J'ai créé une frontière de 95% de remplissage/de frontières, etc.
Si vous à la recherche exacte de la mise à l'échelle, cette réponse ne fonctionnera pas pour vous. Mais si comme moi, vous souhaitez afficher une carte qui centralise dans un récipient, cela devrait être suffisant. J'ai essayé d'afficher la carte de mercator et a constaté que cette méthode est utile dans la centralisation de ma carte, et je pourrais facilement couper la partie de l'Antarctique depuis que je n'en avais pas besoin.
En plus de Centre d'une carte en d3 donné un geoJSON objet, notez que vous pouvez préférer
fitExtent()
surfitSize()
si vous souhaitez spécifier un rembourrage autour des limites de votre objet.fitSize()
définit automatiquement ce padding à 0.Pan/zoom sur la carte, vous devriez regarder la superposition du SVG sur la Notice. Qui seront beaucoup plus facile que de transformer le format SVG. Voir cet exemple http://bost.ocks.org/mike/leaflet/ et puis Comment faire pour modifier le centre de la carte en dépliant
Avec mbostocks de réponse, et d'Herbes Caudill commentaire, j'ai commencé à courir dans des problèmes avec l'Alaska depuis que j'ai été à l'aide d'une projection de mercator. Il est à noter que pour mes propres fins, je suis en train de projet et le centre des Etats-unis. J'ai trouvé que j'avais de marier les deux réponses avec Jan van der Laan réponse avec l'exception suivante pour les polygones qui se chevauchent hémisphères (polygones que l'extrémité avec une valeur absolue Est - Ouest qui est supérieure à 1):
créé une simple projection de mercator:
projection = d3.geo.mercator().l'échelle(1).traduire([0,0]);
créer le chemin d'accès:
path = d3.geo.path().la projection(la projection);
3.définir mes limites:
4.Ajouter exception de l'Alaska et les états qui se chevauchent les hémisphères:
J'espère que cette aide.
Pour les gens qui veulent régler verticaly et horizontaly, voici la solution :
Comment je centrée sur un Topojson, où j'avais besoin de sortir de la fonction: