Refactoring: Load availableMVTVectorLayers dynamically

This commit is contained in:
Pieter Vander Vennet 2025-01-23 12:30:42 +01:00
parent 2b3e3257fd
commit a50c6b531e
14 changed files with 115 additions and 68 deletions

View file

@ -1,6 +1,6 @@
import GeoJsonSource from "./GeoJsonSource" import GeoJsonSource from "./GeoJsonSource"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig" import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import { FeatureSource, UpdatableFeatureSource } from "../FeatureSource" import { FeatureSource, IndexedFeatureSource, UpdatableFeatureSource } from "../FeatureSource"
import { Or } from "../../Tags/Or" import { Or } from "../../Tags/Or"
import FeatureSwitchState from "../../State/FeatureSwitchState" import FeatureSwitchState from "../../State/FeatureSwitchState"
import OverpassFeatureSource from "./OverpassFeatureSource" import OverpassFeatureSource from "./OverpassFeatureSource"
@ -12,13 +12,15 @@ import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeature
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource" import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource"
import DynamicMvtileSource from "../TiledFeatureSource/DynamicMvtTileSource" import DynamicMvtileSource from "../TiledFeatureSource/DynamicMvtTileSource"
import FeatureSourceMerger from "./FeatureSourceMerger" import FeatureSourceMerger from "./FeatureSourceMerger"
import { Feature } from "geojson"
import { OsmFeature } from "../../../Models/OsmFeature"
/** /**
* This source will fetch the needed data from various sources for the given layout. * This source will fetch the needed data from various sources for the given layout.
* *
* Note that special layers (with `source=null` will be ignored) * Note that special layers (with `source=null` will be ignored)
*/ */
export default class ThemeSource extends FeatureSourceMerger { export default class ThemeSource implements IndexedFeatureSource {
/** /**
* Indicates if a data source is loading something * Indicates if a data source is loading something
*/ */
@ -26,6 +28,61 @@ export default class ThemeSource extends FeatureSourceMerger {
public static readonly fromCacheZoomLevel = 15 public static readonly fromCacheZoomLevel = 15
public features: UIEventSource<Feature[]> = new UIEventSource([])
public readonly featuresById: Store<Map<string, Feature>>
private readonly core: Store<ThemeSourceCore>
private readonly addedSources: FeatureSource[] = []
private readonly addedItems: OsmFeature[] = []
constructor(
layers: LayerConfig[],
featureSwitches: FeatureSwitchState,
mapProperties: { bounds: Store<BBox>; zoom: Store<number> },
backend: string,
isDisplayed: (id: string) => Store<boolean>,
mvtAvailableLayers: Store<Set<string>>,
fullNodeDatabaseSource?: FullNodeDatabaseSource
) {
const isLoading = new UIEventSource(true)
this.isLoading = isLoading
const features = this.features = new UIEventSource<Feature[]>([])
const featuresById = this.featuresById = new UIEventSource(new Map())
this.core = mvtAvailableLayers.mapD(mvtAvailableLayers => {
const core = new ThemeSourceCore(layers, featureSwitches, mapProperties, backend, isDisplayed, mvtAvailableLayers, isLoading, fullNodeDatabaseSource)
this.addedSources.forEach(src => core.addSource(src))
this.addedItems.forEach(item => core.addItem(item))
core.features.addCallbackAndRun(data => features.set(data))
core.featuresById.addCallbackAndRun(data => featuresById.set(data))
return core
})
}
public async downloadAll() {
return this.core.data.downloadAll()
}
public addSource(source: FeatureSource) {
this.core.data?.addSource(source)
this.addedSources.push(source)
}
public addItem(obj: OsmFeature) {
this.core.data?.addItem(obj)
this.addedItems.push(obj)
}
}
/**
* This source will fetch the needed data from various sources for the given layout.
*
* Note that special layers (with `source=null` will be ignored)
*/
class ThemeSourceCore extends FeatureSourceMerger {
/** /**
* This source is _only_ triggered when the data is downloaded for CSV export * This source is _only_ triggered when the data is downloaded for CSV export
* @private * @private
@ -40,6 +97,7 @@ export default class ThemeSource extends FeatureSourceMerger {
backend: string, backend: string,
isDisplayed: (id: string) => Store<boolean>, isDisplayed: (id: string) => Store<boolean>,
mvtAvailableLayers: Set<string>, mvtAvailableLayers: Set<string>,
isLoading: UIEventSource<boolean>,
fullNodeDatabaseSource?: FullNodeDatabaseSource fullNodeDatabaseSource?: FullNodeDatabaseSource
) { ) {
const { bounds, zoom } = mapProperties const { bounds, zoom } = mapProperties
@ -58,7 +116,7 @@ export default class ThemeSource extends FeatureSourceMerger {
mapProperties, mapProperties,
{ {
isActive: isDisplayed(layer.id), isActive: isDisplayed(layer.id),
maxAge: layer.maxAgeOfCache, maxAge: layer.maxAgeOfCache
} }
) )
fromCache.set(layer.id, src) fromCache.set(layer.id, src)
@ -66,13 +124,11 @@ export default class ThemeSource extends FeatureSourceMerger {
} }
const mvtSources: UpdatableFeatureSource[] = osmLayers const mvtSources: UpdatableFeatureSource[] = osmLayers
.filter((f) => mvtAvailableLayers.has(f.id)) .filter((f) => mvtAvailableLayers.has(f.id))
.map((l) => ThemeSource.setupMvtSource(l, mapProperties, isDisplayed(l.id))) .map((l) => ThemeSourceCore.setupMvtSource(l, mapProperties, isDisplayed(l.id)))
const nonMvtSources: FeatureSource[] = [] const nonMvtSources: FeatureSource[] = []
const nonMvtLayers: LayerConfig[] = osmLayers.filter((l) => !mvtAvailableLayers.has(l.id)) const nonMvtLayers: LayerConfig[] = osmLayers.filter((l) => !mvtAvailableLayers.has(l.id))
const isLoading = new UIEventSource(false) const osmApiSource = ThemeSourceCore.setupOsmApiSource(
const osmApiSource = ThemeSource.setupOsmApiSource(
osmLayers, osmLayers,
bounds, bounds,
zoom, zoom,
@ -89,7 +145,7 @@ export default class ThemeSource extends FeatureSourceMerger {
nonMvtLayers.map((l) => l.id), nonMvtLayers.map((l) => l.id),
" cannot be fetched from the cache server, defaulting to overpass/OSM-api" " cannot be fetched from the cache server, defaulting to overpass/OSM-api"
) )
overpassSource = ThemeSource.setupOverpass(osmLayers, bounds, zoom, featureSwitches) overpassSource = ThemeSourceCore.setupOverpass(osmLayers, bounds, zoom, featureSwitches)
nonMvtSources.push(overpassSource) nonMvtSources.push(overpassSource)
} }
@ -102,7 +158,7 @@ export default class ThemeSource extends FeatureSourceMerger {
osmApiSource?.isRunning?.addCallbackAndRun(() => setIsLoading()) osmApiSource?.isRunning?.addCallbackAndRun(() => setIsLoading())
const geojsonSources: UpdatableFeatureSource[] = geojsonlayers.map((l) => const geojsonSources: UpdatableFeatureSource[] = geojsonlayers.map((l) =>
ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) ThemeSourceCore.setupGeojsonSource(l, mapProperties, isDisplayed(l.id))
) )
const downloadAll = new OverpassFeatureSource( const downloadAll = new OverpassFeatureSource(
@ -113,11 +169,11 @@ export default class ThemeSource extends FeatureSourceMerger {
overpassUrl: featureSwitches.overpassUrl, overpassUrl: featureSwitches.overpassUrl,
overpassTimeout: featureSwitches.overpassTimeout, overpassTimeout: featureSwitches.overpassTimeout,
overpassMaxZoom: new ImmutableStore(99), overpassMaxZoom: new ImmutableStore(99),
widenFactor: 0, widenFactor: 0
}, },
{ {
ignoreZoom: true, ignoreZoom: true,
isActive: new ImmutableStore(false), isActive: new ImmutableStore(false)
} }
) )
@ -129,7 +185,6 @@ export default class ThemeSource extends FeatureSourceMerger {
downloadAll downloadAll
) )
this.isLoading = isLoading
this._downloadAll = downloadAll this._downloadAll = downloadAll
this._mapBounds = mapProperties.bounds this._mapBounds = mapProperties.bounds
} }
@ -192,7 +247,7 @@ export default class ThemeSource extends FeatureSourceMerger {
backend, backend,
isActive, isActive,
patchRelations: true, patchRelations: true,
fullNodeDatabase, fullNodeDatabase
}) })
} }
@ -224,11 +279,11 @@ export default class ThemeSource extends FeatureSourceMerger {
widenFactor: 1.5, widenFactor: 1.5,
overpassUrl: featureSwitches.overpassUrl, overpassUrl: featureSwitches.overpassUrl,
overpassTimeout: featureSwitches.overpassTimeout, overpassTimeout: featureSwitches.overpassTimeout,
overpassMaxZoom: featureSwitches.overpassMaxZoom, overpassMaxZoom: featureSwitches.overpassMaxZoom
}, },
{ {
padToTiles: zoom.map((zoom) => Math.min(15, zoom + 1)), padToTiles: zoom.map((zoom) => Math.min(15, zoom + 1)),
isActive, isActive
} }
) )
} }

View file

@ -8,8 +8,7 @@ export default class ThemeViewStateHashActor {
private readonly _state: { private readonly _state: {
indexedFeatures: IndexedFeatureSource, indexedFeatures: IndexedFeatureSource,
selectedElement: UIEventSource<Feature>, selectedElement: UIEventSource<Feature>,
guistate: MenuState, guistate: MenuState
previewedImage: UIEventSource<object>
} }
private isUpdatingHash = false private isUpdatingHash = false
@ -39,7 +38,6 @@ export default class ThemeViewStateHashActor {
indexedFeatures: IndexedFeatureSource, indexedFeatures: IndexedFeatureSource,
selectedElement: UIEventSource<Feature>, selectedElement: UIEventSource<Feature>,
guistate: MenuState, guistate: MenuState,
previewedImage: UIEventSource<object>
}) { }) {
this._state = state this._state = state
@ -150,14 +148,8 @@ export default class ThemeViewStateHashActor {
} }
private back() { private back() {
console.log("Going back via hash actor")
const state = this._state const state = this._state
if (state.previewedImage.data) { state.guistate.closeAll()
state.previewedImage.setData(undefined)
return
}
if (state.guistate.closeAll()) {
return
}
state.selectedElement.setData(undefined)
} }
} }

View file

@ -1,5 +1,6 @@
import ThemeConfig from "./ThemeConfig/ThemeConfig" import ThemeConfig from "./ThemeConfig/ThemeConfig"
import { WithImageState } from "./ThemeViewState/WithImageState" import { WithImageState } from "./ThemeViewState/WithImageState"
import { Store } from "../Logic/UIEventSource"
/** /**
* *
@ -10,7 +11,7 @@ import { WithImageState } from "./ThemeViewState/WithImageState"
* It ties up all the needed elements and starts some actors. * It ties up all the needed elements and starts some actors.
*/ */
export default class ThemeViewState extends WithImageState { export default class ThemeViewState extends WithImageState {
constructor(layout: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(layout: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(layout, mvtAvailableLayers) super(layout, mvtAvailableLayers)
} }
} }

View file

@ -35,7 +35,7 @@ export class WithChangesState extends WithLayoutSourceState {
*/ */
readonly hasDataInView: Store<FeatureViewState> readonly hasDataInView: Store<FeatureViewState>
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme, mvtAvailableLayers) super(theme, mvtAvailableLayers)
this.changes = new Changes( this.changes = new Changes(
{ {
@ -82,7 +82,7 @@ export class WithChangesState extends WithLayoutSourceState {
this.perLayerFiltered = this.showNormalDataOn(this.map) this.perLayerFiltered = this.showNormalDataOn(this.map)
this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView
this.toCacheSavers = theme.enableCache ? this.initSaveToLocalStorage() : undefined this.toCacheSavers = theme.enableCache ? this.initSaveToLocalStorage() : undefined

View file

@ -3,6 +3,7 @@ import { MenuState } from "../MenuState"
import Hotkeys from "../../UI/Base/Hotkeys" import Hotkeys from "../../UI/Base/Hotkeys"
import Translations from "../../UI/i18n/Translations" import Translations from "../../UI/i18n/Translations"
import { WithSpecialLayers } from "./WithSpecialLayers" import { WithSpecialLayers } from "./WithSpecialLayers"
import { Store } from "../../Logic/UIEventSource"
/** /**
* Does all things related to: * Does all things related to:
@ -11,9 +12,10 @@ import { WithSpecialLayers } from "./WithSpecialLayers"
export class WithGuiState extends WithSpecialLayers { export class WithGuiState extends WithSpecialLayers {
readonly guistate: MenuState readonly guistate: MenuState
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme, mvtAvailableLayers) super(theme, mvtAvailableLayers)
this.guistate = new MenuState( this.guistate = new MenuState(this.selectedElement)
this.guistate.openMenuIfNeeded(
this.featureSwitches.featureSwitchWelcomeMessage.data, this.featureSwitches.featureSwitchWelcomeMessage.data,
theme.id theme.id
) )

View file

@ -22,7 +22,7 @@ export class WithLayoutSourceState extends WithSelectedElementState {
readonly floors: Store<string[]> readonly floors: Store<string[]>
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme) super(theme)
/* Set up the layout source /* Set up the layout source
* A bit tricky, as this is heavily intertwined with the 'changes'-element, which generates a stream of new and changed features too * A bit tricky, as this is heavily intertwined with the 'changes'-element, which generates a stream of new and changed features too

View file

@ -7,11 +7,12 @@ import { WithVisualFeedbackState } from "./WithVisualFeedbackState"
import { ShowDataLayerOptions } from "../../UI/Map/ShowDataLayerOptions" import { ShowDataLayerOptions } from "../../UI/Map/ShowDataLayerOptions"
import LayerConfig from "../ThemeConfig/LayerConfig" import LayerConfig from "../ThemeConfig/LayerConfig"
import ShowDataLayer from "../../UI/Map/ShowDataLayer" import ShowDataLayer from "../../UI/Map/ShowDataLayer"
import { Store } from "../../Logic/UIEventSource"
export class WithSearchState extends WithVisualFeedbackState { export class WithSearchState extends WithVisualFeedbackState {
public readonly searchState: SearchState public readonly searchState: SearchState
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme, mvtAvailableLayers) super(theme, mvtAvailableLayers)
this.searchState = new SearchState(this) this.searchState = new SearchState(this)
this.initHotkeysSearch() this.initHotkeysSearch()
@ -48,20 +49,12 @@ export class WithSearchState extends WithVisualFeedbackState {
) )
Hotkeys.RegisterHotkey({ nomod: "Escape", onUp: true }, docs.closeSidebar, () => { Hotkeys.RegisterHotkey({ nomod: "Escape", onUp: true }, docs.closeSidebar, () => {
if (this.previewedImage.data !== undefined) {
this.previewedImage.setData(undefined) if (this.guistate.closeAll()) {
return
}
if (this.selectedElement.data) {
this.selectedElement.setData(undefined)
return return
} }
if (this.searchState.showSearchDrawer.data) { if (this.searchState.showSearchDrawer.data) {
this.searchState.showSearchDrawer.set(false) this.searchState.showSearchDrawer.set(false)
return
}
if (this.guistate.closeAll()) {
return
} }
Zoomcontrol.resetzoom() Zoomcontrol.resetzoom()
this.focusOnMap() this.focusOnMap()

View file

@ -28,11 +28,10 @@ export class WithSelectedElementState extends UserMapFeatureswitchState {
}) })
this.mapProperties.lastClickLocation.addCallbackD((lastClick) => { this.mapProperties.lastClickLocation.addCallbackD((lastClick) => {
if (lastClick.mode !== "left" || !lastClick.nearestFeature) { if (lastClick.mode !== "left") {
return return
} }
const f = lastClick.nearestFeature this.setSelectedElement(lastClick.nearestFeature)
this.setSelectedElement(f)
}) })
@ -67,7 +66,7 @@ export class WithSelectedElementState extends UserMapFeatureswitchState {
const current = this.selectedElement.data const current = this.selectedElement.data
if ( if (
current?.properties?.id !== undefined && current?.properties?.id !== undefined &&
current.properties.id === feature.properties.id current.properties.id === feature?.properties?.id
) { ) {
console.log("Not setting selected, same id", current, feature) console.log("Not setting selected, same id", current, feature)
return // already set return // already set

View file

@ -14,7 +14,7 @@ import { LayerConfigJson } from "../ThemeConfig/Json/LayerConfigJson"
import last_click_layerconfig from "../../assets/generated/layers/last_click.json" import last_click_layerconfig from "../../assets/generated/layers/last_click.json"
import { GeoOperations } from "../../Logic/GeoOperations" import { GeoOperations } from "../../Logic/GeoOperations"
import summaryLayer from "../../assets/generated/layers/summary.json" import summaryLayer from "../../assets/generated/layers/summary.json"
import { UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import NearbyFeatureSource from "../../Logic/FeatureSource/Sources/NearbyFeatureSource" import NearbyFeatureSource from "../../Logic/FeatureSource/Sources/NearbyFeatureSource"
import { import {
SummaryTileSource, SummaryTileSource,
@ -43,7 +43,7 @@ export class WithSpecialLayers extends WithChangesState {
readonly visualFeedbackViewportBounds: UIEventSource<BBox> = new UIEventSource<BBox>(undefined) readonly visualFeedbackViewportBounds: UIEventSource<BBox> = new UIEventSource<BBox>(undefined)
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme, mvtAvailableLayers) super(theme, mvtAvailableLayers)
this.favourites = new FavouritesFeatureSource(this) this.favourites = new FavouritesFeatureSource(this)
@ -64,12 +64,12 @@ export class WithSpecialLayers extends WithChangesState {
this.featureSummary = this.setupSummaryLayer() this.featureSummary = this.setupSummaryLayer()
this.initActorsSpecialLayers() this.initActorsSpecialLayers()
this.drawSelectedElement()
this.drawSpecialLayers() this.drawSpecialLayers()
this.drawLastClick() this.drawLastClick()
// Note: the lock-range is handled by UserMapFeatureSwitchState // Note: the lock-range is handled by UserMapFeatureSwitchState
{ {
// Activate metatagging for the 'current_view' layer // Activate metatagging for the 'current_view' layer
console.log(">>>", this.layerState.filteredLayers)
const currentViewLayer = this.layerState.filteredLayers.get("current_view")?.layerDef const currentViewLayer = this.layerState.filteredLayers.get("current_view")?.layerDef
if (currentViewLayer?.tagRenderings?.length > 0) { if (currentViewLayer?.tagRenderings?.length > 0) {
const params = MetaTagging.createExtraFuncParams(this) const params = MetaTagging.createExtraFuncParams(this)
@ -163,8 +163,10 @@ export class WithSpecialLayers extends WithChangesState {
}) })
) )
// show last click = new point/note marker // show last click = new point/note marker
const features = new StaticFeatureSource(lastClickFiltered)
this.featureProperties.trackFeatureSource(features)
new ShowDataLayer(this.map, { new ShowDataLayer(this.map, {
features: new StaticFeatureSource(lastClickFiltered), features,
layer: lastClickLayerConfig, layer: lastClickLayerConfig,
onClick: (feature) => { onClick: (feature) => {
if (this.mapProperties.zoom.data >= Constants.minZoomLevelToAddNewPoint) { if (this.mapProperties.zoom.data >= Constants.minZoomLevelToAddNewPoint) {
@ -179,6 +181,13 @@ export class WithSpecialLayers extends WithChangesState {
}) })
} }
private drawSelectedElement() {
const src = new StaticFeatureSource(
this.selectedElement.map((f) => (f === undefined ? [] : [f]))
)
ShowDataLayer.showMultipleLayers(this.map, src, this.theme.layers)
}
private drawSpecialLayers() { private drawSpecialLayers() {
type AddedByDefaultTypes = (typeof Constants.added_by_default)[number] type AddedByDefaultTypes = (typeof Constants.added_by_default)[number]
@ -187,6 +196,7 @@ export class WithSpecialLayers extends WithChangesState {
| "last_click" // handled by this.drawLastClick() | "last_click" // handled by this.drawLastClick()
| "summary" // handled by setupSummaryLayer | "summary" // handled by setupSummaryLayer
| "range" // handled by UserMapFeatureSwitchState | "range" // handled by UserMapFeatureSwitchState
| "selected_element" // handled by this.drawSelectedElement
> >
const empty = [] const empty = []
/** /**
@ -199,10 +209,7 @@ export class WithSpecialLayers extends WithChangesState {
gps_track: this.geolocation.historicalUserLocationsTrack, gps_track: this.geolocation.historicalUserLocationsTrack,
current_view: this.currentView, current_view: this.currentView,
favourite: this.favourites, favourite: this.favourites,
geocoded_image: new StaticFeatureSource(this.geocodedImages), geocoded_image: new StaticFeatureSource(this.geocodedImages)
selected_element: new StaticFeatureSource(
this.selectedElement.map((f) => (f === undefined ? empty : [f]))
)
} }

View file

@ -1,5 +1,5 @@
import ThemeConfig from "../ThemeConfig/ThemeConfig" import ThemeConfig from "../ThemeConfig/ThemeConfig"
import { UIEventSource } from "../../Logic/UIEventSource" import { Store, UIEventSource } from "../../Logic/UIEventSource"
import Hotkeys from "../../UI/Base/Hotkeys" import Hotkeys from "../../UI/Base/Hotkeys"
import Translations from "../../UI/i18n/Translations" import Translations from "../../UI/i18n/Translations"
import ThemeViewState from "../ThemeViewState" import ThemeViewState from "../ThemeViewState"
@ -11,7 +11,7 @@ export class WithVisualFeedbackState extends ThemeViewState {
*/ */
public readonly visualFeedback: UIEventSource<boolean> = new UIEventSource<boolean>(false) public readonly visualFeedback: UIEventSource<boolean> = new UIEventSource<boolean>(false)
constructor(theme: ThemeConfig, mvtAvailableLayers: Set<string>) { constructor(theme: ThemeConfig, mvtAvailableLayers: Store<Set<string>>) {
super(theme, mvtAvailableLayers) super(theme, mvtAvailableLayers)
this.initHotkeysVisualFeedback() this.initHotkeysVisualFeedback()
@ -72,7 +72,7 @@ export class WithVisualFeedbackState extends ThemeViewState {
if (this.selectedElement.data !== undefined) { if (this.selectedElement.data !== undefined) {
return false return false
} }
if (this.guistate.isSomethingOpen() || this.previewedImage.data !== undefined) { if (this.guistate.isSomethingOpen()) {
return return
} }
if ( if (

View file

@ -9,7 +9,7 @@
export let fullscreen: boolean = false export let fullscreen: boolean = false
export let bodyPadding = "p-4 md:p-5 " export let bodyPadding = "p-4 md:p-5 "
export let shown: UIEventSource<boolean> export let shown: UIEventSource<boolean>
export let dismissable = true export let dismissable = false
/** /**
* Default: 50 * Default: 50
*/ */

View file

@ -16,7 +16,6 @@ import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFea
import FilteredLayer from "../../Models/FilteredLayer" import FilteredLayer from "../../Models/FilteredLayer"
import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource" import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource"
import { TagsFilter } from "../../Logic/Tags/TagsFilter" import { TagsFilter } from "../../Logic/Tags/TagsFilter"
import { featureEach } from "@turf/turf"
class PointRenderingLayer { class PointRenderingLayer {
private readonly _config: PointRenderingConfig private readonly _config: PointRenderingConfig
@ -542,7 +541,7 @@ export default class ShowDataLayer {
mlmap: UIEventSource<MlMap>, mlmap: UIEventSource<MlMap>,
features: FeatureSource, features: FeatureSource,
layers: LayerConfig[], layers: LayerConfig[],
options?: Partial<ShowDataLayerOptions> options?: Partial<Omit<ShowDataLayerOptions, "features" | "layer">>
) { ) {
const perLayer: PerLayerFeatureSourceSplitter<FeatureSourceForLayer> = const perLayer: PerLayerFeatureSourceSplitter<FeatureSourceForLayer> =
new PerLayerFeatureSourceSplitter( new PerLayerFeatureSourceSplitter(

View file

@ -14,7 +14,6 @@ import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader" import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader"
import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager" import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager"
import FavouritesFeatureSource from "../Logic/FeatureSource/Sources/FavouritesFeatureSource" import FavouritesFeatureSource from "../Logic/FeatureSource/Sources/FavouritesFeatureSource"
import { ProvidedImage } from "../Logic/ImageProviders/ImageProvider"
import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler" import GeoLocationHandler from "../Logic/Actors/GeoLocationHandler"
import ThemeSource from "../Logic/FeatureSource/Sources/ThemeSource" import ThemeSource from "../Logic/FeatureSource/Sources/ThemeSource"
import { Map as MlMap } from "maplibre-gl" import { Map as MlMap } from "maplibre-gl"
@ -71,7 +70,6 @@ export interface SpecialVisualizationState {
readonly imageUploadManager: ImageUploadManager readonly imageUploadManager: ImageUploadManager
readonly previewedImage: UIEventSource<ProvidedImage>
readonly nearbyImageSearcher: CombinedFetcher readonly nearbyImageSearcher: CombinedFetcher
readonly geolocation: GeoLocationHandler readonly geolocation: GeoLocationHandler
readonly geocodedImages: UIEventSource<Feature[]> readonly geocodedImages: UIEventSource<Feature[]>

View file

@ -8,6 +8,7 @@ import { Utils } from "./Utils"
import Constants from "./Models/Constants" import Constants from "./Models/Constants"
import ArrowDownTray from "@babeard/svelte-heroicons/mini/ArrowDownTray" import ArrowDownTray from "@babeard/svelte-heroicons/mini/ArrowDownTray"
import { WithSearchState } from "./Models/ThemeViewState/WithSearchState" import { WithSearchState } from "./Models/ThemeViewState/WithSearchState"
import { UIEventSource } from "./Logic/UIEventSource"
function webgl_support() { function webgl_support() {
try { try {
@ -48,11 +49,11 @@ async function main() {
if (!webgl_support()) { if (!webgl_support()) {
throw "WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this." throw "WebGL is not supported or not enabled. This is essential for MapComplete to function, please enable this."
} }
const [theme, availableLayers] = await Promise.all([ const availableLayers = UIEventSource.FromPromise(getAvailableLayers())
DetermineTheme.getTheme(), const theme = await DetermineTheme.getTheme()
await getAvailableLayers(), availableLayers.addCallbackAndRunD(availableLayers => {
]) console.log("The available layers on server are", Array.from(availableLayers))
console.log("The available layers on server are", Array.from(availableLayers)) })
const state = new WithSearchState(theme, availableLayers) const state = new WithSearchState(theme, availableLayers)
const target = document.getElementById("maindiv") const target = document.getElementById("maindiv")
const childs = Array.from(target.children) const childs = Array.from(target.children)