|
1 | | -import { ref, shallowRef, watch } from 'vue' |
| 1 | +import { ref, shallowRef, watch, computed } from 'vue' |
| 2 | +import type TileSource from 'ol/source/Tile' |
2 | 3 | import type Map from 'ol/Map' |
3 | 4 | import VectorSource from 'ol/source/Vector' |
4 | 5 | import VectorLayer from 'ol/layer/Vector' |
@@ -28,6 +29,24 @@ import { inferenceStyle } from '../layers/color-scales' |
28 | 29 |
|
29 | 30 | let featureId = 0 |
30 | 31 |
|
| 32 | +const loadingCount = ref(0) |
| 33 | +export const isLayerLoading = computed(() => loadingCount.value > 0) |
| 34 | + |
| 35 | +export function trackTileSource(source: TileSource): () => void { |
| 36 | + const onStart = () => { |
| 37 | + loadingCount.value++ |
| 38 | + } |
| 39 | + const onEnd = () => { |
| 40 | + loadingCount.value = Math.max(0, loadingCount.value - 1) |
| 41 | + } |
| 42 | + source.on('tileloadstart', onStart) |
| 43 | + source.on(['tileloadend', 'tileloaderror'], onEnd) |
| 44 | + return () => { |
| 45 | + source.un('tileloadstart', onStart) |
| 46 | + source.un(['tileloadend', 'tileloaderror'], onEnd) |
| 47 | + } |
| 48 | +} |
| 49 | + |
31 | 50 | export interface AreaValues { |
32 | 51 | min_area_km2: number |
33 | 52 | max_area_km2: number |
@@ -56,6 +75,13 @@ export const geoJsonResults = shallowRef<any[]>([]) |
56 | 75 | // Cloudless layer management |
57 | 76 | const cloudlessLayer = shallowRef<TileLayer<XYZ> | null>(null) |
58 | 77 |
|
| 78 | +let untrackCloudless: (() => void) | null = null |
| 79 | +watch(cloudlessLayer, (newLayer) => { |
| 80 | + untrackCloudless?.() |
| 81 | + const src = newLayer?.getSource() as TileSource | null |
| 82 | + untrackCloudless = src ? trackTileSource(src) : null |
| 83 | +}) |
| 84 | + |
59 | 85 | // Watch for year changes and update the cloudless layer |
60 | 86 | watch( |
61 | 87 | () => settings.value.year, |
@@ -99,6 +125,20 @@ const s2GridLayer = shallowRef<VectorLayer<VectorSource> | null>(null) |
99 | 125 | const globalPredictionsLayer = shallowRef<VectorTileLayer | null>(null) |
100 | 126 | const globalOverviewLayer = shallowRef<GlTileLayer | null>(null) |
101 | 127 |
|
| 128 | +let untrackGlobalPredictions: (() => void) | null = null |
| 129 | +watch(globalPredictionsLayer, (newLayer) => { |
| 130 | + untrackGlobalPredictions?.() |
| 131 | + const src = newLayer?.getSource() as TileSource | null |
| 132 | + untrackGlobalPredictions = src ? trackTileSource(src) : null |
| 133 | +}) |
| 134 | + |
| 135 | +let untrackGlobalOverview: (() => void) | null = null |
| 136 | +watch(globalOverviewLayer, (newLayer) => { |
| 137 | + untrackGlobalOverview?.() |
| 138 | + const src = newLayer?.getSource() as TileSource | null |
| 139 | + untrackGlobalOverview = src ? trackTileSource(src) : null |
| 140 | +}) |
| 141 | + |
102 | 142 | watch( |
103 | 143 | () => settings.value.threshold, |
104 | 144 | () => { |
@@ -365,5 +405,6 @@ export default function useMap() { |
365 | 405 | geoJsonResults, |
366 | 406 | initCloudlessLayer, |
367 | 407 | updateLayers, |
| 408 | + isLayerLoading, |
368 | 409 | } |
369 | 410 | } |
0 commit comments