2013-05-28 5 views
2

Я использую d3 для рендеринга проекции Меркатора карты мира GeoJSON.Как я могу использовать SVG translate для центрирования проекции d3.js для заданных значений широты и долготы?

Я хотел бы иметь возможность использовать d3 для масштабирования и преобразовывать карту в известные значения широты и долготы по мере того, как пользователь выполняет мое приложение.

projection.center (https://github.com/mbostock/d3/wiki/Geo-Projections#wiki-center) делает то, что я хотел бы, в сочетании с transition().duration(), но для этого требуется перерисовка карты, и поэтому кажется, что стоит продолжать повторять. Я хотел бы использовать родные методы translate() и scale(), которые поставляются с SVG (https://developer.mozilla.org/en-US/docs/SVG/Attribute/transform).

Я нашел несколько полезных примеров, как Майк Босток (в http://bl.ocks.org/mbostock/4699541), а также полезные вопросы, как следующее о центрирования карты к данному объекту GeoJSON (Center a map in d3 given a geoJSON object), но я изо всех сил, чтобы обернуть мою голову вокруг них ,

Возможно, кто-то может помочь мне сконцентрировать мою проекцию на заданные значения широты и долготы, используя SVG's transform="translate(x, y)"?

Большое спасибо заранее.


Редактировать @Lars: Прежде всего, спасибо. Я попробовал ваше предложение, и движение происходит, но проекция, похоже, слишком далеко продвигается. Я включил скриншот и мой проекционный код, ниже:

var SFMap = { 
    initialise: function() { 
     var width = "752"; 
     var height = "420"; 
     SFMap.projection = d3.geo.mercator() 
      .scale(100) 
      .translate([width/2, height/2]) 
      .center([0, 0]); 

     SFMap.path = d3.geo.path() 
      .projection(SFMap.projection); 

     SFMap.svg = d3.select("#sf__map") 
      .append("svg") 
      .attr("width", width) 
      .attr("height", height); 

     SFMap.g = SFMap.svg.append("g"); 

     d3.json("world-110m.topo.json", SFMap.draw); 
    }, 

    draw: function(error, topology) { 
     SFMap.g 
      .selectAll("path") 
      .data(topojson.feature(topology, topology.objects.countries) 
       .features) 
      .enter() 
      .append("path") 
      .attr("d", SFMap.path) 
      .attr("class", "feature"); 
    }, 

Projection movement (View full size)

выше происходит, когда translate ING в Лондон - 51.5171 ° N, 0,1062 ° W - используя следующий код:

var coordinates = SFMap.projection([0.1062, 51.5171]); 
SFMap.g.attr("transform", "translate(" + (-coordinates[0]) + "," + (-coordinates[1]) + ")"); 

Я также попытался инвертировать значения во второй раз.

ответ

2

Предполагая, что центр вашей проекции равен (0,0), все, что вам нужно сделать, это дать координаты точки, которую вы хотите центрировать, к вашей проекционной функции (для перевода в пользовательские координаты) и дать обратную от translate. Что-то вроде

var coordinates = projection(point); 
svg.attr("transform", "translate(" + (-coordinates[0]) + "," + (-coordinates[1]) + ")"); 

Если вы также перевели проекцию, вам необходимо принять это во внимание, например.

svg.attr("transform", "translate(" + (-coordinates[0]+width/2) + 
     "," + (-coordinates[1]+height/2) + ")"); 
+0

Здравствуйте, спасибо! Я обновил свой вопрос, чтобы показать результат. Вы видите, что я делаю неправильно? – Check12

+0

Вещь, которая мешает здесь, - это перевод, который вы добавляете к самой проекции. Я обновлю ответ. Кроме того, ваша ширина и высота должны действительно быть числами, а не строками. –

+0

Вот и все! Благодарим вас за помощь и за обнаружение ошибки типа. :) – Check12