| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  | import { BBox } from "../BBox" | 
					
						
							|  |  |  | import { Store } from "../UIEventSource" | 
					
						
							|  |  |  | import ThemeViewState from "../../Models/ThemeViewState" | 
					
						
							|  |  |  | import Constants from "../../Models/Constants" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export type FeatureViewState = | 
					
						
							|  |  |  |     | "no-data" | 
					
						
							|  |  |  |     | "zoom-to-low" | 
					
						
							|  |  |  |     | "has-visible-feature" | 
					
						
							|  |  |  |     | "all-filtered-away" | 
					
						
							|  |  |  | export default class NoElementsInViewDetector { | 
					
						
							|  |  |  |     public readonly hasFeatureInView: Store<FeatureViewState> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(themeViewState: ThemeViewState) { | 
					
						
							|  |  |  |         const state = themeViewState | 
					
						
							|  |  |  |         const minZoom = Math.min( | 
					
						
							|  |  |  |             ...themeViewState.layout.layers | 
					
						
							|  |  |  |                 .filter((l) => Constants.priviliged_layers.indexOf(<any>l.id) < 0) | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                 .filter((l) => !l.id.startsWith("note_import")) | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                 .map((l) => l.minzoom) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         const mapProperties = themeViewState.mapProperties | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const priviliged: Set<string> = new Set(Constants.priviliged_layers) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.hasFeatureInView = state.mapProperties.bounds.stabilized(100).map( | 
					
						
							|  |  |  |             (bbox) => { | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                 if (!bbox) { | 
					
						
							|  |  |  |                     return undefined | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                 if (mapProperties.zoom.data < minZoom) { | 
					
						
							|  |  |  |                     // Not a single layer will display anything as the zoom is to low
 | 
					
						
							|  |  |  |                     return "zoom-to-low" | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                 let minzoomWithData = 9999 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                 for (const [layerName, source] of themeViewState.perLayerFiltered) { | 
					
						
							|  |  |  |                     if (priviliged.has(layerName)) { | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                     const feats = source.features.data | 
					
						
							|  |  |  |                     if (!(feats?.length > 0)) { | 
					
						
							|  |  |  |                         // Nope, no data loaded
 | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                     const layer = themeViewState.layout.getLayer(layerName) | 
					
						
							|  |  |  |                     if (mapProperties.zoom.data < layer.minzoom) { | 
					
						
							|  |  |  |                         minzoomWithData = Math.min(layer.minzoom) | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  |                     if (!state.layerState.filteredLayers.get(layerName).isDisplayed.data) { | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (const feat of feats) { | 
					
						
							|  |  |  |                         if (BBox.get(feat).overlapsWith(bbox)) { | 
					
						
							|  |  |  |                             // We found at least one item which has visible data
 | 
					
						
							|  |  |  |                             return "has-visible-feature" | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 // If we arrive here, data might have been filtered away
 | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 for (const [layerName, source] of themeViewState.perLayerFiltered) { | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                     if (priviliged.has(layerName)) { | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-06-29 01:44:38 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                     const layer = themeViewState.layout.getLayer(layerName) | 
					
						
							|  |  |  |                     if (mapProperties.zoom.data < layer.minzoom) { | 
					
						
							| 
									
										
										
										
											2023-06-15 02:42:12 +02:00
										 |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     const feats = source.features.data | 
					
						
							|  |  |  |                     if (!(feats?.length > 0)) { | 
					
						
							|  |  |  |                         // Nope, no data loaded
 | 
					
						
							|  |  |  |                         continue | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (const feat of feats) { | 
					
						
							|  |  |  |                         if (BBox.get(feat).overlapsWith(bbox)) { | 
					
						
							|  |  |  |                             // We found at least one item, but as we didn't find it before, it is filtered away
 | 
					
						
							|  |  |  |                             return "all-filtered-away" | 
					
						
							|  |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 return "no-data" | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 ...Array.from(themeViewState.perLayerFiltered.values()).map((f) => f.features), | 
					
						
							|  |  |  |                 mapProperties.zoom, | 
					
						
							|  |  |  |                 ...Array.from(state.layerState.filteredLayers.values()).map((fl) => fl.isDisplayed), | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |