效果展示
HTML
<template>
<div>
<div style="padding: 20px">
<el-radio-group v-model="type" @change="typeChange">
<el-radio
:label="item.value"
:key="item.value"
v-for="item in options"
>{{ item.label }}</el-radio
>
</el-radio-group>
</div>
<div id="featrues" class="dynamic-component-demo"></div>
<div class="box_btn">
<el-button type="primary" @click="commWay('intersect')">交集</el-button>
<el-button type="success" @click="commWay('union')">并集</el-button>
<el-button type="info" @click="commWay('difference')">差集</el-button>
</div>
</div>
</template>
VUE data 初始化
data() {
return {
map: null,
draw: null,
type: "None",
selectedArray: [],
options: [
{ value: "None", label: "无" },
{ value: "Star", label: "五角星" },
{ value: "Spuare", label: "正方形" },
{ value: "Box", label: "长方形" },
{ value: "Regular", label: "正多边形" },
{ value: "fan", label: "扇形" },
],
};
},
公共常量
let source = new VectorSource({ wrapX: false }),
vector = new VectorLayer({
source,
style: new Style({
fill: new Fill({ color: "rgba(255,255,255,0.2)" }),
stroke: new Stroke({ color: "#f00", width: 2 }),
image: new CircleStyle({ radius: 7, fill: new Fill({ color: "#f00" }) }),
}),
});
const highlightStyle = new Style({
fill: new Fill({
color: "rgba(0,0,0,0.5)",
}),
stroke: new Stroke({
color: "#67C23A",
width: 2,
}),
});
图形创建函数
详细代码和逻辑 见
openlayers Draw 理解、特殊图形创建
初始化地图
let map = new Map({
// 设置地图图层
layers: [gaodeMapLayer, vector],
// 设置显示地图的视图
view: new View({
center: transform([104.065735, 30.659462], "EPSG:4326", "EPSG:3857"),
zoom: 9,
minZoom: 1,
maxZoom: 21,
// projection: "EPSG:4326",
rotation: 0,
}),
// 让id为map的div作为地图的容器
target: "featrues",
interactions: defaultInteractions({
doubleClickZoom: false, // 取消双击放大功能交互
// mouseWheelZoom: false, // 取消滚动鼠标中间的滑轮交互
// shiftDragZoom: false, // 取消shift+wheel左键拖动交互
}),
});
this.map = map;
this.addInteraction();
this.addEventListenerMAP(map);
},
methods:{
addEventListenerMAP(map) {
let _this = this;
map.on("pointermove", (e) => {
let pixel = map.getEventPixel(e.originalEvent);
let hit = map.hasFeatureAtPixel(pixel);
map.getTargetElement().style.cursor = hit ? "pointer" : "";
});
map.on("dblclick", function (e) {
map.forEachFeatureAtPixel(e.pixel, function (f) {
const selIndex = _this.selectedArray.indexOf(f);
if (selIndex < 0) {
_this.selectedArray.push(f);
f.setStyle(highlightStyle);
} else {
_this.selectedArray.splice(selIndex, 1);
f.setStyle(undefined);
}
});
});
},
}
差集、并集、差集 实现代码
methods: {
commWay(key) {
let { selectedArray } = this;
if (selectedArray.length <= 1) {
this.$message({
message: "选择图形必须大于2个",
type: "warning",
showClose: true,
});
return;
}
let merge_feature = this.turfMethods([...selectedArray], key);
if (merge_feature) {
source = new VectorSource({
wrapX: false,
features: [merge_feature],
});
vector.setSource(source);
this.selectedArray = [];
}
},
turfMethods(selectedArray, key) {
let Array_ = selectedArray,
first = Array_.shift(),
second = Array_.shift(),
poly1 = turf.polygon(first.getGeometry().getCoordinates()),
poly2 = turf.polygon(second.getGeometry().getCoordinates()),
intersection = turf[key](poly1, poly2);
if (Array_.length > 0) {
return this.turfMethods(
[new GeoJSON().readFeature(intersection), ...Array_],
key
);
} else {
if (intersection) {
return new GeoJSON().readFeature(intersection);
} else {
this.$message({
message: "图形没有交集",
type: "warning",
showClose: true,
});
}
}
},
}