我创建了以下TopoJSON文件:https://gofile.io/d/CKBGhF
我想用基本的D3.js脚本在浏览器中查看它。在https://bost.ocks.org/mike/map/上,我找到了一个关于这个脚本的小教程。但是因为我的地图是由一个向量转换成TopoJSON的,所以它没有真正的坐标。使用QGIS,我首先将它保存为一个GeoJSON,而使用映射器,我将它保存为TopoJSON。
我该怎么看地图?坐标或缩放是否完全错误?还是我的TopoJSON不好?
我的HTML/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>
发布于 2020-06-16 00:48:54
在我的响应中,我将所有代码升级到d3v5,因为d3v4中包含了帮助绘制这些数据的新特性(如d3.geoIdentity
__、projection.fitSize
)。自D3 v4以来,对D3命名空间进行了一些更改(、d3.geo.path
和d3.geo.projectionName
现在是d3.geoPath
和d3.geoProjectionName
__)。在D3v5中,d3.json现在返回了希望。
这里有几件事在起作用。
Topojson.feature
首先,D3只使用d3.geoPath绘制geojson对象,D3不直接绘制topojson。因此,您的数据在存储为topojson时,在这里转换为geojson:
topojson.feature(uk, uk.objects.subunits)
但是,topojson数据uk
没有包含特性的子单元属性。相反,您有一个名为test
的子单位属性。
...463908,4.10162]},"objects":{"test":{"type":"GeometryCollection"...
通常,像mapshaper这样的平台将源文件的文件名作为子属性名,所以我猜您从QGIS导出的源文件是test.geojson
或其他类似的东西。
如果我们记录:
console.log(topojson.feature(uk, uk.objects.test))
我们看到有效的geojson。既然我们有了geojson,我们就可以画它了。
坐标
对于坐标系,topojson默认保留原来的坐标系。当转换回geojson时,您的坐标将与原来相同。因此,除非源数据没有真正的坐标,否则这个语句“它没有真正的坐标”是不正确的。
但是,在生成topojson时,可以从命令行或使用mapshaper来投影或重新设计点。看来您在点上应用了投影,因为当我将topojson转换为geojson时,我看到的坐标看起来像像素值(单位不太可能是从QGIS导出的原始坐标)。
如果使用投影坐标(笛卡尔点,而不是拉长对,无论单位是米还是像素),我们就不能使用D3 geoProjection:这些坐标将三维点投影到平面上。
由于您的值看起来像像素值,所以我们可以直接将您的数据传递给空投影:
var path = d3.geoPath()
或者,更明确地说:
var path = d3.geoPath(null);
var path = d3.geoPath().projection(null);
在D3v3和更早版本中,需要显式地设置
这不适用于geojson中的坐标转换。它将每个geojson坐标视为像素坐标,并相应地绘制您的特征(示例)。
但是,如果我们的功能的预计范围与SVG/画布范围不匹配,则该选项就没有用。相反,我们可以使用geoTransform
或geoIdentity
来应用适当的转换。
geoIdentity
选项是最简单的,因为它提供了方便的fitSize
方法,它允许我们自动地将geojson大小调整到SVG/Canvas维度(fitExtent
允许指定一个边距,而fitSize
不假定有边距)。所有这些选项都可以作为投影传递给d3.geoPath (示例,全屏)。
最后一个示例应该向您展示如何绘制数据。您大部分都有行字符串,这将使填充功能变得困难,除非您只希望显示边框。
再读
根据以往的经验,有几个相关的问题浮现在脑海中:
这个问题解决了可能的预投影几何图形,因为它似乎你已经为屏幕大小预先投影你的几何图形。这带来了对齐的挑战,折衷是更快的渲染时间。
这个问题涉及到预先投影的几何图形和与屏幕相匹配的特征。它更深入地阐述了fitSize
、fitExtent
和geoTransform
。
https://stackoverflow.com/questions/62333032
复制相似问题