ArcGIS Javascript Api三維球中載入2000坐標系底圖,切片規則不一致的問題,The tiling scheme of this layer is not supported by SceneView。 ...
目前我們國家測繪地理信息的坐標體系基準是國家2000坐標系CGCS2000.各類地圖組件如OpenLayers、Mapbox、Cesuim和ArcGIS Javascrip等都主要是支持WGS84(wkid=4326)和墨卡托投影坐標系(wkid=102100)兩種,對CGCS2000坐標系基本上都不支持。特別是在三維地球展示中基本上都是以WGS84球面坐標系載入,因為三維球是個球,當然是要載入球面坐標系了。(但我知道以前科瀾三維是平面的!)所以三維地球都載入不了國內的2000坐標系,要載入也是通過擴展和定製WebTileLayer類進行特殊處理。
ArcGIS Javascript Api 4.*系列一直在朝著二三維一體化的方向發展,其開發商ESRI一直專攻GIS領域,而且是全球頭部GIS軟體平臺,特別是隨著ArcGIS 10.1後,其軟體產品迭代更新的速度極快。三維產品也是其重點發展對象之一。在今年中旬發佈的ArcGIS Javascript Api 4.12版本,不僅性能提升,增加了一些牛逼的功能,更重要的是支持CGCS2000坐標系!!!支持CGCS2000坐標系!!!支持CGCS2000坐標系!!!重要的事情說三遍!
這正是一個喜大普奔的事情,可能是因為ESRI的三維軟體開發團隊在北京的緣故吧,愛國註意情懷和中國市場總得發揮點作用。但我看到這個信息後,一直想試試,因為我對他支持2000坐標系還是存有疑惑,載入應該沒那麼容易!咱天朝的標準規範永遠是跟著參考國際標準,但必須在上面進行小幅修改,開發人員蛋疼的事情太多了!
1 2 var arcgisUrl = 'http://myserver.net/hserver/rest/services/imageserver2000/MapServer'; 3 4 Layer.fromArcGISServerUrl({ 5 url: arcgisUrl 6 7 }).then(function(layer){ 8 9 var customBasemap = new Basemap({ 10 baseLayers: [layer], 11 title: "ArcGIS REST Service", 12 id: "切片" 13 }); 14 15 var map = new Map({ 16 //basemap: "topo-vector" 17 basemap:customBasemap 18 }); 19 20 var view = new SceneView({ 21 container: "viewDiv", 22 map: map, 23 spatialReference: { 24 "wkid": 4490, 25 "latestWkid": 4490 26 } 27 }); 28 });
上述代碼就是我想用我自己的影像地圖作為三維球的底圖,滿懷期待,但最後還是出現我預料中的事情,沒有那麼簡單!
球出來了,提示“The tiling scheme of this layer is not supported by SceneView”,當時沒註意看這個信息,以為是坐標系統還是繼續不支持,但官方明明說了支持2000坐標系啊,不能夠啊!
繼續發揮Chrome強大的調試功能,在SceneViewer.js文件中調試出三塊關鍵代碼行數,checkIfTileInfoSupportedForViewSR,makeGCSWithTileSize,ompatibleWith。經過調試和研究發現,2000坐標系確實是支持的,但是切片規則(Tiling Scheme)必須跟esri規定的要一樣。
天地圖切片規則
級別 |
比例尺 |
解析度(度/像素) |
7 |
4617149.9776692898246525792559 |
0.010986328125 |
8 |
2308574.9888346449123262896279 |
0.0054931640625 |
9 |
1154287.494417322456163144814 |
0.00274658203125 |
10 |
577143.74720866122808157240698 |
0.001373291015625 |
11 |
288571.87360433061404078620349 |
0.0006866455078125 |
12 |
144285.93680216530702039310175 |
0.00034332275390625 |
13 |
72142.968401082653510196550873 |
0.000171661376953125 |
14 |
36071.484200541326755098275436 |
0.0000858306884765625 |
15 |
18035.742100270663377549137718 |
0.00004291534423828125 |
16 |
9017.871050135331688774568859 |
0.000021457672119140625 |
17 |
4508.9355250676658443872844296 |
0.0000107288360595703125 |
18 |
2254.4677625338329221936422148 |
0.00000536441802978515625 |
19 |
1127.2338812669164610968211074 |
0.000002682209014892578125 |
20 |
563.61694063345823054841055369 |
0.0000013411045074462890625 |
esri腳本代碼里第一級解析度固定了 res[0] = 0.703125,下麵以及都是一半的比例尺進行處理。下麵是兩個切片規則的比較。
arcgis javascript api 規定的切片規則 天地圖服務切片規則
可以看出我的服務的切片規則和arcgis的恰好錯開一個層級,我懷疑是因為我們是從0級開始算,arcgis是從第1級開始算導致的吧。但仔細看看其實兩個瓦片規則的解析度還是有細微的差別的。
q.prototype.compatibleWith = function(a) { if (! (a instanceof q)) { if (q._checkUnsupported(a)) return ! 1; a = new q(a) } if (!a.spatialReference.equals(this.spatialReference) || a.pixelSize[0] !== this.pixelSize[0] || a.pixelSize[1] !== this.pixelSize[1]) return ! 1; var c = Math.min(this.levels.length, a.levels.length) - 1, f = this.levels[c].resolution, b = .5 * f; if (!e.floatEqualAbsolute(a.origin[0], this.origin[0], b) || !e.floatEqualAbsolute(a.origin[1], this.origin[1], b)) return ! 1; b = .5 * f / Math.pow(2, c) / Math.max(this.pixelSize[0], this.pixelSize[1]) * 12; return e.floatEqualAbsolute(f, a.levels[c].resolution, b) }
問題如何處理呢?我的服務是用的已有的緩存切片進行發佈的啊!下一步就是操作ArcGIS Server 的信息了,強制去掉一個層級,讓其從第1級開始算瓦片吧,這樣我猜應該能載入了吧。
請聽下會demo彙報......