arcgis三维球中加载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汇报......
上一篇: Gradle-日志
下一篇: gRPC-拦截器简单使用