使用 D3 的 Geojson 地图仅渲染要素集合中的单个路径 [英] Geojson map with D3 only rendering a single path in a feature collection

查看:27
本文介绍了使用 D3 的 Geojson 地图仅渲染要素集合中的单个路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试绘制哥伦比亚某些地区的 geojson 地图.目前它只显示一个路径:,

我的特征集合有 52 个特征,但我只能绘制这一个特征.我不知道我做错了什么,我的代码基于其他教程.如何显示所有路径?

var features = mapData.features;控制台日志(功能);//根据数据更新色阶域//将每个省绘制为路径mapLayer.selectAll('路径').data(特征).enter().append('path').attr('d', 路径).attr('矢量效果', '非缩放中风')

这是我的完整代码:

您可以在检查 svg 时看到它们:所有路径都在那里.

当它们填满时,你为什么不在地图上看到它们?因为多边形是倒置的,所以它们覆盖了除感兴趣区域之外的整个世界.虽然大多数其他地理库/渲染器将 geojson 视为笛卡尔,但 D3 没有.这意味着绕线顺序很重要.您的坐标以错误的顺序缠绕.

解决方案

要正确填充、绘制所有要素并支持鼠标交互,您需要颠倒多边形的缠绕顺序.您可以即时执行此操作,也可以创建新的 geojson 文件来存储预反转数据.

为此,让我们来看看您的数据.您仅使用 MultiPolygons 的功能,让我们看一下结构:

<代码>{类型:功能",特性: {...},几何学: {类型:多多边形",坐标:/*这里的坐标*/}}

坐标的结构如下:

坐标:[polygons]//多边形数组

各个多边形的结构如下:

 [outer ring][inner ring][inner ring]...//外环的坐标数组,每个孔(内环)的坐标数组.

多边形环被构造为一个长纬度数组,第一个和最后一个值相同.

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

所以,为了颠倒坐标的顺序,我们需要颠倒环形数组中的项:

 features.forEach(function(feature) {if(feature.geometry.type == "MultiPolygon") {feature.geometry.coordinates.forEach(function(polygon) {多边形.forEach(功能(环){ring.reverse();})})}})

如果我们也有多边形(它们的嵌套稍微少一些),我们可以使用:

 features.forEach(function(feature) {if(feature.geometry.type == "MultiPolygon") {feature.geometry.coordinates.forEach(function(polygon) {多边形.forEach(功能(环){ring.reverse();})})}else if (feature.geometry.type == "Polygon") {feature.geometry.coordinates.forEach(function(ring) {ring.reverse();})}})

这是更新的 plunker

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

解决方案

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

这篇关于使用 D3 的 Geojson 地图仅渲染要素集合中的单个路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆