2014-01-19 26 views
20

使用d3在Leaflet貼圖頂部繪製SVG製品是獲得結合d3強度的穩固貼圖控制器的簡單方法。有許多例子和指導如何實現這一點,兩個主要方法似乎是:使用d3和小冊子實現動畫縮放

  1. 追加上這表現在博斯托克這裏傳單的「疊加窗格中」新的SVG元素:http://bost.ocks.org/mike/leaflet/

  2. 實施納爾遜高塔這裏證明了鉤到單張天然瓷磚層的生態系統的自定義向量瓦片層:http://bl.ocks.org/NelsonMinar/5624141

第一種方法避免了由ATT單張基於標度的縮放疼痛傳單類,以便在縮放發生時隱藏任何d3元素。當縮放動畫結束時,重新計算元素座標並重新繪製,之後隱藏類將被移除以再次顯示元素。這可以起作用,但與Leaflet的原生GeoJSON圖層相比,它提供了不太乾淨的放大/縮小體驗,因爲後者支持動畫縮放。

第二種方法不包含任何實現特定的代碼,該代碼可以滿足縮放行爲,但無論如何都可以工作! d3元素在動畫縮放期間縮放,然後整齊地用下一個縮放級別矢量進行替換。

我想實現的是兩者的結合。我想繪製基於Geo/TopoJSON的非基於tile的矢量,這些矢量在放大/縮小時是動畫效果的。我在使用不同的單張CSS類,不同的事件鉤子,以及以多種方式附加和/或重複使用SVG元素,但還沒有實現類似於使用Leaflet的本地GeoJSON向量時所經歷的行爲的行爲層。我不想使用本地層的原因是我想利用大量其他的d3功能,而不是Leaflet實現的一部分。

問題:有沒有人在使用基於非基於瓦片的矢量合併Leaflet和d3時實現了動畫縮放?如果是這樣 - 如何?

+0

您可能想看看d3地圖上的動畫縮放([this example](http://bl.ocks.org/mbostock/2206340))。請注意,它比某些其他d3縮放範例要慢,因爲它會在放大時重新計算地圖投影,而不是僅使用圖形變換來縮放圖像。我對Leaflet沒有任何經驗,但如果您可以使用Javascript調用設置比例/投影,那麼您可以在重新計算d3地圖投影的同時通過d3縮放功能來實現。但是,再次,每一步都有很多重新計算,所以縮放可能不會超順暢。 – AmeliaBR

+0

感謝您的提示,但是,我相信解決方案必須基於實際縮放的純圖形方法,而不是在轉換期間計算地理座標的方法。 – averas

回答

19

我覺得this是我已經找到了通過ZJONSSON結合單張及D3,最好的解決方案之一。

D3 +單張集成

在這個例子中,單張地圖開始爲SVG這裏map._initPathRoot(),與SVG然後使用D3 var svg = d3.select("#map").select("svg"), g = svg.append("g");選擇,之後所有的D3的樂趣就可以了。

在此示例中,傳單地圖事件map.on("viewreset", update);用於呼叫update並在地圖viewreset上轉換d3圖層。在此之後,d3轉換選項將決定d3圖層對Leaflet地圖平移/縮放事件的反應。

通過這種方式,您可以擁有完整的d3 + Leaflet庫,無需計算地圖邊界等麻煩,因爲Leaflet很好地處理了這個問題。

動畫矢量縮放

對於動畫,最新的傳單版本包括一個Pan and Zoom animation選項。雖然這不像d3那樣可定製,但您始終可以編輯Leaflet src代碼來更改過渡時間! Leaflet GeoJSON矢量圖層(L.geoJson)無需在Leaflet地圖事件(update)中更新,因爲它們已經作爲SVG添加到地圖中並由Leaflet處理。

注意,如果實施L.geoJson,這也意味着你不會需要map._initPathRoot(),爲單張將圖層添加到地圖爲SVG,所以你可以d3.select它。

也可以在L.geoJson圖層選項添加className變量,因此您可以通過單張onEachFeature期間分配一個唯一的類ID通過CSS或d3.select一個要素樣式。

+0

我正在爲傳單添加geojson圖層,但沒有創建svg圖層? – ratata

+0

默認情況下,Leaflet創建SVG,但也有一個靜態屬性,可以設置http://leafletjs.com/reference.html#path-svg。 – fitzpaddy

+1

此解決方案的一個問題是當您平移時,當前地圖中不可見的d3元素將不可見。有一個例子可以用http://bost.ocks.org/mike/leaflet/上的小冊子來處理這個問題,但是如果不切換到geoJson,我一直無法使用它。 – Meekohi