4
votes

Carte Geojson avec D3 ne rendant qu'un seul chemin dans une collection d'entités

J'essaye de dessiner une carte geojson de certaines régions de la Colombie. Actuellement, il n'affiche qu'un seul chemin :,

 entrez la description de l'image ici

Ma collection de fonctionnalités comporte 52 fonctionnalités, mais je ne peux dessiner que celle-ci. Je ne sais pas ce que je fais de mal, je base mon code sur d'autres tutoriels. Comment puis-je faire pour afficher tous les chemins?

var features = mapData.features;
console.log(features);
// Update color scale domain based on data
// Draw each province as a path
 mapLayer.selectAll('path')
  .data(features)
 .enter().append('path')
  .attr('d', path)
  .attr('vector-effect', 'non-scaling-stroke')

Voici mon code complet:

https://plnkr.co/edit/kSDtyyoWr9TSEDZ5Letv?p=preview


0 commentaires

3 Réponses :


1
votes

Il trace tous les chemins. Voir le DOM pour le SVG dans un inspecteur de page Web pour confirmer. Cependant, vous ne voyez que celui du haut, qui se trouve être la plus grande zone en raison des remplissages. Essayez d'ajouter .style ('fill', 'none') à l'ajout de chemins dans JS. ou ce qui suit en CSS

path {
  fill: none
}


2 commentaires

Bien que cela traite le symptôme, cela ne résout pas en fait la cause première: l'ordre d'enroulement, le changement de remplissage à aucun limitera les options, par exemple la création d'un choroplèth ou permettre l'interaction de la souris pour chaque région.


@AndrewReid Absolument. Pour être clair, ce n'est pas ainsi que vous devez le faire. Au lieu de cela, c'est une réponse à la raison pour laquelle vous ne pouvez pas voir les autres chemins dans le SVG. Inverser l'ordre de rendu / sonnerie est le moyen de s'y prendre en effet



5
votes

Toutes vos fonctionnalités sont dessinées, vous utilisez correctement votre chemin et entrez dans le cycle. Pour voir, définissez votre remplissage sur aucun:

 entrez la description de l'image ici

Vous pouvez les voir en inspectant le svg: tous les chemins sont là.

Pourquoi ne les voyez-vous pas sur la carte quand ils sont remplis? Parce que les polygones sont inversés, ils couvrent le monde entier à l'exception de la région d'intérêt. Alors que la plupart des autres bibliothèques / moteurs de rendu géographiques traitent geojson comme cartésien, D3 ne le fait pas. Cela signifie que l'ordre de liquidation est important. Vos coordonnées sont enroulées dans le mauvais ordre.

Pour remplir correctement, dessiner toutes les entités et prendre en charge l'interaction avec la souris, vous devrez inverser l'ordre d'enroulement des polygones. Vous pouvez le faire à la volée ou créer de nouveaux fichiers geojson pour stocker les données pré-inversées.

Pour ce faire, examinons vos données. Vous travaillez uniquement avec des fonctionnalités multiPolygones, regardons la structure:

 features.forEach(function(feature) {
   if(feature.geometry.type == "MultiPolygon") {
     feature.geometry.coordinates.forEach(function(polygon) {

       polygon.forEach(function(ring) {
         ring.reverse();
       })
     })
   }
   else if (feature.geometry.type == "Polygon") {
     feature.geometry.coordinates.forEach(function(ring) {
       ring.reverse();
     })  
   }
 })

Les coordonnées sont structurées comme suit:

 features.forEach(function(feature) {
   if(feature.geometry.type == "MultiPolygon") {
     feature.geometry.coordinates.forEach(function(polygon) {
       polygon.forEach(function(ring) {
         ring.reverse(); 
       })
     })
   }
 })

Les polygones individuels sont structurés de la manière suivante:

[x,y],[x,y]....

Les anneaux de polygones sont structurés comme un tableau de longs lats, les première et dernière valeurs étant identiques.

 [outer ring][inner ring][inner ring]... // an array of coordinates for an outer ring, an array of coordinates for each hole (inner ring).

Donc, pour inverser l'ordre des coordonnées, nous devons inverser les éléments dans les tableaux en anneau:

 coordinates:[polygons] // an array of polygons

Si nous avions polygones dans le mélange aussi (ils sont légèrement moins imbriqués), nous pourrions utiliser:

{ 
  type:"Feature",
  properties: {...},
  geometry: {
    type: "MultiPolygon",
    coordinate: /* coordinates here */
  }
}

Voici une mise à jour plunker


0 commentaires

0
votes

Si quelqu'un voit un problème similaire, j'ai créé un outil qui vous aidera à rembobiner ou inverser geojson

https://observablehq.com/@bumbeishvili/rewind-geojson

Vous pouvez l'exécuter comme un extrait juste en dessous

<div class="notebook-content">
  
</div>

<script type="module"> 

import notebook from "https://api.observablehq.com/@bumbeishvili/rewind-geojson.js";  //  "download code" url

document.querySelector('.notebook-content').innerHTML =notebook.modules[0].variables
.filter(d=>d)
.map((d,i)=>` <div class=" observable-wrapper div-number-${i}"></div>`)
.join('')
.concat('<div style="display:none" class="hidden"></div>')


import {Inspector, Runtime} from "https://unpkg.com/@observablehq/runtime@3/dist/runtime.js"; 
let i=1;
Runtime.load(notebook, (variable) => { 
if(i==4 ){i++;  return new Inspector(document.querySelector(`.hidden`));}
if(i==13)return;
return new Inspector(document.querySelector(`.observable-wrapper:nth-child(${i++})`));
 }); 


</script>


0 commentaires