346 lines
12 KiB
Markdown
346 lines
12 KiB
Markdown
---
|
||
title: 内容叠加层
|
||
date: 2020-12-25
|
||
author: ac
|
||
tags:
|
||
- Overlay
|
||
- Openlayers
|
||
categories:
|
||
- GIS
|
||
---
|
||
|
||
## Overlay
|
||
|
||
`ol.Overlay`是一个用于在地图上展示信息的一个小部件(Widget),作为内容叠加层添加到`map`中,可以出现在地图上的任何位置。部件需要一个HTML模版,来展示需要显示的内容,`Overlay`部件控制出现的位置,像气泡一样,锚指向设置的位置上。
|
||
|
||

|
||
|
||
### 构造参数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"//添加自定义样式
|
||
});
|
||
```
|
||
|
||
**应用**
|
||
|
||
### 场景一
|
||
已知特定的点位,对其进行注记或说明。
|
||
|
||

|
||
|
||
```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`控件选择要素。
|
||
|
||

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