Skip to content

Commit

Permalink
refactor(ol-source-*): move common setup into useSource composable
Browse files Browse the repository at this point in the history
All source components are using the `useSource` composable now. This refactoring won't affect you most likely but in case you used some undocumented exposed APIs/features it will.

BREAKING CHANGE: The created Source class from the corresponding OpenLayers source isn't wrapped in a computed anymore but in a shallowRef. This will improve the performance and prevent unneeded re-computations.
  Also, the provided `imageLayer` references is now wrapped in a `Ref` which will make it reactive:
  In case the layer changes, the source is updated and applied to the changed layers reference.
  This behavior was already default for all layer types:
  ```diff
  -const layer = inject<ImageLayer<Static> | null>("imageLayer");
  +const layer = inject<Ref<ImageLayer<Static>> | null>("imageLayer");
  ```
closes: #354
  • Loading branch information
d-koppenhagen committed May 22, 2024
1 parent 6dd3fa1 commit 56b386d
Show file tree
Hide file tree
Showing 34 changed files with 337 additions and 865 deletions.
30 changes: 7 additions & 23 deletions docs/pluginsguide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ The example below demonstrates how a source called `FooSource` could be implemen
<script setup lang="ts">
import type { Ref } from "vue";
import { inject, watch, onMounted, onUnmounted, shallowRef } from "vue";
import { inject } from "vue";
import { useSource } from "vue3-openlayers";
// import the source to be wrapped in a component.
import FooSource, { type Options } from "foo-source";
Expand All @@ -96,28 +97,11 @@ const layer = inject<Ref<TileLayer<FooSource>> | null>("tileLayer");
// const layer = inject<Ref<VectorLayer<FooSource>> | null>("vectorLayer");
// const layer = inject<Ref<HeatmapLayer> | null>("heatmapLayer");
// Store a shallowRef of the Source, so it can be watched for changes.
const source = shallowRef(new FooSource(props));
// Watch for source changes and re-apply the source to the layer.
watch(source, () => {
layer?.value?.setSource(source.value);
});
// Watch for layer changes and re-apply the source to the layer.
watch(layer, () => {
layer?.value?.setSource(source.value);
});
// Apply the source once the component is mounted.
onMounted(() => {
layer?.value?.setSource(source.value);
});
// Cleanup when component is destroyed.
onUnmounted(() => {
layer?.value?.setSource(null);
});
// Create the source and watch for changes of the source, the props or the parent layer.
// Changes will be applied and the source will be removed on unmount.
// The last parameter will receive the event names which should be handled by the target component.
// Check out the sources of the composable for more details.
const { source } = useSource(FooSource, layer, props, ["removefeature"]);
// Expose the layer and source, so it can be used as a `ref=""` on the element
defineExpose({
Expand Down
4 changes: 2 additions & 2 deletions src/components/layers/OlImageLayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ const properties = usePropsAsObjectProperties(props);
const imageLayer = shallowRef(new ImageLayer(properties));
useLayer(imageLayer, properties);
provide("imageLayer", imageLayer.value);
provide("imageLayer", imageLayer);
defineExpose({
imageLayer: imageLayer.value,
imageLayer,
});
</script>
2 changes: 1 addition & 1 deletion src/components/map/__test__/OlFeature.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe("OlMap.vue", () => {
},
global: {
provide: {
"ol-options": { debug: true },
"ol-options": { debug: false },
vectorSource,
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/map/__test__/OlMap.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe("OlMap.vue", () => {
},
global: {
provide: {
"ol-options": { debug: true },
"ol-options": { debug: false },
},
},
});
Expand Down
2 changes: 1 addition & 1 deletion src/components/map/__test__/OlOverlay.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe("OlOverlay.vue", () => {
},
global: {
provide: {
"ol-options": { debug: true },
"ol-options": { debug: false },
map,
},
},
Expand Down
44 changes: 10 additions & 34 deletions src/components/sources/OlSourceBingMaps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
<script setup lang="ts">
import BingMaps, { type Options } from "ol/source/BingMaps";
import type { Ref } from "vue";
import { inject, watch, onMounted, onUnmounted, computed } from "vue";
import { inject } from "vue";
import type TileLayer from "ol/layer/Tile";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
import {
IMAGE_SOURCE_EVENTS,
useOpenLayersEvents,
} from "@/composables/useOpenLayersEvents";
import { IMAGE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
import useSource from "@/composables/useSource";
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
defineOptions({
Expand All @@ -22,37 +19,16 @@ const props = defineProps<Omit<Options, "key"> & { apiKey: string }>();
const layer = inject<Ref<TileLayer<BingMaps>> | null>("tileLayer");
const properties = usePropsAsObjectProperties(props);
const source = computed(
() =>
new BingMaps({
...properties,
key: properties.apiKey,
}),
);
useOpenLayersEvents(source, IMAGE_SOURCE_EVENTS);
watch(source, () => {
layer?.value?.setSource(source.value);
});
watch(
() => layer?.value,
() => {
layer?.value?.setSource(source.value);
const { source } = useSource(
BingMaps,
layer,
{
...props,
key: props.apiKey,
},
IMAGE_SOURCE_EVENTS,
);
onMounted(() => {
layer?.value?.setSource(source.value);
});
onUnmounted(() => {
layer?.value?.setSource(null);
});
defineExpose({
layer,
source,
Expand Down
44 changes: 10 additions & 34 deletions src/components/sources/OlSourceBingmaps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,10 @@
<script setup lang="ts">
import BingMaps, { type Options } from "ol/source/BingMaps";
import type { Ref } from "vue";
import { inject, watch, onMounted, onUnmounted, computed } from "vue";
import { inject } from "vue";
import type TileLayer from "ol/layer/Tile";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
import {
IMAGE_SOURCE_EVENTS,
useOpenLayersEvents,
} from "@/composables/useOpenLayersEvents";
import { IMAGE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
import useSource from "@/composables/useSource";
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
defineOptions({
Expand All @@ -22,37 +19,16 @@ const props = defineProps<Omit<Options, "key"> & { apiKey: string }>();
const layer = inject<Ref<TileLayer<BingMaps>> | null>("tileLayer");
const properties = usePropsAsObjectProperties(props);
const source = computed(
() =>
new BingMaps({
...properties,
key: properties.apiKey,
}),
);
useOpenLayersEvents(source, IMAGE_SOURCE_EVENTS);
watch(source, () => {
layer?.value?.setSource(source.value);
});
watch(
() => layer?.value,
() => {
layer?.value?.setSource(source.value);
const { source } = useSource(
BingMaps,
layer,
{
...props,
key: props.apiKey,
},
IMAGE_SOURCE_EVENTS,
);
onMounted(() => {
layer?.value?.setSource(source.value);
});
onUnmounted(() => {
layer?.value?.setSource(null);
});
defineExpose({
layer,
source,
Expand Down
40 changes: 4 additions & 36 deletions src/components/sources/OlSourceCluster.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,12 @@
<script setup lang="ts">
import Cluster, { type Options } from "ol/source/Cluster";
import type { Ref } from "vue";
import { inject, watch, onMounted, onUnmounted, provide, computed } from "vue";
import { inject, provide } from "vue";
import type Geometry from "ol/geom/Geometry";
import type Feature from "ol/Feature";
import type Point from "ol/geom/Point";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
import {
FEATURE_EVENTS,
useOpenLayersEvents,
} from "@/composables/useOpenLayersEvents";
import { FEATURE_EVENTS } from "@/composables/useOpenLayersEvents";
import useSource from "@/composables/useSource";
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
defineOptions({
Expand All @@ -31,36 +28,7 @@ const props = withDefaults(defineProps<Options>(), {
const layer = inject<Ref<Cluster> | null>("vectorLayer");
const properties = usePropsAsObjectProperties(props);
const source = computed(() => new Cluster(properties));
useOpenLayersEvents(source, FEATURE_EVENTS);
const applySource = () => {
layer?.value?.setSource(null);
layer?.value?.setSource(source.value);
layer?.value?.changed();
};
watch(properties, () => {
applySource();
});
watch(
() => layer?.value,
() => {
applySource();
},
);
onMounted(() => {
layer?.value?.setSource(source.value);
layer?.value?.changed();
});
onUnmounted(() => {
layer?.value?.setSource(null);
});
const { source } = useSource(Cluster, layer, props, FEATURE_EVENTS);
provide("vectorLayer", source);
Expand Down
37 changes: 4 additions & 33 deletions src/components/sources/OlSourceGeoTIFF.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@

<script setup lang="ts">
import GeoTIFF, { type Options } from "ol/source/GeoTIFF";
import { inject, onMounted, onUnmounted, watch, type Ref } from "vue";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
import { inject, type Ref } from "vue";
import type TileLayer from "ol/layer/Tile";
import projectionFromProperties from "@/helpers/projection";
import {
TILE_SOURCE_EVENTS,
useOpenLayersEvents,
} from "@/composables/useOpenLayersEvents";
import type { ProjectionLike } from "ol/proj";
import { TILE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
import useSource from "@/composables/useSource";
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
defineOptions({
Expand All @@ -22,32 +17,8 @@ defineOptions({
const props = defineProps<Options>();
const layer = inject<Ref<TileLayer<GeoTIFF>> | null>("tileLayer");
const properties = usePropsAsObjectProperties(props);
const createSource = () =>
new GeoTIFF({
...properties,
projection: projectionFromProperties(
properties.projection as ProjectionLike,
),
});
let source = createSource();
useOpenLayersEvents(source, TILE_SOURCE_EVENTS);
watch(properties, () => {
layer?.value.setSource(null);
source = createSource();
layer?.value.setSource(source);
});
onMounted(() => {
layer?.value.setSource(source);
});
onUnmounted(() => {
layer?.value.setSource(null);
});
const { source } = useSource(GeoTIFF, layer, props, TILE_SOURCE_EVENTS);
defineExpose({
layer,
Expand Down
37 changes: 4 additions & 33 deletions src/components/sources/OlSourceGeoTiff.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@

<script setup lang="ts">
import GeoTIFF, { type Options } from "ol/source/GeoTIFF";
import { inject, onMounted, onUnmounted, watch, type Ref } from "vue";
import usePropsAsObjectProperties from "@/composables/usePropsAsObjectProperties";
import { inject, type Ref } from "vue";
import type TileLayer from "ol/layer/Tile";
import projectionFromProperties from "@/helpers/projection";
import {
TILE_SOURCE_EVENTS,
useOpenLayersEvents,
} from "@/composables/useOpenLayersEvents";
import type { ProjectionLike } from "ol/proj";
import { TILE_SOURCE_EVENTS } from "@/composables/useOpenLayersEvents";
import useSource from "@/composables/useSource";
// prevent warnings caused by event pass-through via useOpenLayersEvents composable
defineOptions({
Expand All @@ -22,32 +17,8 @@ defineOptions({
const props = defineProps<Options>();
const layer = inject<Ref<TileLayer<GeoTIFF>> | null>("tileLayer");
const properties = usePropsAsObjectProperties(props);
const createSource = () =>
new GeoTIFF({
...properties,
projection: projectionFromProperties(
properties.projection as ProjectionLike,
),
});
let source = createSource();
useOpenLayersEvents(source, TILE_SOURCE_EVENTS);
watch(properties, () => {
layer?.value.setSource(null);
source = createSource();
layer?.value.setSource(source);
});
onMounted(() => {
layer?.value.setSource(source);
});
onUnmounted(() => {
layer?.value.setSource(null);
});
const { source } = useSource(GeoTIFF, layer, props, TILE_SOURCE_EVENTS);
defineExpose({
layer,
Expand Down
Loading

0 comments on commit 56b386d

Please sign in to comment.