文章版權由作者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/。
1.前言
這一章我們將詳細講解WebGIS工具欄中另一個基礎工具——平移工具(Pan)。在介紹命令模式時,我們已經知道了此工具為Tool型的。
這個工具主要有如下兩個功能:
A.當切換到此工具上時,按下鼠標不放,移動鼠標時可以拖動地圖。
B.當切換到此工具上時,點擊鼠標(鼠標不做平移),可以使地圖平移,以點擊處為中心。
2.設計
2.1 原理
我們已經知道,WebGIS中圖層的本質是Canvas。平移效果的實現,其實質就是改變各Canvas的左上角坐標。
這里我給出示意圖:
2.2提一個問題
當我把柵格圖層所對應的canvas也平移后(事實上,所有的柵格canvas都是一個母容器(mapCanvas)中的child,平移是直接操作mapCanvas),此時我們再將屏幕地理范圍內的瓦片請求回來時,貼到已經平移后的canvas上,會不會出現瓦片顯示錯亂呢?
答案是:不會的。下面,我大致講一下原因。
在我們做平移時,我們不是簡單的只對canvas的原點做了平移,我們同時還會更具平移大小換算出真實的地理平移,然后對實際的屏幕地理范圍進行相應的改變。這樣便會導致一個這樣的結果:加入柵格圖層的canvas原點是A,平移后變成了A1,而平移后重新請求的瓦片,其每個瓦片的原點所對應的便是A1,而不再是A。這樣,我們便解決了平移柵格圖層后,重新請求瓦片而導致的瓦片錯亂問題。
2.3 平移公式
mapCanvas.y=mapCanvas.y+moveY;
mapCanvas.x=mapCanvas.x+moveX;
screenGeoBounds.bottom=screenGeoBounds.bottom+(sliceLevelLength/tileSize)*(moveY);
screenGeoBounds.top=screenGeoBounds.top+(sliceLevelLength/tileSize)*(moveY);
screenGeoBounds.left=screenGeoBounds.left-(sliceLevelLength/tileSize)*(moveX);
screenGeoBounds.right=screenGeoBounds.right-(sliceLevelLength/tileSize)*(moveX);
其中,mapCanvas表示(柵格或矢量)圖層,screenGeoBounds表示屏幕地理范圍,slieceLevelLength表示地圖當前級別中一個瓦片所代表的實際地理長度,tileSize表示的是一張瓦片的屏幕像素。
3.實現
3.1 拖拽平移的實現
A.當鼠標觸發mouseDown事件時,給全局變量flag賦值true,表示鼠標已經點下,記錄下startPoint。
B.當鼠標觸發mouseMove事件時,判斷flag是否為true,如果是,調用平移公式,使圖層出現移動,算出屏幕像素的移動mouseX和mouseY。
這里還可以繼續擴展,如果有其他圖層或者功能需要監聽到地圖平移時間,可以拋出一個地圖平移事件,拋出的參數可以設置為此時鼠標所在的地理坐標(通過鼠標的屏幕坐標轉換而得),以及鼠標平移的地理長度(通過mouseX和mouseY轉換而得)。屏幕坐標與地理坐標的轉換可以參考這個系列的第十章。
C.當鼠標觸發mouseUp事件時,判斷屏幕地理范圍加上移動的地理長度后,是否在整個瓦片請求的容差范圍內,如果在的話不用觸發瓦片請求;如果不在的話,則需觸發瓦片請求。請求參數即為目前的屏幕地理范圍加上容差范圍。
3.2 點擊平移的實現
A.當鼠標觸發mouseDown事件時,給全局變量isClick賦值true,其他操作同上。
B.當鼠標觸發mouseMove事件時,則將此isClick參數賦值false。
C.當鼠標觸發mouseClick事件時,判斷isClick是否為true,如果是true,則將地圖平移到以startPoint為中心的地方。
4. 提兩個問題
A.在地圖平移后,矢量圖層的canvas的XY都發生了變化,此時根據地理坐標轉換為屏幕坐標公式得出的屏幕坐標,在canvas上能將要素正確顯示嗎?
B.矢量圖層canvas的原點坐標XY有需要還原成初始的(0,0)的時候嗎?
5.總結
對於第四節中的兩個問題,我給出的答案分別是:不能和需要。解答這兩個問題,我們必須將之前給出的地理坐標與屏幕坐標互轉換公式和今天我們講到的平移公式合起來看,才能做很好的回答。這個內容我們將在下一章專門進行講解。歡迎大家持續關注。
-----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
如果您覺得本文確實幫助了您,可以微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^
everybody,good night.