forked from MapComplete/MapComplete
		
	Refactoring: fix background layer switch and hotkeys
This commit is contained in:
		
							parent
							
								
									c2b9a81c51
								
							
						
					
					
						commit
						23b26c4197
					
				
					 5 changed files with 44 additions and 64 deletions
				
			
		| 
						 | 
					@ -23,20 +23,24 @@ export default class BackgroundLayerResetter {
 | 
				
			||||||
        availableLayers.addCallbackAndRunD((availableLayers) => {
 | 
					        availableLayers.addCallbackAndRunD((availableLayers) => {
 | 
				
			||||||
            // We only check on move/on change of the availableLayers
 | 
					            // We only check on move/on change of the availableLayers
 | 
				
			||||||
            const currentBgPolygon: RasterLayerPolygon | undefined = currentBackgroundLayer.data
 | 
					            const currentBgPolygon: RasterLayerPolygon | undefined = currentBackgroundLayer.data
 | 
				
			||||||
 | 
					            if (currentBackgroundLayer === undefined) {
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (availableLayers.findIndex((available) => currentBgPolygon == available) >= 0) {
 | 
					            if (availableLayers.findIndex((available) => currentBgPolygon == available) >= 0) {
 | 
				
			||||||
                // Still available!
 | 
					                // Still available!
 | 
				
			||||||
                return
 | 
					                return
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            console.log("Current layer properties:", currentBgPolygon)
 | 
				
			||||||
            // Oops, we panned out of range for this layer!
 | 
					            // Oops, we panned out of range for this layer!
 | 
				
			||||||
            // What is the 'best' map of the same category which is available?
 | 
					            // What is the 'best' map of the same category which is available?
 | 
				
			||||||
            const availableInSameCat = RasterLayerUtils.SelectBestLayerAccordingTo(
 | 
					            const availableInSameCat = RasterLayerUtils.SelectBestLayerAccordingTo(
 | 
				
			||||||
                availableLayers,
 | 
					                availableLayers,
 | 
				
			||||||
                currentBgPolygon?.properties?.category ?? "osmbasedmap"
 | 
					                currentBgPolygon?.properties?.category
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            console.log("Selecting a different layer:", availableInSameCat.properties.id)
 | 
					            console.log("Selecting a different layer:", availableInSameCat.properties.id)
 | 
				
			||||||
            currentBackgroundLayer.setData(availableInSameCat ?? AvailableRasterLayers.osmCarto)
 | 
					            currentBackgroundLayer.setData(availableInSameCat)
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,7 +71,7 @@ export default class MetaTagging {
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.trace("Recalculating metatags...")
 | 
					        console.debug("Recalculating metatags...")
 | 
				
			||||||
        const metatagsToApply: SimpleMetaTagger[] = []
 | 
					        const metatagsToApply: SimpleMetaTagger[] = []
 | 
				
			||||||
        for (const metatag of SimpleMetaTaggers.metatags) {
 | 
					        for (const metatag of SimpleMetaTaggers.metatags) {
 | 
				
			||||||
            if (metatag.includesDates) {
 | 
					            if (metatag.includesDates) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,7 @@ export class AvailableRasterLayers {
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        geometry: BBox.global.asGeometry(),
 | 
					        geometry: BBox.global.asGeometry(),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static layersAvailableAt(
 | 
					    public static layersAvailableAt(
 | 
				
			||||||
        location: Store<{ lon: number; lat: number }>
 | 
					        location: Store<{ lon: number; lat: number }>
 | 
				
			||||||
    ): Store<RasterLayerPolygon[]> {
 | 
					    ): Store<RasterLayerPolygon[]> {
 | 
				
			||||||
| 
						 | 
					@ -77,44 +78,35 @@ export class AvailableRasterLayers {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class RasterLayerUtils {
 | 
					export class RasterLayerUtils {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Selects, from the given list of available rasterLayerPolygons, a rasterLayer.
 | 
				
			||||||
 | 
					     * This rasterlayer will be of type 'preferredCategory' and will be of the 'best'-layer (if available).
 | 
				
			||||||
 | 
					     * Returns 'undefined' if no such layer is available
 | 
				
			||||||
 | 
					     * @param available
 | 
				
			||||||
 | 
					     * @param preferredCategory
 | 
				
			||||||
 | 
					     * @param ignoreLayer
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
    public static SelectBestLayerAccordingTo(
 | 
					    public static SelectBestLayerAccordingTo(
 | 
				
			||||||
        available: RasterLayerPolygon[],
 | 
					        available: RasterLayerPolygon[],
 | 
				
			||||||
        preferredCategory: string | string[]
 | 
					        preferredCategory: string,
 | 
				
			||||||
 | 
					        ignoreLayer?: RasterLayerPolygon
 | 
				
			||||||
    ): RasterLayerPolygon {
 | 
					    ): RasterLayerPolygon {
 | 
				
			||||||
        available = [...available]
 | 
					        let secondBest: RasterLayerPolygon = undefined
 | 
				
			||||||
 | 
					        for (const rasterLayer of available) {
 | 
				
			||||||
        if (preferredCategory === undefined) {
 | 
					            if (rasterLayer === ignoreLayer) {
 | 
				
			||||||
            return available[0]
 | 
					                continue
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            const p = rasterLayer.properties
 | 
				
			||||||
        let prefered: string[]
 | 
					            if (p.category === preferredCategory) {
 | 
				
			||||||
        if (typeof preferredCategory === "string") {
 | 
					                if (p.best) {
 | 
				
			||||||
            prefered = [preferredCategory]
 | 
					                    return rasterLayer
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            prefered = preferredCategory
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                if (!secondBest) {
 | 
				
			||||||
        for (let i = prefered.length - 1; i >= 0; i--) {
 | 
					                    secondBest = rasterLayer
 | 
				
			||||||
            const category = prefered[i]
 | 
					 | 
				
			||||||
            //Then sort all layers of the preferred type to the top. Stability of the sorting will force a 'best' photo layer on top
 | 
					 | 
				
			||||||
            available.sort((ap, bp) => {
 | 
					 | 
				
			||||||
                const a = ap.properties
 | 
					 | 
				
			||||||
                const b = bp.properties
 | 
					 | 
				
			||||||
                if (a.category === category && b.category === category) {
 | 
					 | 
				
			||||||
                    return 0
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (a.category !== category) {
 | 
					 | 
				
			||||||
                    return 1
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                return -1
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        const best = available.find((l) => l.properties.best)
 | 
					        return secondBest
 | 
				
			||||||
        if (best) {
 | 
					 | 
				
			||||||
            return best
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return available[0]
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ import { QueryParameters } from "../Logic/Web/QueryParameters"
 | 
				
			||||||
import UserRelatedState from "../Logic/State/UserRelatedState"
 | 
					import UserRelatedState from "../Logic/State/UserRelatedState"
 | 
				
			||||||
import LayerConfig from "./ThemeConfig/LayerConfig"
 | 
					import LayerConfig from "./ThemeConfig/LayerConfig"
 | 
				
			||||||
import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler"
 | 
					import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler"
 | 
				
			||||||
import { AvailableRasterLayers, RasterLayerPolygon } from "./RasterLayers"
 | 
					import { AvailableRasterLayers, RasterLayerPolygon, RasterLayerUtils } from "./RasterLayers"
 | 
				
			||||||
import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource"
 | 
					import LayoutSource from "../Logic/FeatureSource/Sources/LayoutSource"
 | 
				
			||||||
import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
 | 
					import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
 | 
				
			||||||
import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropertiesStore"
 | 
					import FeaturePropertiesStore from "../Logic/FeatureSource/Actors/FeaturePropertiesStore"
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,7 @@ import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader"
 | 
				
			||||||
import ShowOverlayRasterLayer from "../UI/Map/ShowOverlayRasterLayer"
 | 
					import ShowOverlayRasterLayer from "../UI/Map/ShowOverlayRasterLayer"
 | 
				
			||||||
import { Utils } from "../Utils"
 | 
					import { Utils } from "../Utils"
 | 
				
			||||||
import { EliCategory } from "./RasterLayerProperties"
 | 
					import { EliCategory } from "./RasterLayerProperties"
 | 
				
			||||||
 | 
					import BackgroundLayerResetter from "../Logic/Actors/BackgroundLayerResetter"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -300,34 +301,16 @@ export default class ThemeViewState implements SpecialVisualizationState {
 | 
				
			||||||
                this.mapProperties.rasterLayer.setData(AvailableRasterLayers.osmCarto)
 | 
					                this.mapProperties.rasterLayer.setData(AvailableRasterLayers.osmCarto)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        const self = this
 | 
					        const setLayerCategory = (category: EliCategory) => {
 | 
				
			||||||
 | 
					            const available = this.availableLayers.data
 | 
				
			||||||
        function setLayerCategory(category: EliCategory) {
 | 
					            const current = this.mapProperties.rasterLayer
 | 
				
			||||||
            const available = self.availableLayers.data
 | 
					            const best = RasterLayerUtils.SelectBestLayerAccordingTo(
 | 
				
			||||||
            const matchingCategoryLayers = available.filter(
 | 
					                available,
 | 
				
			||||||
                (l) => l.properties.category === category
 | 
					                category,
 | 
				
			||||||
 | 
					                current.data
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            const best =
 | 
					            console.log("Best layer for category", category, "is", best.properties.id)
 | 
				
			||||||
                matchingCategoryLayers.find((l) => l.properties.best) ?? matchingCategoryLayers[0]
 | 
					            current.setData(best)
 | 
				
			||||||
            const rasterLayer = self.mapProperties.rasterLayer
 | 
					 | 
				
			||||||
            if (rasterLayer.data !== best) {
 | 
					 | 
				
			||||||
                rasterLayer.setData(best)
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // The current layer is already selected...
 | 
					 | 
				
			||||||
            // We switch the layers again
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (category === "osmbasedmap") {
 | 
					 | 
				
			||||||
                rasterLayer.setData(undefined)
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // search the _second_ best layer
 | 
					 | 
				
			||||||
                const secondbest = matchingCategoryLayers.find(
 | 
					 | 
				
			||||||
                    (l) => l.properties.best && l !== best
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                const secondNotBest = matchingCategoryLayers.find((l) => l !== best)
 | 
					 | 
				
			||||||
                rasterLayer.setData(secondbest ?? secondNotBest)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Hotkeys.RegisterHotkey(
 | 
					        Hotkeys.RegisterHotkey(
 | 
				
			||||||
| 
						 | 
					@ -454,5 +437,6 @@ export default class ThemeViewState implements SpecialVisualizationState {
 | 
				
			||||||
        new ChangeToElementsActor(this.changes, this.featureProperties)
 | 
					        new ChangeToElementsActor(this.changes, this.featureProperties)
 | 
				
			||||||
        new PendingChangesUploader(this.changes, this.selectedElement)
 | 
					        new PendingChangesUploader(this.changes, this.selectedElement)
 | 
				
			||||||
        new SelectedElementTagsUpdater(this)
 | 
					        new SelectedElementTagsUpdater(this)
 | 
				
			||||||
 | 
					        new BackgroundLayerResetter(this.mapProperties.rasterLayer, this.availableLayers)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -343,7 +343,7 @@ export class MapLibreAdaptor implements MapProperties, ExportableMap {
 | 
				
			||||||
            // already the correct background layer, nothing to do
 | 
					            // already the correct background layer, nothing to do
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        await this.awaitStyleIsLoaded()
 | 
					        // await this.awaitStyleIsLoaded()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (background !== this.rasterLayer?.data?.properties) {
 | 
					        if (background !== this.rasterLayer?.data?.properties) {
 | 
				
			||||||
            // User selected another background in the meantime... abort
 | 
					            // User selected another background in the meantime... abort
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue