Vue2 + Openlayers 实现绘制、平移和框选平移功能

2023-10-18 12:59

本文主要是介绍Vue2 + Openlayers 实现绘制、平移和框选平移功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Vue2 + Openlayers 实现绘制、平移和框选平移功能
    • Vue2安装
    • 安装Openlayers
      • 最新版本Openlayers安装
      • 指定版本Openlayers安装
      • 其他方式安装可以参照Openlayers官网
    • 初始化地图
    • 绘制方法的实现
    • 平移功能(拖拽功能)的实现
    • 框选平移功能的实现
      • 框选平移详细介绍
        • 绘制两个图形
    • 清空功能的实现
    • 注意事项
    • 项目源码


Vue2 + Openlayers 实现绘制、平移和框选平移功能

Vue2安装

本文不详细介绍Vue2的安装,具体可以参考这篇博客
Vue2安装

安装Openlayers

Openlayers有多种引用或安装方式,博主采用的是npm安装方式。

最新版本Openlayers安装

npm install -s ol

指定版本Openlayers安装

运行npm install -s ol后,找到package.json中的ol,将后面的版本号改成想要的版本,再运行npm install即可
本文采用的是5.3.3版本

其他方式安装可以参照Openlayers官网

Openlayers官网

初始化地图

使用Openlayers例子中的OSM地图。
Openlayers地图加载可以有很多参数,具体请看Openlayers官方API
博主使用的版本是5.3.3,但是官方文档看5.3.0的就可以

<script>//引入
import Map from "ol/Map"
import {Tile as TileLayer} from "ol/layer";
import OSM from 'ol/source/OSM';
import View from "ol/View"
import {fromLonLat} from "ol/proj";export default {name: "Map",data(){return {// 根据个人需求可以选择把数据不定义成全局的,但是有些功能需要全局变量,请读者自行斟酌map:{},  //地图容器,后续可能会涉及到map的相关操作,比如map.addLayer等,所以定义成全局的drawSource:new Vector(),	//绘制图层的数据源,后续某些功能可能会需要清空drawSource,所以定义成全局的//绘制功能初始化的地方,因为可能会需要用map.addInteraction()和map.removeInteraction(),所以定义成全局的draw :{}	}},methods:{//地图初始化方法initialMap(){//用that代替this,防止某些位置this指向发生变化let that = thisthat.map = new Map({target:"map", //挂载到id为map的div容器上layers:[new TileLayer({source: new OSM()	//OSM地图}),//绘制图层new VectorLayer({source:that.drawSource,	//数据源style: new Style({//图层样式fill: new Fill({color: "rgba(0, 0, 255, 0.2)", //填充颜色}),stroke: new Stroke({color: "#0000ff", //边框颜色width: 2, // 边框宽度}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),})],//设置视图,包括中心点,坐标系,默认缩放级别,最大、最小缩放级别view: new View({projection:'EPSG:3857',	//坐标系center: fromLonLat([120.2,30.35]),	//中心点zoom: 10,	  //默认缩放级别minZoom:1,	//最小缩放级别maxZoom:18	//最大缩放级别})})console.log(that.map.getLayers())},},mounted() {this.initialMap()	//立即执行初始化地图方法}
}
</script>

绘制方法的实现

<script>//引入
import Map from "ol/Map"
import {Tile as TileLayer, Vector as VectorLayer} from "ol/layer";
import OSM from 'ol/source/OSM';
import View from "ol/View"
import {fromLonLat} from "ol/proj";
import {DoubleClickZoom, Draw} from "ol/interaction";
import {Fill, Stroke, Style,Circle} from "ol/style";
import {Vector} from "ol/source"export default {name: "Map",data(){return {map:{},  //地图容器,后续可能会涉及到map的相关操作,比如map.addLayer等,所以定义成全局的drawSource:new Vector(), //正常项目可能需要在其他函数中清空drawSource,所以定义成全局的drawVector:{}, //平移功能需要声明哪些图层可以被平移,所以定义成全局的draw :{}, //绘制功能,可能会在其他函数中使用this.map.removeInteraction(this.draw),所以定义成全局}},methods:{//地图初始化方法initialMap(){//用that代替this,防止某些位置this指向发生变化let that = thisthat.map = new Map({target:"map", //挂载到id为map的div容器上layers:[new TileLayer({source: new OSM()	//OSM地图}),that.drawVector = new VectorLayer({source:that.drawSource,style: new Style({//图层样式fill: new Fill({color: "rgba(0, 0, 255, 0.2)", //填充颜色}),stroke: new Stroke({color: "#0000ff", //边框颜色width: 2, // 边框宽度}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),})],//设置视图,包括中心点,坐标系,默认缩放级别,最大、最小缩放级别view: new View({projection:'EPSG:3857',	//坐标系center: fromLonLat([120.2,30.35]),	//中心点zoom: 10,	  //默认缩放级别minZoom:1,	//最小缩放级别maxZoom:18	//最大缩放级别})})console.log(that.map.getLayers())},//绘制方法sketch() {let that = this;//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);//双击执行取消绘制that.map.on("dblclick", function () {that.MyDraw.setActive(false);});//初始化绘制交互that.draw = new Draw({//绘制对象source: that.drawSource, //绘制层数据源,勾绘的要素属于的数据集type: "Polygon",	//绘制的类型,这里绘制一个多边形,也可以是POINT(点)、LINE_STRING(线)、CIRCLE(圆)//设置一些样式style: new Style({fill: new Fill({color: "rgba(0,0,255,0.2)",}),stroke: new Stroke({color: "#0000ff",width: 2,}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),});// 加载交互绘制控件函数that.MyDraw = {//执行绘制函数的方法init: function () {that.map.addInteraction(that.draw);	//添加交互//绑定交互绘制工具开始绘制的事件that.draw.on("drawstart", function (evt) {//逻辑代码});//绑定交互绘制工具结束绘制的事件that.draw.on("drawend", function (evt) {//逻辑代码that.MyDraw.setActive(false); //绘制完毕以后关闭控件})},//控制控件开启或关闭的函数,active要传boolean类型/** setActive()是Openlayers中Interaction的函数,作用是开启和关闭控件* 这里也可以不用setActive()函数,可以使用this.map.addInteraction()加载控件和this.map.removeInteraction()* 在绘制结束的时候移除控件。如果使用这种方法,就需要把map定义成全局的。*/setActive: function (active) {that.draw.setActive(active); //激活控件},};that.MyDraw.init();	//执行绘制函数方法}},mounted() {this.initialMap()	//立即执行初始化地图方法}
}
</script>

上面的函数也可以写成另一种形式,效果都是一样的

    sketch2(){let that = this;//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);//双击执行取消绘制that.map.on("dblclick", function () {that.map.removeInteraction(that.draw)});//初始化绘制交互that.draw = new Draw({//绘制对象source: that.drawSource, //绘制层数据源,勾绘的要素属于的数据集type: "Polygon",	//绘制的类型,这里绘制一个多边形,也可以是POINT(点)、LINE_STRING(线)、CIRCLE(圆)//设置一些样式style: new Style({fill: new Fill({color: "rgba(0,0,255,0.2)",}),stroke: new Stroke({color: "#0000ff",width: 2,}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),});// 加载交互绘制控件函数(function initDraw() {that.map.addInteraction(that.draw);	//添加交互//绑定交互绘制工具开始绘制的事件that.draw.on("drawstart", function (evt) {//逻辑代码});//绑定交互绘制工具结束绘制的事件that.draw.on("drawend", function (evt) {//逻辑代码})})()}

效果展示
绘制功能展示

平移功能(拖拽功能)的实现

平移功能使用ol-ext实现
博主使用的版本是3.2.3,下面的方式是安装最新版的ol-ext,也可以使用开篇提到的方式更改成指定版本

npm install ol-ext

    //平移功能(拖拽功能)translation(){let that = thisconst dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction); //移除双击缩放功能,使双击只用于关闭平移状态that.interactionDrag = new ExtTransform({enableRotatedTransform: false, //地图旋转时启用变换hitTolerance: 2,  //偏移量translate: true, // 拖拽stretch: false, // 拉伸scale: false, // 缩放rotate: false, // 旋转translateFeature: false, //显示中心位置noFlip: false, //防止特征几何翻转,默认为 falselayers: [that.drawVector], //指定可以拖拽的图层});//添加交互that.map.addInteraction(that.interactionDrag);that.interactionDrag.on(["translatestart"], function (evt) {});that.interactionDrag.on(["translating"], function (evt) {//逻辑代码});that.interactionDrag.on(["translateend"], function (evt) {//逻辑代码});that.map.on("dblclick",function (){//双击移除控件,不再平移that.map.removeInteraction(that.interactionDrag)})}

框选平移功能的实现

    //框选平移boxSelectAndMove() {let that = this;//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);// 创建绘制矩形工具let drawBox = new Draw({source: new Vector(),type: 'Circle', //绘制的图形是圆形//官网描述geometryFunction://将坐标数组和可选的现有几何图形和投影作为参数并返回几何图形的函数。//可选的现有几何是在没有第二个参数的情况下调用函数时返回的几何。geometryFunction: createBox(),  //将圆形改成矩形框,如果没有这行代码绘制出来的框会变成圆形//设置一些样式style: new Style({image: new Circle({radius: 7,fill: new Fill({color: "rgba(255, 128, 0,1)",}),}),fill: new Fill({color: "rgba(1, 92, 199,0.1)",}),stroke: new Stroke({color: "rgba(56, 239, 255,1)",width: 1})})});that.map.addInteraction(drawBox) //添加交互let myTransform = {} //定义一个接收初始化框选平移的变量,后面需要双击的时候移除交互,所以定义在这里drawBox.on('drawstart', function (evt) {//逻辑代码})drawBox.on('drawend', function (evt) {let polygon = evt.feature.getGeometry() // 用polygon存储画出来的矩形框的信息,包括坐标等let features = that.drawSource.getFeatures() //取出所有要素,每一个都要判断是否相交let needToMoveFeatures = [] //相交的要素存在这里let isIntersect = false // 是否相交for(let i=0;i<features.length;i++){let coordinates = features[i].values_.geometry.flatCoordinatesfor(let j=0;j<coordinates.length;j+=2){// containsXY()是Openlayers的内置函数,可以判断点是否在多边形内。// 这里的应用是判断每一个feature的顶点是否在polygon内// 因为画的是矩形框,如果框选到了feature,那么这个feature的某一个顶点一定在矩形框内// 如果是其他逻辑,需要参照Openlayers官方文档使用其他方法if(polygon.containsXY(coordinates[j], coordinates[j + 1])){// 如果已经判断相交,直接跳出循环即可isIntersect = trueneedToMoveFeatures.push(features[i])break}}}if(isIntersect){that.map.removeInteraction(drawBox)// 这里不再写注释了,和平移功能的实现是一样的myTransform = new ExtTransform({enableRotatedTransform: false,layers: [that.drawVector],hitTolerance: 2,scale: false,rotate: false,keepAspectRatio: false,keepRectangle: false,translate: true,translateFeature: false,noFlip: false,stretch: false,})that.map.addInteraction(myTransform)  //添加控件myTransform.setSelection(needToMoveFeatures) //ol-ext中transform函数,可以直接把所有框选的要素当成一个整体myTransform.on('translatestart',function (evt){//逻辑代码})myTransform.on('translating',function (evt){//逻辑代码})myTransform.on('translateend',function (evt){//逻辑代码console.log(evt)//这里的evt包含了平移结束以后的feature信息,具体信息见下图})}})that.map.on('dblclick', function () {that.map.removeInteraction(drawBox)that.map.removeInteraction(myTransform)})},

效果展示
框选平移的实现

框选平移详细介绍

绘制两个图形

绘制了两个要素,一个是四边形,一个是六边形。
由于两个要素都是polygon类型的,所以四边形的要素坐标会显示5个,第一个和第五个是一样的。同理,六边形的坐标会显示7个,第一个和第七个也是一样的。
坐标系有两种情况,一种是一对一对的出现,另一种就是我后面截图上显示的情况,也就是横坐标和纵坐标是分开显示的

绘制了两个要素
控制台状态

我在绘制完成后(drawend事件的回调函数里)输出了evt,可以看到两个要素的具体信息

四边形要素具体信息
六边形要素具体信息
框选平移结束后的信息

框选平移结束事件后(translateend的回调函数中),我输出了evt,可以在这里面看到移动后要素的信息。
这里需要注意的是,看的是oldgeoms里面的信息。

框选平移结束后信息

可以根据不同需求,获取不同的信息。
这种方式是在框选平移结束后就需要要素的信息时使用,如果需要在别的函数里面获取新的要素信息,可以直接使用source.getFeatures()函数,就可以查看到最新的要素信息。
比如我这里就应该是this.drawSource.getFeatures()
这就需要把source定义成全局变量。

清空功能的实现

清空功能就不再赘述了,根据需求进行清空即可。记得清空source

    clear(){//只写了最简单的,根据需求增加即可this.drawSource.clear()},

注意事项

最好把每个交互都设置成全局变量,在执行每个函数之前都要移除一下交互,比如在执行平移的时候,要移除绘制的交互。

这样做可以避免用户在点击添加后发现自己点错了,又去点击平移,会导致两个函数都在执行,又绘制又平移,可能会出现错误。

项目源码

<template><div><div id="map"></div><div class="Cards"><Card style="margin-top: 8px; width: 250px; z-index: 5"><Row><Button style="margin-right: 6px; width:100px;" type="success" @click="sketch"><Icon type="md-add"/>添加</Button><Button style="margin-right: 6px; width:100px;" type="error" @click="clear"><Icon type="md-close" />清空</Button></Row><Row style="margin-top: 4px;"><Button style="margin-right: 6px; width:100px;" type="info" @click="translation"><Icon type="md-move"/>平移</Button><Button style="margin-right: 6px; width:100px;" type="warning" @click="boxSelectAndMove()"><Icon type="md-move"/>框选平移</Button></Row></Card></div></div>
</template><script>//引入
import Map from "ol/Map"
import {Tile as TileLayer, Vector as VectorLayer} from "ol/layer";
import OSM from 'ol/source/OSM';
import View from "ol/View"
import {fromLonLat} from "ol/proj";
import {DoubleClickZoom, Draw} from "ol/interaction";
import {Fill, Stroke, Style,Circle} from "ol/style";
import {Vector} from "ol/source"
import ExtTransform from "ol-ext/interaction/Transform"
import {unByKey} from "ol/Observable";
import {GeoJSON} from "ol/format";
import {createBox} from "ol/interaction/Draw";export default {name: "Map",data(){return {map:{},  //地图容器,后续可能会涉及到map的相关操作,比如map.addLayer等,所以定义成全局的drawSource:new Vector(), //正常项目可能需要在其他函数中清空drawSource,所以定义成全局的drawVector:{}, //平移功能需要声明哪些图层可以被平移,所以定义成全局的draw :{}, //绘制功能,可能会在其他函数中使用this.map.removeInteraction(this.draw),所以定义成全局}},methods:{//地图初始化方法initialMap(){//用that代替this,防止某些位置this指向发生变化let that = thisthat.map = new Map({target:"map", //挂载到id为map的div容器上layers:[new TileLayer({source: new OSM()	//OSM地图}),that.drawVector = new VectorLayer({source:that.drawSource,style: new Style({//图层样式fill: new Fill({color: "rgba(0, 0, 255, 0.2)", //填充颜色}),stroke: new Stroke({color: "#0000ff", //边框颜色width: 2, // 边框宽度}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),})],//设置视图,包括中心点,坐标系,默认缩放级别,最大、最小缩放级别view: new View({projection:'EPSG:3857',	//坐标系center: fromLonLat([120.2,30.35]),	//中心点zoom: 10,	  //默认缩放级别minZoom:1,	//最小缩放级别maxZoom:18	//最大缩放级别})})},//绘制方法sketch() {let that = this;that.map.removeInteraction(that.draw)that.map.removeInteraction(that.interactionDrag)//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);//双击执行取消绘制that.map.on("dblclick", function () {that.MyDraw.setActive(false);that.map.removeInteraction(that.draw)});//初始化绘制交互that.draw = new Draw({//绘制对象source: that.drawSource, //绘制层数据源,勾绘的要素属于的数据集type: "Polygon",	//绘制的类型,这里绘制一个多边形,也可以是POINT(点)、LINE_STRING(线)、CIRCLE(圆)//设置一些样式style: new Style({fill: new Fill({color: "rgba(0,0,255,0.2)",}),stroke: new Stroke({color: "#0000ff",width: 2,}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),});// 加载交互绘制控件函数that.MyDraw = {//执行绘制函数的方法init: function () {that.map.addInteraction(that.draw);	//添加交互//绑定交互绘制工具开始绘制的事件that.draw.on("drawstart", function (evt) {//逻辑代码});//绑定交互绘制工具结束绘制的事件that.draw.on("drawend", function (evt) {//逻辑代码that.MyDraw.setActive(false); //绘制完毕以后关闭控件console.log(evt)})},//控制控件开启或关闭的函数,active要传boolean类型/** setActive()是Openlayers中Interaction的函数,作用是开启和关闭控件* 这里也可以不用setActive()函数,可以使用this.map.addInteraction()加载控件和this.map.removeInteraction()* 在绘制结束的时候移除控件。如果使用这种方法,就需要把map定义成全局的。*/setActive: function (active) {that.draw.setActive(active); //激活控件},};that.MyDraw.init();	//执行绘制函数方法},//第二种绘制方法sketch2(){let that = this;//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);//双击执行取消绘制that.map.on("dblclick", function () {that.map.removeInteraction(that.draw)});//初始化绘制交互that.draw = new Draw({//绘制对象source: that.drawSource, //绘制层数据源,勾绘的要素属于的数据集type: "Polygon",	//绘制的类型,这里绘制一个多边形,也可以是POINT(点)、LINE_STRING(线)、CIRCLE(圆)//设置一些样式style: new Style({fill: new Fill({color: "rgba(0,0,255,0.2)",}),stroke: new Stroke({color: "#0000ff",width: 2,}),image: new Circle({radius: 7,fill: new Fill({color: "#0000ff",}),}),}),});// 加载交互绘制控件函数(function initDraw() {that.map.addInteraction(that.draw);	//添加交互//绑定交互绘制工具开始绘制的事件that.draw.on("drawstart", function (evt) {//逻辑代码});//绑定交互绘制工具结束绘制的事件that.draw.on("drawend", function (evt) {//逻辑代码})})()},//清空clear(){this.drawSource.clear()},//平移功能(拖拽功能)translation(){let that = thisthat.map.removeInteraction(that.draw)const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction); //移除双击缩放功能,使双击只用于关闭编辑状态that.interactionDrag = new ExtTransform({enableRotatedTransform: false,hitTolerance: 2,  //偏移量translate: true, // 拖拽stretch: false, // 拉伸scale: false, // 缩放rotate: false, // 旋转translateFeature: false, //显示中心位置noFlip: false, //防止特征几何翻转,默认为 falselayers: [that.drawVector], //指定可以拖拽的图层});//添加交互that.map.addInteraction(that.interactionDrag);that.interactionDrag.on(["translatestart"], function (evt) {});that.interactionDrag.on(["translating"], function (evt) {//逻辑代码});that.interactionDrag.on(["translateend"], function (evt) {//逻辑代码});that.map.on("dblclick",function (){//双击移除控件,不再平移that.map.removeInteraction(that.interactionDrag)})},//框选平移boxSelectAndMove() {let that = this;that.map.removeInteraction(that.draw)that.map.removeInteraction(that.interactionDrag)//移除双击缩放功能,使双击只用于关闭编辑状态const dblClickInteraction = that.map.getInteractions().getArray().find((interaction) => {return interaction instanceof DoubleClickZoom;});that.map.removeInteraction(dblClickInteraction);// 创建绘制矩形工具let drawBox = new Draw({source: new Vector(),type: 'Circle', //绘制的图形是圆形//将坐标数组和可选的现有几何图形和投影作为参数并返回几何图形的函数。可选的现有几何是在没有第二个参数的情况下调用函数时返回的几何。geometryFunction: createBox(),  //将圆形改成矩形框,如果没有这行代码绘制出来的框会变成圆形//设置一些样式style: new Style({image: new Circle({radius: 7,fill: new Fill({color: "rgba(255, 128, 0,1)",}),}),fill: new Fill({color: "rgba(1, 92, 199,0.1)",}),stroke: new Stroke({color: "rgba(56, 239, 255,1)",width: 1})})});that.map.addInteraction(drawBox) //添加交互let myTransform = {} //定义一个接收初始化框选平移的变量,后面需要双击的时候移除交互,所以定义在这里drawBox.on('drawstart', function (evt) {//逻辑代码})drawBox.on('drawend', function (evt) {let polygon = evt.feature.getGeometry() // 用polygon存储画出来的矩形框的信息,包括坐标等let features = that.drawSource.getFeatures() //取出所有要素,每一个都要判断是否相交let needToMoveFeatures = [] //相交的要素存在这里let isIntersect = false // 是否相交for(let i=0;i<features.length;i++){let coordinates = features[i].values_.geometry.flatCoordinatesfor(let j=0;j<coordinates.length;j+=2){// containsXY()是Openlayers的内置函数,可以判断点是否在多边形内。// 这里的应用是判断每一个feature的顶点是否在polygon内// 因为画的是矩形框,如果框选到了feature,那么这个feature的某一个顶点一定在矩形框内// 如果是其他逻辑,需要参照Openlayers官方文档使用其他方法if(polygon.containsXY(coordinates[j], coordinates[j + 1])){// 如果已经判断相交,直接跳出循环即可isIntersect = trueneedToMoveFeatures.push(features[i])break}}}if(isIntersect){that.map.removeInteraction(drawBox)// 这里不再写注释了,和平移功能的实现是一样的myTransform = new ExtTransform({enableRotatedTransform: false,layers: [that.drawVector],hitTolerance: 2,scale: false,rotate: false,keepAspectRatio: false,keepRectangle: false,translate: true,translateFeature: false,noFlip: false,stretch: false,})that.map.addInteraction(myTransform)  //添加控件myTransform.setSelection(needToMoveFeatures) //ol-ext中transform函数,可以直接把所有框选的要素当成一个整体myTransform.on('translatestart',function (evt){//逻辑代码})myTransform.on('translating',function (evt){//逻辑代码})myTransform.on('translateend',function (evt){//逻辑代码console.log(evt)//这里的evt包含了平移结束以后的feature信息,具体信息见下图})}})that.map.on('dblclick', function () {that.map.removeInteraction(drawBox)that.map.removeInteraction(myTransform)})},},mounted() {this.initialMap()	//立即执行初始化地图方法}
}
</script><style scoped>#map{width: 100%;height: 100%;position: absolute;}.Cards{position: absolute;top: 0%;right: 10%;}
</style>

博主第一次写文,如果写的不好请多多担待,有哪里写错了,也请大家批评斧正!感谢各位的支持!

这篇关于Vue2 + Openlayers 实现绘制、平移和框选平移功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/232715

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

【WebGPU Unleashed】1.1 绘制三角形

一部2024新的WebGPU教程,作者Shi Yan。内容很好,翻译过来与大家共享,内容上会有改动,加上自己的理解。更多精彩内容尽在 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信号:digital_twin123 在 3D 渲染领域,三角形是最基本的绘制元素。在这里,我们将学习如何绘制单个三角形。接下来我们将制作一个简单的着色器来定义三角形内的像素

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、