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