2014-02-18 39 views
3

我想要做什么?与d3地理比例匹配的传单缩放级别

  • 在传单(或任何地图框架)之上覆盖SVG图层。
  • 在我的SVG图层中使用d3js和d3.geo.mercator位置元素,以使它们正确放置在单张上。
  • 我只能访问缩放级别,地图中心(lat/long),地图SVG元素的宽度和高度。
  • 我只需要听取缩放级别和地图中心的变化,以知道何时重新定位我的SVG元素。

我已经使SVG元素与传单层的大小相同;并将其作为覆盖。

现在我该怎么做?

我有一些与传单的值(Map.zoom,Map.width,Map.height,Map.center)对齐的全局变量。

Map.center = [43, -72]; 
Map.zoom = 3; 

Map.projection = d3.geo.mercator() 
      .center([Map.center[1], Map.center[0]]) 
      // I think this is the problem. I don't really understand this. 
      .scale(256 * Math.pow(2, Map.zoom)) 
      .translate([Map.width/2, Map.height/2]) 

Map.lt = new L.Map...(center is Map.center, zoom is Map.zoom) 

任何时间传单更改我更新全局值并重新计算Map.projection。

我有一个函数:

function transform(d) { 
    d = Map.projection(d.value.geometry.coordinates[0], d.value.geometry.coordinates[1]); 

    return "translate(" + d[0] + "," + d[1] + ")"; 
} 

然后在对象和元素,我需要定位我打电话:

object.attr("transform", transform); 

我的问题是,层不同步。

当我在[43,-72]中将我的地图居中时,我查看返回的x,y值(来自Map.projection),它正好在我的SVG图层的中间,所以我猜测有些东西与我的规模不符。我不知道如何让这些值正确排列。

我不想使用d3.geo.tile或d3.geo.path(),因为我需要更多的灵活性来控制我的元素的定位和动画。

我只想知道如何通过利用d3函数排列与我的SVG图层定位的传单。我不希望依靠传单来定位我的物品,因为我未来可能不会使用传单;我只需要能够缩放/翻译我的d3.geo.mercator投影,使其与传单一致。我怎样才能做到这一点?

谢谢!

Example

+0

你见过[本教程](http://bost.ocks.org/mike/leaflet/)吗?你需要什么样的额外定制,'d3.geo.path'不允许你这样做? –

+0

是的,我有。以这种方式使用d3并不适合我想构建应用程序的方式。这也使用传单进行投影 - 这是我不想做的事情,因为我可能会在稍后时间抛出传单。 我只是想知道如何执行相同的计算单张,以便我可以随意将我的元素与任何地图框架对齐,只要我知道其中心,缩放级别以及地图的宽度/高度。 – jreid42

回答

3
Map.projection = d3.geo.mercator() 
      .center([Map.center[1], Map.center[0]]) 
      .scale((1 << 8 + Map.zoom)/2/Math.PI) 
      .translate([Map.width/2, Map.height/2]) 

不知道如何工作的,但看了一些其他的例子,想通了。

0

这里是我结束了(不要感到惊讶JS的陌生感 - 这是ES6):

const convertZoomLevelToMercator = (zoomLevel) => 
    Math.pow(2, 8 + zoomLevel)/2/Math.PI; 
const convertZoomLevelFromMercator = (zoomLevelInMercator) => 
    Math.log(zoomLevelInMercator * 2 * Math.PI)/Math.LN2 - 8; 

测试:

console.log(convertZoomLevelToMercator(1)); 
console.log(convertZoomLevelToMercator(5)); 
console.log(convertZoomLevelToMercator(10)); 
console.log(convertZoomLevelToMercator(15)); 
console.log(convertZoomLevelToMercator(20)); 
console.log('----'); 
console.log(convertZoomLevelFromMercator(convertZoomLevelToMercator(1))); 
console.log(convertZoomLevelFromMercator(convertZoomLevelToMercator(5))); 
console.log(convertZoomLevelFromMercator(convertZoomLevelToMercator(10))); 
console.log(convertZoomLevelFromMercator(convertZoomLevelToMercator(15))); 
console.log(convertZoomLevelFromMercator(convertZoomLevelToMercator(20))); 

输出:

81.48733086305042 
1303.797293808806 
41721.51340188181 
1335088.428860218 
42722829.72352698 
---- 
1 
5 
10 
15 
20