使用 d3.js 和 TopoJSON 绘制 map ,阿尔伯斯西伯利亚投影

标签 map d3.js geojson topojson

我正在尝试使用 d3.js 制作 Choropleth,但我一开始就被卡住了。我找到了一个 Shapefile 并从中生成了 GeoJSON 和 TopoJson 文件,就像 here .该 map 使用阿尔伯斯-西伯利亚投影。我对这个投影的发现:

投影:Albers 等积圆锥

  • 单位:米
  • 球体:克拉索夫斯基
  • 中央经线: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

    map 信息:“阿尔伯斯-西伯利亚”,9、1001、7、105、0、64、52、18500000、0。

    所以我终于得到了这段代码,它什么也没做(甚至卡住),怎么了?
    <!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 文件。

    最佳答案

    第一个问题是您的 GeoJSON 文件不是以度为单位的 [longitude°, latitude°],也称为 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 投影有一个为美国为中心的 map 设计的默认旋转和中心,因此除了定义中心之外,您还需要覆盖默认旋转。事实上,+lon_0(中央经线)投影参数映射到投影的旋转,而不是投影的中心。给予:
    var projection = d3.geo.albers()
        .rotate([-105, 0])
        .center([-10, 65])
        .parallels([52, 64])
        .scale(700)
        .translate([width / 2, height / 2]);
    

    (我修改了 center 参数以将俄罗斯置于视口(viewport)的中心。如果您愿意,可以 compute this automatically。)您现在应该看到如下内容:

    Albers Siberia

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

    关于使用 d3.js 和 TopoJSON 绘制 map ,阿尔伯斯西伯利亚投影,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16083999/

    相关文章:

    map - 将 map[interface {}]interface {} 转换为 map[string]string

    javascript - 如何在 d3 中绘制具有预定义起始位置和边距级别的一堆矩形

    javascript - 径向时间序列,附加圆圈

    javascript - d3 - 使用 d3 动态创建多列数据

    Python - 使用 min() 在 JSON 对象中查找最小值?

    python - 在模型中包含 GeoDjango Point

    nhibernate - 流畅的 nhibernate 命名查询,而不使用 map 的 hbm 文件

    entity-framework - 将属性映射到 Entity Framework CTP5 中的(不同命名的)外键字段

    java - 使用值对 map 进行排序的最佳方法

    javascript - 谷歌地图获取geojson数据