OpenLayers 设置线段样式
前言
图形绘制是指在地图上绘制点、线、面、圆、矩形等图形。可以通过鼠标单机绘制,也可以键盘按键配合进行绘制。对于绘制的几何图形可以调整线段和端点样式。
1. 图形绘制
本篇文章主要介绍如何设置几何对象线段样式,对于如何进行图形绘制请参考文章OpenLayers 绘制几何对象
2. 创建线段样式结构
在页面中创建线段样式结构并添加其CSS
。线段样式可以调整线宽、端点样式、拐点样式、虚线样式以及间隔等。其中端点样式具有三个值:butt
、round
和square
;拐点样式具有三个值:bevel
、 round
和miter
。
.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%;
}<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>
3. 重设样式
创建重设样式方法,在该方法中传递样式对象,然后同构解构该对象生成样式对象,在添加新的样式图层前将原来的图层移除。
function setStyle(styleObj) {const { width, lineCap, lineJoin, lineDash, lineDashOffset } = styleObjmap.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)
}
4. 监听滑块事件
监听滑块移动事件,在滑块值发生改变时调用重设样式方法。
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 = valueconst 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)}});
});
5. 监听单选框事件
监听单选框事件,获取单选框点击值然后调用重设样式函数。
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)})
});
6. 完整代码
其中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%;}</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><li class="draw-li" data-type="None">清除</li></ul></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) {if (type === "None") {removeInteraction()// 清除图形vectorSource.clear()removeAllActiveClass(".draw-ul", "active")return}let geometryFunction = nullswitch (type) {case "Square":type = "Circle"geometryFunction = ol.interaction.Draw.createRegularPolygon(4)breakcase "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.targetconst geomType = targetEle.dataset.typeif (geomType !== "None") {toogleAciveClass(targetEle, ".draw-ul")}if (geomType) {drawShape(geomType)}})// 移除绘制控件function removeInteraction() {if (drawInteraction) {map.removeInteraction(drawInteraction)}}let lineWidth = 2.5let lineDash = [30, 40, 50, 60]layui.use(function () {const slider = layui.slider;// 线条宽度slider.render({elem: '#stroke-width-value',value: 5, //初始值change: function (value) {lineWidth = valueconst 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 } = styleObjmap.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)}
</script>
OpenLayers示例数据下载,请回复关键字:ol数据
全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试
【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。
欢迎访问我的博客网站-长谈GIS:
http://shanhaitalk.com
都看到这了,不要忘记点赞、收藏 + 关注 哦 !
本号不定时更新有关 GIS开发 相关内容,欢迎关注 !