350 lines
14 KiB
Markdown
350 lines
14 KiB
Markdown
|
---
|
|||
|
title: 图层控制
|
|||
|
date: 2020-10-20
|
|||
|
author: ac
|
|||
|
tags:
|
|||
|
- OpenLayers
|
|||
|
categories:
|
|||
|
- GIS
|
|||
|
---
|
|||
|
|
|||
|
## 1. 简述
|
|||
|
|
|||
|
在`ol`中对图层显隐性的控制可以通过修改图层的`visible`属性或设置不透明度`opacity`属性来实现。
|
|||
|
|
|||
|
与且它地图`API`对比,获取图层的方法比较繁琐,比如在`ArcGIS for JS`中使用`map.getLayerById()`就可直接获得对应的图层了,但在`ol`中添加到`map`中的图层都存储在一个图层集合`layers`中的,需要使用`map.getLayers()`方法先获得该集合,再循环遍历筛选才能得到想要的图层。
|
|||
|
|
|||
|
> 图层集合中先添加进来的图层在底部,会被后加入的图层遮挡。所以通常将瓦片底图放在底部,上面的图层依次按面、线、点要素添加,这样有利于各图层的显示。如果想当前图层不被遮挡可以设置后续加入图层的`opacity`不透明度属性。
|
|||
|
|
|||
|
核心代码:
|
|||
|
|
|||
|
```javascript
|
|||
|
function changeLayerVisibility(layerId,prop) {
|
|||
|
//获取图层数组
|
|||
|
var layers = map.getLayers();
|
|||
|
for(var i=0;i<layers.getLength();i++){
|
|||
|
if(layers.item(i).get("id") === layerId){
|
|||
|
layers.item(i).setVisible(prop);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
相关API:
|
|||
|
|
|||
|
<img src="./images/image-20201110143812069.png" alt="image-20201110143812069"/>
|
|||
|
|
|||
|
`map.getLayers()`返回的是图层(`BaseLayer`)集合对象。
|
|||
|
|
|||
|
`ol.Collection`是对`JS`中数组的扩展,添加许多方便的方法,如`item(index)`方法获取相应index位置的数组元素。`BaseLayer`是`Layer`的基类。
|
|||
|
|
|||
|
**在构建`Layer`时,传入的`option`都会有相应的`get/set`访问器,所以可以拿到初始化图层时自定义的`id`属性。**
|
|||
|
|
|||
|
## 2. 示例
|
|||
|
|
|||
|
这里使用了一个很久很久以前比较流行的`js`树形插件`ztree`。
|
|||
|
|
|||
|
<img src="./images/image-20201214112707035.png" alt="image-20201214112707035" style="zoom: 50%;" />
|
|||
|
|
|||
|
下面我们使用`ztree`树形插件来创建图层控制示例(完整代码):
|
|||
|
|
|||
|
```html
|
|||
|
<!doctype html>
|
|||
|
<html lang="en">
|
|||
|
<head>
|
|||
|
<meta charset="utf-8">
|
|||
|
<style>
|
|||
|
.map {
|
|||
|
height: 400px;
|
|||
|
width: 100%;
|
|||
|
}
|
|||
|
</style>
|
|||
|
<link rel="stylesheet" href="css/ol.css" type="text/css">
|
|||
|
<link rel="stylesheet" href="lib/zTree_v3/css/zTreeStyle/zTreeStyle.css" type="text/css">
|
|||
|
<script src="lib/ol.js"></script>
|
|||
|
<script src="lib/jquery-3.1.1.js"></script>
|
|||
|
<script src="lib/zTree_v3/js/jquery.ztree.all.min.js"></script>
|
|||
|
<title>Layer</title>
|
|||
|
</head>
|
|||
|
<body>
|
|||
|
<h2>ztree图层控制</h2>
|
|||
|
<p>zTree 是一个依靠 jQuery 实现的多功能 “树插件”。</p>
|
|||
|
<div id="map" class="map"></div>
|
|||
|
<div id="treeDemo" class="ztree"></div>
|
|||
|
<script type="text/javascript">
|
|||
|
|
|||
|
var zTreeObj;
|
|||
|
// zTree 的参数配置,深入使用请参考 API 文档(setting 配置详解)
|
|||
|
var setting = {
|
|||
|
check: {
|
|||
|
enable: true,
|
|||
|
nocheckInherit: false
|
|||
|
},
|
|||
|
data: {
|
|||
|
simpleData: {enable: true}
|
|||
|
},
|
|||
|
view:{
|
|||
|
showIcon:false
|
|||
|
},
|
|||
|
callback:{
|
|||
|
//配置复选框点击事件的处理函数
|
|||
|
onCheck:handleCheck
|
|||
|
}
|
|||
|
};
|
|||
|
// zTree 的数据属性,深入使用请参考 API 文档(zTreeNode 节点数据详解)
|
|||
|
var zNodes = [
|
|||
|
{
|
|||
|
Id:1,pid:0,name:"矢量数据", open:true, checked:true,children:
|
|||
|
[
|
|||
|
{id:11,pId:1,name:"GeoJson数据",id:"GeoJsonData", checked:true},
|
|||
|
{id:12,pId:1,name:"kml数据",id:"kmlData", checked:true},
|
|||
|
{id:13,pId:1,name:"gpx数据",id:"gpxData", checked:true},
|
|||
|
{id:14,pId:1,name:"loader函数加载的数据",id:"load", checked:true},
|
|||
|
{id:15,pId:1,name:"已知坐标添加的图层",id:"pointLayer", checked:true},
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
id:2,pId:0,name:"栅格数据", open:true, checked:true,children:
|
|||
|
[
|
|||
|
{id:21,pId:2,name:"OpenStreetMap",id:"osm", checked:true},
|
|||
|
{id:22,pId:2,name:"ArcGIS MapServer瓦片",id:"arcgis_tile", checked:true},
|
|||
|
{id:23,pId:2,name:"ArcGIS online瓦片服务",id:"arcgis_online", checked:true},
|
|||
|
{id:24,pId:2,name:"Bing影像 Aerial",id:"bing_Aerial", checked:true},
|
|||
|
{id:25,pId:2,name:"Bing影像 AerialWithLabelsOnDemand",id:"bing_AerialWithLabelsOnDemand", checked:true},
|
|||
|
{id:26,pId:2,name:"Bing影像 RoadOnDemand",id:"bing_RoadOnDemand", checked:true},
|
|||
|
{id:27,pId:2,name:"Bing影像 CanvasDark",id:"bing_CanvasDark", checked:true},
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
id:3,pId:0,name:"公共网络地图服务",open:true,checked:true,children:
|
|||
|
[
|
|||
|
{id:31,pId:3,name:"百度地图",id:"BMap", checked:true},
|
|||
|
{id:32,pId:3,name:"天地图矢量图层",id:"tdt_vec", checked:true},
|
|||
|
{id:33,pId:3,name:"天地图矢量注记图层",id:"tdt_cva", checked:true},
|
|||
|
{id:34,pId:3,name:"Mapbox",id:"mapbox_tile", checked:true},
|
|||
|
]
|
|||
|
}
|
|||
|
];
|
|||
|
$(document).ready(function(){
|
|||
|
zTreeObj = $.fn.zTree.init($("#treeDemo"), setting, zNodes);
|
|||
|
});
|
|||
|
//ztree复选框点击事件处理函数
|
|||
|
function handleCheck(e,treeId,treeNode){
|
|||
|
if(treeNode.level !== 0){
|
|||
|
//叶子节点时
|
|||
|
changeLayerVisibility(treeNode.id,treeNode.checked)
|
|||
|
}else{
|
|||
|
//非叶子节点时
|
|||
|
if(treeNode.children !== null){
|
|||
|
for(var j=0;j<treeNode.children.length;j++){
|
|||
|
changeLayerVisibility(treeNode.children[j].id,treeNode.checked);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function changeLayerVisibility(layerId,prop) {
|
|||
|
var layers = map.getLayers();
|
|||
|
for(var i=0;i<layers.getLength();i++){
|
|||
|
if(layers.item(i).get("id") === layerId){
|
|||
|
layers.item(i).setVisible(prop);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//初始化地图,加载图层
|
|||
|
var map;
|
|||
|
function initMap() {
|
|||
|
var shenzhen = [113.958334, 22.535640];
|
|||
|
var url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer';
|
|||
|
var onlineTileUrl = 'http://server.arcgisonline.com/arcgis/rest/services/USA_Topo_Maps/MapServer/tile/{z}/{y}/{x}'
|
|||
|
var bingKey = 'AmosL5A0GtVryl4sXNZm6U5EQMD6brAd5E8AJPGJf8AUU1saDYXDkb5CwQFijans';
|
|||
|
var key = "bf156eb3c72350d62b008dc8a4ae1016";
|
|||
|
var mapboxkey = "pk.eyJ1IjoicWl1c2hpamllIiwiYSI6ImNrYTYzNmlhdDAzb2YydG13YjZic2t2M3AifQ.XiCKl8HOEAy0MBo5v2yjvA";
|
|||
|
var vectorSource = new ol.source.Vector({
|
|||
|
format: new ol.format.GeoJSON(),
|
|||
|
loader: function (extent, resolution, projection) {
|
|||
|
var proj = projection.getCode();
|
|||
|
var url = 'http://gisserver.tianditu.gov.cn/TDTService/wfs?service=WFS&' +
|
|||
|
'version=1.1.0&request=GetFeature&typename=LRRL&' +
|
|||
|
'outputFormat=application/json&srsname=' + proj + '&' +
|
|||
|
'bbox=' + extent.join(',') + ',' + proj;
|
|||
|
var xhr = new XMLHttpRequest();
|
|||
|
xhr.open('GET', url);
|
|||
|
var onError = function () {
|
|||
|
vectorSource.removeLoadedExtent(extent);
|
|||
|
}
|
|||
|
xhr.onerror = onError;
|
|||
|
xhr.onload = function () {
|
|||
|
if (xhr.status == 200) {
|
|||
|
vectorSource.addFeatures(
|
|||
|
vectorSource.getFormat().readFeatures(xhr.responseText));
|
|||
|
} else {
|
|||
|
onError();
|
|||
|
}
|
|||
|
}
|
|||
|
xhr.send();
|
|||
|
},
|
|||
|
strategy: ol.loadingstrategy.bbox
|
|||
|
})
|
|||
|
var pointFeature = new ol.Feature({
|
|||
|
geometry: new ol.geom.Point([12703928.421,2575539.521]),
|
|||
|
name: '点要素'
|
|||
|
});
|
|||
|
var resolutions = [];
|
|||
|
for(var i=0;i<19;i++){
|
|||
|
resolutions[i] = Math.pow(2,18 - i)
|
|||
|
}
|
|||
|
|
|||
|
map = new ol.Map({
|
|||
|
target:"map",
|
|||
|
view: new ol.View({
|
|||
|
center:ol.proj.fromLonLat(shenzhen),
|
|||
|
zoom:8
|
|||
|
}),
|
|||
|
layers:[
|
|||
|
//加载矢量Vector服务图层
|
|||
|
new ol.layer.Vector({
|
|||
|
source:new ol.source.Vector({
|
|||
|
url:'data/geojson/countries.geojson',
|
|||
|
format:new ol.format.GeoJSON()
|
|||
|
}),
|
|||
|
name:"国界(JSON格式的矢量图层)",
|
|||
|
id:"GeoJsonData"
|
|||
|
}),
|
|||
|
//加载矢量Vector服务图层
|
|||
|
new ol.layer.Vector({
|
|||
|
source:new ol.source.Vector({
|
|||
|
url:'data/kml/2012_Earthquakes_Mag5.kml',
|
|||
|
format:new ol.format.KML({
|
|||
|
extractStyles:false
|
|||
|
})
|
|||
|
}),
|
|||
|
name:"点(KML格式的矢量图层)",
|
|||
|
id:"kmlData"
|
|||
|
}),
|
|||
|
new ol.layer.Vector({
|
|||
|
source:new ol.source.Vector({
|
|||
|
url:'data/gpx/fells_loop.gpx',
|
|||
|
format:new ol.format.GPX()
|
|||
|
}),
|
|||
|
name:"GPX数据",
|
|||
|
id:"gpxData"
|
|||
|
}),
|
|||
|
new ol.layer.Vector({
|
|||
|
source: vectorSource,
|
|||
|
name: "天地图中的道路数据",
|
|||
|
id: "load"
|
|||
|
}),
|
|||
|
new ol.layer.Vector({
|
|||
|
source: new ol.source.Vector({
|
|||
|
features:[pointFeature]
|
|||
|
}),
|
|||
|
id:"pointLayer"
|
|||
|
}),
|
|||
|
//加载瓦片图层
|
|||
|
new ol.layer.Tile({
|
|||
|
source:new ol.source.OSM(),
|
|||
|
name:"世界地图(OSM瓦片)",
|
|||
|
id:"osm"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
// extent:[-13884991, 2870341, -7455066, 6338219],
|
|||
|
source:new ol.source.TileArcGISRest({
|
|||
|
url:url
|
|||
|
}),
|
|||
|
name:"ArcGIS瓦片服务",
|
|||
|
id:"arcgis_tile"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
// extent:[-13884991, 2870341, -7455066, 6338219],
|
|||
|
source:new ol.source.XYZ({
|
|||
|
url:onlineTileUrl
|
|||
|
}),
|
|||
|
name:"ArcGIS online瓦片服务",
|
|||
|
id:"arcgis_online"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
source:new ol.source.BingMaps({key:bingKey,imagerySet:"Aerial"}),
|
|||
|
name:"BingMaps(Aerial)",
|
|||
|
id:"bing_Aerial"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
source:new ol.source.BingMaps({key:bingKey,imagerySet:"AerialWithLabelsOnDemand"}),
|
|||
|
name:"BingMaps(AerialWithLabelsOnDemand)",
|
|||
|
id:"bing_AerialWithLabelsOnDemand"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
source:new ol.source.BingMaps({key:bingKey,imagerySet:"RoadOnDemand"}),
|
|||
|
name:"BingMaps(RoadOnDemand)",
|
|||
|
id:"bing_RoadOnDemand"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
source:new ol.source.BingMaps({key:bingKey,imagerySet:"CanvasDark"}),
|
|||
|
name:"BingMaps(CanvasDark)",
|
|||
|
id:"bing_CanvasDark"
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
id:"BMap",
|
|||
|
source:new ol.source.TileImage({
|
|||
|
//设置坐标参考
|
|||
|
projection:ol.proj.get('EPSG:3857'),
|
|||
|
//设置分辨率
|
|||
|
tileGrid:new ol.tilegrid.TileGrid({
|
|||
|
origin:[0,0],
|
|||
|
resolutions:resolutions
|
|||
|
}),
|
|||
|
//设置百度地图的瓦片地图请求地址
|
|||
|
tileUrlFunction:function (tileCoord,pixelRatio,proj) {
|
|||
|
if(!tileCoord){
|
|||
|
return "";
|
|||
|
}
|
|||
|
var z = tileCoord[0];
|
|||
|
var x = tileCoord[1];
|
|||
|
var y = tileCoord[2];
|
|||
|
|
|||
|
if(x < 0){
|
|||
|
x = "M" + (-x);
|
|||
|
}
|
|||
|
if(y < 0){
|
|||
|
x = "M" + (-y);
|
|||
|
}
|
|||
|
return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&style=pl&udt=20151021&scale=1&p=1";
|
|||
|
}
|
|||
|
})
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
id:"tdt_vec",
|
|||
|
title:"天地图矢量图层",
|
|||
|
source:new ol.source.XYZ({
|
|||
|
// url:"http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk="+key,
|
|||
|
url: 'http://t' + Math.round(Math.random() * 7) + '.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk='+key,
|
|||
|
crossOrigin:"anonymous",
|
|||
|
wrapX:false
|
|||
|
})
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
id:"tdt_cva",
|
|||
|
title:"天地图矢量注记图层",
|
|||
|
source:new ol.source.XYZ({
|
|||
|
url:"https://t2.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk="+key,
|
|||
|
crossOrigin:"anonymous",
|
|||
|
wrapX:false
|
|||
|
})
|
|||
|
}),
|
|||
|
new ol.layer.Tile({
|
|||
|
id:"mapbox_tile",
|
|||
|
source: new ol.source.XYZ({
|
|||
|
url: 'https://api.mapbox.com/styles/v1/mapbox/streets-v11/tiles/256/{z}/{x}/{y}?access_token='+mapboxkey
|
|||
|
})
|
|||
|
}),
|
|||
|
]
|
|||
|
});
|
|||
|
}
|
|||
|
window.onload = initMap();
|
|||
|
</script>
|
|||
|
</body>
|
|||
|
</html>
|
|||
|
```
|
|||
|
|