问题
使用此块作为示例可能存在问题,因为它没有使用投影。该示例使用预投影的topojson,其坐标处于像素坐标空间中 - 它设计为在900 x 600像素窗口上显示,输入文件中的坐标值范围位于[0,0]和[900,600]的边界框内。因此,该示例不使用地理投影。
地理坐标不会完全落在此范围内。
为什么没有绘制任何内容?
与示例不同,您的topojson要素包含地理坐标 - 纬度和经度。
为了在d3或任何其他框架或程序中投影地理特征,必须应用投影以将地理坐标从三维坐标空间转换为适合显示在二维svg或canvas网格上的平面笛卡尔坐标。
您没有对要素应用必要的投影。当您使用geoPath时,通常需要指定一个geoProjection:
var path = d3.geoPath().projection(d3.geoProjection)
然而,您没有使用投影,因此d3默认使用空投影。对于您的topojson/geojson中的每个坐标,输入的x和y值被视为像素坐标,不进行任何变换/平移/缩放。
由于您的要素位于西半球,x(经度)值为负数。具有负x值的像素位于屏幕左侧。
南半球的值为负值,因此它们也将在屏幕外绘制。在这种情况下,在svg或画布上方 - 因为y值从屏幕顶部从零开始增加。
最后,如果您在地球的东北象限中有任何要素,则它们将显示为其坐标将是正数(假设您的svg高90像素,宽180像素)。但是,它们将颠倒,因为当一个人在svg/canvas坐标空间中向上移动地图时,y值会减小,而不是增加。
解决方法
您将需要使用投影来解决这个问题。最基本的设置可能是使用简单的投影(例如墨卡托投影),并使用fitSize或fitExtent自动缩放和居中所需显示的特征。您可以使用以下内容:
var projection = d3.geoMercator();
var path = d3.geoPath().projection(projection);
projection.fitSize([width,height],geojson object);
你如何获取geojson?你已经有了:
topojson.feature(aisp, aisp.objects.convert) // convert topojson to geojson.
您需要传递geojson对象,而不是它包含的要素数组,因此我们不会在.fitSize中使用topojson.feature(aisp, aisp.objects.convert).features
。
FitSize需要一个宽度和高度,并将投影的比例和平移设置为适当的值。FitExtent取两个点标记要素边界框的左上角和右下角:projection.fitExtent([[x1,y1],[x2,y2]],geojson);
这种方法不设置投影的更复杂参数,如旋转或圆锥投影(例如Albers,平行线),但在许多情况下已足够。
示例
这里有一个使用fitSize的地图示例(我更改了文件名)。
...[-10,-21],[-6,-22],[-9
- Gerardo Furtadoaisp.convert
- 这是未定义的,你需要使用aisp.objects.convert
(在附加网格时,而不是初始路径)。 (当我查看它时,topojson 检查通过了,但是我相信一旦错误消失,你会有一个不同的问题,“我的要素在哪里?”) - Andrew Reid...1.3:CRS84"}}}
。我发现GitHub有时会截断长的地理/拓扑JSON文件,原因不明 - 这曾经给我带来了很多烦恼。 - Andrew Reid