我正试图使这张美国Map的比例缩小。无论是我的SVG,甚至手动。
这是我最简单的代码:
function initializeMapDifferent(){
var svg = d3.select("#map").append("svg")
.attr("width", 1000)
.attr("height", 500);
d3.json("https://d3js.org/us-10m.v1.json", function (error, us){
svg.append("g")
.attr("class", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("fill", "gray")
.attr("d", d3.geoPath());
});
}
字符串
我试过这样的东西:
var path = d3.geoPath()
.projection(d3.geoConicConformal()
.parallels([33, 45])
.rotate([96, -39])
.fitSize([width, height], conus));
型
但是每次我在路径变量中添加任何东西时,我都会从D3的内部部分得到NAN错误。感谢您的帮助!
2条答案
按热度按时间piztneat1#
为什么数据不能正常投影
关键问题是您的数据 * 已经 * 投影。D3 geoProjection使用未投影的数据或纬度对中的数据。WGS 84基准面中的数据。本质上,d3 geoProjection采用球面坐标并将其转换为平面坐标x,y坐标。
你的数据不符合这一点-它已经是平面的。你可以看到最明显的,因为阿拉斯加不是它应该在的地方(除非有人改变了阿拉斯加的纬度对,这是不太可能的)。其他的迹象和症状已经预测的数据可能是一个覆盖整个地球的特征,NaN错误。
这是一个复合投影,很难取消投影,但你可以在d3.js中显示已经投影的数据。
“投影”已投影数据
投影:
最简单的,你可以将你的投影定义为null:
字符串
这将从geojson几何中获取x,y数据并将其显示为x,y数据。但是,如果x,y坐标超过svg的宽度和高度,则Map将不会包含在svg中(如您在
.attr("d", d3.geoPath());
示例中所发现的那样)。这个问题中的特定文件是预先投影的,以适应960 x600Map,因此这是空投影的理想选择-它的设计考虑到了尺寸。它的单位是像素,所有坐标都在所需的尺寸范围内。但是,大多数投影几何使用单位为米的坐标系,因此,特征坐标的边界框可能是数百万个单位。在这些情况下,空投影将不起作用-它将Map单位值转换为像素值,而不进行缩放。
地理标识
如果你只需要缩放和居中特征,你可以使用geoIdentity。这是实现geoTransform,但使用标准投影方法,如
scale
,translate
,最重要的是-fitSize
/fitExtent
。所以,我们可以将投影设置为geoIdentity:型
这与上面使用的空投影相同,它从geojson几何中获取x,y数据,并将其显示为x,y数据,而不进行转换-将geojson中的每个坐标视为像素坐标。但是,我们可以将fitSize应用于此(或fitExtent),它将自动缩放并将数据转换为指定的边界框:
型
或
型
请记住,大多数投影数据使用地理约定,y=0位于底部,y值随着向北移动而增加。在svg/canvas坐标空间中,y=0位于顶部,y值随着向下移动而增加。因此,我们经常需要翻转y轴:
型
geoIdentity Demo
的字符串
GeoTransform
如果你想对数据的显示方式有更多的控制,你可以使用
geoTransform
。Mike Bostock:
但是如果你的几何体已经是平面的呢?也就是说,如果你只想投影几何体,但仍然要平移或缩放它以适应视口呢?
您可以实现自定义几何体变换以获得对投影过程的完全控制。
使用
geoTransform
是相对简单的,假设 * 你不想改变投影的类型 *。例如,如果你想缩放数据,你可以用geoTransform
实现一个简短的缩放函数:型
不过,这会在你缩小的时候将所有内容缩放到左上角。为了保持居中,你可以添加一些代码来将投影居中:
型
geoTransform Demo:
下面是一个使用文件和geoTransform的示例:
的内存
解投影数据
这种方法在某些情况下是有用的。但它需要你知道用于创建数据的投影。使用QGIS/ArcGIS甚至mapshaper,你可以改变数据的投影,使其被“投影”为WGS 84(又名EPSG 4326)。一旦转换,你就有了未投影的数据。
如果您不知道用于创建数据的投影,则无法取消投影-您不知道应用了什么转换以及使用了什么参数。
一旦取消投影,您可以正常使用常规的d3投影,因为您在正确的坐标空间中有坐标:经度纬度对。
如果您还有未投影的数据,并且希望在同一Map中混合这两种数据,则取消投影非常有用。或者,您可以投影未投影的数据,以便两者使用相同的坐标系。将Map中不匹配的坐标系与d3组合起来并不容易,而且d3可能不是实现此目的的正确工具。如果您确实希望使用d3复制特定投影以匹配已使用没有投影的特征,那么这个question可能有用。
如何判断您的数据是否已投影?
您可以检查要素的几何是否符合纬度和经度的限制。例如,如果您要记录:
型
您很快就会看到,这些值超过了+/- 90度N/S和+/- 180度E/W。不太可能是lat long对。
或者,您可以将您的数据导入到在线服务(如mapshaper.org),并与您知道未投影(或使用WGS 84“投影”)的另一个topojson/geojson进行比较。
如果处理geojson,您可能会幸运地看到定义投影的属性,例如:
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
(CRS代表坐标参考系统)或EPSG编号:EPSG:4326
(EPSG代表欧洲石油调查组)。此外,如果您的数据投影为空投影,而不是标准投影(缩放/缩小以确保您没有在错误的区域中查看),则可能正在处理投影数据。同样,如果您的视口完全被一个要素覆盖(并且您没有放大)。NaN坐标也是一个潜在的指示器。然而,投影数据的最后这些指示器也可能意味着其他问题。
最后,数据源还可能指示数据已经在Meta数据中投影或如何使用:查看此block,我们可以看到定义
geoPath
时没有使用投影。ipakzgxi2#
如果你像我一样从datav.aliyun.com这个地方下载了geoJson数据,你可能需要反转数据才能在d3中使用,像这样:
字符串
您需要安装草皮:
npm i @turf/rewind