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>
|
||
```
|
||
|