Vue+Openlayer使用draw实现绘制点线面功能
实现代码:<template><div><span size="mini" @click="drawFeature('Point')">画点</span><span size="mini" @click="drawFeature('LineString')">画线</span><span size="mini" @cli
·
目录
import { Draw } from "ol/interaction";
//绘制线要素
drawFeature() {
this.draw = new Draw({
source: this.lineStringLayer.getSource(),
type: "LineString", //Point,LineString,Polygon,Circle
});
this.map.addInteraction(this.draw);
},
完整代码:
<template>
<div id="map" style="height: 100vh; width: 100vw"></div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import { OSM, Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer";
import { Draw } from "ol/interaction";
import { Fill, Stroke, Style, Text, Circle } from "ol/style";
export default {
data() {
return {
map: {},
vectorLayer: {},
draw: {},
};
},
created() {},
mounted() {
this.initMap();
this.addLayer();
this.drawFeature();
},
computed: {},
methods: {
initMap() {
this.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
projection: "EPSG:4326",
center: [104.2979180563, 30.528298024],
zoom: 18,
}),
});
},
addLayer() {
this.vectorLayer = new VectorLayer({
source: new VectorSource(),
});
this.map.addLayer(this.vectorLayer);
},
//绘制线要素核心代码
drawFeature() {
this.draw = new Draw({
source: this.vectorLayer.getSource(),
type: "LineString", //Point,LineString,Polygon,Circle
});
this.map.addInteraction(this.draw);
},
},
};
</script>
基本效果
实现代码:
<template>
<div id="map" style="height: 100vh; width: 100vw">
<div style="position: fixed; top: 150px; left: 10px; z-index: 999">
<el-button @click="drawFeature('Point')">画点</el-button>
<el-button @click="drawFeature('LineString')">画线</el-button>
<el-button @click="drawFeature('Polygon')">画面</el-button>
<el-button @click="drawFeature('Circle')">画圆</el-button>
<el-button @click="draw.removeLastPoint()">撤回</el-button>
<el-button @click="map.removeInteraction(draw)">取消</el-button>
<el-button @click="clearDrawLayer()">清除</el-button>
</div>
</div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import { Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource } from "ol/source";
import Draw from "ol/interaction/Draw";
import { Fill, Stroke, Style, Text, Circle } from "ol/style";
export default {
name: "",
data() {
return {
map: {},
draw_source: new VectorSource(),
draw_vector: {},
draw: {},
};
},
mounted() {
this.initMap();
this.addDrawLayer();
},
methods: {
//添加绘制点线面图层
addDrawLayer() {
this.draw_vector = new VectorLayer({
source: this.draw_source,
//绘制好后,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
//边界样式
color: "#ffcc33",
width: 3,
}),
//点样式继承image
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
});
this.map.addLayer(this.draw_vector);
},
//清除绘制图层
clearDrawLayer() {
this.map.removeInteraction(this.draw); //移除交互
this.draw_vector.getSource().clear(); //清除图层上的所有要素
},
//绘制点线面
drawFeature(featureType = "") {
this.map.removeInteraction(this.draw);
this.draw = new Draw({
source: this.draw_source,
type: featureType,
//绘制时,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "#ffcc33",
width: 2,
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
});
this.map.addInteraction(this.draw);
},
// 初始化地图
initMap() {
this.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
visible: true,
name: "OSM",
}),
],
view: new View({
projection: "EPSG:4326",
center: [115, 39],
zoom: 4,
}),
});
},
},
};
</script>
注意:绘制完后,可以通过e.feature.getGeometry().getCoordinates()获取到绘制的范围的经纬度坐标数组 。如下:
this.draw.on("drawend", function (e) {
console.log(" e:", e);
console.log(" e.feature:", e.feature);
console.log(" e.feature.getGeometry():", e.feature.getGeometry());
console.log(
" e.feature.getGeometry().getCoordinates():",
e.feature.getGeometry().getCoordinates()
);
});
在线预览:
js封装绘制功能:
DrawTool.js:
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import { Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource, XYZ } from "ol/source";
import Draw from "ol/interaction/Draw";
import { Fill, Stroke, Style, Text, Icon, Circle } from "ol/style";
export default class DrawTool {
constructor({ domId_map }) {
this.domId_map = domId_map
this.map = null
this.draw_source = new VectorSource()
this.draw_vector = null
this.draw = null
}
initMap() {
this.map = new Map({
target: this.domId_map,
layers: [
new TileLayer({
source: new XYZ({
url:
"http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5a257cd2df1b3311723bd77b0de14baf",
}),
visible: true,
// name: "OSM",
}),
],
view: new View({
projection: "EPSG:4326",
center: [115, 39],
zoom: 4,
}),
})
this.addDrawLayer()
}
//添加绘制点线面图层
addDrawLayer() {
this.draw_vector = new VectorLayer({
source: this.draw_source,
//绘制好后,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
//边界样式
color: "#ffcc33",
width: 3,
}),
//点样式继承image
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
});
this.map.addLayer(this.draw_vector);
}
//清除绘制图层
clearDrawLayer() {
this.map.removeInteraction(this.draw); //移除交互
// this.draw_vector.getSource().clear(); //清除图层上的所有要素
this.draw_source.clear(); //清除图层上的所有要素
}
// 撤回操作
removeLastPoint() {
this.draw.removeLastPoint()
}
// 取消绘制
cancelDraw() {
this.map.removeInteraction(this.draw); //移除交互
}
//绘制点线面
drawFeature(featureType = "") {
if (this.draw) {
this.map.removeInteraction(this.draw);
}
this.draw = new Draw({
source: this.draw_source,
type: featureType,
//绘制时,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "#ffcc33",
width: 2,
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
});
this.map.addInteraction(this.draw);
}
}
测试:
<template>
<div class="main">
<div id="olContainer" style="height: 100vh; width: 100vw"></div>
<div style="position: fixed; top: 150px; left: 10px; z-index: 999">
<el-button @click="state.draw.drawFeature('Point')">画点</el-button>
<el-button @click="state.draw.drawFeature('LineString')">画线</el-button>
<el-button @click="state.draw.drawFeature('Polygon')">画面</el-button>
<el-button @click="state.draw.drawFeature('Circle')">画圆</el-button>
<el-button @click="state.draw.removeLastPoint()">撤回</el-button>
<el-button @click="state.draw.cancelDraw()">取消</el-button>
<el-button @click="state.draw.clearDrawLayer()">清除</el-button>
</div>
</div>
</template>
<script setup>
import { reactive } from 'vue';
import DrawTool from './DrawTool'
const state = reactive({
draw: null
})
onMounted(() => {
let draw = new DrawTool({ domId_map: 'olContainer' })
draw.initMap()
state.draw = draw
console.log("state:", state)
})
</script>
<style lang="scss" scoped>
.main {
position: relative;
height: 100vh;
width: 100vw;
#olContainer {
position: absolute;
height: 100vh;
width: 100vw;
}
}
</style>
可以手绘
效果图
使用代码:
<template>
<div style="height: 100vh; width: 100vw">
<div id="map" style="height: 100%; width: 100%"></div>
<div style="position: fixed; top: 150px; left: 490px; z-index: 999">
<LjDraw :map="map"></LjDraw>
</div>
</div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import { Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource } from "ol/source";
import Draw from "ol/interaction/Draw";
import { Fill, Stroke, Style, Text, Circle } from "ol/style";
import LjDraw from "@/components/LjDraw/index.vue";
export default {
name: "",
components: { LjDraw },
data() {
return {
map: {},
};
},
beforeMount() {
// _isMounted是当前实例mouned()是否执行 此时为false
window.parentMounted = this._isMounted;
},
mounted() {
//父组件中初始化地图对象map
this.initMap();
// _isMounted是当前实例mouned()是否执行 此时为true
window.parentMounted = this._isMounted;
},
methods: {
// 初始化地图
initMap() {
this.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
visible: true,
name: "OSM",
}),
],
view: new View({
projection: "EPSG:4326",
center: [115, 39],
zoom: 4,
}),
});
},
},
watch: {},
};
</script>
LjDraw 组件代码:
<!--LjDraw-->
<template>
<div>
<el-button size="mini">
<select
v-model="currentDrawFeature"
style="
background-color: rgb(66, 66, 66);
color: white;
padding: 2px 7px;
outline: none;
"
@change="drawFeature()"
>
<option value="">请选择</option>
<option value="Point" label="画点"></option>
<option value="LineString">画线</option>
<option value="Polygon">画面</option>
<option value="Circle">画圆</option>
</select>
</el-button>
<el-button size="mini"
><el-checkbox v-model="enableFreeHand">手绘</el-checkbox></el-button
>
<el-button size="mini" @click="draw.removeLastPoint()">撤回</el-button>
<el-button size="mini" @click="cancelDraw()">取消</el-button>
<el-button size="mini" @click="clearDrawLayer()">清除</el-button>
</div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import { Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource } from "ol/source";
import Draw from "ol/interaction/Draw";
import { Fill, Stroke, Style, Text, Icon, Circle } from "ol/style";
export default {
name: "LjDraw",
props: {
map: {
default: {},
required: true,
},
},
data() {
return {
draw_source: new VectorSource(),
draw_vector: {},
draw: {},
currentDrawFeature: "", //当前正在绘制的要素类型
enableFreeHand: false, //是否允许手绘
};
},
mounted() {
let pMountedTimer = {}; //定时器
pMountedTimer = setInterval(() => {
if (window.parentMounted) {
//在这里执行初始化
this.addDrawLayer();
clearInterval(pMountedTimer); //清除定时器
}
}, 1000);
},
methods: {
//添加绘制点线面图层
addDrawLayer() {
this.draw_vector = new VectorLayer({
source: this.draw_source,
//绘制好后,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
//边界样式
color: "#ffcc33",
width: 3,
}),
//点样式继承image
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
zIndex: 9999,
});
this.map.addLayer(this.draw_vector);
},
//取消绘制
cancelDraw() {
this.map.removeInteraction(this.draw); //移除交互
this.currentDrawFeature = ""; //取消选中要素!!
},
//清空绘制图层
clearDrawLayer() {
this.map.removeInteraction(this.draw); //移除交互
this.draw_vector.getSource().clear(); //清除图层上的所有要素
this.currentDrawFeature = ""; //取消选中要素!!
},
//绘制点线面
drawFeature() {
this.map.removeInteraction(this.draw); //移除交互
if (!this.currentDrawFeature) return; //这里一定要判断
this.draw = new Draw({
source: this.draw_source,
type: this.currentDrawFeature,
//绘制时,在地图上呈现的样式
style: new Style({
fill: new Fill({
color: "rgba(255, 255, 255, 0.2)",
}),
stroke: new Stroke({
color: "#ffcc33",
width: 2,
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: "#ffcc33",
}),
}),
}),
freehand: this.enableFreeHand, //手绘
});
this.map.addInteraction(this.draw);
},
// 初始化地图
initMap() {
this.map = new Map({
target: "map",
layers: [
new TileLayer({
source: new OSM(),
visible: true,
name: "OSM",
}),
],
view: new View({
projection: "EPSG:4326",
center: [115, 39],
zoom: 4,
}),
});
},
},
watch: {
enableFreeHand: {
handler() {
this.drawFeature();
},
},
},
};
</script>
更多推荐
已为社区贡献65条内容
所有评论(0)