上一篇文章寫了 如何在天地圖上循環顯示標注點以及懸停顯示信息窗口。以及在標注點下面顯示標注點的名字。
但實際運用中我們常常有這樣的需求。
1.盡可能把所有的標注點放在我們地圖的可視范圍內。
2.在滿足1的情況下,讓縮放級別盡可能的高,以使我們可以看到更多的信息。
為了滿足上面的需求,實際上就是要我們根據所有的標注點的經緯度,分析出初始化地圖時的 地圖中心點 和 地圖縮放級別。
地圖中心點比較好求,直接用所有標注點的
(最大經度+最小經度)/2 = 中心點經度
(最大緯度+最小緯度)/2 = 中心點緯度
而縮放級別我們則要從 最大經度差和最大緯度差入手。
我們這里還要比較一下最大經度差和最大緯度差,再確定以哪一個為計算標准。
步驟:
1.准備數據。標注點的信息。
- var lnglats = [
- {"B":"23.1","L":"113.3","PName":"1111","Status":1},
- {"B":"23.2","L":"113.4","PName":"2222","Status":1},
- {"B":"22.9","L":"113.1","PName":"3333","Status":3004},
- {"B":"23.7","L":"113.8","PName":"第四個點","Status":1},
- {"B":"23.8","L":"113.5","PName":"第五個點","Status":1},
- {"B":"23.3","L":"113.2","PName":"第六個點","Status":1},
- {"B":"23.1","L":"113.7","PName":"7777","Status":1},
- {"B":"23.5","L":"113.3","PName":"8888","Status":1}];
- //這是頁面需要的數據。實際應用中常用ajax獲取。坐標點狀態。點的類型。點的名字。
2.計算最大經緯度。
- var maxl = lnglats[0].L,minl=lnglats[0].L,maxb=lnglats[0].B,minb=lnglats[0].B;
- $.each(lnglats,
- function(i, res) {
- if(res.L > maxl) maxl =res.L;
- if(res.L < minl) minl =res.L;
- if(res.B > maxb) maxb =res.B;
- if(res.B < minb) minb =res.B;
- });
3.計算 地圖中心點,注意 parseFloat。
- var cenB =(parseFloat(maxb)+parseFloat(minb))/2;
- seFloat(maxl)+parseFloat(minl))/2;
4.下面是計算縮放級別。 這個也是查了不少資料最后才得到的方法。 是以最大經度差與最大緯度差 按一定的比例計算出比較大的標准值。 然后再由這個標准值來計算級別。
首先定義兩個數組。 zoomArr表示對應的顯示級別。 而diffArr對應 經緯度的差值。 這個差值大於180的時候,顯示級別為1. 差值大於90度的時候,顯示級別為2,差值大於45度的時候,顯示級別為3……依次類推。最終得到最適合的縮放級別。 而這些差值與級別的對應關系,以及經緯差值之間的計算比例,是經過了我不少的調試得出來的。 也是花了一點功夫的。 越是顯示級別大的時候,越小的差值引起的誤差就可能越大。所以我們這里默認最大的顯示級別為14。也就是說,如果差值比我們差值數組中最小的差值還小的話,我們就返回14。
其他的地圖api大概也可以使用類似的方法。
- var zoom = getZoom(maxl, minl, maxb, minb);
- //通過經緯度縮放級別
- function getZoom(maxJ, minJ, maxW, minW) {
- if (maxJ == minJ && maxW == minW) return 13;
- var diff = maxJ - minJ;
- if (diff < (maxW - minW) * 2.1) diff = (maxW - minW) * 2.1;
- diff = parseInt(10000 * diff) / 10000;
- var zoomArr = new Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
- var diffArr = new Array(180, 90, 45, 22, 11, 5.5, 2.75, 1.37, 0.68, 0.34, 0.17, 0.08, 0.04);
- for (var i = 0; i < diffArr.length; i++) {
- if ((diff - diffArr[i]) >= 0) {
- return zoomArr[i];
- }
- }
- return 14;
- }
5.用計算出的縮放級別與中心點加載天地圖。
- //加載基本地圖和導航
- function loadMap(){
- try {
- map = new TMap("mapDiv"); //初始化地圖對象
- if (zoom == 1) { // 如果級別是1的話,就顯示整張地圖了。
- cenB = 0;
- cenL = 0;
- }
- map.centerAndZoom(new TLngLat(cenL, cenB), zoom);//設置顯示地圖的中心點和級別
- map.enableHandleMouseScroll(); //允許鼠標雙擊放大地圖
- } catch(err) {
- alert('天地圖加載不成功,請稍候再試!你可以先使用其他功能!');
- }
- }
至於標注點的顯示等功能,則參考上一文章的內容。
最終地圖初始化時的效果圖:
如果所示:我們標注點數據中的所有點都在天地圖的可視范圍內了。
注意:后來發現天地圖有這個功能的原生接口。大家可以用這個。上面的就當拓展思路吧。
setViewport(view:Array<TLngLat>) | none | 根據提供的坐標點數組設置地圖視野,調整后的視野會保證包含提供的坐標點。 |
http://api.tianditu.com/api-new/class.html
演示地址:http://runningls.com/demos/tianditu/index.html?to=loadzoom