上一篇是使用openlayers原生实现的,这一节使用vue3-openlayers
实现(有轮子真好)
1 需求
使用openlayers绘图功能绘制多边形
2 分析
主要是openlayers中draw功能的使用
3 实现
为了方便,就不加载底图了,直接使用绘制功能
2.1 简单实现
<template>
<ol-map
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
style="width: 100%; height: 100%"
>
<ol-view
ref="view"
:center="center"
:rotation="rotation"
:zoom="zoom"
:projection="projection"
/>
<ol-vector-layer>
<ol-source-vector :projection="projection">
<ol-interaction-draw
:type="'Polygon'"
:features="features"
:source="source"
@drawend="drawend"
@drawstart="drawstart"
>
<ol-style>
<ol-style-stroke color="rgba(228, 147, 87, 1)" :width="2"></ol-style-stroke>
<ol-style-fill color="rgba(228, 147, 87, 0.5)"></ol-style-fill>
<!-- <ol-style-circle :radius="5">
<ol-style-fill color="#00dd11" />
<ol-style-stroke color="blue" :width="2" />
</ol-style-circle> -->
</ol-style>
</ol-interaction-draw>
</ol-source-vector>
<ol-style>
<ol-style-stroke color="red" :width="2"></ol-style-stroke>
<ol-style-fill color="rgba(255,0,0,0.3)"></ol-style-fill>
<ol-style-circle :radius="7">
<ol-style-fill color="red"></ol-style-fill>
</ol-style-circle>
</ol-style>
</ol-vector-layer>
</ol-map>
</template>
<script setup lang="ts">
import { DrawEvent } from 'ol/interaction/Draw';
const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const rotation = ref(0);
const features=ref([])
const source=ref([])
const drawstart = (event:Event) => {
console.log(event);
};
const drawend = (event:DrawEvent) => {
console.log(event.feature.getGeometry());
};
</script>
<style scoped lang="scss">
</style>
2.2 进阶实现(overrideStyleFunction属性的使用)
<template>
<ol-map
:loadTilesWhileAnimating="true"
:loadTilesWhileInteracting="true"
style="width: 100%; height: 100%"
>
<ol-view
ref="view"
:center="center"
:rotation="rotation"
:zoom="zoom"
:projection="projection"
/>
<ol-vector-layer>
<ol-source-vector :projection="projection">
<ol-interaction-draw
:type="'Polygon'"
:features="features"
:source="source"
@drawend="drawend"
@drawstart="drawstart"
>
<ol-style :overrideStyleFunction="handleStyleFunction">
<!-- <ol-style-stroke color="rgba(228, 147, 87, 1)" :width="2"></ol-style-stroke>
<ol-style-fill color="rgba(228, 147, 87, 0.5)"></ol-style-fill> -->
<!-- <ol-style-circle :radius="5">
<ol-style-fill color="#00dd11" />
<ol-style-stroke color="blue" :width="2" />
</ol-style-circle> -->
</ol-style>
</ol-interaction-draw>
</ol-source-vector>
<ol-style :overrideStyleFunction="styleFunction">
<!-- <ol-style-stroke color="red" :width="2"></ol-style-stroke>
<ol-style-fill color="rgba(255,0,0,0.3)"></ol-style-fill>
<ol-style-circle :radius="7">
<ol-style-fill color="red"></ol-style-fill>
</ol-style-circle> -->
</ol-style>
</ol-vector-layer>
</ol-map>
</template>
<script setup lang="ts">
import { FeatureLike } from 'ol/Feature';
import { LineString, Point } from 'ol/geom';
import { DrawEvent } from 'ol/interaction/Draw';
import { Circle, Fill, Stroke, Style } from 'ol/style';
const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const rotation = ref(0);
const features = ref([]);
const source = ref([]);
const drawstart = (event: Event) => {
console.log(event);
};
const drawend = (event: DrawEvent) => {
console.log(event.feature.getGeometry());
};
const handleStyleFunction = (feature: FeatureLike, currentStyle: Style) => {
const geometry = feature.getGeometry();
const coord = geometry.getCoordinates();
const type = geometry.getType();
const styles: Array<Style> = [];
for (let i = 0; i < coord.length - 1; i++) {
styles.push(
new Style({
geometry: new Point(coord[i]),
image: new Circle({
fill: new Fill({ color: [255, 255, 255, 1] }),
stroke: new Stroke({
color: 'rgba(228, 147, 87, 1)',
width: 2
}),
radius: 4
})
})
);
}
if (type === 'LineString') {
for (let i = 0; i < coord.length - 1; i++) {
styles.push(
new Style({
geometry: new LineString([coord[i], coord[i + 1]]),
stroke: new Stroke({
color: 'orange',
lineDash: coord.length > 2 && i < coord.length - 2 ? [] : [10],
width: 2
})
})
);
}
}
return styles;
};
const styleFunction = (feature: FeatureLike, currentStyle: Style) => {
const styles = [];
const coord = feature.getGeometry().getCoordinates();
for (let i = 0; i < coord[0].length - 1; i++) {
styles.push(
new Style({
geometry: new Point(coord[0][i]),
image: new Circle({
radius: 4,
fill: new Fill({
color: '#ffff'
}),
stroke: new Stroke({
color: 'orange',
width: 2
})
})
})
);
}
styles.push(
new Style({
fill: new Fill({
color: [128, 128, 255, 0.5]
}),
stroke: new Stroke({
color: 'blue',
width: 2
})
})
);
return styles;
};
</script>
<style scoped lang="scss"></style>
存在问题:与上一篇一样,在点击鼠标后并且鼠标有移动时,前一段虚线才会变成实线,并且顶点加上Point,因为只有鼠标移动才会有新的坐标点加入到绘制,因为openlayers没有提供绘制过程中的钩子函数,所以只能是当前效果