2014-02-18 74 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