首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >让我们制作一个TopoJSON地图并使用D3.js查看它

让我们制作一个TopoJSON地图并使用D3.js查看它
EN

Stack Overflow用户
提问于 2020-06-11 20:29:23
回答 1查看 2.8K关注 0票数 2

我创建了以下TopoJSON文件:https://gofile.io/d/CKBGhF

我想用基本的D3.js脚本在浏览器中查看它。在https://bost.ocks.org/mike/map/上,我找到了一个关于这个脚本的小教程。但是因为我的地图是由一个向量转换成TopoJSON的,所以它没有真正的坐标。使用QGIS,我首先将它保存为一个GeoJSON,而使用映射器,我将它保存为TopoJSON。

我该怎么看地图?坐标或缩放是否完全错误?还是我的TopoJSON不好?

我的HTML/Javascript代码(我只更改了文件名):

代码语言:javascript
运行
复制
<!DOCTYPE html>
<meta charset="utf-8">
<style>

/* CSS goes here. */

</style>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

var width = 960,
    height = 1160;

var projection = d3.geo.mercator()
    .scale(500)
    .translate([width / 2, height / 2]);

var path = d3.geo.path()
    .projection(projection);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

d3.json("topojson_mapshaper.json", function(error, uk) {
  svg.append("path")
      .datum(topojson.feature(uk, uk.objects.subunits))
      .attr("d", path);
});

</script>
EN

回答 1

Stack Overflow用户

发布于 2020-06-16 00:48:54

在我的响应中,我将所有代码升级到d3v5,因为d3v4中包含了帮助绘制这些数据的新特性(如d3.geoIdentity__、projection.fitSize)。自D3 v4以来,对D3命名空间进行了一些更改(d3.geo.pathd3.geo.projectionName现在是d3.geoPathd3.geoProjectionName__)。在D3v5中,d3.json现在返回了希望。

这里有几件事在起作用。

Topojson.feature

首先,D3只使用d3.geoPath绘制geojson对象,D3不直接绘制topojson。因此,您的数据在存储为topojson时,在这里转换为geojson:

代码语言:javascript
运行
复制
topojson.feature(uk, uk.objects.subunits)

但是,topojson数据uk没有包含特性的子单元属性。相反,您有一个名为test的子单位属性。

代码语言:javascript
运行
复制
 ...463908,4.10162]},"objects":{"test":{"type":"GeometryCollection"...

通常,像mapshaper这样的平台将源文件的文件名作为子属性名,所以我猜您从QGIS导出的源文件是test.geojson或其他类似的东西。

如果我们记录:

代码语言:javascript
运行
复制
console.log(topojson.feature(uk, uk.objects.test))

我们看到有效的geojson。既然我们有了geojson,我们就可以画它了。

坐标

对于坐标系,topojson默认保留原来的坐标系。当转换回geojson时,您的坐标将与原来相同。因此,除非源数据没有真正的坐标,否则这个语句“它没有真正的坐标”是不正确的。

但是,在生成topojson时,可以从命令行或使用mapshaper来投影或重新设计点。看来您在点上应用了投影,因为当我将topojson转换为geojson时,我看到的坐标看起来像像素值(单位不太可能是从QGIS导出的原始坐标)。

如果使用投影坐标(笛卡尔点,而不是拉长对,无论单位是米还是像素),我们就不能使用D3 geoProjection:这些坐标将三维点投影到平面上。

由于您的值看起来像像素值,所以我们可以直接将您的数据传递给空投影:

代码语言:javascript
运行
复制
var path = d3.geoPath()

或者,更明确地说:

代码语言:javascript
运行
复制
var path = d3.geoPath(null);
var path = d3.geoPath().projection(null);

在D3v3和更早版本中,需要显式地设置

这不适用于geojson中的坐标转换。它将每个geojson坐标视为像素坐标,并相应地绘制您的特征(示例)。

但是,如果我们的功能的预计范围与SVG/画布范围不匹配,则该选项就没有用。相反,我们可以使用geoTransformgeoIdentity来应用适当的转换。

geoIdentity选项是最简单的,因为它提供了方便的fitSize方法,它允许我们自动地将geojson大小调整到SVG/Canvas维度(fitExtent允许指定一个边距,而fitSize不假定有边距)。所有这些选项都可以作为投影传递给d3.geoPath (示例全屏)。

最后一个示例应该向您展示如何绘制数据。您大部分都有行字符串,这将使填充功能变得困难,除非您只希望显示边框。

再读

根据以往的经验,有几个相关的问题浮现在脑海中:

这个问题解决了可能的预投影几何图形,因为它似乎你已经为屏幕大小预先投影你的几何图形。这带来了对齐的挑战,折衷是更快的渲染时间。

这个问题涉及到预先投影的几何图形和与屏幕相匹配的特征。它更深入地阐述了fitSizefitExtentgeoTransform

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62333032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档