最近做了一個小網站,底圖用的是天地圖的服務,用ArcGIS JavaScript提供的一些GIS功能.個人覺得,天地圖API簡單易上手,連我這個菜鳥看幾個範例程式碼都能快速的做出包含地圖的網站.只是,目前的天地圖,基本上只有資料,沒有GIS相關的esri的東西.
網上看了esri的ClusterLayer的範例程式碼,網址如下: https://developers.arcgis.com/javascript/jssamples/layers_point_clustering.html 以及根據國內一些技術牛人寫的文章,進行修改.由於是相當菜的菜鳥,可能出問題的地方相當多,相當糾結的一點點排查.
問題1:天地圖不顯示
天地圖的類庫之前測試正常,在ClusterLayer中卻不顯示.經逐行調試,發現將天地圖的類庫與clusterLayer中的類庫在一起require時,出現了奇怪的指向問題.調試過程中,天地圖的類庫沒有正確指向自己寫的代碼,卻指向了未知的esri的代碼.後來將天地圖在獨立的require塊中添加,地圖顯示正常.
問題2:clusterLayer不顯示
這個問題相當之蛋疼.基本上把esri的clusterLayer的代碼都看了一遍之後,發現
問題2.1 在天地圖頁面中,無論怎麼縮放,clusterLayer中clusters的個數與未經處理資料的個數是一致的,沒有出現隨著縮放而彙總的效果(這裡說的效果是資料層面的,既彙總的個數不是顯示層面的,因為資料不顯示....),經仔細調試,發現_clusterResolution值與ersi提供的範例程式碼中的值差好很多個數量級.進一步追蹤,發現是map.extent.getWidth()值相當之小,只有個位元.進一步核查發現,esri的範例程式碼中底圖資料是arcgisonline的圖,其空間參考為webMercator,wkid:102100.而封裝好的ArcGIS JavaScript版的天地圖的空間參考為wgs84,wkid:4326.因此,在clusterLayer中,map.extent.getWdith()就出現了及其小的問題,導致了後續的聚類異常。
解決方案:在ClusterLayer中,將_clusterResolution改為如下:
if (map.spatialReference.isWebMercator()) { this._clusterResolution = map.extent.getWidth() / map.width; // probably a bad default... } else { //WGS 84座標,轉換為web Mercator var latlng1 = new Point(map.extent.xmax, map.extent.ymax, map.spatialReference); //右上方 var latlng2 = new Point(map.extent.xmin, map.extent.ymin, map.spatialReference); //左下角 var webMercator1 = webMercatorUtils.geographicToWebMercator(latlng1); var webMercator2 = webMercatorUtils.geographicToWebMercator(latlng2); this._clusterResolution = (webMercator1.x - webMercator2.x) / map.width; }
修改完成之後,再來源資料層面,可以看到clusters的個數隨著縮放而在動態改變著.
問題2.2 clusterlayer不顯示. 上述問題解決之後,地圖中仍然沒有出現彙總點.在代碼中百般調試,百般推測,百般琢磨,並在介面中輸出了clusterLayer中的核心的參數,比如graphics.length等,發現結果都是正常的,就是沒有顯示彙總點.以為天地圖的某種顯示機制與Graphics有某種衝突,就自己添加了一些Graphics,圖層中也是顯示正常的.糾結了近一天,晚上突然想明白,還是座標系的問題!官方給的ClusterLayer是基於webMercator投影的,因此,彙總之後的點簇的座標,仍然是WebMercator的,由於範例程式碼中給的ArcGISOnline的圖也是基於webMercator的,所以,點能正常顯示.而網上的天地圖封裝類庫是基於wgs84的經緯度座標.所以,經過彙總之後的點簇座標,就無法顯示了,因為遠遠超出了經緯度的座標範圍.
解決方案:將彙總之後的點簇座標,再轉換為wgs84的座標,即可.在ClusterLayer中修改如下函數:
_showAllClusters: function () { var tp; if (map.spatialReference.isWebMercator()) { //map為WebMercator座標系 tp="webm"; } else { //map為非WebMercator座標系 tp="nowebm"; } for (var i = 0, il = this._clusters.length; i < il; i++) { var c = this._clusters[i]; this._showCluster(c,tp); } }, _showCluster: function (c, tp) { var point if (tp == "webm") { point = new Point(c.x, c.y, this._sr); } else { var latlng = new Point(parseFloat(c.x), parseFloat(c.y), this._sr); point = webMercatorUtils.webMercatorToGeographic(latlng); } this.add( new Graphic( point, null, c.attributes ) );
糾結了N久的問題,終於解決!
轉自:http://www.mamicode.com/info-detail-613651.html