当前位置: 首页 > news >正文

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弹窗,在弹窗关闭之后,通过添加交互事件,在地图上点击目标要素打开PopupSelect类用于图层要素交互,可以通过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之路】 已经接入了智能助手,欢迎关注,欢迎提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注 !

http://www.xdnf.cn/news/761275.html

相关文章:

  • 【第四十七周】HippoRAG 2 复现与分析(一):环境部署与代码分析
  • linux文件管理(补充)
  • 纯汇编自制操作系统(四、应用程序等的实现)
  • [Python] Python自动化:PyAutoGUI的基本操作
  • ArkTS基础
  • [PCIe]Gen6 PAM4的功耗相比Gen5 NRZ增加了多少?
  • C++测开,自动化测试,业务(第一段实习)
  • 微软常用运行库合集(VisualC++)2025.04.22
  • 阴盘奇门 api数据接口
  • Redis:安装与常用命令
  • Mybatis-Plus 学习
  • RTMP播放器谁更强?深入解析SmartPlayer与VLC、PotPlayer等方案的技术差异
  • 落石石头检测数据集VOC+YOLO格式1185张1类别
  • WEBSTORM前端 —— 第3章:移动 Web —— 第5节:响应式网页
  • 字节golang后端二面
  • 位运算 #常见位运算总结 #题解
  • 优化06-物理读和IO
  • Markdown笔记
  • 81、使用DTU控制水下灯光控制
  • 商品模块中的多规格设计:实现方式与电商/ERP系统的架构对比
  • [AD] Reaper NBNS+LLMNR+Logon 4624+Logon ID
  • GNSS终端授时之四:高精度的PTP授时
  • PINN for PDE(偏微分方程)1 - 正向问题
  • io流2——字节输入流,文件拷贝
  • Docker容器创建Redis主从集群
  • 卢昌海 | 质量的起源
  • 基于FashionMnist数据集的自监督学习(生成式自监督学习VAE算法)
  • [蓝桥杯]螺旋折线
  • 2024 CKA模拟系统制作 | Step-By-Step | 8、题目搭建-创建 Ingress
  • win32相关(互斥体)