4 votes

Vous recherchez une carte du monde avec une projection spécifique en d3js

J'ai joué avec les cartes d3js (v5), j'essaie de générer cette carte (la capture d'écran a été prise à partir d'un site web aléatoire), Pour mon cas particulier, il n'est pas nécessaire de présenter l'Antarctique.

enter image description here

J'ai lu la documentation ici : https://github.com/d3/d3-geo#projections, et suivi les instructions et utilisé geoMercator, j'ai obtenu cette carte plate qui est coupée dans le nord supérieur pour une raison quelconque.

enter image description here

Quelle est l'approche correcte pour obtenir la mise en page de la première carte? Des suggestions?

1 votes

Tout d'abord, il est important de préciser qu'il n'y a pas de carte dans D3, D3 est juste une collection de méthodes. Cela étant dit, pour supprimer l'Antarctique, examinez les propriétés de votre fichier de carte : vous avez probablement un code ISO alpha 2 ou 3. Ainsi, filtrez simplement l'Antarctique. Par exemple : stackoverflow.com/a/48228748/5768908

0 votes

@Gerardo Furtado merci pour votre réponse, je vais filtrer l'Antarctique, cela semble en effet être une tâche facile, mais comment puis-je montrer la partie nord de la carte qui est coupée ?

9voto

Andrew Reid Points 16844

La projection que vous regardez est une projection de Mercator.

Avec d3.geoMercator(), la valeur de l'échelle est dérivée de la circonférence du cylindre formant la surface de projection. La valeur de l'échelle est le nombre de pixels par radian. La valeur par défaut anticipe l'étirement des 360 degrés du cylindre sur 960 pixels : 960/Math.PI/2.

Pour les distances angulaires verticales, il n'y a pas de facteur d'échelle, à mesure que l'on se déplace vers des longitudes extrêmes, la distance angulaire entre les points est de plus en plus exagérée, de sorte que les pôles seront à ± infini sur l'axe des y. En raison de cela, les projections de Mercator, en particulier les projections web de Mercator, sont souvent tronquées à environ ±85 degrés. Avec une étendue de [-180,85] et [180,-85], un Mercator est un carré.

Cette limite est incorporée dans d3-geoMercator, qui "Définit une projection.clipExtent par défaut de telle sorte que le monde est projeté dans un carré, coupé à environ ±85° de latitude. (docs)"

Cela signifie que si nous voulons montrer l'étendue complète d'un d3-geoMercator, sur 960 x 960 pixels, nous pouvons utiliser :

d3.geoMercator()
 .scale(960/Math.PI/2)  // 960 pixels sur 2 radians
 .translate([480,480])  // le centre du SVG/canvas

Ce qui nous donne :

entrer la description de l'image ici

Le centre par défaut de d3-geoMercator est [0°,0°], donc si nous voulons que [0°,0°] soit au milieu du SVG/canvas, nous décalons le centre pour qu'il soit au milieu, avec un décalage de [largeur/2,hauteur/2]

Maintenant que nous montrons le monde entier, nous pouvons affiner pour ne montrer que la partie que nous voulons. La méthode la plus simple pourrait être de couper des pixels en bas du svg/canvas. Utilisant le code ci-dessus avec une hauteur de canvas/svg de 700 pixels (et gardant 960 pixels de large, en utilisant le même échelle et la même translation) j'obtiens :

entrer la description de l'image ici

Je n'ai pas retiré l'Antarctique de cette image - il se trouve juste qu'il est coupé sans avoir besoin de le filtrer (ce n'est pas nécessairement une pratique idéale : il est toujours dessiné).

Ainsi, un SVG/Canvas de largeur 960, hauteur 700, avec une échelle de projection de 960/Math.PI/2 et une translation de [480,480] semble être correct. Ces valeurs s'adapteront ensemble pour différentes tailles de viewport.

Avec des cartes, il y a souvent beaucoup d'ajustements visuels pour obtenir l'effet visuel désiré, ajuster projection.translate() ou projection.center() peut aider à déplacer la carte à l'endroit souhaité. Mais nous pouvons le faire de manière computationnelle. Je vais parler ici d'une méthode, en utilisant projection.fitSize() (bien que cela ne résoudra pas le rapport de format requis sans étapes supplémentaires).

projection.fitSize([largeur,hauteur],geojson) prend un tableau spécifiant les dimensions du SVG/canvas et un objet geojson et ajuste l'échelle de projection et les valeurs de translation de telle sorte que l'entité geojson soit contenue dans le SVG/canvas. L'entité geojson pourrait être une boîte englobante de la partie du monde que vous voulez montrer, alors vous pourriez utiliser :

projection.fitSize([largeur,hauteur], {
    type: "Polygon",
    coordinates: [[ 
      [-179.999,84] , 
      [-179.999,-57] , 
      [179.999,-57] , 
      [179.999,84], 
      [-179.999,84] 
     ]]
   })

Là où ~84 degrés au nord est l'extrémité nord du Groenland et ~56 degrés au sud est approximativement la pointe de l'Amérique du Sud. Cela garantira que l'ensemble de la partie du monde que vous voulez voir est visible. Cependant, comme mentionné ci-dessus, cela ne tient pas compte du rapport de format, donc si vous contraignez l'étendue ci-dessus à des dimensions carrées, vous montrerez toujours l'ensemble complet du Mercator.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X