我试图使用d3加载我的ontario地图的topojson文件,但我得到的是一堆随机行,就像Random lines when loading a TopoJSON file in D3一样。
我的文件正在使用WGS84,因此也不是问题。我究竟做错了什么? Js代码如下。
var width = 960, height = 700;
var svg = d3.select('#map').append('svg')
.attr('width', width)
.attr('height', height)
d3.json('CensusSubDiv.json', function(error, CensusSubDiv) {
if (error) return console.error(error);
svg.append('path')
.datum(topojson.feature(CensusSubDiv, CensusSubDiv.objects.CensusSubDivision))
.attr('d', d3.geo.path().projection(d3.geo.mercator()))
.attr('id', 'ont')
;
});
答案 0 :(得分:0)
因此,正如我在评论中提到的,您的数据可能使用WGS84作为基准,但D3要求WGS84用作"投影" (d3需要纬度和经度,它代表三维地球上的点,因此实际上是未投影的,因此我的引号)。因此,预测数据有时会标记为WGS84以及其他标识符。
好消息是,您可以非常轻松地显示投影数据 - 更好的消息is that this is faster。我们只是在绘制数据之前对数据进行转换和缩放,而不是进行三维数学运算。坏消息是这对d3 v4 来说最简单(我的例子使用它,它只改变了几点:例如:d3.geo.path
- > d3.geoPath
,d3.geo.projection
- &gt ; d3.geoProjection
等。)
由于您的数据已经投影过,我们可以使用d3.geoIdentity
,这允许我们使用projection.fitSize()
(修改比例和翻译)方法,但不会投影数据。 FitSize采用数组作为显示区域的宽度/高度和geojson对象:
projection.fitSize([width,height],geojsonObject)
fitSize不是d3v3的一部分,但我们依赖于d3v5,因此更新并不是件坏事,projection.fitExtent允许边距
与SVG坐标空间一样,Y值从屏幕顶部的0开始,随着向下移动而增加,在大多数投影坐标空间中,Y值从地图的底部开始,随着向北移动而增加,我们还需要在y轴上翻转身份:
var projection = d3.geoIdentity()
.reflectY(true)
.fitSize([width,height],geojsonObject)
这使我们可以非常轻松地显示数据。有关上述变更的数据,请参阅this block。
但是,请注意,您已经预测了数据,如果您不知道该数据的投射方式,则无法调整未投影的其他地理数据或其他预计:您不能以给定的经度纬度投射一个点,因为您不知道如何以与已投影数据相同的方式投影它。
这可能不是一个值得关注的问题,例如在一个等值区域,或许您只需要人口普查细分的大纲。但是,如果您想将城市置于地图之上,如果这些城市的坐标与您的人口普查数据的预测方式相同,则会遇到一些困难。
如果您想覆盖安大略省的其他地理数据(未投影数据),则需要取消投影数据。在mapshaper中,当您最初将数据导入窗口时(确保您也拖动.prj文件 - 否则mapshaper不知道要重新投影数据的投影),您可以打开控制台并键入{{1}这应该给你以度为单位的坐标(虽然topojson仍然有编码的整数坐标,如果导出到geojson,坐标将以纯文本形式存储)。当然,如果您选择取消投影数据,则需要再次使用更典型的投影,例如d3.geoMercator()。