meface/docs/article/gis/openlayers/overlay.md

346 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 内容叠加层
date: 2020-12-25
author: ac
tags:
- Overlay
- Openlayers
categories:
- GIS
---
## Overlay
`ol.Overlay`是一个用于在地图上展示信息的一个小部件Widget作为内容叠加层添加到`map`中可以出现在地图上的任何位置。部件需要一个HTML模版来展示需要显示的内容`Overlay`部件控制出现的位置,像气泡一样,锚指向设置的位置上。
![image-20201214154539548](./images/image-20201214154539548.png)
### 构造参数Option
```javascript
<!--创建叠加层-->
var popup = new ol.Overlay({
//设置该叠加层的标识方便在map中获取该图层map.getOverlayById
id:'bubble',
//HTMLElement元素也是叠加层内容内容模版
element: document.getElementById('popup'),
//设置偏移量[x,y],像素为单位
// offset:[200,200],
//该叠加层的锚点 值为Coordinate
position:ol.proj.fromLonLat([113.958334, 22.535640]),
//设置锚点相对于叠加层内容的位置'bottom-left', 'bottom-center', 'bottom-right', 'center-left', 'center-center', 'center-right', 'top-left', 'top-center', and 'top-right'.
positioning:"center-center",
//是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
stopEvent:true,
//是否替换第一个overlay容器
insertFirst:false,
autoPan: true,//当气泡显示在窗口边缘存在气泡显示不完全时view视图将移动到显示整个气泡的视图
autoPanAnimation: {
duration: 250
},
// className:"customClass"//添加自定义样式
});
```
**应用**
### 场景一
已知特定的点位,对其进行注记或说明。
![image-20201214154539548](./images/image-20201214154539548.png)
```html
<!doctype html>
<html >
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>
<script src="lib/ol.js"></script>
<title>OpenLayers example</title>
<meta charset="UTF-8">
</head>
<body>
<h2>Overlay 地图注记</h2>
<div id="map" class="map"></div>
<!--popup容器-->
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content">
叠加层的内容(模版)
</div>
</div>
<script type="text/javascript">
var map = new ol.Map({
layers: [
//加载瓦片图层
new ol.layer.Tile({
source:new ol.source.OSM(),
name:"世界地图(OSM瓦片)",
id:"osm"
})
],
target: document.getElementById('map'),
view: new ol.View({
center: [12703928.421141896,2575539.5219027703],
zoom: 11
})
});
//根据已知坐标点指定气泡位置
var shenzhen = ol.proj.fromLonLat([114.05 ,22.55]);
<!--创建叠加层-->
var popup = new ol.Overlay({
//Overlay 的基本属性
id:'pipe',//设置该叠加层的标识方便在map中获取该图层map.getOverlayById
element: document.getElementById('popup'),//HTMLElement元素也是叠加层内容
// offset:[200,200],//设置偏移量[x,y],像素为单位
position:shenzhen,//该叠加层的锚点 值为Coordinate
positioning:"center-center",//
stopEvent:true,//是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
insertFirst:true,//是否替换第一个overlay容器
autoPan: true,
autoPanAnimation: {
duration: 2500
},
// className:"abcclass"
});
popup.setPosition(shenzhen);
map.addOverlay(popup);
//绑定气泡的关闭按钮的点击事件,隐藏气泡
document.getElementById('popup-closer').onclick = function() {
popup.setPosition(undefined);
clickPopup.setPosition(undefined);
this.blur();
return false;//取消a标签的默认行为点击a标签的默认行为是会跳转页面的
};
</script>
</body>
</html>
```
### 场景二
点击矢量要素,展示要素信息。获取要素信息的方法可以使用`map`中的`getFeaturesAtPixel()`方法获取`layers`集合中的矢量图层在该像素点处的要素集合,也可以使用矢量数据源`ol.source.Vector`中的`getFeaturesAtCoordinate`方法获取要素信息。当然也可以使用`select`控件选择要素。
![image-20201214170455692](./images/image-20201214170455692.png)
```html
<!doctype html>
<html >
<head>
<link rel="stylesheet" href="css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>
<script src="lib/ol.js"></script>
<title>OpenLayers example</title>
<meta charset="UTF-8">
</head>
<body>
<h2>Openlayers 内容叠加层</h2>
<div id="map" class="map"></div>
<!--popup容器-->
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content">
叠加层的内容
</div>
</div>
<script type="text/javascript">
var vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON({geometryName:"geom"}),
loader: function (extent, resolution, projection) {
var proj = projection.getCode();
var url = 'http://localhost:8080/geoserver/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=test:tiger_roads&' +
'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 nyc = ol.proj.fromLonLat([-73.92722, 40.774221]);
var map = new ol.Map({
layers: [
//加载瓦片图层
new ol.layer.Tile({
source:new ol.source.OSM(),
name:"世界地图(OSM瓦片)",
id:"osm"
}),
new ol.layer.Vector({
source: vectorSource,
id: "nyc"
})
],
target: document.getElementById('map'),
view: new ol.View({
center: nyc,
zoom: 11
})
});
<!--创建叠加层-->
var popup = new ol.Overlay({
//Overlay 的基本属性
id:'bubble',//设置该叠加层的标识方便在map中获取该图层map.getOverlayById
element: document.getElementById('popup'),//HTMLElement元素也是叠加层内容
// offset:[200,200],//设置偏移量[x,y],像素为单位
position:nyc,//该叠加层的锚点 值为Coordinate
positioning:"bottom-right",//设置锚点相对于叠加层内容的位置'bottom-left', 'bottom-center', 'bottom-right', 'center-left', 'center-center', 'center-right', 'top-left', 'top-center', and 'top-right'.
stopEvent:true,//是否应该停止在viewport中的事件传播。默认true图层会在ol-overlaycontainer-stopevent里面false则会在ol-overlaycontainer中
insertFirst:false,//是否替换第一个overlay容器
autoPan: true,//当气泡显示在窗口边缘存在气泡显示不完全时view视图将移动到显示整个气泡的视图
autoPanAnimation: {
duration: 2500
},
// className:"customClass"//添加自定义样式
});
popup.setPosition(nyc);
map.addOverlay(popup);
//绑定气泡的关闭按钮的点击事件,隐藏气泡
document.getElementById('popup-closer').onclick = function(e) {
console.log("closer");
popup.setPosition(undefined);
this.blur();
return false;//取消a标签的默认行为点击a标签的默认行为是会跳转页面的
};
map.on('click',function(e){
var features = map.getFeaturesAtPixel(e.pixel,{
//设置点击要素的容差
'hitTolerance':5
});
if(features){
var popupWidget = map.getOverlayById('bubble');
popupWidget.setPosition(e.coordinate);
var featurtesInfo = createInfoTemplate(features);
var content = document.getElementById('popup-content');
content.innerHTML = featurtesInfo;
}else{
popupWidget.setPosition(undefined);
}
})
function createInfoTemplate(features) {
var template = '<table>'+
'<tr><th>gid</th><th>cfcc</th><th>name</th></tr>';
for(var i=0;i<features.length;i++){
var property = features[i].values_;
template += '<tr><td>'+property["gid"]+'</td><td>'+property["cfcc"]+'</td><td>'+property["name"]+'</td></tr>';
}
return template;
}
</script>
</body>
</html>
```