Карта с Д3.js and TopoJSON, Albers Siberia projection

Я пытаюсь сделать хороплет с Д3.js, но я был сбит с толку только в начале. Я нашел Шейп-файл и сгенерировал файлы GeoJSON и TopoJson из него так же, как здесь. На карте используется проекция Альберс-Сибирь. Что я нашел об этой проекции:

Проекция: Коническая Коника Равной Площади Альберса

  • Единицы Измерения: Метры
  • Эллипсоида: Красовского
  • центральный меридиан: 105
  • Стандартная Параллель 1: 52
  • Стандартная Параллель 2: 64
  • Справочная Широта: 0
  • Смещение: 18500000
  • False Northing: 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: "Альберс-Сибирь", 9, 1001, 7, 105, 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 файлы здесь.
И еще один вопрос: Как я могу ссылаться на значение края

1 ответов


первая проблема заключается в том, что ваш файл 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

затем "unproject" файл GeoJSON путем преобразования его в WGS 84:

ogr2ogr -f GeoJSON -s_srs albers.prj -t_srs EPSG:4326 map_rus_wgs84_geo.json map_rus_geo.json

теперь вы можете конвертировать в TopoJSON в WGS 84, а не проецировать координирует. Я также взял на себя смелость сделать некоторые упрощения:

topojson -o map_rus_wgs84_topo.json -s 1e-7 -- russia=map_rus_wgs84_geo.json

вторая проблема заключается в том, что ваше определение проекции в D3 неверно. Д3.Гео.проекция albers имеет поворот и центр по умолчанию, который предназначен для карты с центром в США, поэтому в дополнение к определению центра Вам также нужно переопределить поворот по умолчанию. Фактически, параметр проекции +lon_0 (центральный меридиан) соответствует вращению проекции, а не центру проекции. Дача:

var projection = d3.geo.albers()
    .rotate([-105, 0])
    .center([-10, 65])
    .parallels([52, 64])
    .scale(700)
    .translate([width / 2, height / 2]);

(я подделал параметр center, чтобы поместить Россию в центр окна просмотра. Ты можешь!--16-->вычислить это автоматически если вы предпочитаете.) Теперь вы должны увидеть что-то вроде этого:

Albers Siberia

также можно работать с проецированными (Декартовыми) координатами в TopoJSON, а затем определить d3.Гео.путь с проекцией null (identity), но я оставлю это для отдельного вопроса.