阅读 6
^ 关注我,带你一起学GIS ^
注:当前使用的是 ol [9.2.4] 版本,天地图使用的
key
请到天地图官网申请,并替换为自己的key
前言
❝图形绘制是指在地图上绘制点、线、面、圆、矩形等图形,可以通过鼠标单机绘制,也可以键盘按键配合进行绘制。对于绘制的几何图形可以进行样式调整,也可以对绘制状态进行修改,本篇文章主要介绍如何进行撤销操作。
1. 构建HTML
结构
在页面中添加撤销按钮并将调整清除按钮位置,然后添加相应CSS
。
.draw-action {
position: absolute;
padding: 5px;
top: 60px;
left: 400px;
background-color: #ffcc00ad;
border-radius: 2.5px;
}
.draw-action-btn {
padding: 5px;
margin: 0 5px;
min-width: 50px;
background-color: azure;
background: #cae4cf82;
transition: background-color 10s ease-in-out 10s;
text-align: center;
border-radius: 2.5px;
transition: color ease-in-out 0.25s;
border: none;
}
.draw-action-btn:hover {
cursor: pointer;
color: #fff;
filter: brightness(120%);
background: linear-gradient(135deg, #c850c0, #4158d0);
}
<div class="draw-action">
<button class="draw-action-btn draw-action-undo">撤销</button>
<button class="draw-action-btn" id="clearDraw">清除</button>
</div>
2. 撤销绘制
在Draw
控件中有一个方法removeLastPoint
,使用此方法会移除绘制图形最后一个点。
// 撤销操作
document.querySelector(".draw-action-undo").addEventListener('click', evt => {
if (drawInteraction) {
drawInteraction.removeLastPoint()
}
})
3. 清除绘制
创建清除结果方法,在点击清除按钮时移除绘制图形和交互控件,然后移除激活样式。
// 清除绘制
function clearResult() {
removeInteraction()
// 清除图形
vectorSource.clear()
removeAllActiveClass(".draw-ul", "active")
return
}
document.getElementById("clearDraw").addEventListener("click", evt => {
clearResult()
})
4. 完整代码
其中libs
文件夹下的包需要更换为自己下载的本地包或者引用在线资源。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>OpenLayers 撤销绘制</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="../../libs/css/ol9.2.4.css">
<link rel="stylesheet" href="../../libs/layui/css/layui.css">
<script src="../../js/config.js"></script>
<script src="../../js/util.js"></script>
<script src="../../libs/js/ol9.2.4.js"></script>
<script src="../../libs/layui/layui.js"></script>
<style>
* {
padding: 0;
margin: 0;
font-size: 14px;
font-family: '微软雅黑';
}
html,
body {
width: 100%;
height: 100%;
}
#map {
position: absolute;
top: 50px;
bottom: 0;
width: 100%;
}
#top-content {
position: absolute;
width: 100%;
height: 50px;
line-height: 50px;
background: linear-gradient(135deg, #ff00cc, #ffcc00, #00ffcc, #ff0066);
color: #fff;
text-align: center;
font-size: 32px;
}
#top-content span {
font-size: 32px;
}
.draw-shape {
position: absolute;
padding: 5px;
top: 60px;
left: 100px;
background-color: #ffcc00ad;
border-radius: 2.5px;
}
.draw-ul {
list-style-type: none;
}
.draw-ul::after {
display: block;
clear: both;
content: "";
}
.draw-li {
float: left;
padding: 5px;
margin: 0 5px;
min-width: 50px;
background-color: azure;
background: #cae4cf82;
transition: background-color 10s ease-in-out 10s;
text-align: center;
border-radius: 2.5px;
transition: color ease-in-out 0.25s;
}
.draw-li:hover {
cursor: pointer;
color: #fff;
filter: brightness(120%);
background: linear-gradient(135deg, #c850c0, #4158d0);
}
.active {
color: #fff;
background: linear-gradient(135deg, #c850c0, #4158d0);
}
.stroke-style {
position: absolute;
padding: 10px;
top: 120px;
left: 100px;
background-color: #c19b03ab;
border-radius: 2.5px;
}
.stroke-line-style {
display: flex;
}
.line-style {
margin-top: 15px;
width: 80%;
}
.draw-action {
position: absolute;
padding: 5px;
top: 60px;
left: 400px;
background-color: #ffcc00ad;
border-radius: 2.5px;
}
.draw-action-btn {
padding: 5px;
margin: 0 5px;
min-width: 50px;
background-color: azure;
background: #cae4cf82;
transition: background-color 10s ease-in-out 10s;
text-align: center;
border-radius: 2.5px;
transition: color ease-in-out 0.25s;
border: none;
}
.draw-action-btn:hover {
cursor: pointer;
color: #fff;
filter: brightness(120%);
background: linear-gradient(135deg, #c850c0, #4158d0);
}
</style>
</head>
<body>
<div id="top-content">
<span>OpenLayers 撤销绘制</span>
</div>
<div id="map" title="地图显示"></div>
<div class="draw-shape">
<ul class="draw-ul">
<li class="draw-li" data-type="LineString">线</li>
<li class="draw-li" data-type="Polygon">多边形</li>
<li class="draw-li" data-type="Square">正方形</li>
<li class="draw-li" data-type="Box">矩形</li>
</ul>
</div>
<div class="draw-action">
<button class="draw-action-btn draw-action-undo">撤销</button>
<button class="draw-action-btn" id="clearDraw">清除</button>
</div>
<div class="stroke-style">
<div class="layui-form">
<div class="layui-form-item">
<label class="layui-form-label">端点样式</label>
<div class="layui-input-block">
<input type="radio" name="lineCap" lay-filter="cap-radio-filter" value="butt" title="butt">
<input type="radio" name="lineCap" lay-filter="cap-radio-filter" value="round" title="round"
checked>
<input type="radio" name="lineCap" lay-filter="cap-radio-filter" value="square" title="square">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">拐点样式</label>
<div class="layui-input-block">
<input type="radio" name="lineJoin" lay-filter="join-radio-filter" value="bevel" title="bevel">
<input type="radio" name="lineJoin" lay-filter="join-radio-filter" value="round" title="round"
checked>
<input type="radio" name="lineJoin" lay-filter="join-radio-filter" value="miter" title="miter">
</div>
</div>
<div class="layui-form-item stroke-line-style">
<label class="layui-form-label">线宽(pixel)</label>
<div id="stroke-width-value" class="line-style"></div>
</div>
<div class="layui-form-item stroke-line-style">
<label class="layui-form-label">虚线样式</label>
<div id="line-dash-value" class="line-style"></div>
</div>
<div class="layui-form-item stroke-line-style">
<label class="layui-form-label">虚线偏移</label>
<div id="line-dash-offset" class="line-style"></div>
</div>
</div>
</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=" + TDTTOKEN,
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=" + TDTTOKEN,
attibutions: "天地图注记描述",
crossOrigin: "anoymous",
wrapX: false
})
})
const map = new ol.Map({
target: "map",
loadTilesWhileInteracting: true,
view: new ol.View({
center: [102.845864, 25.421639],
zoom: 5,
worldsWrap: false,
minZoom: 1,
maxZoom: 20,
projection: 'EPSG:4326',
}),
layers: [TDTImgLayer]
})
const style = new ol.style.Style({
fill: new ol.style.Fill({
color: "#9b65ff30"
}),
stroke: new ol.style.Stroke({
color: "yellow",
width: 5,
lineCap: 'round',
lineJoin: 'round',
// lineDash: [20, 30, 40, 50],
lineDashOffset: 0
}),
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: "#fff"
}),
radius: 5,
stroke: new ol.style.Stroke({
color: "blue",
width: 1,
})
})
})
const vectorSource = new ol.source.Vector({ wrapX: false })
let vectorLayer = new ol.layer.Vector({
source: vectorSource,
style
})
map.addLayer(vectorLayer)
let drawInteraction = null
/**
* 根据几何类型绘制几何对象
*/
function drawShape(type) {
clearResult()
let geometryFunction = null
switch (type) {
case "Square":
type = "Circle"
geometryFunction = ol.interaction.Draw.createRegularPolygon(4)
break
case "Box":
type = "Circle"
geometryFunction = ol.interaction.Draw.createBox()
break
}
drawInteraction = new ol.interaction.Draw({
source: vectorSource,
type,
geometryFunction,
style,
// freehand: true // 是否开启自由绘制模式
})
map.addInteraction(drawInteraction)
}
// 事件委托
const targetEle = document.querySelector(".draw-ul")
targetEle.addEventListener('click', evt => {
removeInteraction()
const targetEle = evt.target
const geomType = targetEle.dataset.type
if (geomType !== "None") {
toogleAciveClass(targetEle, ".draw-ul")
}
if (geomType) {
drawShape(geomType)
}
})
let lineWidth = 2.5
let lineDash = [30, 40, 50, 60]
layui.use(function () {
const slider = layui.slider;
// 线条宽度
slider.render({
elem: '#stroke-width-value',
value: 5, //初始值
change: function (value) {
lineWidth = value
const styleObj = {
width: lineWidth
}
setStyle(styleObj)
}
});
// 虚线间隔
slider.render({
elem: '#line-dash-value',
value: 0, //初始值
change: function (value) {
lineDash = [value, 40, 50, 60]
const styleObj = {
lineDash: lineDash
}
setStyle(styleObj)
}
});
// 偏移值
slider.render({
elem: '#line-dash-offset',
value: 0, //初始值
change: function (value) {
const styleObj = {
lineDashOffset: value
}
setStyle(styleObj)
}
});
});
layui.use(function () {
const form = layui.form;
const layer = layui.layer;
// radio 事件
form.on('radio(cap-radio-filter)', function (data) {
const elem = data.elem; // 获得 radio 原始 DOM 对象
const checked = elem.checked; // 获得 radio 选中状态
const value = elem.value; // 获得 radio 值
const styleObj = {
lineCap: value
}
setStyle(styleObj)
})
form.on('radio(join-radio-filter)', function (data) {
const elem = data.elem; // 获得 radio 原始 DOM 对象
const checked = elem.checked; // 获得 radio 选中状态
const value = elem.value; // 获得 radio 值
const styleObj = {
lineJoin: value
}
setStyle(styleObj)
})
});
function setStyle(styleObj) {
const { width, lineCap, lineJoin, lineDash, lineDashOffset } = styleObj
map.removeLayer(vectorLayer)
const style = new ol.style.Style({
fill: new ol.style.Fill({
color: "#9b65ff30"
}),
stroke: new ol.style.Stroke({
color: "yellow",
width: width || lineWidth,
lineCap: lineCap || 'round',
lineJoin: lineJoin || 'round',
lineDash: lineDash || lineDash,
lineDashOffset: lineDashOffset || 0
})
})
vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: style
})
map.addLayer(vectorLayer)
}
// 移除绘制控件
function removeInteraction() {
if (drawInteraction) {
map.removeInteraction(drawInteraction)
}
}
// 清除绘制
function clearResult() {
removeInteraction()
// 清除图形
vectorSource.clear()
removeAllActiveClass(".draw-ul", "active")
return
}
document.getElementById("clearDraw").addEventListener("click", evt => {
clearResult()
})
// 撤销操作
document.querySelector(".draw-action-undo").addEventListener('click', evt => {
if (drawInteraction) {
drawInteraction.removeLastPoint()
}
})
</script>
❝
OpenLayers示例数据下载,请在公众号后台回复:ol数据
全国信息化工程师-GIS 应用水平考试资料,请在公众号后台回复:GIS考试
❝
GIS之路公众号已经接入了智能助手,欢迎大家前来提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏+关注 哦!
本号不定时更新有关 GIS开发 相关内容,欢迎关注