Skip to content

Commit 9db2dc7

Browse files
committed
feat(ol-source-vector): pass-through events
the following events are now passed-through: - `addfeature` - `change` - `changefeature` - `clear` - `error` - `featuresloadend` - `featuresloaderror` - `featuresloadstart` - `propertychange` - `removefeature`
1 parent 730d9a2 commit 9db2dc7

File tree

3 files changed

+191
-5
lines changed

3 files changed

+191
-5
lines changed

docs/componentsguide/sources/vector/index.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import GeomPoint from "@demos/GeomPoint.vue"
77
import VectorSourceDemo1 from "@demos/VectorSourceDemo1.vue"
88
import VectorSourceDemo2 from "@demos/VectorSourceDemo2.vue"
99
import VectorSourceDemo3 from "@demos/VectorSourceDemo3.vue"
10+
import AnimatedClusterDemo2 from "@demos/AnimatedClusterDemo2.vue"
1011
</script>
1112

1213
## Usage
1314

14-
### GeoJSON
15+
### `ol-feature` component (GeoJSON)
1516

16-
Static features with the help of ol-feature, should be used only for tiny static layers.
17+
Static features with the help of `ol-feature`, should be used only for tiny static layers.
1718

1819
<ClientOnly>
1920
<GeomPoint />
@@ -75,6 +76,8 @@ const coordinate = ref([40, 40]);
7576
</script>
7677
```
7778

79+
### `url` property
80+
7881
Load features simply by providing url value and format GeoJSON
7982

8083
<ClientOnly>
@@ -121,6 +124,12 @@ const geoJson = new format.GeoJSON();
121124
</script>
122125
```
123126

127+
### `features` property
128+
129+
<ClientOnly>
130+
<AnimatedClusterDemo2 />
131+
</ClientOnly>
132+
124133
### `urlFunction`
125134

126135
Next example loads features from remote WFS service by viewport BBOX. With format and strategy you can define custom vector source format and loading strategy.
@@ -303,3 +312,16 @@ strategy available with inject('ol-loadingstrategy');
303312

304313
- **Type**: `Boolean`
305314
- **Default**: `true`
315+
316+
## Events
317+
318+
- `addfeature`
319+
- `change`
320+
- `changefeature`
321+
- `clear`
322+
- `error`
323+
- `featuresloadend`
324+
- `featuresloaderror`
325+
- `featuresloadstart`
326+
- `propertychange`
327+
- `removefeature`

src/components/sources/OlSourceVector.vue

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ const props = withDefaults(
4040
}
4141
);
4242
43+
const emit = defineEmits([
44+
"addfeature",
45+
"change",
46+
"changefeature",
47+
"clear",
48+
"error",
49+
"featuresloadend",
50+
"featuresloaderror",
51+
"featuresloadstart",
52+
"propertychange",
53+
"removefeature",
54+
]);
55+
4356
const vectorLayer = inject<Ref<VectorLayer<VectorSource>> | null>(
4457
"vectorLayer",
4558
null
@@ -49,9 +62,22 @@ const layer = heatmapLayer || vectorLayer;
4962
5063
const { properties } = usePropsAsObjectProperties(props);
5164
52-
const source = computed(
53-
() => new VectorSource(properties as Options<Geometry>)
54-
);
65+
const source = computed(() => {
66+
const vs = new VectorSource(properties as Options<Geometry>);
67+
68+
vs.on("addfeature", (...args) => emit("addfeature", ...args));
69+
vs.on("change", (...args) => emit("change", ...args));
70+
vs.on("changefeature", (...args) => emit("changefeature", ...args));
71+
vs.on("clear", (...args) => emit("clear", ...args));
72+
vs.on("error", (...args) => emit("error", ...args));
73+
vs.on("featuresloadend", (...args) => emit("featuresloadend", ...args));
74+
vs.on("featuresloaderror", (...args) => emit("featuresloaderror", ...args));
75+
vs.on("featuresloadstart", (...args) => emit("featuresloadstart", ...args));
76+
vs.on("propertychange", (...args) => emit("propertychange", ...args));
77+
vs.on("removefeature", (...args) => emit("removefeature", ...args));
78+
79+
return vs;
80+
});
5581
5682
const applySource = () => {
5783
// @ts-ignore

src/demos/AnimatedClusterDemo2.vue

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
<template>
2+
<label for="count">Marker:</label>
3+
<input type="number" id="count" v-model="count" />
4+
<ol-map
5+
:loadTilesWhileAnimating="true"
6+
:loadTilesWhileInteracting="true"
7+
renderer="webgl"
8+
style="height: 400px"
9+
>
10+
<ol-view
11+
ref="view"
12+
:center="center"
13+
:rotation="rotation"
14+
:zoom="zoom"
15+
:projection="projection"
16+
/>
17+
18+
<ol-tile-layer>
19+
<ol-source-osm />
20+
</ol-tile-layer>
21+
22+
<ol-interaction-clusterselect @select="featureSelected" :pointRadius="20">
23+
<ol-style>
24+
<ol-style-stroke color="green" :width="5"></ol-style-stroke>
25+
<ol-style-fill color="rgba(255,255,255,0.5)"></ol-style-fill>
26+
<ol-style-icon :src="markerIcon" :scale="0.05"></ol-style-icon>
27+
</ol-style>
28+
</ol-interaction-clusterselect>
29+
30+
<ol-animated-clusterlayer :animationDuration="500" :distance="40">
31+
<ol-source-vector
32+
ref="vectorsource"
33+
:features="features"
34+
@featuresloadstart="featuresloadstart"
35+
@featuresloadend="featuresloadend"
36+
@featuresloaderror="featuresloaderror"
37+
/>
38+
39+
<ol-style :overrideStyleFunction="overrideStyleFunction">
40+
<ol-style-stroke color="red" :width="2"></ol-style-stroke>
41+
<ol-style-fill color="rgba(255,255,255,0.1)"></ol-style-fill>
42+
43+
<ol-style-circle :radius="20">
44+
<ol-style-stroke
45+
color="black"
46+
:width="15"
47+
:lineDash="[]"
48+
lineCap="butt"
49+
></ol-style-stroke>
50+
<ol-style-fill color="black"></ol-style-fill>
51+
</ol-style-circle>
52+
53+
<ol-style-text>
54+
<ol-style-fill color="white"></ol-style-fill>
55+
</ol-style-text>
56+
</ol-style>
57+
</ol-animated-clusterlayer>
58+
</ol-map>
59+
</template>
60+
61+
<script setup>
62+
import { computed, ref } from "vue";
63+
import { Point } from "ol/geom";
64+
import Feature from "ol/Feature";
65+
import { tile } from "ol/loadingstrategy";
66+
import markerIcon from "@/assets/marker.png";
67+
68+
const center = ref([40, 40]);
69+
const projection = ref("EPSG:4326");
70+
const zoom = ref(5);
71+
const rotation = ref(0);
72+
const count = ref(5000);
73+
74+
const features = computed(() => {
75+
return Array.from({ length: count.value }, (_, i) => {
76+
return new Feature({
77+
geometry: new Point([
78+
getRandomInRange(24, 45, 3),
79+
getRandomInRange(35, 41, 3),
80+
]),
81+
index: i,
82+
});
83+
});
84+
});
85+
86+
const overrideStyleFunction = (feature, style) => {
87+
const clusteredFeatures = feature.get("features");
88+
const size = clusteredFeatures.length;
89+
90+
const color = size > 20 ? "192,0,0" : size > 8 ? "255,128,0" : "0,128,0";
91+
const radius = Math.max(8, Math.min(size, 20));
92+
const dash = (2 * Math.PI * radius) / 6;
93+
const calculatedDash = [0, dash, dash, dash, dash, dash, dash];
94+
95+
style.getImage().getStroke().setLineDash(dash);
96+
style
97+
.getImage()
98+
.getStroke()
99+
.setColor("rgba(" + color + ",0.5)");
100+
style.getImage().getStroke().setLineDash(calculatedDash);
101+
style
102+
.getImage()
103+
.getFill()
104+
.setColor("rgba(" + color + ",1)");
105+
106+
style.getImage().setRadius(radius);
107+
108+
style.getText().setText(size.toString());
109+
};
110+
111+
const getRandomInRange = (from, to, fixed) => {
112+
return (Math.random() * (to - from) + from).toFixed(fixed) * 1;
113+
};
114+
115+
const featureSelected = (event) => {
116+
console.log(event);
117+
};
118+
119+
function featuresloadstart() {
120+
console.log("features load start");
121+
}
122+
function featuresloaderror() {
123+
console.log("features load error");
124+
}
125+
function featuresloadend() {
126+
console.log("features load end");
127+
}
128+
</script>
129+
130+
<style>
131+
input {
132+
margin: 0.5rem;
133+
padding: 0.25rem 0.5rem;
134+
font-size: 1rem;
135+
border: 1px solid black;
136+
width: 100px;
137+
}
138+
</style>

0 commit comments

Comments
 (0)