Вопрос

Я пытаюсь нарисовать карту с помощью TopoJSON, поэтому я последовал этому примеру

но у меня ничего не получается нарисовать.

вот что я написал

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
<style>

path {
  fill: #ccc;
  stroke: #fff;
  stroke-width: .5px;
}

path:hover {
  fill: red;
}

</style>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script>

var width = 960,
    height = 500;

var path = d3.geo.path();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

  d3.json("tunisia.json", function(error, topology) {

  console.log(topology);

  svg.selectAll("path")
      .data(topojson.feature(topology, topology.objects.governorates).features)
      .enter().append("path")
      .attr("d", path);
});

</script>

</body>
</html>

После некоторой отладки выясняется, что путь в моем случае добавляется следующим образом:

<svg width="960" height="500">
<path></path>
<path></path>
</svg>

в то время как обычно это должно быть так:

<svg width="960" height="500">
 <path d="M183.85631949544694,17.16574961388676L184.64695256075555,18.261986556132797L184.24437929962187,21.436416964644536L184.9109502450185,22.72190753660925L183.42733139583214,23.600229178621248L181.43637647772152,23.38526266060535L162.4858998398068,18.04698631290296L162.95134674943927,16.322885588815097L161.24381018256219,15.20848145955324L160.04585728433227,11.701769628478132L161.0879861841512,10.793553936506555L172.9773901748378,14.256236175137701Z"></path>
</svg>

вот данные, которые я использую:https://raw.githubusercontent.com/mtimet/tnacmaps/master/topojson/tunisia.json

не могли бы вы, пожалуйста, проверить, что я делаю не так

Это было полезно?

Решение

С вашим файлом json нет никаких проблем.

Проблема, с которой вы столкнулись, заключается в том, что вы не определяете проекцию для вашего d3.geo.path() это означает, что он возвращается к значению по умолчанию.В соответствии с документацией, приведенной по ссылке выше:

#d3.geo.path()

Создает новый генератор географических маршрутов с настройками по умолчанию:тот самый Альберсуза проекция и радиус точки 4,5 пикселя.

Ваши географические данные относятся к карте Туниса, поэтому проекция Альберсуса не будет содержать никаких координат в вашем наборе данных.Вот почему данные пути в вашем выводе пусты.

Чтобы исправить это, вам нужно определить проекцию.Вы можете сделать это, когда загружаете свои данные, и вы можете использовать d3.geo.bounds(), проходя в вашем featureCollection чтобы определить географические границы ваших данных.

var featureCollection = topojson.feature(topology, topology.objects.governorates);
var bounds = d3.geo.bounds(featureCollection);

Затем, исходя из этих границ, вы можете вычислить центр вашей коллекции объектов:

var centerX = d3.sum(bounds, function(d) {return d[0];}) / 2,
    centerY = d3.sum(bounds, function(d) {return d[1];}) / 2;

Затем вы можете использовать это для центрирования вашей проекции.Например, если вы используете проекцию меркатора, вы могли бы выполнить следующее:

var projection = d3.geo.mercator()
  .scale(3000)
  .center([centerX, centerY]);

Выбор шкалы 3000 произволен, просто казалось, что в данном случае она хорошо работает, настройте ее так, как подходит именно вам.

Наконец, вам нужно установить .projection() из вашего path к проекции, которую вы сделали, прежде чем фактически создать svg-пути.

path.projection(projection);

svg.selectAll("path")
  .data(featureCollection.features)
  .enter().append("path")
  .attr("d", path);

ЗДЕСЬ это рабочий пример использования ваших данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top