| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | import FloorLevelInputElement from "../Input/FloorLevelInputElement" | 
					
						
							|  |  |  | import MapState, { GlobalFilter } from "../../Logic/State/MapState" | 
					
						
							|  |  |  | import { TagsFilter } from "../../Logic/Tags/TagsFilter" | 
					
						
							|  |  |  | import { RegexTag } from "../../Logic/Tags/RegexTag" | 
					
						
							|  |  |  | import { Or } from "../../Logic/Tags/Or" | 
					
						
							|  |  |  | import { Tag } from "../../Logic/Tags/Tag" | 
					
						
							|  |  |  | import Translations from "../i18n/Translations" | 
					
						
							|  |  |  | import Combine from "../Base/Combine" | 
					
						
							|  |  |  | import { OsmFeature } from "../../Models/OsmFeature" | 
					
						
							|  |  |  | import { BBox } from "../../Logic/BBox" | 
					
						
							|  |  |  | import { TagUtils } from "../../Logic/Tags/TagUtils" | 
					
						
							|  |  |  | import FeaturePipeline from "../../Logic/FeatureSource/FeaturePipeline" | 
					
						
							|  |  |  | import { Store } from "../../Logic/UIEventSource" | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*** | 
					
						
							|  |  |  |  * The element responsible for the level input element and picking the right level, showing and hiding at the right time, ... | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | export default class LevelSelector extends Combine { | 
					
						
							|  |  |  |     constructor(state: MapState & { featurePipeline: FeaturePipeline }) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const levelsInView: Store<Record<string, number>> = state.currentBounds.map((bbox) => { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             if (bbox === undefined) { | 
					
						
							|  |  |  |                 return {} | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             const allElementsUnfiltered: OsmFeature[] = [].concat( | 
					
						
							|  |  |  |                 ...state.featurePipeline.GetAllFeaturesAndMetaWithin(bbox).map((ff) => ff.features) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             const allElements = allElementsUnfiltered.filter((f) => BBox.get(f).overlapsWith(bbox)) | 
					
						
							|  |  |  |             const allLevelsRaw: string[] = allElements.map((f) => f.properties["level"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const levels: Record<string, number> = { "0": 0 } | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             for (const levelDescription of allLevelsRaw) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if (levelDescription === undefined) { | 
					
						
							|  |  |  |                     levels["0"]++ | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 for (const level of TagUtils.LevelsParser(levelDescription)) { | 
					
						
							|  |  |  |                     levels[level] = (levels[level] ?? 0) + 1 | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return levels | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const levelSelect = new FloorLevelInputElement(levelsInView) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         state.globalFilters.data.push({ | 
					
						
							|  |  |  |             filter: { | 
					
						
							|  |  |  |                 currentFilter: undefined, | 
					
						
							|  |  |  |                 state: undefined, | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             id: "level", | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             onNewPoint: undefined, | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         const isShown = levelsInView.map( | 
					
						
							|  |  |  |             (levelsInView) => { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 if (state.locationControl.data.zoom <= 16) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     return false | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 } | 
					
						
							|  |  |  |                 if (Object.keys(levelsInView).length == 1) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                     return false | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 return true | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             }, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             [state.locationControl] | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         function setLevelFilter() { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             console.log( | 
					
						
							|  |  |  |                 "Updating levels filter to ", | 
					
						
							|  |  |  |                 levelSelect.GetValue().data, | 
					
						
							|  |  |  |                 " is shown:", | 
					
						
							|  |  |  |                 isShown.data | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             const filter: GlobalFilter = state.globalFilters.data.find((gf) => gf.id === "level") | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             if (!isShown.data) { | 
					
						
							|  |  |  |                 filter.filter = { | 
					
						
							|  |  |  |                     state: "*", | 
					
						
							|  |  |  |                     currentFilter: undefined, | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 filter.onNewPoint = undefined | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 state.globalFilters.ping() | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             const l = levelSelect.GetValue().data | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             if (l === undefined) { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             let neededLevel: TagsFilter = new RegexTag("level", new RegExp("(^|;)" + l + "(;|$)")) | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             if (l === "0") { | 
					
						
							|  |  |  |                 neededLevel = new Or([neededLevel, new Tag("level", "")]) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             filter.filter = { | 
					
						
							|  |  |  |                 state: l, | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 currentFilter: neededLevel, | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             const t = Translations.t.general.levelSelection | 
					
						
							|  |  |  |             filter.onNewPoint = { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 confirmAddNew: t.confirmLevel.PartialSubs({ level: l }), | 
					
						
							|  |  |  |                 safetyCheck: t.addNewOnLevel.Subs({ level: l }), | 
					
						
							|  |  |  |                 tags: [new Tag("level", l)], | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             state.globalFilters.ping() | 
					
						
							|  |  |  |             return | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         isShown.addCallbackAndRun((shown) => { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             console.log("Is level selector shown?", shown) | 
					
						
							|  |  |  |             setLevelFilter() | 
					
						
							|  |  |  |             if (shown) { | 
					
						
							|  |  |  |                 levelSelect.RemoveClass("invisible") | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 levelSelect.SetClass("invisible") | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         levelsInView.addCallbackAndRun((levels) => { | 
					
						
							|  |  |  |             if (!isShown.data) { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                 return | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             const value = levelSelect.GetValue() | 
					
						
							|  |  |  |             if (!(levels[value.data] === undefined || levels[value.data] === 0)) { | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 return | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |             // Nothing in view. Lets switch to a different level (the level with the most features)
 | 
					
						
							|  |  |  |             let mostElements = 0 | 
					
						
							|  |  |  |             let mostElementsLevel = undefined | 
					
						
							|  |  |  |             for (const level in levels) { | 
					
						
							|  |  |  |                 const count = levels[level] | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |                 if (mostElementsLevel === undefined || mostElements < count) { | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |                     mostElementsLevel = level | 
					
						
							|  |  |  |                     mostElements = count | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |             console.log( | 
					
						
							|  |  |  |                 "Force switching to a different level:", | 
					
						
							|  |  |  |                 mostElementsLevel, | 
					
						
							|  |  |  |                 "as it has", | 
					
						
							|  |  |  |                 mostElements, | 
					
						
							|  |  |  |                 "elements on that floor", | 
					
						
							|  |  |  |                 levels, | 
					
						
							|  |  |  |                 "(old level: " + value.data + ")" | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             value.setData(mostElementsLevel) | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |         }) | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  |         levelSelect.GetValue().addCallback((_) => setLevelFilter()) | 
					
						
							| 
									
										
										
										
											2022-08-06 17:30:23 +02:00
										 |  |  |         super([levelSelect]) | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-09-08 21:40:48 +02:00
										 |  |  | } |