javascript - Geojson map with D3 only rendering a single path in a feature collection - Stack Overflow

I'm trying to draw a geojson map of some regions of Colombia. Currently it only shows a single pat

I'm trying to draw a geojson map of some regions of Colombia. Currently it only shows a single path:,

My feature collection has 52 features, but I can only draw this one feature. I do not know what I'm doing wrong, I'm based my code on other tutorials. How can I do to show all the paths?

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')

Here is my full code:

I'm trying to draw a geojson map of some regions of Colombia. Currently it only shows a single path:,

My feature collection has 52 features, but I can only draw this one feature. I do not know what I'm doing wrong, I'm based my code on other tutorials. How can I do to show all the paths?

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')

Here is my full code:

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

Share Improve this question edited Mar 1, 2019 at 17:32 Andrew Reid 38.3k7 gold badges73 silver badges90 bronze badges asked Mar 1, 2019 at 14:56 unusuariounusuario 1611 silver badge14 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 6

Problem

All your features are drawing, you are correctly using your path and enter cycle. To see, set your fill to none:

You can see them when inspecting the svg: all the paths are there.

Why don't you see them in the map when they have fill? Because the the polygons are inverted, they cover the entire world except for the region of interest. While most other geographic libraries/renderers treat geojson as Cartesian, D3 does not. This means winding order matters. Your coordinates are wound in the wrong order.

Solution

To properly fill, draw all features, and support mouse interaction, you'll need to reverse the winding order of the polygons. You can do this on the fly, or create new geojson files to store the pre-reversed data.

To do so let's take a look at your data. You are working with only features that are MultiPolygons, let's look at the structure:

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

Coordinates are structured as so:

 coordinates:[polygons] // an array of polygons

The individual polygons are structured as so:

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

Polygon rings are structured as an array of long lats, with the first and last values being the same.

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

So, to reverse the ordering of the coordinates, we need to reverse the items in the ring arrays:

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

If we had polygons in the mix too (they are slightly less nested), we could use:

 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();
     })  
   }
 })

Here's an updated plunker

It is drawing all the paths. See the DOM for the SVG in a web page inspector to confirm. However, you are seeing only the top one which happens to be the larger area because of fills. Try adding .style('fill', 'none') to the paths addition in JS. or the following in CSS

path {
  fill: none
}

If someone will see a similar problem, I created a tool which will help you to rewind or reverse geojson

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

You can run it as a snippet just bellow

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

<script type="module"> 

import notebook from "https://api.observablehq./@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./@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>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744985317a4604577.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信