^ 关注我,带你一起学GIS ^
注:当前使用的是 ol [9.2.4] 版本,天地图使用的
key
请到天地图官网申请,并替换为自己的key
前言
❝OpenLayers量测工具用于地理信息系统应用中的距离和面积量测功能,是GIS开发的常用功能。它通过Draw交互类和sphere对象实现,可创建指定量测类型(距离或面积)的对象,并添加到地图上,用户通过交互操作进行量测。量测时,OpenLayers会自动将地理坐标转换为像素坐标,方便操作。该工具广泛应用于地理信息测量、地图绘制与分析等领域,为用户提供便捷、高效的量测解决方案。
本节主要介绍OpenLayers 量测距离。
1. 初始化绘制参数
绘制参数主要有下图几种类型,包括交互绘制对象、提示信息元素以及叠加图层,还包含绘制图层数据源和绘制监听对象。
/**###########################初始化绘制参数开始############################**/
let drawAction = undefined // 绘制对象
let sketch = undefined // 绘制要素
let helpTooltip // 绘制提示叠加层
let measureTooltip // 测量提示叠加层
let helpTooltipElement // 绘制提示元素
let measureTooltipElement // 测量提示元素
let listener = undefined // 绘制元素监听事件
let source = undefined // 绘制图层数据源
/**###########################初始化绘制参数结束############################**/
2. 添加绘制图层
创建绘制图层函数,添加矢量图层和矢量数据源并设置绘制图层样式。使用setProperties
方法添加layerName
自定义属性,最后将绘制图层添加到地图上。
// 创建绘制图层
function addDrawLayer() {
source = new ol.source.Vector()
const drawLayer = new ol.layer.Vector({
source: source,
style: {
'fill-color': 'rgba(255, 255, 255, 0.2)',
'stroke-color': '#ffcc33',
'stroke-width': 2,
'circle-radius': 7,
'circle-fill-color': '#ffcc33',
},
})
// 自定义图层属性
drawLayer.setProperties({ "layerName": "measureLayer" })
map.addLayer(drawLayer)
}
3. 计算绘制距离
在OpenLayers中可以通过ol.sphere
对象的getLength
方法计算距离。该方法具有一个几何类型参数,将线几何传递进去即可。对于量测结果大于100时使用KM单位进行表示,否则使用m进行表示。
// 计算距离
const formatLength = function (line) {
const length = ol.sphere.getLength(line)
let output
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + " " + "KM"
} else {
output = Math.round(length * 100) / 100 + ' ' + 'm'
}
return output
}
4. 添加绘制样式
第二节中添加了图层样式,此处需要与图层样式做区分。在OpenLayers中,图层样式用于控制绘制完成之后的样式状态,而绘制样式用于控制在绘制过程中的样式状态。
// 绘制样式
const drawStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)',
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
lineDash: [10, 10],
width: 2,
}),
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.7)',
}),
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)',
}),
}),
});
5. 创建叠加图层
在OpenLayers有一个单独的图层类型Overlay,专门用于显示叠加图层。在创建提示信息、绘制信息等信息弹窗时特别有用。下面两个方法分别创建了绘制提示信息叠加图层和测量提示信息叠加图层。叠加图层对象接受一个HTML元素作为信息弹窗载体,可以通过offset属性调整其显示位置。offset参数为数组形式[x,y],其中x表示横坐标偏移量,也就是X轴,正值向右,负值向左;y表示纵坐标,也就是Y轴,正值向下,负值向上。
// 添加绘制提示
function createHelpTooltip() {
if (helpTooltipElement) {
helpTooltipElement.parentNode.remove(helpTooltipElement)
}
helpTooltipElement = document.createElement("div")
helpTooltipElement.className = "ol-tooltip hidden"
helpTooltip = new ol.Overlay({
element: helpTooltipElement,
offset: [5, 15],
positionning: "center-left"
})
helpTooltip.setProperties({ "layerName": "helpOverlay" })
map.addOverlay(helpTooltip)
}
function createMeasureTooltip() {
if (measureTooltipElement) {
measureTooltipElement.parentNode.remove(measureTooltipElement)
}
measureTooltipElement = document.createElement("div")
measureTooltipElement.className = "ol-tooltip ol-tooltip-measure"
measureTooltip = new ol.Overlay({
element: measureTooltipElement,
offset: [-38, -35],
positionning: "bottom-center",
stopEvent: false,
insertFirst: true
})
measureTooltip.setProperties({ "layerName": "measureOverlay" })
map.addOverlay(measureTooltip)
}
6. 创建绘制对象
通过interaction
类创建绘制对象,使用addInteraction
方法将其添加到地图中并且添加绘制样式类。之后添加信息提示叠加图层。最重要的两步是监听开始绘制事件和监听绘制结束事件。
监听开始绘制事件
获取当前绘制对象,并监听其几何属性,在几何对象change事件中,更新量测计算结果和提示信息。
监听绘制结束事件
当绘制完成后,移除几何对象监听事件,将监听要素和测量元素设置为空,并且更新最终量测结果。
function addDrawAction() {
// 创建交互绘制对象
drawAction = new ol.interaction.Draw({
source: source,
type: "LineString",
style: drawStyle
})
map.addInteraction(drawAction)
// 创建叠加层
createMeasureTooltip();
createHelpTooltip();
// 监听开始绘制事件
drawAction.on('drawstart', function (evt) {
sketch = evt.feature
let tooltipCoord = evt.coordinate
listener = sketch.getGeometry().on('change', function (evt) {
const geom = evt.target
const output = formatLength(geom)
tooltipCoord = geom.getLastCoordinate()
measureTooltipElement.innerHTML = output;
measureTooltip.setPosition(tooltipCoord);
})
})
// 监听结束绘制事件
drawAction.on('drawend', function (evt) {
measureTooltipElement.className = 'ol-tooltip ol-tooltip-static'
measureTooltip.setOffset([-40, -30])
sketch = null
measureTooltipElement = null
createMeasureTooltip()
// 移除绘制事件
ol.Observable.unByKey(listener)
})
}
7. 监听鼠标移动事件
在鼠标移动事件中更改绘制提示信息,当还未开始绘制时显示”点击开始绘制”,当绘制开始后,更新提示信息为”点击继续绘制线”。并且更新会绘制信息叠加图层显示坐标。
// 监听鼠标移动事件
const pointMoveHandler = function (evt) {
if (evt.dragging) {
return
}
let helpMsg = "点击开始绘制"
if (sketch) {
const geom = sketch.getGeometry()
if (geom instanceof ol.geom.LineString) {
helpMsg = "点击继续绘制线"
}
}
if (helpTooltipElement) {
helpTooltipElement.innerHTML = helpMsg
helpTooltipElement.classList.remove("hidden")
}
helpTooltip.setPosition(evt.coordinate)
}
8. 开始绘制事件
当点击绘制按钮时将鼠标指针修改为”crosshair”,然后添加绘制图层和绘制对象,并监听鼠标移动事件。
document.querySelector(".measure-distance").addEventListener('click', function () {
setCursor("crosshair")
addDrawLayer()
addDrawAction()
// 监听鼠标移除事件
map.getViewport().addEventListener('mouseout', function () {
// helpTooltipElement.classList.add("hidden")
})
map.on('pointermove', pointMoveHandler)
})
9. 清除图层
当点击清除按钮时,移除绘制交互对象,结束绘制,并移除所有绘制对象,包括绘制图层以及绘制提示信息和测量提示信息叠加图层,将鼠标指针恢复为默认样式。
document.querySelector(".measure-clear").addEventListener('click', function () {
setCursor("default")
removeAllLayer()
map.removeInteraction(drawAction)
// 移除绘制事件
ol.Observable.unByKey(listener)
sketch = null
if (measureTooltipElement) {
measureTooltipElement.parentNode.remove(measureTooltipElement)
measureTooltipElement = null
}
if (helpTooltipElement) {
helpTooltipElement.parentNode.remove(helpTooltipElement)
helpTooltipElement = null
}
})
注:本文参考OpenLayers官方例子修改。
❝
OpenLayers示例数据下载,请在公众号后台回复:ol数据
全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试
❝
GIS之路公众号已经接入了智能助手,欢迎大家前来提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏+关注 哦!
本号不定时更新有关 GIS开发 相关内容,欢迎关注