我正在尝试用d3.js制作一个等值线,但我刚刚开始时被卡住了。我找到了一个Shapefile并从中生成了GeoJSON和TopoJson文件,就像here一样。该地图使用Albers-Siberia投影。我发现了这个预测:
预测:Albers Equal-Area Conic
PROJ.4:+ proj = aea + lat_1 = 52 + lat_2 = 64 + lat_0 = 0 + lon_0 = 105 + x_0 = 18500000 + y_0 = 0 + ellps = krass + units = m + towgs84 = 28,-130 ,-95,0,0,0,0 + no_defs
MapInfo:“Albers-Siberia”,9,1001,1,710,0,64,52,18500000,0。
所以我最终得到了这个代码,它什么也没做(甚至freez up),出了什么问题?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Choropleth</title>
<script type="text/javascript" src="d3/d3.v3.js"></script>
<script type="text/javascript" src="d3/queue.v1.min.js"></script>
<script type="text/javascript" src="d3/topojson.v0.min.js"></script>
</head>
<body>
<h1>My Choropleth</h1>
<script type="text/javascript">
var width = 960,
height = 500;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var pr = d3.geo.albers()
.center([105,0])
.parallels([52, 64])
.scale(1000);
var path = d3.geo.path().projection(pr);
d3.json("map_rus_topo.json", function(error, map) {
svg.append("path")
.datum(topojson.object(map, map.objects.map_rus))
.attr("d", path);
});
</script>
</body>
您可以找到所有JSON文件here 还有一个问题:如何在我的 TopoJson文件中引用区域字段的值。
答案 0 :(得分:17)
第一个问题是你的GeoJSON文件不是度[经度°,纬度°],也称为EPSG:4326 or WGS 84。要将GeoJSON文件转换为WGS 84,首先需要创建一个投影文件,比如说albers.prj
,这样就可以告诉OGR源投影是什么。
+proj=aea +lat_1=52 +lat_2=64 +lat_0=0 +lon_0=105 +x_0=18500000 +y_0=0 +ellps=krass +units=m +towgs84=28,-130,-95,0,0,0,0 +no_defs
然后,通过将GeoJSON文件转换为WGS 84来“取消项目”:
ogr2ogr -f GeoJSON -s_srs albers.prj -t_srs EPSG:4326 map_rus_wgs84_geo.json map_rus_geo.json
现在您可以转换为WGS 84中的TopoJSON,而不是投影坐标。我也冒昧地做了一些简化:
topojson -o map_rus_wgs84_topo.json -s 1e-7 -- russia=map_rus_wgs84_geo.json
第二个问题是D3中的投影定义不正确。 d3.geo.albers投影有一个默认的旋转和中心,专为以美国为中心的地图设计,因此除了定义中心外,您还需要覆盖默认旋转。事实上,+ lon_0(中央子午线)投影参数映射到投影的旋转,而不是投影的中心。给出:
var projection = d3.geo.albers()
.rotate([-105, 0])
.center([-10, 65])
.parallels([52, 64])
.scale(700)
.translate([width / 2, height / 2]);
(我用中心参数捏造将俄罗斯置于视口的中心。如果您愿意,可以compute this automatically。)您现在应该看到类似的内容:
也可以在TopoJSON中使用投影(笛卡尔)坐标,然后使用null(标识)投影定义d3.geo.path,但我会将其留给单独的问题。