More refactoring

This commit is contained in:
pietervdvn 2021-09-29 01:12:29 +02:00
parent 231f4f2c97
commit 6890c5189e
12 changed files with 52 additions and 59 deletions

View file

@ -25,7 +25,9 @@ export default class BackgroundSelector extends VariableUiElement {
if (baseLayers.length <= 1) { if (baseLayers.length <= 1) {
return undefined; return undefined;
} }
return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer) return new DropDown(Translations.t.general.backgroundMap.Clone(), baseLayers, State.state.backgroundLayer, {
select_class: 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full'
})
} }
) )
) )

View file

@ -20,7 +20,7 @@ export class DownloadPanel extends Toggle {
constructor() { constructor() {
const state: { const state: {
featurePipeline: FeaturePipeline, featurePipeline: FeaturePipeline,
layoutToUse: UIEventSource<LayoutConfig>, layoutToUse: LayoutConfig,
currentBounds: UIEventSource<BBox> currentBounds: UIEventSource<BBox>
} = State.state } = State.state

View file

@ -31,14 +31,14 @@ export default class ImportButton extends Toggle {
const button = new SubtleButton(imageUrl, message) const button = new SubtleButton(imageUrl, message)
button.onClick(() => { button.onClick(async () => {
if (isImported.data) { if (isImported.data) {
return return
} }
originalTags.data["_imported"] = "yes" originalTags.data["_imported"] = "yes"
originalTags.ping() // will set isImported as per its definition originalTags.ping() // will set isImported as per its definition
const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon) const newElementAction = new CreateNewNodeAction(newTags.data, lat, lon)
State.state.changes.applyAction(newElementAction) await State.state.changes.applyAction(newElementAction)
State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get(
newElementAction.newElementId newElementAction.newElementId
)) ))

View file

@ -56,9 +56,9 @@ export default class SimpleAddUI extends Toggle {
const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset) const presetsOverview = SimpleAddUI.CreateAllPresetsPanel(selectedPreset)
function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) { async function createNewPoint(tags: any[], location: { lat: number, lon: number }, snapOntoWay?: OsmWay) {
const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay}) const newElementAction = new CreateNewNodeAction(tags, location.lat, location.lon, {snapOnto: snapOntoWay})
State.state.changes.applyAction(newElementAction) await State.state.changes.applyAction(newElementAction)
selectedPreset.setData(undefined) selectedPreset.setData(undefined)
isShown.setData(false) isShown.setData(false)
State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get( State.state.selectedElement.setData(State.state.allElements.ContainingFeatures.get(

View file

@ -15,15 +15,15 @@ export default class DeleteImage extends Toggle {
const isDeletedBadge = Translations.t.image.isDeleted.Clone() const isDeletedBadge = Translations.t.image.isDeleted.Clone()
.SetClass("rounded-full p-1") .SetClass("rounded-full p-1")
.SetStyle("color:white;background:#ff8c8c") .SetStyle("color:white;background:#ff8c8c")
.onClick(() => { .onClick(async() => {
State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data)) await State.state?.changes?.applyAction(new ChangeTagAction(tags.data.id, new Tag(key, oldValue), tags.data))
}); });
const deleteButton = Translations.t.image.doDelete.Clone() const deleteButton = Translations.t.image.doDelete.Clone()
.SetClass("block w-full pl-4 pr-4") .SetClass("block w-full pl-4 pr-4")
.SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;") .SetStyle("color:white;background:#ff8c8c; border-top-left-radius:30rem; border-top-right-radius: 30rem;")
.onClick(() => { .onClick( async() => {
State.state?.changes?.applyAction( await State.state?.changes?.applyAction(
new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data) new ChangeTagAction(tags.data.id, new Tag(key, ""), tags.data)
) )
}); });

View file

@ -29,10 +29,10 @@ export class ImageUploadFlow extends Toggle {
key = imagePrefix + ":" + freeIndex; key = imagePrefix + ":" + freeIndex;
} }
console.log("Adding image:" + key, url); console.log("Adding image:" + key, url);
State.state.changes Promise.resolve(State.state.changes
.applyAction(new ChangeTagAction( .applyAction(new ChangeTagAction(
tags.id, new Tag(key, url), tagsSource.data tags.id, new Tag(key, url), tagsSource.data
)) )))
}) })

View file

@ -47,7 +47,7 @@ export class DropDown<T> extends InputElement<T> {
} }
options = options ?? {} options = options ?? {}
options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200 w-full' options.select_class = options.select_class ?? 'bg-indigo-100 p-1 rounded hover:bg-indigo-200'
{ {

View file

@ -51,14 +51,14 @@ export default class DeleteWizard extends Toggle {
const confirm = new UIEventSource<boolean>(false) const confirm = new UIEventSource<boolean>(false)
function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) { async function softDelete(reason: string, tagsToApply: { k: string, v: string }[]) {
if (reason !== undefined) { if (reason !== undefined) {
tagsToApply.splice(0, 0, { tagsToApply.splice(0, 0, {
k: "fixme", k: "fixme",
v: `A mapcomplete user marked this feature to be deleted (${reason})` v: `A mapcomplete user marked this feature to be deleted (${reason})`
}) })
} }
(State.state?.changes ?? new Changes()) await (State.state?.changes ?? new Changes())
.applyAction(new ChangeTagAction( .applyAction(new ChangeTagAction(
id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data id, new And(tagsToApply.map(kv => new Tag(kv.k, kv.v))), tagsSource.data
)) ))

View file

@ -58,10 +58,10 @@ export default class TagRenderingQuestion extends Combine {
console.error("MultiAnswer failed - probably not a single option was possible", configuration) console.error("MultiAnswer failed - probably not a single option was possible", configuration)
throw "MultiAnswer failed - probably not a single option was possible" throw "MultiAnswer failed - probably not a single option was possible"
} }
const save = () => { const save = async () => {
const selection = inputElement.GetValue().data; const selection = inputElement.GetValue().data;
if (selection) { if (selection) {
(State.state?.changes ?? new Changes()) await (State.state?.changes ?? new Changes())
.applyAction(new ChangeTagAction( .applyAction(new ChangeTagAction(
tags.data.id, selection, tags.data tags.data.id, selection, tags.data
)) ))

View file

@ -63,6 +63,7 @@ export default class ShowDataLayer {
}) })
State.state.selectedElement.addCallbackAndRunD(selected => { State.state.selectedElement.addCallbackAndRunD(selected => {
if (self._leafletMap.data === undefined) { if (self._leafletMap.data === undefined) {
return; return;
@ -76,18 +77,21 @@ export default class ShowDataLayer {
if (leafletLayer.getPopup().isOpen()) { if (leafletLayer.getPopup().isOpen()) {
return; return;
} }
if (selected.properties.id === feature.properties.id) { if (selected.properties.id !== feature.properties.id) {
// A small sanity check to prevent infinite loops: return;
}
if (feature.id !== feature.properties.id) {
// Probably a feature which has renamed
console.trace("Not opening the popup for", feature)
return;
}
if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again if (selected.geometry.type === feature.geometry.type // If a feature is rendered both as way and as point, opening one popup might trigger the other to open, which might trigger the one to open again
&& feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too && feature.id === feature.properties.id // the feature might have as id 'node/-1' and as 'feature.properties.id' = 'the newly assigned id'. That is no good too
) { ) {
console.log("Opening popup of feature", feature)
leafletLayer.openPopup() leafletLayer.openPopup()
} }
if (feature.id !== feature.properties.id) {
console.trace("Not opening the popup for", feature)
}
}
}) })
} }
@ -167,8 +171,10 @@ export default class ShowDataLayer {
return; return;
} }
const tagSource = feature.properties.id === undefined ? new UIEventSource<any>(feature.properties) : let tagSource = State.state.allElements.getEventSourceById(feature.properties.id)
State.state.allElements.getEventSourceById(feature.properties.id) if(tagSource === undefined){
tagSource = new UIEventSource<any>(feature.properties)
}
const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0) const clickable = !(layer.title === undefined && (layer.tagRenderings ?? []).length === 0)
const style = layer.GenerateLeafletStyle(tagSource, clickable); const style = layer.GenerateLeafletStyle(tagSource, clickable);
const baseElement = style.icon.html; const baseElement = style.icon.html;

View file

@ -1,32 +1,14 @@
import FeatureSource, {Tiled} from "../../Logic/FeatureSource/FeatureSource"; import FeatureSource, {Tiled} from "../../Logic/FeatureSource/FeatureSource";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import {Utils} from "../../Utils";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"; import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import ShowDataLayer from "./ShowDataLayer"; import ShowDataLayer from "./ShowDataLayer";
import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource"; import StaticFeatureSource from "../../Logic/FeatureSource/Sources/StaticFeatureSource";
import {GeoOperations} from "../../Logic/GeoOperations"; import {GeoOperations} from "../../Logic/GeoOperations";
import {Tiles} from "../../Models/TileRange"; import {Tiles} from "../../Models/TileRange";
import * as clusterstyle from "../../assets/layers/cluster_style/cluster_style.json"
export default class ShowTileInfo { export default class ShowTileInfo {
public static readonly styling = new LayerConfig({ public static readonly styling = new LayerConfig(
id: "tileinfo_styling", clusterstyle, "tileinfo", true)
title: {
render: "Tile {z}/{x}/{y}"
},
tagRenderings: [
"all_tags"
],
source: {
osmTags: "tileId~*"
},
color: {"render": "#3c3"},
width: {
"render": "1"
},
label: {
render: "<div class='rounded-full text-xl font-bold' style='width: 2rem; height: 2rem; background: white'>{count}</div>"
}
}, "tileinfo", true)
constructor(options: { constructor(options: {
source: FeatureSource & Tiled, leafletMap: UIEventSource<any>, layer?: LayerConfig, source: FeatureSource & Tiled, leafletMap: UIEventSource<any>, layer?: LayerConfig,

View file

@ -22,7 +22,7 @@ export class TileHierarchyAggregator implements FeatureSource {
public readonly name; public readonly name;
private readonly featuresStatic = [] private readonly featuresStatic = []
private readonly featureProperties: { count: number, tileId: number }; private readonly featureProperties: { count: string, tileId: string, id: string };
private constructor(parent: TileHierarchyAggregator, z: number, x: number, y: number) { private constructor(parent: TileHierarchyAggregator, z: number, x: number, y: number) {
this._parent = parent; this._parent = parent;
@ -34,8 +34,9 @@ export class TileHierarchyAggregator implements FeatureSource {
this.name = "Count(" + this._tileIndex + ")" this.name = "Count(" + this._tileIndex + ")"
const totals = { const totals = {
tileId: this._tileIndex, id: ""+this._tileIndex,
count: 0 tileId: ""+this._tileIndex,
count: ""+0
} }
this.featureProperties = totals this.featureProperties = totals
@ -106,7 +107,7 @@ export class TileHierarchyAggregator implements FeatureSource {
if (total === 0) { if (total === 0) {
this.features.setData(TileHierarchyAggregator.empty) this.features.setData(TileHierarchyAggregator.empty)
} else { } else {
this.featureProperties.count = total; this.featureProperties.count = "" + total;
this.features.data = this.featuresStatic this.features.data = this.featuresStatic
this.features.ping() this.features.ping()
} }
@ -145,7 +146,6 @@ export class TileHierarchyAggregator implements FeatureSource {
return new TileHierarchyAggregator(undefined, 0, 0, 0) return new TileHierarchyAggregator(undefined, 0, 0, 0)
} }
private visitSubTiles(f : (aggr: TileHierarchyAggregator) => boolean){ private visitSubTiles(f : (aggr: TileHierarchyAggregator) => boolean){
const visitFurther = f(this) const visitFurther = f(this)
if(visitFurther){ if(visitFurther){
@ -153,8 +153,9 @@ export class TileHierarchyAggregator implements FeatureSource {
} }
} }
getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number) : FeatureSource{ getCountsForZoom(locationControl: UIEventSource<{ zoom : number }>, cutoff: number = 0) : FeatureSource{
const self = this const self = this
return new StaticFeatureSource( return new StaticFeatureSource(
locationControl.map(loc => { locationControl.map(loc => {
const features = [] const features = []
@ -205,9 +206,11 @@ class SingleTileCounter implements Tiled {
const self = this const self = this
source.features.map(f => { source.features.map(f => {
self.countsPerLayer.data.set(layer.id, f.length) const isDisplayed = source.layer.isDisplayed.data
self.countsPerLayer.data.set(layer.id, isDisplayed ? f.length : 0)
self.countsPerLayer.ping() self.countsPerLayer.ping()
}) }, [source.layer.isDisplayed])
} }