2016-08-14 59 views
0

我有問題需要了解傳單中的圖層排序是如何工作的,而我完全是Javascript/Coffeescript的新手。縮放後的傳單層次排列

我正在使用的代碼是Ruby & Rails應用程序的一部分,可以找到here。我們的想法是

  • 設置一個OSM底圖
  • 加分的熱圖
  • 讓用戶選擇一個矩形區域作爲進一步的東西到Rails應用程序
  • 反應中發生的一個選擇工具用戶通過將熱圖更改爲標記簇設置來縮放

問題:縮放會導致圖層重繪。因此,用戶選擇矩形結束於熱圖的透明層下。我希望它保持在最佳狀態。我試圖應用featuregroup.bringToBack()和featuregroup.bringToFront()m,但它不能按預期工作。

我爲這個stackoverflow問題寫了一些example code with jsfiddle來以更簡單的方式說明問題和我的方法。你需要leaflet.js,這leaflet.cssleaflet-heat.js工作:

# prepare basemap 
osmUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png' 
osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors' 
osm = L.tileLayer(osmUrl, 
    maxZoom: 18 
    attribution: osmAttrib) 

# initialize the map with basemap 
map = L.map('map').setView([ 
    17 
    75 
], 5).addLayer(osm) 

# coordinate vectors 
lat = [14, 15, 16, 18, 19, 20] 
lng = [72, 73, 74, 76, 77, 78] 

# function: layer arrangement in relation to zoom state 
arrange_layers = -> 
    if map.getZoom() > 5 
    console.log "1" 
    heatItem.bringToFront() 
    if map.getZoom() <= 5 
    console.log "2" 
    heatItem.bringToBack() 
    return 

#function: react to user zooming 
map.on 'zoomend', (e) -> 
    arrange_layers() 
    console.log map.getZoom(); 
    return 

# add circles to map 
for lati in lat 
    for lngi in lng 
    L.circle([ 
     lati 
     lngi 
     ], 50000, 
     color: 'black' 
     fillColor: '#black' 
     fillOpacity: 0.5).addTo(map) 

# add heatmap to map 
heatItem = new (L.FeatureGroup) 
heat = L.heatLayer([ 
    [ 
    15 
    73 
    3000 
    ] 
    [ 
    19 
    77 
    10000 
    ] 
], radius: 25).addTo(heatItem) 
heatItem.addTo(map) 

編輯:

我的問題的解決方案是改變單張1.0,並添加與定義Z值一些自定義窗格。現在我可以控制圖層順序。校正的示例代碼看起來是這樣的,並且取決於leaflet.jsleaflet.cssleaflet-heat.js

# prepare basemap 
osmUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png' 
osmAttrib = '&copy; <a href="http://openstreetmap.org/copyright">OpenStreetMap</a> contributors' 
osm = L.tileLayer(osmUrl, 
    maxZoom: 18 
    attribution: osmAttrib) 

# initialize the map with basemap 
map = L.map('map').setView([ 
    17 
    75 
], 5).addLayer(osm) 

# coordinate vectors 
lat = [14, 15, 16, 18, 19, 20] 
lng = [72, 73, 74, 76, 77, 78] 

# create pane 
map.createPane 'circles' 
map.getPane('circles').style.zIndex = 450 

# add circles to map 
for lati in lat 
    for lngi in lng 
    L.circle([ 
     lati 
     lngi 
     ], 50000, 
     color: 'black' 
     fillColor: '#black' 
     fillOpacity: 0.5 
     pane: 'circles').addTo(map) 

# add heatmap to map 
heatItem = new (L.FeatureGroup) 
heat = L.heatLayer([ 
    [ 
    15 
    73 
    3000 
    ] 
    [ 
    19 
    77 
    10000 
    ] 
], radius: 25).addTo(heatItem) 
heatItem.addTo(map) 

回答

1

不幸的是,Leaflet.heat插件創建,在一個<canvas>元件,其不能通過.bringToFront().bringToBack()方法進行排序位於的層。

你的heat圖層不提供這些方法,所以你的heatItem.bringToBack()將不起作用,即使它沒有輸出任何錯誤。

您可以嘗試使用Leaflet 1.0,使用它可以使用map.createPane()創建您可以訂購的「窗格」(圖層容器)。

順便說一句,您的JSFiddle使用Leaflet 0.7.2(當前穩定版本是0.7.7)與前CDN不支持https協議。更新的jsfiddle:https://jsfiddle.net/emwmc4xw/98/


編輯

我不知道,如果Leaflet.heat可以採取pane選項(你可以看看它的代碼)。

作爲解決方法,您可以在所有其他圖層上定義它,例如您的圈子。然後,您可以將zIndex設置爲400以上或以下,這是默認的overlayPane,其中如果未指定窗格,Leaflet.heat畫布和您的圓圈將默認進入。

更新JSFiddle:https://jsfiddle.net/emwmc4xw/120/

+0

非常感謝!我試圖用Leaflet 1.0實現你的建議解決方案,但是[失敗了](https://jsfiddle.net/nevrome/emwmc4xw/119/)。你能否給我一個想法缺少什麼? – nevrome

+0

您應該使用「瀏覽器控制檯」調試您的JSFiddle:在PC/Linux上點擊F12,在Mac上點擊Cmd + Alt + i。使用戶的外部資源按正確的順序加載:Leaflet然後插件。 – ghybs

+0

酷 - 這個工程。現在我只需要在Rails應用程序中實現傳單1.0,並設置一些自定義窗格。謝謝! – nevrome