forked from MapComplete/MapComplete
		
	More refactoring
This commit is contained in:
		
							parent
							
								
									231f4f2c97
								
							
						
					
					
						commit
						6890c5189e
					
				
					 12 changed files with 52 additions and 59 deletions
				
			
		|  | @ -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' | ||||||
|  |                     }) | ||||||
|                 } |                 } | ||||||
|             ) |             ) | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|          |          | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|             )) |             )) | ||||||
|  |  | ||||||
|  | @ -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( | ||||||
|  |  | ||||||
|  | @ -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) | ||||||
|                 ) |                 ) | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|                 )) |                 ))) | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -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' | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         { |         { | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|                 )) |                 )) | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|                     )) |                     )) | ||||||
|  |  | ||||||
|  | @ -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,17 +77,20 @@ 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 (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
 |              | ||||||
|                 ) { |             if (feature.id !== feature.properties.id) { | ||||||
|                     leafletLayer.openPopup() |                 // Probably a feature which has renamed
 | ||||||
|                 } |                 console.trace("Not opening the popup for", feature) | ||||||
|                 if (feature.id !== feature.properties.id) { |                 return; | ||||||
|                     console.trace("Not opening the popup for", feature) |             } | ||||||
|                 } |             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
 | ||||||
|  |             ) { | ||||||
|  |                 console.log("Opening popup of feature", feature) | ||||||
|  |                 leafletLayer.openPopup() | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|  | @ -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; | ||||||
|  |  | ||||||
|  | @ -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, | ||||||
|  |  | ||||||
|  | @ -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]) | ||||||
|  |          | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue