一、思路
根据openLayers官网示例,可以看出,绘制时所需要的东西:
1. 当前要素feature
2. 测量过程中的提示文字(如:点击继续测量)
3. 测量结果
所以,实现这个功能也是重点围绕着这三点去实现;
二、实现
2.1、引入模块
引入的模块就不介绍了,都是ol常用模块
2.2、初始化变量
let sketch; //当前要素
let continuePolygonMsg = '单击此处绘制多边形'; //绘制面提示文字
let continueLineMsg = '单击此处绘制线'; //绘制线提示文字
let helpTooltipElement; //帮助提示框元素
let helpTooltip;
let measureTooltipElement; // 测量提示元素
let measureTooltip; //测量值
2.3、设置数据源、图层、画笔
图层的样式style属性,是从官网copy的
let source = new VectorSource();
let vector = new VectorLayer({
source: source,
});
map.addLayer(vector);
let draw;
draw = new Draw({
source: source,
type: type, // type作为参数,在外部引用函数时传入
});
map.addInteraction(draw);
2.4、提示文字
提示文字包括:绘制未开始时的提示文字、绘制过程中的提示文字;
// 创建元素
this.createMeasureTooltip();
this.createHelpTooltip();
// 监听鼠标移动
map.on('pointermove', pointerMoveHandler);
// 鼠标移动函数,展示提示文字
var pointerMoveHandler = function(evt) {
if (evt.dragging) {
return;
}
let helpMsg = '点击开始绘制';
if (sketch) {
// 测量时的提示文字
const geom = sketch.getGeometry();
if (geom instanceof Polygon) {
helpMsg = continuePolygonMsg;
} else if (geom instanceof LineString) {
helpMsg = continueLineMsg;
}
}
// 设置提示对话框
helpTooltipElement.innerHTML = helpMsg;
helpTooltip.setPosition(evt.coordinate);
helpTooltipElement.classList.remove('hidden');
};
// 鼠标移出,隐藏样式
map.getViewport().addEventListener('mouseout', function() {
helpTooltipElement.classList.add('hidden');
});
// 创建测量提示元素
function createMeasureTooltip() {
// 如已经有了则移除
if (measureTooltipElement) {
measureTooltipElement.parentNode.removeChild(measureTooltipElement);
}
// 创建div,new一个Overlay对象,div作为element的属性值
measureTooltipElement = document.createElement('div');
measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
measureTooltip = new Overlay({
element: measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center'
});
map.addOverlay(measureTooltip);
}
// 同理,创建帮助提示框元素
function createHelpTooltip() {
if (helpTooltipElement) {
helpTooltipElement.parentNode.removeChild(helpTooltipElement);
}
helpTooltipElement = document.createElement('div');
helpTooltipElement.className = 'ol-tooltip hidden';
helpTooltip = new Overlay({
element: helpTooltipElement,
offset: [15, 0],
positioning: 'center-left'
});
map.addOverlay(helpTooltip);
}
2.5、开始绘制
监听开始,结束绘制;
let listener;
// 开始绘制
draw.on('drawstart', function(evt) {
sketch = evt.feature;
var tooltipCoord = evt.coordinate;
// 获取测量值,设置到工具提示框
listener = sketch.getGeometry().on('change', function(evt) {
var geom = evt.target;
var output;
// 判断是线还是面
if (geom instanceof Polygon) {
output = formatArea(geom);
tooltipCoord = geom.getInteriorPoint().getCoordinates();
} else if (geom instanceof LineString) {
output = formatLength(geom);
tooltipCoord = geom.getLastCoordinate();
}
measureTooltipElement.innerHTML = output;
measureTooltip.setPosition(tooltipCoord);
});
map.on('pointermove', pointerMoveHandler);
});
// 绘制结束
draw.on('drawend', function() {
measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
measureTooltip.setOffset([0, -7]);
// 清空要素和提示框
sketch = null;
measureTooltipElement = null;
// 创建展示结果
createMeasureTooltip();
unByKey(listener);
});
// 面积测量函数
const formatArea = function(polygon) {
var sourceProj = map.getView().getProjection(); // 获取投影坐标系
var area = getArea(polygon, {
projection: sourceProj
});
var output;
if (area > 10000) {
output =
Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>';
} else {
output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>';
}
return output;
};
// 长度测量函数
const formatLength = function(line) {
var sourceProj = map.getView().getProjection(); // 获取投影坐标系
var length = getLength(line, {
projection: sourceProj
});
var output;
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
} else {
output = Math.round(length * 100) / 100 + ' ' + 'm';
}
return output;
};
所需要的组件中引入即可,结束!