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

OpenLayers 设置线段样式

前言

图形绘制是指在地图上绘制点、线、面、圆、矩形等图形。可以通过鼠标单机绘制,也可以键盘按键配合进行绘制。对于绘制的几何图形可以调整线段和端点样式。

1. 图形绘制

本篇文章主要介绍如何设置几何对象线段样式,对于如何进行图形绘制请参考文章OpenLayers 绘制几何对象

2. 创建线段样式结构

在页面中创建线段样式结构并添加其CSS。线段样式可以调整线宽、端点样式、拐点样式、虚线样式以及间隔等。其中端点样式具有三个值:buttroundsquare;拐点样式具有三个值:bevelroundmiter

.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之路】 已经接入了智能助手,欢迎关注,欢迎提问。

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

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

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

http://www.dtcms.com/a/267528.html

相关文章:

  • 深入学习c++之---AVL树
  • 支持零样本和少样本的文本到语音48k star的配音工具:GPT-SoVITS-WebUI
  • 完成ssl不安全警告
  • DQL-6-分页查询
  • Redis的编译安装
  • PVE DDNS IPV6
  • 超详细yolo8/11-detect目标检测全流程概述:配置环境、数据标注、训练、验证/预测、onnx部署(c++/python)详解
  • Altium Designer使用教程 第一章(Altium Designer工程与窗口)
  • ESXi 8.0 SATA硬盘直通
  • python-字符串
  • 量化可复用的UI评审标准(试验稿)
  • OPENPPP2 VDNS 核心域模块深度解析
  • 电源管理芯片(PMIC) 和 电池管理芯片(BMIC)又是什么?ING
  • webpack+vite前端构建工具 -11实战中的配置技巧
  • 合肥工会入会的注意事项和常见问答
  • springBoot接口层时间参数JSON序列化问题,兼容处理
  • Modbus_TCP_V4 客户端
  • Day52
  • 人工智能-基础篇-18-什么是RAG(检索增强生成:知识库+向量化技术+大语言模型LLM整合的技术框架)
  • ES6-in 的用法
  • Apollo自动驾驶系统中Planning(路径规划)模块的架构设计和核心逻辑
  • leetcode86.分隔链表
  • 1. 两数之和 (leetcode)
  • 【网络】Linux 内核优化实战 - net.ipv4.tcp_timestamps
  • 【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
  • CSS 文字浮雕效果:巧用 text-shadow 实现 3D 立体文字
  • 一体化步进伺服电机在无人机扫地机器人中的应用案例
  • 隐马尔可夫模型:语音识别系统的时序解码引擎
  • 写传播和写策略
  • 【Linux】常用基本指令