D3 Geo Tile Baselayer Offset

时间:2014-03-13 18:58:27

标签: d3.js tile

我正在使用d3.geo.tile()并且之前已成功使用它,但这次tile图层似乎没有以相同比例绘制并转换为点图层。下面的代码创建了一个平移和绘制的地图,但绘制了非洲地中海的圆圈。如果我放大,它会很好地缩放瓷砖和圆圈,就像我的xy坐标关闭一样,但它们不是。

我感觉它实际上是在没有偏移和缩放它的情况下绘制基础层,因为它应该以坐标12,42为中心,但这对我来说是一个很大的谜,因为这个完全相同的代码可以在不同的情况下正常工作应用

如果有人能发现某些问题,或只是提示,那会有所帮助。

function createNewMap(){
 width = 1200, height = 800;
 var tile = d3.geo.tile()
  .size([1200, 800]);

var projection = d3.geo.mercator()
  .scale((1 << 12) / 2 / Math.PI)
  .translate([width / 2, height / 2]);

var center = projection([12, 42]);

var zoom = d3.behavior.zoom()
 .scale(projection.scale() * 2 * Math.PI)
 .scaleExtent([1 << 10, 1 << 17])
 .translate([width - center[0], height - center[1]])
 .on("zoom", zoomed);

projection
 .scale(1 / 2 / Math.PI)
 .translate([0, 0]);

var svg = d3.select("#newMapId").append("svg")
 .attr("width", width)
 .attr("height", height)
 .call(zoom);

 var raster = svg.append("g");
 var vector = svg.append("g");

 vector.selectAll("g").data(dataModule.polisData).enter().append("g")
  .attr("class", "sites")
  .attr("transform", function(d) {return "translate(" + (projection([d.xcoord,d.ycoord])[0]) + "," + (projection([d.xcoord,d.ycoord])[1]) + ")scale("+(projection.scale())+")"})
  .append("circle")
  .attr("class", "sitecirc");

  zoomed();

 function zoomed() {
  var tiles = tile
   .scale(zoom.scale())
   .translate(zoom.translate())
   ();

  var image = raster
   .attr("transform", "scale(" + tiles.scale + ")translate(" + tiles.translate + ")")
   .selectAll("image")
   .data(tiles, function(d) { return d; });

  image.exit()
   .remove();

  image.enter().append("image")
   .attr("xlink:href", function(d) { return "http://" + ["a", "b", "c", "d"][Math.random() * 4 | 0] + ".tiles.mapbox.com/v3/elijahmeeks.map-zm593ocx/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
   .attr("width", 1)
   .attr("height", 1)
   .attr("x", function(d) { return d[0]; })
   .attr("y", function(d) { return d[1]; });

  vector
   .attr("transform", "translate(" + zoom.translate() + ")scale(" + zoom.scale() + ")");

  d3.selectAll(".sitecirc")
   .attr("r", 10 / zoom.scale());

 }

Points are appended and projected correctly, base layer doesn't seem to scale and translate

1 个答案:

答案 0 :(得分:2)

您的代码似乎基于我更改SVG transform on zoom的示例。当您拥有复杂的几何体时,如果平移或缩放时只需要缩放和平移,则更改变换是一种很好的技术 - 它通常比重新投影所有内容更快 - 但它也比changing the projection on zoom更复杂。

如果要更改缩放投影,代码不会发生太大变化。实质上:

projection
    .scale(zoom.scale() / 2 / Math.PI)
    .translate(zoom.translate());

然后重新运行d3.geo.path重新渲染。如bl.ocks.org/9535021

所示

u.s. state capitals

此外,如果放大很多,修复投影和更改变换可能会导致精度问题。另一个原因是,只有在通过避免重新投影提供显着的性能提升时才使用该技术。在这里重新投票是超级便宜的,因为它只是少数点。