前面我们说到地形是三维场景的”骨骼”,栅格瓦片图层就是我们浏览三维能感知的”皮肤”了,通常我们叠加的是各种卫星影像或瓦片数据。
Mars3D支持多种服务来源的高精度影像地图数据的加载和渲染。图层支持排序和透明混合,支持设置影像图层相关属性,比如透明度、亮度、对比度、色调等。
1、栅格瓦片介绍
目前我们所见的所有地图底图服务都是瓦片地图的方式发布的。瓦片地图金字塔模型是一种多分辨率层次模型,从瓦片金字塔的底层到顶层,分辨率越来越低,但表示的地理范围不变。
当我们建立好了影像金字塔后,前端再请求地图时,则将只是在切好的瓦片缓存中,找到对应级别里对应的瓦片即可。然后在前端将这些请求到的瓦片拼接出来,便可以得到用户需要的级别下的可视范围内的瓦片了。
瓦片的特征
- 瓦片分辨率通常是256x256
- 最小的地图等级为0,此时,世界地图只有一张瓦片构成
- 具有唯一的瓦片等级(z)和瓦片行列坐标编号(x, y)
- 瓦片等级越高,组成世界地图的瓦片数也多,可以展示的地图越详细
某一瓦片等级地图的瓦片是由低一级的各瓦片,切割成的4个瓦片组成,四叉树结构组成了瓦片金字塔
1.1 为什么会出现瓦片金字塔这个概念
现在,我假设我们的服务器上有一个1G的影像,需要将其在前端展示。我们传统的做法是,首先将服务起中的1G影像下载到前端然后浏览器加载渲染出图。但是大家想一想,首先客户端下载1G的影像需要的事件,一定是一个漫长的过程,其次浏览器加载这么大的文件,也多半会导致崩溃。而最重要的问题是,我们的需求仅仅是浏览全图中的某一个区域下的某几个级别,现在却将全图加载完毕了,二者还导致了数据垩不安全性(下载到本地),同时我们每一次的放大、缩小和拖拽都会使浏览器花上足够的时间去渲染。可见传统的方式是不符合实际需求的。到了后来有了新的解决办法,比如arcgis的IMS版本中提出了动态出图的概念。也就是前端发出的请求里包含了需要显示的范围、显示窗口的大萧等参数后,后台动态的在原始数据中切出一个符合需求的瓦片,然后将这个数据返回给前台,并且在服务器中,将这个瓦片做缓存。可是这个方法,前端出图依旧很慢,并且使服务器压力过大。终于瓦片金字塔方案出现了。
1.2 栅格瓦片的数据来源
可以直接访问在线互联网服务、如百度、高德、腾讯、谷歌等
- 下载在线互联网服务到本地离线使用,如wms、wmts、arcgis等
- 对源数据进行切片
2. 图层类型清单
栅格瓦片图层,均是继承自BaseTileLayer(opens new window)类的子类对象。
目前有以下类型:
类型名 | 说明 | 对应的图层类 | 备注 |
---|---|---|---|
image | 单张图片 | ImageLayer | 通用标准 |
xyz | 标准金字塔地图 | XyzLayer | 通用标准 |
wms | OGC WMS标准服务 | WmsLayer | 通用标准 |
wmts | OGC WMTS标准服务 | WmtsLayer | 通用标准 |
arcgis | ArcGIS标准服务 | ArcGisLayer | 通用标准 |
arcgis_cache | ArcGIS切片 | ArcGisCacheLayer | 通用标准 |
tdt | 天地图 | TdtLayer | 在线地图 |
gaode | 高德 | GaodeLayer | 在线地图 |
baidu | 百度 | BaiduLayer | 在线地图 |
tencent | 腾讯 | TencentLayer | 在线地图 |
osm | OpenStreetMap(OSM) | OsmLayer | 国外在线地图 |
bing | 微软 BingMaps | BingLayer | 国外在线地图 |
mapbox | Mapbox地图 | MapboxLayer | 国外在线地图 |
ion | Cesium Ion服务 | IonLayer | 国外在线地图 |
谷歌地图 | GoogleLayer | 目前已被封 | |
gee | 谷歌地球企业服务 | GeeLayer | 需部署私服 |
3. 瓦片图层参数调试
当我们拿到各类瓦片服务地址后,如果不具备相关GIS知识储备,如果将一个瓦片正常的调试加载成功,并不是一件容易的事情,特别是非标准坐标系、非标准的服务时。
我们也提供了一个瓦片图层加载和调试的页面来可视化页面中,建议先在该页面做调试
- 打开瓦片图层参数调试编辑页面(opens new window),在这个页面的图层URL输入框内输入服务url地址,并设置一些已知的参数后,单击加载图层按钮。
- 如果地球上未能正常显示瓦片图层,尝试修改坐标系、加载层级等参数。
- 如果是WMS、WMTS等类型服务,有特殊自定义参数时,需要在代码中修改写死这些固定的参数去调试。
- 在瓦片图层正常显示后,并调整好所有参数,单击“保存参数”按钮,保存的参数json,会自动下载一个json文件。
- 如果图层是初始化就加载的,可以打开项目的config.json文件,拷贝刚下载的json到config.json文件的layers参数中即可。
- 如果代码中直接 new 图层类,可以将json中的参数拷贝到类参数中。
4. 瓦片图层的创建和使用
4.1 快速开始(初始化 new Map时候传入)
在构造Map时传入basemaps或layers参数中配置相关图层,并设置show:true后进行加载展示栅格瓦片图层var map = new mars3d.Map('mars3dContainer', {
basemaps: [
{
name: '天地图卫星',
icon: 'img/basemaps/tdt_img.png',
type: 'tdt',
layer: 'img_d',
key: ['天地图token值'],
show: true,
},
{
name: '单张图片',
icon: 'img/basemaps/offline.png',
type: 'image',
url: 'img/tietu/world.jpg',
},
],
layers: [
{
"type": "tdt",
"name": "天地图注记",
"layer": "img_z",
"key": ["天地图token值"],
"show": true
},
]
})
4.2 代码中创建图层
可以有下面2种方式来创建图层对象: ```javascript //用工厂方法,指定type来创建图层对象 var layer = mars3d.LayerUtil.create({ type: ‘xyz’, url: ‘https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png‘, subdomains: ‘abc’, }) map.addLayer(layer)
//直接创建具体类型的图层对象 var tileLayer = new mars3d.layer.XyzLayer({ url: ‘https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png‘, subdomains: ‘abc’, }) map.addLayer(tileLayer)
> 在Map创建后可以通过[map.addLayer(opens new window)](http://mars3d.cn/api/Map.html#addLayer)和[map.removeLayer(opens new window)](http://mars3d.cn/api/Map.html#removeLayer)方法来控制图层的加载和删除
> 在图层本身也有 [layer.addTo(opens new window)](http://mars3d.cn/api/BaseLayer.html#addTo)和[layer.remove(opens new window)](http://mars3d.cn/api/BaseLayer.html#remove)2个方法支持添加或移除图层。
<a name="IicqX"></a>
#### 4.3 加载xyz数据步骤
所有瓦片最基础最常见的就是xyz图层,也是其他类似图层的基础。
1. 当瓦片是标准金字塔命名的时候,格式一般都默认的{z}/{x}/{y}.jpg或{z}/{x}/{y}.png 目录组织的金字塔目录。如下图:

2. 当数据量大的时候,直接拷贝切片会很慢很慢,一般操作是分层压缩成压缩包(并按4G分卷),拷贝到服务器中后在进行解压
2. 在目标服务器中安装好任意http服务器,确保可正常提供web信息浏览服务即可。如:Nginx(推荐), IIS, Tomcat等,将图片文件夹单独发布成一个站点,比如我将下载的数据目录test发布后,可以通过浏览器访问到图片即可 http://localhost/mapdata/maptile/test/1/1/0.png
2. 在Mars3D框架中打开[瓦片图层参数调试编辑页面(opens new window)](http://mars3d.cn/example/c20_tileLayer_edit.html),在这个页面的图层URL输入框内输入刚才的服务url地址 http://localhost:8888/mapdata/exp/{z}/{x}/{y}.png,单击加载图层按钮。
2. 如果地球上未能正常显示瓦片图层,尝试修改坐标系. 加载层级等参数。
2. 在瓦片图层正常显示后,优化配置参数,因为瓦片不是全球的数据,肯定只是局部范围,为了避免无效请求,可以配置层级和边界值,这样客户端就不请求区域外和层级外的数据,单击“保存参数”按钮,保存的参数json,会自动下载一个json文件。
2. 如果代码中直接 new [XyzLayer图层类(opens new window)](http://mars3d.cn/api/XyzLayer.html),可以将json中的参数拷贝到类参数中。
```javascript
var tileLayer = new mars3d.layer.XyzLayer({
url: 'http://localhost/mapdata/maptile/test/{z}/{x}/{y}.png',
minimumLevel: 1,
maximumLevel: 18,
minimumTerrainLevel: 1,
maximumTerrainLevel: 18,
rectangle: { "xmin": 114.85, "xmax": 119.68, "ymin": 29.34, "ymax": 34.74 }
})
map.addLayer(tileLayer)
- 如果图层是初始化就加载的,可以打开项目的config.json文件,拷贝刚下载的json到config.json文件的layers参数中即可。
{ "name": "测试瓦片", "type": "xyz", "url": "http://localhost/mapdata/maptile/test/{z}/{x}/{y}.png", "minimumLevel": 1, "maximumLevel": 18, "minimumTerrainLevel": 1, "maximumTerrainLevel": 18, "rectangle": { "xmin": 114.85, "xmax": 119.68, "ymin": 29.34, "ymax": 34.74 } },