使用d3.js和TopoJSON,Albers Siberia投影进行映射

KoG*_*Gor 6 map geojson d3.js topojson

我正试图用d3.js制作一个等值线,但我刚开始时就被卡住了.我发现了一个Shape文件,并从它产生的以GeoJSON和TopoJson文件,就像在这里.该地图使用Albers-Siberia投影.我发现这个预测:

预测:Albers Equal-Area Conic

  • 单位:米
  • Spheroid:Krasovsky
  • 中央经络:105
  • 标准并行1:52
  • 标准并行2:64
  • 参考纬度:0
  • 假东方:18500000
  • 假北距:0

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>
Run Code Online (Sandbox Code Playgroud)

您可以在此处找到所有JSON文件.
还有一个问题:我怎么能参考的价值区域领域在 TopoJson文件.

mbo*_*ock 17

第一个问题是您的GeoJSON文件不是度[经度°,纬度°],也称为EPSG:4326或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
Run Code Online (Sandbox Code Playgroud)

然后,通过将GeoJSON文件转换为WGS 84来"取消项目":

ogr2ogr -f GeoJSON -s_srs albers.prj -t_srs EPSG:4326 map_rus_wgs84_geo.json map_rus_geo.json
Run Code Online (Sandbox Code Playgroud)

现在您可以转换为WGS 84中的TopoJSON,而不是投影坐标.我也冒昧地做了一些简化:

topojson -o map_rus_wgs84_topo.json -s 1e-7 -- russia=map_rus_wgs84_geo.json
Run Code Online (Sandbox Code Playgroud)

第二个问题是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]);
Run Code Online (Sandbox Code Playgroud)

(我用中心参数捏造将俄罗斯置于视口的中心.如果您愿意,可以自动计算.)您现在应该看到如下内容:

阿尔伯斯西伯利亚

也可以使用TopoJSON中的投影(笛卡尔)坐标,然后使用null(标识)投影定义d3.geo.path,但我会将其留给单独的问题.

  • topojson命令行工具假定GeoJSON输入为UTF-8,Shapefile输入为Windows1252,并始终生成UTF-8输出.如果shapefile输入采用不同的编码,则可以使用`--shapefile-encoding`,但这种情况极为罕见.如果您的GeoJSON输入不是UTF-8,请使用`ogr2ogr -lco ENCODING = UTF-8`来修复它. (2认同)