OpenLayers 地图标注之图文标注
注:当前使用的是 ol 5.3.0 版本,天地图使用的
key
请到天地图官网申请,并替换为自己的key
地图标注是将空间位置信息点与地图关联、通过图标、窗口等形式把相关信息展现到地图上。在WebGIS
中地图标注是重要的功能之一,可以为用户提供个性化服务,如兴趣点等。地图标注表现方式有图文标注、Popup
标注、聚合标注等。本节主要介绍加载图文标注。
1. 地图标注基本原理
地图标注通过在已知坐标点添加图片、文字或者图文的方式展现内容信息。可以通过鼠标点击获取目标点位置坐标,也可以通过属性传递获取。
2. 加载地图标注
OpenLayers
地图标注由叠加类Overlay
实现,主要内容参数为HTMLElement
。示例通过document.createElement
创建标注内容。
const htmlEle = document.createElement("div")
const closeEle = document.createElement('span')
const mainEle = document.createElement('div')mainEle.className = 'ol-popup-main'
mainEle.textContent = "这是四川省"closeEle.textContent = "x"
closeEle.className = "ol-popup-close"
htmlEle.className = "ol-popup"htmlEle.appendChild(mainEle)
htmlEle.appendChild(closeEle)
通过map.addOverlay
加载地图标注。
const marker = new ol.Overlay({id: "maker",position: chengdu,element: htmlEle,offset: [0, -70], // x、y轴偏移量,正值向右向下,负值相反positioning: 'top-center', // 定位方式,顶部居中aotuPan: true,autoPanMargin: 1.25,
})
marker.setProperties({ layerName: 'overlay' }) // 设置标注图层属性
map.addOverlay(marker)
3. 移除标注图层
可以根据图层名称或者传入标注图层进行移除。
function removeOverlayByName(layerName) {const overlays = map.getOverlays().getArray()// console.log("overlays:", overlays)overlays.forEach(layer => {console.log("layer.layerName:", layer.get('layerName'))if (layer.get('layerName') === layerName) map.removeOverlay(layer)});
}
function removeOverlayByLayer(overlay) {map.removeOverlay(overlay)
}
4. 打开和关闭Popup
OpenLayers
中可以通过map.addOverlay
实现Popup
弹窗,在弹窗关闭之后,通过添加交互事件,在地图上点击目标要素打开Popup
。Select
类用于图层要素交互,可以通过Select.getFeatures()
方法获取被选择的要素。
function openPopup(overlay) {map.addOverlay(overlay)
}function selectFeature(layer) {const selectEvt = new ol.interaction.Select({layers: [layer], // 用于选择要素的图层style: new ol.style.Style({image: new ol.style.Circle({radius: 5,fill: new ol.style.Fill({color: 'yellow'}),stroke: new ol.style.Stroke({color: 'red'})})})})// 激活选择事件selectEvt.setActive(true)map.addInteraction(selectEvt)map.on('click', evt => {console.log("getLayers:", map.getLayers().getArray())const layers = map.getLayers().getArray()layers.forEach(layer => {const props = layer.getProperties()if (props.layerName === "pointLayer") {openPopup(marker)}})})
}
5. 完整代码
其中libs
文件夹下的包需要更换为自己下载的本地包或者引用在线资源。
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>图文标注</title><meta charset="utf-8" /><script src="../libs/js/ol-5.3.3.js"></script><script src="../libs/js/jquery-2.1.1.min.js"></script><link rel="stylesheet" href="../libs/css//ol.css"><style>* {padding: 0;margin: 0;font-size: 14px;font-family: '微软雅黑';}html,body {width: 100%;height: 100%;}#map {position: absolute;width: 100%;height: 100%;}.ol-mouse-position {padding: 5px;top: 10px;height: 40px;line-height: 40px;background: #060505ba;text-align: center;color: #fff;border-radius: 5px;}.ol-popup {position: relative;font-size: 16px;color: #4c4c4c;background-color: #ddd;border-radius: 5px;}.ol-popup::before {display: block;content: "";width: 0;height: 0;border-left: 15px solid transparent;border-right: 15px solid transparent;border-top: 10px solid #ddd;position: absolute;bottom: -8px;left: 50%;transform: translateX(-50%);}.ol-popup-main {padding: 20px;}.ol-popup-close {position: absolute;display: inline-block;top: -6px;right: 5px;color: #878282b5;font-size: 20px;}.ol-popup-close:hover {cursor: pointer;color: #0e0e0eb5;filter: brightness(120%);}</style>
</head><body><div id="map" title="地图显示"></div>
</body></html><script>//地图投影坐标系const projection = ol.proj.get('EPSG:3857');//==============================================================================////============================天地图服务参数简单介绍==============================////================================vec:矢量图层==================================////================================img:影像图层==================================////================================cva:注记图层==================================////======================其中:_c表示经纬度投影,_w表示球面墨卡托投影================////==============================================================================//const TDTImgLayer = new ol.layer.Tile({title: "天地图影像图层",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",attibutions: "天地图注记描述",crossOrigin: "anoymous",wrapX: false})})const TDTImgCvaLayer = new ol.layer.Tile({title: "天地图影像注记图层",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",attibutions: "天地图注记描述",crossOrigin: "anoymous",wrapX: false})})const map = new ol.Map({target: "map",loadTilesWhileInteracting: true,view: new ol.View({// center: [11421771, 4288300],// center: [102.6914059817791, 25.10595662891865],center: [104.0635986160487, 30.660919181071225],zoom: 10,worldsWrap: true,minZoom: 1,maxZoom: 20,projection: "EPSG:4326"}),// 鼠标控件:鼠标在地图上移动时显示坐标信息。controls: ol.control.defaults().extend([// 加载鼠标控件new ol.control.MousePosition()])})map.addLayer(TDTImgLayer)map.addLayer(TDTImgCvaLayer)map.on('click', evt => {// 输出点击坐标console.log(evt.coordinate)})// 设置标注点const chengdu = [104.0635986160487, 30.660919181071225]// 添加点const pointLayer = new ol.layer.Vector({source: new ol.source.Vector({features: [new ol.Feature({geometry: new ol.geom.Point(chengdu),name: "chengdu"})]}),style: new ol.style.Style({image: new ol.style.Circle({radius: 5,fill: new ol.style.Fill({color: 'blue'})}),fill: new ol.style.Fill({color: "yellow"})})})pointLayer.setProperties({ "layerName": "pointLayer" })map.addLayer(pointLayer)const htmlEle = document.createElement("div")const closeEle = document.createElement('span')const mainEle = document.createElement('div')htmlEle.className = "ol-popup"mainEle.className = 'ol-popup-main'closeEle.className = "ol-popup-close"mainEle.textContent = "这是四川省"closeEle.textContent = "x"htmlEle.appendChild(mainEle)htmlEle.appendChild(closeEle)// 注册关闭popup事件closeEle.addEventListener('click', evt => {removeOverlayByName("overlay")// removeOverlayByLayer(marker)})const marker = new ol.Overlay({id: "maker",position: chengdu,element: htmlEle,offset: [0, -70], // x、y轴偏移量,正值向右向下,负值相反positioning: 'top-center', // 定位方式,顶部居中aotuPan: true,autoPanMargin: 1.25,})marker.setProperties({ layerName: 'overlay' })map.addOverlay(marker)selectFeature(pointLayer)function removeOverlayByName(layerName) {const overlays = map.getOverlays().getArray()// console.log("overlays:", overlays)overlays.forEach(layer => {console.log("layer.layerName:", layer.get('layerName'))if (layer.get('layerName') === layerName) map.removeOverlay(layer)});}function removeOverlayByLayer(overlay) {map.removeOverlay(overlay)}function openPopup(overlay) {map.addOverlay(overlay)}/*** pointLayer 点击监听事件* openlayers 中要素点击事件通过ol.interaction.Select实现,* 通过 getFeatures() 获取点击的要素*/function selectFeature(layer) {const selectEvt = new ol.interaction.Select({layers: [layer], // 用于选择要素的图层style: new ol.style.Style({image: new ol.style.Circle({radius: 5,fill: new ol.style.Fill({color: 'yellow'}),stroke: new ol.style.Stroke({color: 'red'})})})})// 激活选择事件selectEvt.setActive(true)map.addInteraction(selectEvt)map.on('click', evt => {console.log("getLayers:", map.getLayers().getArray())const layers = map.getLayers().getArray()layers.forEach(layer => {const props = layer.getProperties()if (props.layerName === "pointLayer") {openPopup(marker)}})// 获取选择要素// const features = selectEvt.getFeatures().getArray()// console.log("feats:", features)// 若点击点要素,则打开Popup// if (features.length) {// openPopup(marker)// }// 监听状态// selectEvt.on('change:active', evt => {// features.forEach(features.remove, features) // })})}
</script>
OpenLayers示例数据下载,请回复关键字:ol数据
全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试
【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏 + 关注 哦 !
本号不定时更新有关 GIS开发 相关内容,欢迎关注 !