forked from MapComplete/MapComplete
More refactoring
This commit is contained in:
parent
6890c5189e
commit
c2d477c97a
12 changed files with 91 additions and 73 deletions
|
@ -25,20 +25,18 @@ import ScrollableFullScreen from "./UI/Base/ScrollableFullScreen";
|
||||||
import Translations from "./UI/i18n/Translations";
|
import Translations from "./UI/i18n/Translations";
|
||||||
import MapControlButton from "./UI/MapControlButton";
|
import MapControlButton from "./UI/MapControlButton";
|
||||||
import LZString from "lz-string";
|
import LZString from "lz-string";
|
||||||
import AllKnownLayers from "./Customizations/AllKnownLayers";
|
|
||||||
import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers";
|
import AvailableBaseLayers from "./Logic/Actors/AvailableBaseLayers";
|
||||||
import LeftControls from "./UI/BigComponents/LeftControls";
|
import LeftControls from "./UI/BigComponents/LeftControls";
|
||||||
import RightControls from "./UI/BigComponents/RightControls";
|
import RightControls from "./UI/BigComponents/RightControls";
|
||||||
import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson";
|
import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson";
|
||||||
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
|
import LayoutConfig from "./Models/ThemeConfig/LayoutConfig";
|
||||||
import LayerConfig from "./Models/ThemeConfig/LayerConfig";
|
|
||||||
import Minimap from "./UI/Base/Minimap";
|
import Minimap from "./UI/Base/Minimap";
|
||||||
import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler";
|
import SelectedFeatureHandler from "./Logic/Actors/SelectedFeatureHandler";
|
||||||
import Combine from "./UI/Base/Combine";
|
import Combine from "./UI/Base/Combine";
|
||||||
import {SubtleButton} from "./UI/Base/SubtleButton";
|
import {SubtleButton} from "./UI/Base/SubtleButton";
|
||||||
import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo";
|
import ShowTileInfo from "./UI/ShowDataLayer/ShowTileInfo";
|
||||||
import {Tiles} from "./Models/TileRange";
|
import {Tiles} from "./Models/TileRange";
|
||||||
import {TileHierarchyAggregator} from "./UI/ShowDataLayer/PerTileCountAggregator";
|
import {TileHierarchyAggregator} from "./UI/ShowDataLayer/TileHierarchyAggregator";
|
||||||
import FilterConfig from "./Models/ThemeConfig/FilterConfig";
|
import FilterConfig from "./Models/ThemeConfig/FilterConfig";
|
||||||
import FilteredLayer from "./Models/FilteredLayer";
|
import FilteredLayer from "./Models/FilteredLayer";
|
||||||
import {BBox} from "./Logic/BBox";
|
import {BBox} from "./Logic/BBox";
|
||||||
|
@ -435,6 +433,7 @@ export class InitUiElements {
|
||||||
features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements),
|
features: clusterCounter.getCountsForZoom(State.state.locationControl, State.state.layoutToUse.clustering.minNeededElements),
|
||||||
leafletMap: State.state.leafletMap,
|
leafletMap: State.state.leafletMap,
|
||||||
layerToShow: ShowTileInfo.styling,
|
layerToShow: ShowTileInfo.styling,
|
||||||
|
enablePopups: false
|
||||||
})
|
})
|
||||||
|
|
||||||
State.state.featurePipeline = new FeaturePipeline(
|
State.state.featurePipeline = new FeaturePipeline(
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default class TitleHandler {
|
||||||
if (layer.source.osmTags.matchesProperties(tags)) {
|
if (layer.source.osmTags.matchesProperties(tags)) {
|
||||||
const tagsSource = state.allElements.getEventSourceById(tags.id)
|
const tagsSource = state.allElements.getEventSourceById(tags.id)
|
||||||
const title = new TagRenderingAnswer(tagsSource, layer.title)
|
const title = new TagRenderingAnswer(tagsSource, layer.title)
|
||||||
return new Combine([defaultTitle, " | ", title]).ConstructElement().innerText;
|
return new Combine([defaultTitle, " | ", title]).ConstructElement()?.innerText ?? defaultTitle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return defaultTitle
|
return defaultTitle
|
||||||
|
|
|
@ -39,11 +39,10 @@ export class ElementStorage {
|
||||||
}
|
}
|
||||||
|
|
||||||
getEventSourceById(elementId): UIEventSource<any> {
|
getEventSourceById(elementId): UIEventSource<any> {
|
||||||
if (this._elements.has(elementId)) {
|
if(elementId === undefined){
|
||||||
return this._elements.get(elementId);
|
return undefined;
|
||||||
}
|
}
|
||||||
console.error("Can not find eventsource with id ", elementId);
|
return this._elements.get(elementId);
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
has(id) {
|
has(id) {
|
||||||
|
|
|
@ -62,11 +62,35 @@ export default class FeaturePipeline {
|
||||||
/**
|
/**
|
||||||
* Maps tileid onto last download moment
|
* Maps tileid onto last download moment
|
||||||
*/
|
*/
|
||||||
const tileFreshnesses = new Map<number, Date>()
|
const tileFreshnesses = new UIEventSource<Map<number, Date>>(new Map<number, Date>())
|
||||||
const osmSourceZoomLevel = 14
|
const osmSourceZoomLevel = 14
|
||||||
const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12))
|
const useOsmApi = state.locationControl.map(l => l.zoom > (state.overpassMaxZoom.data ?? 12))
|
||||||
this.relationTracker = new RelationsTracker()
|
this.relationTracker = new RelationsTracker()
|
||||||
|
|
||||||
|
console.log("Tilefreshnesses are", tileFreshnesses.data)
|
||||||
|
const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000));
|
||||||
|
const neededTilesFromOsm = state.currentBounds.map(bbox => {
|
||||||
|
if (bbox === undefined) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const range = bbox.containingTileRange(osmSourceZoomLevel)
|
||||||
|
const tileIndexes = []
|
||||||
|
if (range.total > 100) {
|
||||||
|
// Too much tiles!
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
Tiles.MapRange(range, (x, y) => {
|
||||||
|
const i = Tiles.tile_index(osmSourceZoomLevel, x, y);
|
||||||
|
if (tileFreshnesses.data.get(i) > oldestAllowedDate) {
|
||||||
|
console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available")
|
||||||
|
// The cached tiles contain decently fresh data
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tileIndexes.push(i)
|
||||||
|
})
|
||||||
|
return tileIndexes
|
||||||
|
}, [tileFreshnesses])
|
||||||
|
|
||||||
const updater = new OverpassFeatureSource(state,
|
const updater = new OverpassFeatureSource(state,
|
||||||
{
|
{
|
||||||
relationTracker: this.relationTracker,
|
relationTracker: this.relationTracker,
|
||||||
|
@ -75,8 +99,9 @@ export default class FeaturePipeline {
|
||||||
// This callback contains metadata of the overpass call
|
// This callback contains metadata of the overpass call
|
||||||
const range = bbox.containingTileRange(osmSourceZoomLevel)
|
const range = bbox.containingTileRange(osmSourceZoomLevel)
|
||||||
Tiles.MapRange(range, (x, y) => {
|
Tiles.MapRange(range, (x, y) => {
|
||||||
tileFreshnesses.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness)
|
tileFreshnesses.data.set(Tiles.tile_index(osmSourceZoomLevel, x, y), freshness)
|
||||||
})
|
})
|
||||||
|
tileFreshnesses.ping();
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -137,17 +162,17 @@ export default class FeaturePipeline {
|
||||||
}, state)
|
}, state)
|
||||||
|
|
||||||
localStorage.tileFreshness.forEach((value, key) => {
|
localStorage.tileFreshness.forEach((value, key) => {
|
||||||
if (tileFreshnesses.has(key)) {
|
if (tileFreshnesses.data.has(key)) {
|
||||||
const previous = tileFreshnesses.get(key)
|
const previous = tileFreshnesses.data.get(key)
|
||||||
if (value < previous) {
|
if (value < previous) {
|
||||||
tileFreshnesses.set(key, value)
|
tileFreshnesses.data.set(key, value)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tileFreshnesses.set(key, value)
|
tileFreshnesses.data.set(key, value)
|
||||||
}
|
}
|
||||||
|
tileFreshnesses.ping()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,30 +203,7 @@ export default class FeaturePipeline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Tilefreshnesses are", tileFreshnesses)
|
|
||||||
const oldestAllowedDate = new Date(new Date().getTime() - (60 * 60 * 24 * 30 * 1000));
|
|
||||||
|
|
||||||
const neededTilesFromOsm = state.currentBounds.map(bbox => {
|
|
||||||
if (bbox === undefined) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const range = bbox.containingTileRange(osmSourceZoomLevel)
|
|
||||||
const tileIndexes = []
|
|
||||||
if (range.total > 100) {
|
|
||||||
// Too much tiles!
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
Tiles.MapRange(range, (x, y) => {
|
|
||||||
const i = Tiles.tile_index(osmSourceZoomLevel, x, y);
|
|
||||||
if (tileFreshnesses.get(i) > oldestAllowedDate) {
|
|
||||||
console.debug("Skipping tile", osmSourceZoomLevel, x, y, "as a decently fresh one is available")
|
|
||||||
// The cached tiles contain decently fresh data
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tileIndexes.push(i)
|
|
||||||
})
|
|
||||||
return tileIndexes
|
|
||||||
})
|
|
||||||
|
|
||||||
const osmFeatureSource = new OsmFeatureSource({
|
const osmFeatureSource = new OsmFeatureSource({
|
||||||
isActive: useOsmApi,
|
isActive: useOsmApi,
|
||||||
|
|
|
@ -28,8 +28,9 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
|
||||||
|
|
||||||
this.layer = upstream.layer;
|
this.layer = upstream.layer;
|
||||||
const layer = upstream.layer;
|
const layer = upstream.layer;
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
|
|
||||||
const features: { feature: any; freshness: Date }[] = upstream.features.data;
|
const features: { feature: any; freshness: Date }[] = upstream.features.data;
|
||||||
const newFeatures = features.filter((f) => {
|
const newFeatures = features.filter((f) => {
|
||||||
if (
|
if (
|
||||||
|
@ -60,11 +61,6 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!layer.isDisplayed) {
|
|
||||||
// The layer itself is either disabled or hidden due to zoom constraints
|
|
||||||
// We should return true, but it might still match some other layer
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -75,20 +71,8 @@ export default class FilteringFeatureSource implements FeatureSourceForLayer, Ti
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|
||||||
layer.isDisplayed.addCallback(isShown => {
|
|
||||||
if (isShown) {
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
self.features.setData([])
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
layer.appliedFilters.addCallback(_ => {
|
layer.appliedFilters.addCallback(_ => {
|
||||||
if (!layer.isDisplayed.data) {
|
|
||||||
// Currently not shown.
|
|
||||||
// Note that a change in 'isSHown' will trigger an update as well, so we don't have to watch it another time
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
update()
|
update()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default class MetaTagging {
|
||||||
}
|
}
|
||||||
somethingChanged = somethingChanged || metatag.applyMetaTagsOnFeature(feature, freshness)
|
somethingChanged = somethingChanged || metatag.applyMetaTagsOnFeature(feature, freshness)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e)
|
console.error("Could not calculate metatag for ", metatag.keys.join(","), ":", e, e.stack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -149,14 +149,13 @@ export class Changes {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyAction(action: OsmChangeAction) {
|
public async applyAction(action: OsmChangeAction): Promise<void> {
|
||||||
action.Perform(this).then(changes => {
|
const changes = await action.Perform(this)
|
||||||
console.log("Received changes:", changes)
|
console.log("Received changes:", changes)
|
||||||
this.pendingChanges.data.push(...changes);
|
this.pendingChanges.data.push(...changes);
|
||||||
this.pendingChanges.ping();
|
this.pendingChanges.ping();
|
||||||
this.allChanges.data.push(...changes)
|
this.allChanges.data.push(...changes)
|
||||||
this.allChanges.ping()
|
this.allChanges.ping()
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||||
|
|
|
@ -19,6 +19,9 @@ export class RegexTag extends TagsFilter {
|
||||||
if (fromTag === undefined) {
|
if (fromTag === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(typeof fromTag === "number"){
|
||||||
|
fromTag = "" + fromTag;
|
||||||
|
}
|
||||||
if (typeof possibleRegex === "string") {
|
if (typeof possibleRegex === "string") {
|
||||||
return fromTag === possibleRegex;
|
return fromTag === possibleRegex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
||||||
|
|
||||||
export default class Constants {
|
export default class Constants {
|
||||||
|
|
||||||
public static vNumber = "0.10.0-alpha-3";
|
public static vNumber = "0.10.0-alpha-4";
|
||||||
public static ImgurApiKey = '7070e7167f0a25a'
|
public static ImgurApiKey = '7070e7167f0a25a'
|
||||||
|
|
||||||
// The user journey states thresholds when a new feature gets unlocked
|
// The user journey states thresholds when a new feature gets unlocked
|
||||||
|
|
36
assets/layers/cluster_style/cluster_style.json
Normal file
36
assets/layers/cluster_style/cluster_style.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"id": "cluster_style",
|
||||||
|
"description": "The style for the clustering in all themes.",
|
||||||
|
"source": {
|
||||||
|
"osmTags": "tileId~*"
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"render": "#3c3",
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "count>200",
|
||||||
|
"then": "#f33"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "count>100",
|
||||||
|
"then": "#c93"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "count>50",
|
||||||
|
"then": "#cc3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"render": "1"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"render": "<div class='rounded-full text-xl font-bold' style='width: 2rem; height: 2rem; background: white'>{count}</div>",
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "count>99",
|
||||||
|
"then": "<div class='rounded-full text-xl font-bold flex flex-col' style='width: 2.5rem; height: 2.5rem; background: white'>>99</div>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
"nl": "Een kaart om toeristisch relevante info op aan te duiden"
|
"nl": "Een kaart om toeristisch relevante info op aan te duiden"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"nl": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen"
|
"nl": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:<br/><ul><li>Eetgelegenheden</li><li>Cafés en bars</li><li>(Fiets)oplaadpunten</li><li>Fietspompen, fietserverhuur en fietswinkels</li><li>Uitkijktorens</li><li>...</li></ul> Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.<br/><br/>Met de steun van Toerisme Vlaanderen<img src='./assets/themes/toerisme_vlaanderen/logo.png' />"
|
||||||
},
|
},
|
||||||
"icon": "./assets/svg/star.svg",
|
"icon": "./assets/svg/star.svg",
|
||||||
"startZoom": 8,
|
"startZoom": 8,
|
||||||
|
@ -39,9 +39,5 @@
|
||||||
"binocular",
|
"binocular",
|
||||||
"observation_tower"
|
"observation_tower"
|
||||||
],
|
],
|
||||||
"overiddeAll": {
|
|
||||||
"minZoomVisible": 0
|
|
||||||
},
|
|
||||||
|
|
||||||
"hideFromOverview": true
|
"hideFromOverview": true
|
||||||
}
|
}
|
|
@ -1008,7 +1008,7 @@
|
||||||
"title": "Surveillance under Surveillance"
|
"title": "Surveillance under Surveillance"
|
||||||
},
|
},
|
||||||
"toerisme_vlaanderen": {
|
"toerisme_vlaanderen": {
|
||||||
"description": "Op deze kaart kan je info zien voor toeristen en zelf aanpasingen maken, zichtbaar voor iedereen",
|
"description": "Op deze kaart kan je info zien die relevant is voor toerisme, zoals:<br/><ul><li>Eetgelegenheden</li><li>Cafés en bars</li><li>(Fiets)oplaadpunten</li><li>Fietspompen, fietserverhuur en fietswinkels</li><li>Uitkijktorens</li><li>...</li></ul> Zie je fouten op de kaart? Dan kan je zelf makkelijk aanpasingen maken, die zichtbaar zijn voor iedereen. Hiervoor dien je een gratis OpenStreetMap account voor te maken.<br/><br/>Met de steun van Toerisme Vlaanderen<img src='./assets/themes/toerisme_vlaanderen/logo.png' />",
|
||||||
"shortDescription": "Een kaart om toeristisch relevante info op aan te duiden",
|
"shortDescription": "Een kaart om toeristisch relevante info op aan te duiden",
|
||||||
"title": "Toeristisch relevante info"
|
"title": "Toeristisch relevante info"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue