1.切片地址规律分析
地图切片地址传统上无外乎类似谷歌的切片,即level(zoom),x和y坐标,然而有些网站为了为难我们“引用”
他们的地图,在切片地址上做了手脚。下面我以某个网站记做XXX.com(该网站并不存在,只是个例子)为例进行讲解:
1)通过F12查看img,我们可以看到其中一块地图切片的地址为http:XXX.com/L04/R00000005/C0000000e.png
仔细观察的话会发现,实际上也是符合level,x,y规律的。只是他一定进行了某种转换,让我们不会就这么轻易的“引用”他的地图。只看L和R没什么规律,但是当我们看到C0000000e时,什么时候才会出现字母呢,对了,当用到16进制的时候,因此我认为就是传统的谷歌切片格式进行16进制转换形成的网址,而且L要补齐2位,R和C要补齐8位。
2.写程序实验进行转换
这里我以ArcGIS API for JavaScript为例进行说明,对于一个API中没有的地图类,我们会新建一个类,这里先讲解LRC的转换,
function (level, col, row) {
var z = level;
var x = row;
var y = col;
x='C'+padLeft(8,x.toString(16));
y='R'+padLeft(8,y.toString(16));
z='L'+padLeft(2,z);
var url = "http://www.resdc.cn/data/DataProduct/土壤数据/中国土壤类型空间分布数据//_alllayers/"+z+"/"+y+"/"+x+".png";
return url;
}
对于完整的新建类实例,可以参考博客ArcGIS API for Javascript3.23加载谷歌地图-https://blog.csdn.net/yy284872497/article/details/78918064
这里只贴出本实例代码,记做roil.js,我们把它放到API文件下,并新建一个bism文件下,地址为bism/roil
define(["dojo/_base/declare", "esri/layers/TiledMapServiceLayer", "esri/geometry/Extent", "esri/SpatialReference", "esri/layers/TileInfo"],
function (declare, TiledMapServiceLayer, Extent, SpatialReference, TileInfo) {
return declare(TiledMapServiceLayer, {
//定义坐标系
constructor: function (properties) {
this.spatialReference = new SpatialReference({
wkid:102113
});
// 定义空间范围
this.fullExtent = new Extent(-20037508.342787, -20037508.342787, 20037508.342787, 20037508.342787, this.spatialReference);
this.initialExtent = new Extent(5916776.8, 1877209.3, 19242502.6, 7620381.8, this.spatialReference);
// 定义切片大小
this.tileInfo = new TileInfo({
"rows": 256,
"cols": 256,
"compressionQuality": 0,
"origin": {
"x": -20037508.342787,
"y": 20037508.342787
},
"spatialReference": {
"wkid": 102113
},
"lods": [
{ "level": 0, "resolution": 156543.033928, "scale": 591657527.591555 },
{ "level": 1, "resolution": 78271.5169639999, "scale": 295828763.795777 },
{ "level": 2, "resolution": 39135.7584820001, "scale": 147914381.897889 },
{ "level": 3, "resolution": 19567.8792409999, "scale": 73957190.948944 },
{ "level": 4, "resolution": 9783.93962049996, "scale": 36978595.474472 },
{ "level": 5, "resolution": 4891.96981024998, "scale": 18489297.737236 },
{ "level": 6, "resolution": 2445.98490512499, "scale": 9244648.868618 },
{ "level": 7, "resolution": 1222.99245256249, "scale": 4622324.434309 },
{ "level": 8, "resolution": 611.49622628138, "scale": 2311162.217155 },
{ "level": 9, "resolution": 305.748113140558, "scale": 1155581.108577 },
{ "level": 10, "resolution": 152.874056570411, "scale": 577790.554289 },
{ "level": 11, "resolution": 76.4370282850732, "scale": 288895.277144 },
{ "level": 12, "resolution": 38.2185141425366, "scale": 144447.638572 },
{ "level": 13, "resolution": 19.1092570712683, "scale": 72223.819286 },
{ "level": 14, "resolution": 9.55462853563415, "scale": 36111.909643 },
{ "level": 15, "resolution": 4.77731426794937, "scale": 18055.954822 },
{ "level": 16, "resolution": 2.38865713397468, "scale": 9027.977411 },
{ "level": 17, "resolution": 1.19432856685505, "scale": 4513.988705 },
{ "level": 18, "resolution": 0.597164283559817, "scale": 2256.994353 },
{ "level": 19, "resolution": 0.298582141647617, "scale": 1128.497176 }
]
});
// 定义为常用的19层
this.loaded = true;
this.onLoad(this);
},
getTileUrl:
function (level, col, row) {
var z = level;
var x = row;
var y = col;
x='C'+padLeft(8,x.toString(16));
y='R'+padLeft(8,y.toString(16));
z='L'+padLeft(2,z);
var url = "http://www.resdc.cn/data/DataProduct/土壤数据/中国土壤类型空间分布数据//_alllayers/"+z+"/"+y+"/"+x+".png";
return url;
}
});
}
)
//定义切片地址
function padLeft(num, val) {
return (new Array(num).join('0') + val).slice(-num);
}
最后,使用ArcGIS JS API编写代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/dijit/themes/tundra/tundra.css"/>
<link rel="stylesheet" type="text/css" href="http://localhost/arcgis_js_api/library/3.17/3.17/esri/css/esri.css" />
<script type="text/javascript" src="http://localhost/arcgis_js_api/library/3.17/3.17/init.js"></script>
<script>
require(["esri/map","bism/roil","dojo/domReady!"],
function(Map,roil){
var myMap = new Map("mapDiv");
var roil = new roil();
myMap.addLayer(roil)
})
</script>
</head>
<body class="tundra">
<div id="mapDiv" style="width:1500px; height:750px; border:1px solid #000;"></div>
</body>
</html>
我们最终实现的引用第三方地图的效果如下: