Chore: reformat all files with prettier

This commit is contained in:
Pieter Vander Vennet 2023-06-14 20:39:36 +02:00
parent 5757ae5dea
commit d008dcb54d
214 changed files with 8926 additions and 8196 deletions

View file

@ -1,6 +1,6 @@
import {Store, UIEventSource} from "../UIEventSource"
import {Utils} from "../../Utils"
import {RasterLayerPolygon, RasterLayerUtils,} from "../../Models/RasterLayers"
import { Store, UIEventSource } from "../UIEventSource"
import { Utils } from "../../Utils"
import { RasterLayerPolygon, RasterLayerUtils } from "../../Models/RasterLayers"
/**
* When a user pans around on the map, they might pan out of the range of the current background raster layer.
@ -35,7 +35,7 @@ export default class BackgroundLayerResetter {
availableLayers,
currentBgPolygon?.properties?.category
)
if(!availableInSameCat){
if (!availableInSameCat) {
return
}
console.log("Selecting a different layer:", availableInSameCat.properties.id)

View file

@ -1,15 +1,15 @@
import {QueryParameters} from "../Web/QueryParameters"
import {BBox} from "../BBox"
import { QueryParameters } from "../Web/QueryParameters"
import { BBox } from "../BBox"
import Constants from "../../Models/Constants"
import {GeoLocationState} from "../State/GeoLocationState"
import {UIEventSource} from "../UIEventSource"
import {Feature, LineString, Point} from "geojson"
import {FeatureSource, WritableFeatureSource} from "../FeatureSource/FeatureSource"
import {LocalStorageSource} from "../Web/LocalStorageSource"
import {GeoOperations} from "../GeoOperations"
import {OsmTags} from "../../Models/OsmFeature"
import { GeoLocationState } from "../State/GeoLocationState"
import { UIEventSource } from "../UIEventSource"
import { Feature, LineString, Point } from "geojson"
import { FeatureSource, WritableFeatureSource } from "../FeatureSource/FeatureSource"
import { LocalStorageSource } from "../Web/LocalStorageSource"
import { GeoOperations } from "../GeoOperations"
import { OsmTags } from "../../Models/OsmFeature"
import StaticFeatureSource from "../FeatureSource/Sources/StaticFeatureSource"
import {MapProperties} from "../../Models/MapProperties"
import { MapProperties } from "../../Models/MapProperties"
/**
* The geolocation-handler takes a map-location and a geolocation state.
@ -39,7 +39,9 @@ export default class GeoLocationHandler {
/**
* The last moment that the map has moved
*/
public readonly mapHasMoved: UIEventSource<Date | undefined> = new UIEventSource<Date | undefined>(undefined)
public readonly mapHasMoved: UIEventSource<Date | undefined> = new UIEventSource<
Date | undefined
>(undefined)
private readonly selectedElement: UIEventSource<any>
private readonly mapProperties?: MapProperties
private readonly gpsLocationHistoryRetentionTime?: UIEventSource<number>
@ -80,8 +82,11 @@ export default class GeoLocationHandler {
// The map hasn't moved yet; we received our first coordinates, so let's move there!
self.MoveMapToCurrentLocation()
}
if (timeSinceLastRequest < Constants.zoomToLocationTimeout &&
(this.mapHasMoved.data === undefined || this.mapHasMoved.data.getTime() < geolocationState.requestMoment.data?.getTime() )
if (
timeSinceLastRequest < Constants.zoomToLocationTimeout &&
(this.mapHasMoved.data === undefined ||
this.mapHasMoved.data.getTime() <
geolocationState.requestMoment.data?.getTime())
) {
// still within request time and the map hasn't moved since requesting to jump to the current location
self.MoveMapToCurrentLocation()
@ -154,8 +159,8 @@ export default class GeoLocationHandler {
return
}
const properties = {
id: "gps-"+i,
const properties = {
id: "gps-" + i,
"user:location": "yes",
date: new Date().toISOString(),
}
@ -164,7 +169,7 @@ export default class GeoLocationHandler {
for (const k in keysToCopy) {
// For some weird reason, the 'Object.keys' method doesn't work for the 'location: GeolocationCoordinates'-object and will thus not copy all the properties when using {...location}
// As such, they are copied here
if(location[k]){
if (location[k]) {
properties[k] = location[k]
}
}

View file

@ -20,14 +20,15 @@ import { FixImages } from "../Models/ThemeConfig/Conversion/FixImages"
import Svg from "../Svg"
import {
DoesImageExist,
PrevalidateTheme, ValidateTagRenderings,
PrevalidateTheme,
ValidateTagRenderings,
ValidateThemeAndLayers,
} from "../Models/ThemeConfig/Conversion/Validation"
import {DesugaringContext, Each, On} from "../Models/ThemeConfig/Conversion/Conversion";
import {PrepareLayer, RewriteSpecial} from "../Models/ThemeConfig/Conversion/PrepareLayer";
import {AllSharedLayers} from "../Customizations/AllSharedLayers";
import {TagRenderingConfigJson} from "../Models/ThemeConfig/Json/TagRenderingConfigJson";
import questions from "../assets/tagRenderings/questions.json";
import { DesugaringContext, Each, On } from "../Models/ThemeConfig/Conversion/Conversion"
import { PrepareLayer, RewriteSpecial } from "../Models/ThemeConfig/Conversion/PrepareLayer"
import { AllSharedLayers } from "../Customizations/AllSharedLayers"
import { TagRenderingConfigJson } from "../Models/ThemeConfig/Json/TagRenderingConfigJson"
import questions from "../assets/tagRenderings/questions.json"
export default class DetermineLayout {
private static readonly _knownImages = new Set(Array.from(licenses).map((l) => l.path))

View file

@ -1,11 +1,11 @@
import {GeoOperations} from "./GeoOperations"
import { GeoOperations } from "./GeoOperations"
import Combine from "../UI/Base/Combine"
import BaseUIElement from "../UI/BaseUIElement"
import List from "../UI/Base/List"
import Title from "../UI/Base/Title"
import {BBox} from "./BBox"
import {Feature, Geometry, MultiPolygon, Polygon} from "geojson"
import {GeoJSONFeature} from "maplibre-gl";
import { BBox } from "./BBox"
import { Feature, Geometry, MultiPolygon, Polygon } from "geojson"
import { GeoJSONFeature } from "maplibre-gl"
export interface ExtraFuncParams {
/**
@ -13,7 +13,10 @@ export interface ExtraFuncParams {
* Note that more features then requested can be given back.
* Format: [ [ geojson, geojson, geojson, ... ], [geojson, ...], ...]
*/
getFeaturesWithin: (layerId: string, bbox: BBox) => Feature<Geometry, Record<string, string>>[][]
getFeaturesWithin: (
layerId: string,
bbox: BBox
) => Feature<Geometry, Record<string, string>>[][]
getFeatureById: (id: string) => Feature<Geometry, Record<string, string>>
}
@ -55,7 +58,6 @@ class EnclosingFunc implements ExtraFunction {
}
for (const otherFeatures of otherFeaturess) {
for (const otherFeature of otherFeatures) {
if (seenIds.has(otherFeature.properties.id)) {
continue
}
@ -72,7 +74,7 @@ class EnclosingFunc implements ExtraFunction {
<Feature<Polygon | MultiPolygon, any>>otherFeature
)
) {
result.push({feat: otherFeature})
result.push({ feat: otherFeature })
}
}
}
@ -158,11 +160,14 @@ class IntersectionFunc implements ExtraFunction {
}
for (const otherFeatures of otherLayers) {
for (const otherFeature of otherFeatures) {
const intersections = GeoOperations.LineIntersections(feat, <Feature<any, Record<string, string>>>otherFeature)
const intersections = GeoOperations.LineIntersections(
feat,
<Feature<any, Record<string, string>>>otherFeature
)
if (intersections.length === 0) {
continue
}
result.push({feat: otherFeature, intersections})
result.push({ feat: otherFeature, intersections })
}
}
}
@ -254,7 +259,14 @@ class ClosestNObjectFunc implements ExtraFunction {
const maxDistance = options?.maxDistance ?? 500
const uniqueTag: string | undefined = options?.uniqueTag
let allFeatures: Feature[][]
console.log("Calculating closest", options?.maxFeatures, "features around", feature, "in layer", features)
console.log(
"Calculating closest",
options?.maxFeatures,
"features around",
feature,
"in layer",
features
)
if (typeof features === "string") {
const name = features
const bbox = GeoOperations.bbox(
@ -272,7 +284,6 @@ class ClosestNObjectFunc implements ExtraFunction {
let closestFeatures: { feat: any; distance: number }[] = []
for (const feats of allFeatures) {
for (const otherFeature of feats) {
if (
otherFeature === feature ||
@ -333,7 +344,7 @@ class ClosestNObjectFunc implements ExtraFunction {
const uniqueTagsMatch =
otherFeature.properties[uniqueTag] !== undefined &&
closestFeature.feat.properties[uniqueTag] ===
otherFeature.properties[uniqueTag]
otherFeature.properties[uniqueTag]
if (uniqueTagsMatch) {
targetIndex = -1
if (closestFeature.distance > distance) {
@ -341,7 +352,7 @@ class ClosestNObjectFunc implements ExtraFunction {
// We want to see the tag `uniquetag=some_value` only once in the entire list (e.g. to prevent road segements of identical names to fill up the list of 'names of nearby roads')
// AT this point, we have found a closer segment with the same, identical tag
// so we replace directly
closestFeatures[i] = {feat: otherFeature, distance: distance}
closestFeatures[i] = { feat: otherFeature, distance: distance }
}
break
}
@ -468,7 +479,15 @@ export class ExtraFunctions {
.SetClass("flex-col")
.AsMarkdown()
static readonly types = ["distanceTo", "overlapWith", "enclosingFeatures", "intersectionsWith", "closest", "closestn", "get"] as const
static readonly types = [
"distanceTo",
"overlapWith",
"enclosingFeatures",
"intersectionsWith",
"closest",
"closestn",
"get",
] as const
private static readonly allFuncs = [
new DistanceToFunc(),
new OverlapFunc(),
@ -479,8 +498,9 @@ export class ExtraFunctions {
new GetParsed(),
]
public static constructHelpers(params: ExtraFuncParams): Record<ExtraFuncType, (feature: Feature) => Function> {
public static constructHelpers(
params: ExtraFuncParams
): Record<ExtraFuncType, (feature: Feature) => Function> {
const record: Record<string, (feature: GeoJSONFeature) => Function> = {}
for (const f of ExtraFunctions.allFuncs) {
if (this.types.indexOf(<any>f._name) < 0) {

View file

@ -1,5 +1,5 @@
import {FeatureSource} from "../FeatureSource"
import {UIEventSource} from "../../UIEventSource"
import { FeatureSource } from "../FeatureSource"
import { UIEventSource } from "../../UIEventSource"
/**
* Constructs a UIEventStore for the properties of every Feature, indexed by id

View file

@ -1,5 +1,5 @@
import {IdbLocalStorage} from "../../Web/IdbLocalStorage"
import {UIEventSource} from "../../UIEventSource"
import { IdbLocalStorage } from "../../Web/IdbLocalStorage"
import { UIEventSource } from "../../UIEventSource"
/**
* A class which allows to read/write a tile to local storage.
@ -14,14 +14,18 @@ export default class TileLocalStorage<T> {
private readonly _layername: string
private readonly inUse = new UIEventSource(false)
private readonly cachedSources: Record<number, UIEventSource<T> & { flush: () => void }> = {}
private readonly _maxAgeSeconds: number;
private readonly _maxAgeSeconds: number
private constructor(layername: string, maxAgeSeconds: number) {
this._layername = layername
this._maxAgeSeconds = maxAgeSeconds;
this._maxAgeSeconds = maxAgeSeconds
}
public static construct<T>(backend: string, layername: string, maxAgeS: number): TileLocalStorage<T> {
public static construct<T>(
backend: string,
layername: string,
maxAgeS: number
): TileLocalStorage<T> {
const key = backend + "_" + layername
const cached = TileLocalStorage.perLayer[key]
if (cached) {
@ -59,7 +63,10 @@ export default class TileLocalStorage<T> {
await this.inUse.AsPromise((inUse) => !inUse)
this.inUse.setData(true)
await IdbLocalStorage.SetDirectly(this._layername + "_" + tileIndex, data)
await IdbLocalStorage.SetDirectly(this._layername + "_" + tileIndex + "_date", Date.now())
await IdbLocalStorage.SetDirectly(
this._layername + "_" + tileIndex + "_date",
Date.now()
)
this.inUse.setData(false)
} catch (e) {
@ -80,7 +87,9 @@ export default class TileLocalStorage<T> {
if (!TileLocalStorage.useIndexedDb) {
return undefined
}
const date = <any>await IdbLocalStorage.GetDirectly(this._layername + "_" + tileIndex + "_date")
const date = <any>(
await IdbLocalStorage.GetDirectly(this._layername + "_" + tileIndex + "_date")
)
const maxAge = this._maxAgeSeconds
const timeDiff = Date.now() - date
if (timeDiff >= maxAge) {

View file

@ -1,8 +1,8 @@
import {FeatureSource} from "./FeatureSource"
import { FeatureSource } from "./FeatureSource"
import FilteredLayer from "../../Models/FilteredLayer"
import SimpleFeatureSource from "./Sources/SimpleFeatureSource"
import {Feature} from "geojson"
import {UIEventSource} from "../UIEventSource"
import { Feature } from "geojson"
import { UIEventSource } from "../UIEventSource"
/**
* In some rare cases, some elements are shown on multiple layers (when 'passthrough' is enabled)
@ -59,8 +59,11 @@ export default class PerLayerFeatureSourceSplitter<T extends FeatureSource = Fea
let foundALayer = false
for (let i = 0; i < layers.length; i++) {
const layer = layers[i]
if(!layer.layerDef?.source){
console.error("PerLayerFeatureSourceSplitter got a layer without a source:", layer.layerDef.id)
if (!layer.layerDef?.source) {
console.error(
"PerLayerFeatureSourceSplitter got a layer without a source:",
layer.layerDef.id
)
continue
}
if (layer.layerDef.source.osmTags.matchesProperties(f.properties)) {

View file

@ -6,7 +6,7 @@ import { UIEventSource } from "../../UIEventSource"
import { FeatureSource, IndexedFeatureSource } from "../FeatureSource"
import { ChangeDescription, ChangeDescriptionTools } from "../../Osm/Actions/ChangeDescription"
import { Feature } from "geojson"
import {Utils} from "../../../Utils";
import { Utils } from "../../../Utils"
export default class ChangeGeometryApplicator implements FeatureSource {
public readonly features: UIEventSource<Feature[]> = new UIEventSource<Feature[]>([])
@ -70,7 +70,7 @@ export default class ChangeGeometryApplicator implements FeatureSource {
// We only apply the last change as that one'll have the latest geometry
const change = changesForFeature[changesForFeature.length - 1]
copy.geometry = ChangeDescriptionTools.getGeojsonGeometry(change)
if(Utils.SameObject(copy.geometry, feature.geometry)){
if (Utils.SameObject(copy.geometry, feature.geometry)) {
// No actual changes: pass along the original
newFeatures.push(feature)
continue

View file

@ -30,7 +30,7 @@ export default class FeatureSourceMerger implements IndexedFeatureSource {
}
public addSource(source: FeatureSource) {
if(!source){
if (!source) {
return
}
this._sources.push(source)

View file

@ -1,14 +1,14 @@
/**
* Fetches a geojson file somewhere and passes it along
*/
import {Store, UIEventSource} from "../../UIEventSource"
import {Utils} from "../../../Utils"
import {FeatureSource} from "../FeatureSource"
import {BBox} from "../../BBox"
import {GeoOperations} from "../../GeoOperations"
import {Feature} from "geojson"
import { Store, UIEventSource } from "../../UIEventSource"
import { Utils } from "../../../Utils"
import { FeatureSource } from "../FeatureSource"
import { BBox } from "../../BBox"
import { GeoOperations } from "../../GeoOperations"
import { Feature } from "geojson"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import {Tiles} from "../../../Models/TileRange"
import { Tiles } from "../../../Models/TileRange"
export default class GeoJsonSource implements FeatureSource {
public readonly features: Store<Feature[]>
@ -65,13 +65,13 @@ export default class GeoJsonSource implements FeatureSource {
return
}
this.LoadJSONFrom(url, eventsource, layer)
.then((fs) => console.debug("Loaded",fs.length, "features from", url))
.then((fs) => console.debug("Loaded", fs.length, "features from", url))
.catch((err) => console.warn("Could not load ", url, "due to", err))
return true // data is loaded, we can safely unregister
})
} else {
this.LoadJSONFrom(url, eventsource, layer)
.then((fs) => console.debug("Loaded",fs.length, "features from", url))
.then((fs) => console.debug("Loaded", fs.length, "features from", url))
.catch((err) => console.warn("Could not load ", url, "due to", err))
}
this.features = eventsource
@ -105,7 +105,7 @@ export default class GeoJsonSource implements FeatureSource {
let i = 0
let skipped = 0
for (const feature of json.features) {
if(feature.geometry.type === "Point"){
if (feature.geometry.type === "Point") {
// See https://github.com/maproulette/maproulette-backend/issues/242
feature.geometry.coordinates = feature.geometry.coordinates.map(Number)
}

View file

@ -32,7 +32,9 @@ export class LastClickFeatureSource implements WritableFeatureSource {
}
const renderings = Utils.Dedup(
allPresets.map((uiElem) => Utils.runningFromConsole ? "" : uiElem.ConstructElement().innerHTML)
allPresets.map((uiElem) =>
Utils.runningFromConsole ? "" : uiElem.ConstructElement().innerHTML
)
)
const properties = {

View file

@ -1,16 +1,16 @@
import GeoJsonSource from "./GeoJsonSource"
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
import {FeatureSource} from "../FeatureSource"
import {Or} from "../../Tags/Or"
import { FeatureSource } from "../FeatureSource"
import { Or } from "../../Tags/Or"
import FeatureSwitchState from "../../State/FeatureSwitchState"
import OverpassFeatureSource from "./OverpassFeatureSource"
import {Store, UIEventSource} from "../../UIEventSource"
import { Store, UIEventSource } from "../../UIEventSource"
import OsmFeatureSource from "./OsmFeatureSource"
import FeatureSourceMerger from "./FeatureSourceMerger"
import DynamicGeoJsonTileSource from "../TiledFeatureSource/DynamicGeoJsonTileSource"
import {BBox} from "../../BBox"
import { BBox } from "../../BBox"
import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeatureSource"
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource";
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource"
/**
* This source will fetch the needed data from various sources for the given layout.
@ -41,7 +41,7 @@ export default class LayoutSource extends FeatureSourceMerger {
(l) =>
new LocalStorageFeatureSource(backend, l.id, 15, mapProperties, {
isActive: isDisplayed(l.id),
maxAge: l.maxAgeOfCache
maxAge: l.maxAgeOfCache,
})
)
@ -127,7 +127,7 @@ export default class LayoutSource extends FeatureSourceMerger {
backend,
isActive,
patchRelations: true,
fullNodeDatabase
fullNodeDatabase,
})
}

View file

@ -7,7 +7,7 @@ import { TagsFilter } from "../../Tags/TagsFilter"
import { Feature } from "geojson"
import FeatureSourceMerger from "../Sources/FeatureSourceMerger"
import OsmObjectDownloader from "../../Osm/OsmObjectDownloader"
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource";
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource"
/**
* If a tile is needed (requested via the UIEventSource in the constructor), will download the appropriate tile and pass it via 'handleTile'
@ -24,16 +24,16 @@ export default class OsmFeatureSource extends FeatureSourceMerger {
/**
* If given: this featureSwitch will not update if the store contains 'false'
*/
isActive?: Store<boolean>,
patchRelations?: true | boolean,
isActive?: Store<boolean>
patchRelations?: true | boolean
fullNodeDatabase?: FullNodeDatabaseSource
};
}
public readonly isRunning: UIEventSource<boolean> = new UIEventSource<boolean>(false)
private readonly _downloadedTiles: Set<number> = new Set<number>()
private readonly _downloadedData: Feature[][] = []
private readonly _patchRelations: boolean;
private readonly _patchRelations: boolean
/**
* Downloads data directly from the OSM-api within the given bounds.
* All features which match the TagsFilter 'allowedFeatures' are kept and converted into geojson
@ -45,12 +45,12 @@ export default class OsmFeatureSource extends FeatureSourceMerger {
/**
* If given: this featureSwitch will not update if the store contains 'false'
*/
isActive?: Store<boolean>,
patchRelations?: true | boolean,
isActive?: Store<boolean>
patchRelations?: true | boolean
fullNodeDatabase?: FullNodeDatabaseSource
}) {
super()
this.options = options;
this.options = options
this._bounds = options.bounds
this.allowedTags = options.allowedFeatures
this.isActive = options.isActive ?? new ImmutableStore(true)

View file

@ -1,6 +1,6 @@
import {FeatureSource} from "../FeatureSource"
import {ImmutableStore, Store} from "../../UIEventSource"
import {Feature} from "geojson"
import { FeatureSource } from "../FeatureSource"
import { ImmutableStore, Store } from "../../UIEventSource"
import { Feature } from "geojson"
/**
* A simple, read only feature store.
@ -8,13 +8,7 @@ import {Feature} from "geojson"
export default class StaticFeatureSource<T extends Feature = Feature> implements FeatureSource<T> {
public readonly features: Store<T[]>
constructor(
features:
| Store<T[]>
| T[]
| { features: T[] }
| { features: Store<T[]> }
) {
constructor(features: Store<T[]> | T[] | { features: T[] } | { features: Store<T[]> }) {
if (features === undefined) {
throw "Static feature source received undefined as source"
}

View file

@ -1,9 +1,9 @@
import {FeatureSource, FeatureSourceForLayer} from "../FeatureSource"
import { FeatureSource, FeatureSourceForLayer } from "../FeatureSource"
import StaticFeatureSource from "./StaticFeatureSource"
import {BBox} from "../../BBox"
import { BBox } from "../../BBox"
import FilteredLayer from "../../../Models/FilteredLayer"
import {Store} from "../../UIEventSource"
import {Feature} from "geojson";
import { Store } from "../../UIEventSource"
import { Feature } from "geojson"
/**
* Results in a feature source which has all the elements that touch the given features
@ -30,7 +30,10 @@ export default class BBoxFeatureSource<T extends Feature = Feature> extends Stat
}
}
export class BBoxFeatureSourceForLayer<T extends Feature = Feature> extends BBoxFeatureSource<T> implements FeatureSourceForLayer {
export class BBoxFeatureSourceForLayer<T extends Feature = Feature>
extends BBoxFeatureSource<T>
implements FeatureSourceForLayer
{
readonly layer: FilteredLayer
constructor(features: FeatureSourceForLayer<T>, mustTouch: Store<BBox>) {

View file

@ -72,7 +72,9 @@ export default class DynamicGeoJsonTileSource extends DynamicTileSource {
if (!isWhiteListed) {
console.debug(
"Not downloading tile",
zxy,"for layer",layer.id,
zxy,
"for layer",
layer.id,
"as it is not on the whitelist"
)
return undefined

View file

@ -1,11 +1,10 @@
import {OsmNode, OsmObject, OsmWay} from "../../Osm/OsmObject"
import {UIEventSource} from "../../UIEventSource"
import {BBox} from "../../BBox";
import StaticFeatureSource from "../Sources/StaticFeatureSource";
import {Tiles} from "../../../Models/TileRange";
import { OsmNode, OsmObject, OsmWay } from "../../Osm/OsmObject"
import { UIEventSource } from "../../UIEventSource"
import { BBox } from "../../BBox"
import StaticFeatureSource from "../Sources/StaticFeatureSource"
import { Tiles } from "../../../Models/TileRange"
export default class FullNodeDatabaseSource {
private readonly loadedTiles = new Map<number, Map<number, OsmNode>>()
private readonly nodeByIds = new Map<number, OsmNode>()
private readonly parentWays = new Map<number, UIEventSource<OsmWay[]>>()
@ -13,7 +12,7 @@ export default class FullNodeDatabaseSource {
private smallestZoom = 99
private largestZoom = 0
public handleOsmJson(osmJson: any, z: number, x: number, y: number) : void {
public handleOsmJson(osmJson: any, z: number, x: number, y: number): void {
const allObjects = OsmObject.ParseObjects(osmJson.elements)
const nodesById = new Map<number, OsmNode>()
@ -81,14 +80,14 @@ export default class FullNodeDatabaseSource {
* Gets (at least) all nodes which are part of this BBOX; might also return some nodes that fall outside of the bbox but are closeby
* @param bbox
*/
getNodesWithin(bbox: BBox) : Map<number, OsmNode>{
getNodesWithin(bbox: BBox): Map<number, OsmNode> {
const allById = new Map<number, OsmNode>()
for (let z = this.smallestZoom; z < this.largestZoom; z++) {
const range = Tiles.tileRangeFrom(bbox, z)
Tiles.MapRange(range, (x, y ) => {
Tiles.MapRange(range, (x, y) => {
const tileId = Tiles.tile_index(z, x, y)
const nodesById = this.loadedTiles.get(tileId)
nodesById?.forEach((v,k) => allById.set(k,v))
nodesById?.forEach((v, k) => allById.set(k, v))
})
}
return allById

View file

@ -1,8 +1,8 @@
import DynamicTileSource from "./DynamicTileSource"
import {Store} from "../../UIEventSource"
import {BBox} from "../../BBox"
import { Store } from "../../UIEventSource"
import { BBox } from "../../BBox"
import TileLocalStorage from "../Actors/TileLocalStorage"
import {Feature} from "geojson"
import { Feature } from "geojson"
import StaticFeatureSource from "../Sources/StaticFeatureSource"
export default class LocalStorageFeatureSource extends DynamicTileSource {
@ -15,26 +15,27 @@ export default class LocalStorageFeatureSource extends DynamicTileSource {
zoom: Store<number>
},
options?: {
isActive?: Store<boolean>,
isActive?: Store<boolean>
maxAge?: number // In seconds
}
) {
const storage = TileLocalStorage.construct<Feature[]>(backend, layername, options?.maxAge ?? 24 * 60 * 60)
const storage = TileLocalStorage.construct<Feature[]>(
backend,
layername,
options?.maxAge ?? 24 * 60 * 60
)
super(
zoomlevel,
(tileIndex) =>
new StaticFeatureSource(
storage
.getTileSource(tileIndex)
.mapD((features) => {
if (features.length === undefined) {
console.trace("These are not features:", features)
storage.invalidate(zoomlevel, tileIndex)
return []
}
return features.filter((f) => !f.properties.id.match(/(node|way)\/-[0-9]+/));
}
)
storage.getTileSource(tileIndex).mapD((features) => {
if (features.length === undefined) {
console.trace("These are not features:", features)
storage.invalidate(zoomlevel, tileIndex)
return []
}
return features.filter((f) => !f.properties.id.match(/(node|way)\/-[0-9]+/))
})
),
mapProperties,
options

View file

@ -408,7 +408,10 @@ export class GeoOperations {
/**
* Calculates line intersection between two features.
*/
public static LineIntersections(feature: Feature<LineString | MultiLineString | Polygon | MultiPolygon>, otherFeature: Feature<LineString | MultiLineString | Polygon | MultiPolygon>): [number, number][] {
public static LineIntersections(
feature: Feature<LineString | MultiLineString | Polygon | MultiPolygon>,
otherFeature: Feature<LineString | MultiLineString | Polygon | MultiPolygon>
): [number, number][] {
return turf
.lineIntersect(feature, otherFeature)
.features.map((p) => <[number, number]>p.geometry.coordinates)
@ -420,8 +423,7 @@ export class GeoOperations {
* @param features
* @param zoomlevel
*/
public static spreadIntoBboxes(features: Feature[], zoomlevel: number) : Map<number, Feature[]> {
public static spreadIntoBboxes(features: Feature[], zoomlevel: number): Map<number, Feature[]> {
const perBbox = new Map<number, Feature[]>()
for (const feature of features) {
@ -430,7 +432,7 @@ export class GeoOperations {
Tiles.MapRange(tilerange, (x, y) => {
const tileNumber = Tiles.tile_index(zoomlevel, x, y)
let newFeatureList = perBbox.get(tileNumber)
if(newFeatureList === undefined){
if (newFeatureList === undefined) {
newFeatureList = []
perBbox.set(tileNumber, newFeatureList)
}
@ -703,18 +705,18 @@ export class GeoOperations {
public static along(a: Coord, b: Coord, distanceMeter: number): Coord {
return turf.along(
<any> {
type:"Feature",
geometry:{
type:"LineString",
coordinates: [a, b]
}
}, distanceMeter, {units: "meters"}
<any>{
type: "Feature",
geometry: {
type: "LineString",
coordinates: [a, b],
},
},
distanceMeter,
{ units: "meters" }
).geometry.coordinates
}
/**
* Returns 'true' if one feature contains the other feature
*

View file

@ -1,10 +1,10 @@
import { Mapillary } from "./Mapillary";
import { WikimediaImageProvider } from "./WikimediaImageProvider";
import { Imgur } from "./Imgur";
import GenericImageProvider from "./GenericImageProvider";
import { Store, UIEventSource } from "../UIEventSource";
import ImageProvider, { ProvidedImage } from "./ImageProvider";
import { WikidataImageProvider } from "./WikidataImageProvider";
import { Mapillary } from "./Mapillary"
import { WikimediaImageProvider } from "./WikimediaImageProvider"
import { Imgur } from "./Imgur"
import GenericImageProvider from "./GenericImageProvider"
import { Store, UIEventSource } from "../UIEventSource"
import ImageProvider, { ProvidedImage } from "./ImageProvider"
import { WikidataImageProvider } from "./WikidataImageProvider"
/**
* A generic 'from the interwebz' image picker, without attribution
@ -44,7 +44,10 @@ export default class AllImageProviders {
UIEventSource<ProvidedImage[]>
>()
public static LoadImagesFor(tags: Store<Record<string, string>>, tagKey?: string[]): Store<ProvidedImage[]> {
public static LoadImagesFor(
tags: Store<Record<string, string>>,
tagKey?: string[]
): Store<ProvidedImage[]> {
if (tags.data.id === undefined) {
return undefined
}

View file

@ -80,12 +80,12 @@ export default class Maproulette {
* Maproulette.codeToIndex("qdsf") // => undefined
*
*/
public static codeToIndex(code: string) : number | undefined{
if(code === "Created"){
public static codeToIndex(code: string): number | undefined {
if (code === "Created") {
return Maproulette.STATUS_OPEN
}
for (let i = 0; i < 9; i++) {
if(Maproulette.STATUS_MEANING[""+i] === code){
if (Maproulette.STATUS_MEANING["" + i] === code) {
return i
}
}

View file

@ -1,14 +1,14 @@
import SimpleMetaTaggers, {MetataggingState, SimpleMetaTagger} from "./SimpleMetaTagger"
import {ExtraFuncParams, ExtraFunctions, ExtraFuncType} from "./ExtraFunctions"
import SimpleMetaTaggers, { MetataggingState, SimpleMetaTagger } from "./SimpleMetaTagger"
import { ExtraFuncParams, ExtraFunctions, ExtraFuncType } from "./ExtraFunctions"
import LayerConfig from "../Models/ThemeConfig/LayerConfig"
import {Feature} from "geojson"
import { Feature } from "geojson"
import FeaturePropertiesStore from "./FeatureSource/Actors/FeaturePropertiesStore"
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"
import {GeoIndexedStoreForLayer} from "./FeatureSource/Actors/GeoIndexedStore"
import {IndexedFeatureSource} from "./FeatureSource/FeatureSource"
import { GeoIndexedStoreForLayer } from "./FeatureSource/Actors/GeoIndexedStore"
import { IndexedFeatureSource } from "./FeatureSource/FeatureSource"
import OsmObjectDownloader from "./Osm/OsmObjectDownloader"
import {Utils} from "../Utils";
import {UIEventSource} from "./UIEventSource";
import { Utils } from "../Utils"
import { UIEventSource } from "./UIEventSource"
/**
* Metatagging adds various tags to the elements, e.g. lat, lon, surface area, ...
@ -18,7 +18,10 @@ import {UIEventSource} from "./UIEventSource";
export default class MetaTagging {
private static errorPrintCount = 0
private static readonly stopErrorOutputAt = 10
private static retaggingFuncCache = new Map<string, ((feature: Feature, propertiesStore: UIEventSource<any>) => void)[]>()
private static retaggingFuncCache = new Map<
string,
((feature: Feature, propertiesStore: UIEventSource<any>) => void)[]
>()
constructor(state: {
layout: LayoutConfig
@ -96,7 +99,7 @@ export default class MetaTagging {
// The calculated functions - per layer - which add the new keys
// Calculated functions are defined by the layer
const layerFuncs = this.createRetaggingFunc(layer, ExtraFunctions.constructHelpers(params))
const state: MetataggingState = {layout, osmObjectDownloader}
const state: MetataggingState = { layout, osmObjectDownloader }
let atLeastOneFeatureChanged = false
let strictlyEvaluated = 0
@ -177,20 +180,20 @@ export default class MetaTagging {
}
public static createExtraFuncParams(state: {
indexedFeatures: IndexedFeatureSource,
indexedFeatures: IndexedFeatureSource
perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer>
}) {
return {
getFeatureById: (id) => state.indexedFeatures.featuresById.data.get(id),
getFeaturesWithin: (layerId, bbox) => {
if (layerId === '*' || layerId === null || layerId === undefined) {
if (layerId === "*" || layerId === null || layerId === undefined) {
const feats: Feature[][] = []
state.perLayer.forEach((layer) => {
feats.push(layer.GetFeaturesWithin(bbox))
})
return feats
}
return [state.perLayer.get(layerId).GetFeaturesWithin(bbox)];
return [state.perLayer.get(layerId).GetFeaturesWithin(bbox)]
},
}
}
@ -202,23 +205,30 @@ export default class MetaTagging {
* @param layerId
* @private
*/
private static createFunctionForFeature([key, code, isStrict]: [string, string, boolean],
helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>,
layerId: string = "unkown layer"
private static createFunctionForFeature(
[key, code, isStrict]: [string, string, boolean],
helperFunctions: Record<ExtraFuncType, (feature: Feature) => Function>,
layerId: string = "unkown layer"
): ((feature: Feature, propertiesStore?: UIEventSource<any>) => void) | undefined {
if (code === undefined) {
return undefined
}
const calculateAndAssign: ((feat: Feature, store?: UIEventSource<any>) => string | any) = (feat, store) => {
const calculateAndAssign: (feat: Feature, store?: UIEventSource<any>) => string | any = (
feat,
store
) => {
try {
let result = new Function("feat", "{" + ExtraFunctions.types.join(", ") + "}", "return " + code + ";")(feat, helperFunctions)
let result = new Function(
"feat",
"{" + ExtraFunctions.types.join(", ") + "}",
"return " + code + ";"
)(feat, helperFunctions)
if (result === "") {
result = undefined
}
const oldValue= feat.properties[key]
if(oldValue == result){
const oldValue = feat.properties[key]
if (oldValue == result) {
return oldValue
}
delete feat.properties[key]
@ -229,16 +239,16 @@ export default class MetaTagging {
if (MetaTagging.errorPrintCount < MetaTagging.stopErrorOutputAt) {
console.warn(
"Could not calculate a " +
(isStrict ? "strict " : "") +
" calculated tag for key " +
key +
" defined by " +
code +
" (in layer" +
layerId +
") due to \n" +
e +
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
(isStrict ? "strict " : "") +
" calculated tag for key " +
key +
" defined by " +
code +
" (in layer" +
layerId +
") due to \n" +
e +
"\n. Are you the theme creator? Doublecheck your code. Note that the metatags might not be stable on new features",
e,
e.stack
)
@ -276,9 +286,12 @@ export default class MetaTagging {
return undefined
}
let functions: ((feature: Feature, propertiesStore?: UIEventSource<any>) => void)[] = MetaTagging.retaggingFuncCache.get(layer.id)
let functions: ((feature: Feature, propertiesStore?: UIEventSource<any>) => void)[] =
MetaTagging.retaggingFuncCache.get(layer.id)
if (functions === undefined) {
functions = calculatedTags.map(spec => this.createFunctionForFeature(spec, helpers, layer.id))
functions = calculatedTags.map((spec) =>
this.createFunctionForFeature(spec, helpers, layer.id)
)
MetaTagging.retaggingFuncCache.set(layer.id, functions)
}

View file

@ -1,20 +1,23 @@
import {OsmCreateAction, PreviewableAction} from "./OsmChangeAction"
import {Tag} from "../../Tags/Tag"
import {Changes} from "../Changes"
import {ChangeDescription} from "./ChangeDescription"
import { OsmCreateAction, PreviewableAction } from "./OsmChangeAction"
import { Tag } from "../../Tags/Tag"
import { Changes } from "../Changes"
import { ChangeDescription } from "./ChangeDescription"
import CreateNewWayAction from "./CreateNewWayAction"
import CreateWayWithPointReuseAction, {MergePointConfig} from "./CreateWayWithPointReuseAction"
import {And} from "../../Tags/And"
import {TagUtils} from "../../Tags/TagUtils"
import {FeatureSource, IndexedFeatureSource} from "../../FeatureSource/FeatureSource"
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig";
import {Position} from "geojson";
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource";
import CreateWayWithPointReuseAction, { MergePointConfig } from "./CreateWayWithPointReuseAction"
import { And } from "../../Tags/And"
import { TagUtils } from "../../Tags/TagUtils"
import { FeatureSource, IndexedFeatureSource } from "../../FeatureSource/FeatureSource"
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"
import { Position } from "geojson"
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
/**
* More or less the same as 'CreateNewWay', except that it'll try to reuse already existing points
*/
export default class CreateMultiPolygonWithPointReuseAction extends OsmCreateAction implements PreviewableAction {
export default class CreateMultiPolygonWithPointReuseAction
extends OsmCreateAction
implements PreviewableAction
{
public newElementId: string = undefined
public newElementIdNumber: number = undefined
private readonly _tags: Tag[]
@ -29,9 +32,9 @@ export default class CreateMultiPolygonWithPointReuseAction extends OsmCreateAct
outerRingCoordinates: Position[],
innerRingsCoordinates: Position[][],
state: {
layout: LayoutConfig;
changes: Changes;
indexedFeatures: IndexedFeatureSource,
layout: LayoutConfig
changes: Changes
indexedFeatures: IndexedFeatureSource
fullNodeDatabase?: FullNodeDatabaseSource
},
config: MergePointConfig[],
@ -43,7 +46,7 @@ export default class CreateMultiPolygonWithPointReuseAction extends OsmCreateAct
this.theme = state?.layout?.id ?? ""
this.createOuterWay = new CreateWayWithPointReuseAction(
[],
<[number,number][]> outerRingCoordinates,
<[number, number][]>outerRingCoordinates,
state,
config
)

View file

@ -1,9 +1,9 @@
import {ChangeDescription} from "./ChangeDescription"
import {OsmCreateAction} from "./OsmChangeAction"
import {Changes} from "../Changes"
import {Tag} from "../../Tags/Tag"
import { ChangeDescription } from "./ChangeDescription"
import { OsmCreateAction } from "./OsmChangeAction"
import { Changes } from "../Changes"
import { Tag } from "../../Tags/Tag"
import CreateNewNodeAction from "./CreateNewNodeAction"
import {And} from "../../Tags/And"
import { And } from "../../Tags/And"
export default class CreateNewWayAction extends OsmCreateAction {
public newElementId: string = undefined

View file

@ -1,17 +1,17 @@
import {OsmCreateAction, PreviewableAction} from "./OsmChangeAction"
import {Tag} from "../../Tags/Tag"
import {Changes} from "../Changes"
import {ChangeDescription} from "./ChangeDescription"
import {BBox} from "../../BBox"
import {TagsFilter} from "../../Tags/TagsFilter"
import {GeoOperations} from "../../GeoOperations"
import {FeatureSource, IndexedFeatureSource} from "../../FeatureSource/FeatureSource"
import { OsmCreateAction, PreviewableAction } from "./OsmChangeAction"
import { Tag } from "../../Tags/Tag"
import { Changes } from "../Changes"
import { ChangeDescription } from "./ChangeDescription"
import { BBox } from "../../BBox"
import { TagsFilter } from "../../Tags/TagsFilter"
import { GeoOperations } from "../../GeoOperations"
import { FeatureSource, IndexedFeatureSource } from "../../FeatureSource/FeatureSource"
import StaticFeatureSource from "../../FeatureSource/Sources/StaticFeatureSource"
import CreateNewNodeAction from "./CreateNewNodeAction"
import CreateNewWayAction from "./CreateNewWayAction"
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig";
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource";
import {Position} from "geojson";
import LayoutConfig from "../../../Models/ThemeConfig/LayoutConfig"
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
import { Position } from "geojson"
export interface MergePointConfig {
withinRangeOfM: number
@ -56,7 +56,10 @@ interface CoordinateInfo {
/**
* More or less the same as 'CreateNewWay', except that it'll try to reuse already existing points
*/
export default class CreateWayWithPointReuseAction extends OsmCreateAction implements PreviewableAction {
export default class CreateWayWithPointReuseAction
extends OsmCreateAction
implements PreviewableAction
{
public newElementId: string = undefined
public newElementIdNumber: number = undefined
private readonly _tags: Tag[]
@ -66,9 +69,9 @@ export default class CreateWayWithPointReuseAction extends OsmCreateAction imple
*/
private readonly _coordinateInfo: CoordinateInfo[]
private readonly _state: {
layout: LayoutConfig;
changes: Changes;
indexedFeatures: IndexedFeatureSource,
layout: LayoutConfig
changes: Changes
indexedFeatures: IndexedFeatureSource
fullNodeDatabase?: FullNodeDatabaseSource
}
private readonly _config: MergePointConfig[]
@ -77,9 +80,9 @@ export default class CreateWayWithPointReuseAction extends OsmCreateAction imple
tags: Tag[],
coordinates: Position[],
state: {
layout: LayoutConfig;
changes: Changes;
indexedFeatures: IndexedFeatureSource,
layout: LayoutConfig
changes: Changes
indexedFeatures: IndexedFeatureSource
fullNodeDatabase?: FullNodeDatabaseSource
},
config: MergePointConfig[]
@ -90,7 +93,7 @@ export default class CreateWayWithPointReuseAction extends OsmCreateAction imple
this._config = config
// The main logic of this class: the coordinateInfo contains all the changes
this._coordinateInfo = this.CalculateClosebyNodes(<[number,number][]> coordinates)
this._coordinateInfo = this.CalculateClosebyNodes(<[number, number][]>coordinates)
}
public async getPreview(): Promise<FeatureSource> {
@ -245,7 +248,7 @@ export default class CreateWayWithPointReuseAction extends OsmCreateAction imple
},
})
}
nodeIdsToUse.push({lat, lon, nodeId: id})
nodeIdsToUse.push({ lat, lon, nodeId: id })
}
const newWay = new CreateNewWayAction(this._tags, nodeIdsToUse, {
@ -321,7 +324,7 @@ export default class CreateWayWithPointReuseAction extends OsmCreateAction imple
if (!config.ifMatches.matchesProperties(node.properties)) {
continue
}
closebyNodes.push({node, d, config})
closebyNodes.push({ node, d, config })
}
}

View file

@ -8,7 +8,7 @@ import { And } from "../../Tags/And"
import { Tag } from "../../Tags/Tag"
import { OsmId } from "../../../Models/OsmFeature"
import { Utils } from "../../../Utils"
import OsmObjectDownloader from "../OsmObjectDownloader";
import OsmObjectDownloader from "../OsmObjectDownloader"
export default class DeleteAction extends OsmChangeAction {
private readonly _softDeletionTags: TagsFilter
@ -72,9 +72,11 @@ export default class DeleteAction extends OsmChangeAction {
changes: Changes,
object?: OsmObject
): Promise<ChangeDescription[]> {
const osmObject = object ?? (await new OsmObjectDownloader(changes.backend, changes).DownloadObjectAsync(this._id))
const osmObject =
object ??
(await new OsmObjectDownloader(changes.backend, changes).DownloadObjectAsync(this._id))
if(osmObject === "deleted"){
if (osmObject === "deleted") {
// already deleted in the meantime - no more changes necessary
return []
}

View file

@ -4,7 +4,7 @@
*/
import { Changes } from "../Changes"
import { ChangeDescription } from "./ChangeDescription"
import {FeatureSource} from "../../FeatureSource/FeatureSource";
import { FeatureSource } from "../../FeatureSource/FeatureSource"
export default abstract class OsmChangeAction {
public readonly trackStatistics: boolean

View file

@ -1,21 +1,21 @@
import OsmChangeAction, {PreviewableAction} from "./OsmChangeAction"
import {Changes} from "../Changes"
import {ChangeDescription} from "./ChangeDescription"
import {Tag} from "../../Tags/Tag"
import {FeatureSource} from "../../FeatureSource/FeatureSource"
import {OsmNode, OsmObject, OsmWay} from "../OsmObject"
import {GeoOperations} from "../../GeoOperations"
import OsmChangeAction, { PreviewableAction } from "./OsmChangeAction"
import { Changes } from "../Changes"
import { ChangeDescription } from "./ChangeDescription"
import { Tag } from "../../Tags/Tag"
import { FeatureSource } from "../../FeatureSource/FeatureSource"
import { OsmNode, OsmObject, OsmWay } from "../OsmObject"
import { GeoOperations } from "../../GeoOperations"
import StaticFeatureSource from "../../FeatureSource/Sources/StaticFeatureSource"
import CreateNewNodeAction from "./CreateNewNodeAction"
import ChangeTagAction from "./ChangeTagAction"
import {And} from "../../Tags/And"
import {Utils} from "../../../Utils"
import {OsmConnection} from "../OsmConnection"
import {Feature} from "@turf/turf"
import {Geometry, LineString, Point} from "geojson"
import { And } from "../../Tags/And"
import { Utils } from "../../../Utils"
import { OsmConnection } from "../OsmConnection"
import { Feature } from "@turf/turf"
import { Geometry, LineString, Point } from "geojson"
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
export default class ReplaceGeometryAction extends OsmChangeAction implements PreviewableAction{
export default class ReplaceGeometryAction extends OsmChangeAction implements PreviewableAction {
/**
* The target feature - mostly used for the metadata
*/
@ -45,7 +45,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
public readonly newElementId: string
constructor(
state: {
osmConnection: OsmConnection,
osmConnection: OsmConnection
fullNodeDatabase?: FullNodeDatabaseSource
},
feature: any,
@ -460,7 +460,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
}
}
console.log("Adding tags", this.newTags,"to conflated way nr", this.wayToReplaceId)
console.log("Adding tags", this.newTags, "to conflated way nr", this.wayToReplaceId)
if (this.newTags !== undefined && this.newTags.length > 0) {
const addExtraTags = new ChangeTagAction(
this.wayToReplaceId,

View file

@ -1,10 +1,10 @@
import {OsmWay} from "../OsmObject"
import {Changes} from "../Changes"
import {GeoOperations} from "../../GeoOperations"
import { OsmWay } from "../OsmObject"
import { Changes } from "../Changes"
import { GeoOperations } from "../../GeoOperations"
import OsmChangeAction from "./OsmChangeAction"
import {ChangeDescription} from "./ChangeDescription"
import { ChangeDescription } from "./ChangeDescription"
import RelationSplitHandler from "./RelationSplitHandler"
import {Feature, LineString} from "geojson"
import { Feature, LineString } from "geojson"
import OsmObjectDownloader from "../OsmObjectDownloader"
interface SplitInfo {

View file

@ -1,16 +1,16 @@
import {OsmNode, OsmObject, OsmRelation, OsmWay} from "./OsmObject"
import {Store, UIEventSource} from "../UIEventSource"
import { OsmNode, OsmObject, OsmRelation, OsmWay } from "./OsmObject"
import { Store, UIEventSource } from "../UIEventSource"
import Constants from "../../Models/Constants"
import OsmChangeAction from "./Actions/OsmChangeAction"
import {ChangeDescription, ChangeDescriptionTools} from "./Actions/ChangeDescription"
import {Utils} from "../../Utils"
import {LocalStorageSource} from "../Web/LocalStorageSource"
import { ChangeDescription, ChangeDescriptionTools } from "./Actions/ChangeDescription"
import { Utils } from "../../Utils"
import { LocalStorageSource } from "../Web/LocalStorageSource"
import SimpleMetaTagger from "../SimpleMetaTagger"
import {FeatureSource, IndexedFeatureSource} from "../FeatureSource/FeatureSource"
import {GeoLocationPointProperties} from "../State/GeoLocationState"
import {GeoOperations} from "../GeoOperations"
import {ChangesetHandler, ChangesetTag} from "./ChangesetHandler"
import {OsmConnection} from "./OsmConnection"
import { FeatureSource, IndexedFeatureSource } from "../FeatureSource/FeatureSource"
import { GeoLocationPointProperties } from "../State/GeoLocationState"
import { GeoOperations } from "../GeoOperations"
import { ChangesetHandler, ChangesetTag } from "./ChangesetHandler"
import { OsmConnection } from "./OsmConnection"
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
import OsmObjectDownloader from "./OsmObjectDownloader"
@ -408,7 +408,7 @@ export class Changes {
neededIds.map(async (id) => {
try {
const osmObj = await downloader.DownloadObjectAsync(id)
return {id, osmObj}
return { id, osmObj }
} catch (e) {
console.error(
"Could not download OSM-object",
@ -422,7 +422,7 @@ export class Changes {
osmObjects = Utils.NoNull(osmObjects)
for (const {osmObj, id} of osmObjects) {
for (const { osmObj, id } of osmObjects) {
if (osmObj === "deleted") {
pending = pending.filter((ch) => ch.type + "/" + ch.id !== id)
}
@ -573,9 +573,9 @@ export class Changes {
)
console.log(
"Using current-open-changeset-" +
theme +
" from the preferences, got " +
openChangeset.data
theme +
" from the preferences, got " +
openChangeset.data
)
return await self.flushSelectChanges(pendingChanges, openChangeset)

View file

@ -131,7 +131,8 @@ export class ChangesetHandler {
const changeset = generateChangeXML(csId, this._remappings)
console.log(
"Opened a new changeset (openChangeset.data is undefined):",
changeset, extraMetaTags
changeset,
extraMetaTags
)
const changes = await this.UploadChange(csId, changeset)
const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(

View file

@ -1,8 +1,8 @@
import {Utils} from "../../Utils"
import { Utils } from "../../Utils"
import polygon_features from "../../assets/polygon-features.json"
import OsmToGeoJson from "osmtogeojson"
import {OsmFeature, OsmId, OsmTags, WayId} from "../../Models/OsmFeature"
import {Feature, LineString, Polygon} from "geojson"
import { OsmFeature, OsmId, OsmTags, WayId } from "../../Models/OsmFeature"
import { Feature, LineString, Polygon } from "geojson"
export abstract class OsmObject {
private static defaultBackend = "https://www.openstreetmap.org/"
@ -198,7 +198,6 @@ export class OsmNode extends OsmObject {
this.LoadData(extraData)
}
/**
*
* const obj = new OsmNode(1234)
@ -213,11 +212,11 @@ export class OsmNode extends OsmObject {
*/
ChangesetXML(changesetId: string, header?: string): string {
let tags = this.TagsXML()
return (
` <node id="${this.id}" ${header ?? ""} ${changesetId ? (' changeset="' + changesetId+ '" ') : ""}${this.VersionXML()} lat="${this.lat}" lon="${this.lon}">
return ` <node id="${this.id}" ${header ?? ""} ${
changesetId ? ' changeset="' + changesetId + '" ' : ""
}${this.VersionXML()} lat="${this.lat}" lon="${this.lon}">
${tags} </node>
`
)
}
SaveExtraData(element) {
@ -269,11 +268,11 @@ export class OsmWay extends OsmObject {
nds += ' <nd ref="' + this.nodes[node] + '"/>\n'
}
return (
` <way id="${this.id}" ${header ?? ""} ${changesetId ? ('changeset="' + changesetId + '" ') : ""} ${this.VersionXML()}>
return ` <way id="${this.id}" ${header ?? ""} ${
changesetId ? 'changeset="' + changesetId + '" ' : ""
} ${this.VersionXML()}>
${nds}${tags} </way>
`
)
}
SaveExtraData(element, allNodes: OsmNode[]) {

View file

@ -132,7 +132,7 @@ class CountryTagger extends SimpleMetaTagger {
CountryTagger.coder
.GetCountryCodeAsync(lon, lat)
.then((countries) => {
if(!countries){
if (!countries) {
console.warn("Country coder returned ", countries)
return
}
@ -315,8 +315,7 @@ export default class SimpleMetaTaggers {
},
(feature) => {
Utils.AddLazyProperty(feature.properties, "_surface", () => {
return "" + GeoOperations.surfaceAreaInSqMeters(feature)
return "" + GeoOperations.surfaceAreaInSqMeters(feature)
})
return true

View file

@ -2,38 +2,26 @@
* The part of the global state which initializes the feature switches, based on default values and on the layoutToUse
*/
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
import {UIEventSource} from "../UIEventSource"
import {QueryParameters} from "../Web/QueryParameters"
import { UIEventSource } from "../UIEventSource"
import { QueryParameters } from "../Web/QueryParameters"
import Constants from "../../Models/Constants"
import {Utils} from "../../Utils"
import { Utils } from "../../Utils"
class FeatureSwitchUtils {
static initSwitch(
key: string,
deflt:boolean,
documentation: string
): UIEventSource<boolean> {
const defaultValue = deflt
const queryParam = QueryParameters.GetQueryParameter(
key,
"" + defaultValue,
documentation
)
// It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened
return queryParam.sync(
(str) => (str === undefined ? defaultValue : str !== "false"),
[],
(b) => (b == defaultValue ? undefined : "" + b)
)
}
static initSwitch(key: string, deflt: boolean, documentation: string): UIEventSource<boolean> {
const defaultValue = deflt
const queryParam = QueryParameters.GetQueryParameter(key, "" + defaultValue, documentation)
// It takes the current layout, extracts the default value for this query parameter. A query parameter event source is then retrieved and flattened
return queryParam.sync(
(str) => (str === undefined ? defaultValue : str !== "false"),
[],
(b) => (b == defaultValue ? undefined : "" + b)
)
}
}
export class OsmConnectionFeatureSwitches {
public readonly featureSwitchFakeUser: UIEventSource<boolean>
public readonly featureSwitchApiURL: UIEventSource<string>
@ -52,8 +40,7 @@ export class OsmConnectionFeatureSwitches {
}
}
export default class FeatureSwitchState extends OsmConnectionFeatureSwitches{
export default class FeatureSwitchState extends OsmConnectionFeatureSwitches {
/**
* The layout that is being used in this run
*/
@ -154,7 +141,6 @@ export default class FeatureSwitchState extends OsmConnectionFeatureSwitches{
"Enable the export as GeoJSON and CSV button"
)
let testingDefaultValue = false
if (
this.featureSwitchApiURL.data !== "osm-test" &&

View file

@ -21,7 +21,9 @@ export class GeoLocationState {
* 'granted' means that it is granted
* 'denied' means that we don't have access
*/
public readonly permission: UIEventSource<GeolocationPermissionState> = new UIEventSource("prompt")
public readonly permission: UIEventSource<GeolocationPermissionState> = new UIEventSource(
"prompt"
)
/**
* Important to determine e.g. if we move automatically on fix or not

View file

@ -69,7 +69,7 @@ export default class LayerState {
new Tag("level", "" + level),
new RegexTag("level", new RegExp("(.*;)?" + level + "(;.*)?")),
]
if(level === "0") {
if (level === "0") {
conditionsOrred.push(new Tag("level", "")) // No level tag is the same as level '0'
}
console.log("Setting levels filter to", conditionsOrred)

View file

@ -1,20 +1,20 @@
import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig"
import {OsmConnection} from "../Osm/OsmConnection"
import {MangroveIdentity} from "../Web/MangroveReviews"
import {Store, Stores, UIEventSource} from "../UIEventSource"
import { OsmConnection } from "../Osm/OsmConnection"
import { MangroveIdentity } from "../Web/MangroveReviews"
import { Store, Stores, UIEventSource } from "../UIEventSource"
import StaticFeatureSource from "../FeatureSource/Sources/StaticFeatureSource"
import {FeatureSource} from "../FeatureSource/FeatureSource"
import {Feature} from "geojson"
import {Utils} from "../../Utils"
import { FeatureSource } from "../FeatureSource/FeatureSource"
import { Feature } from "geojson"
import { Utils } from "../../Utils"
import translators from "../../assets/translators.json"
import codeContributors from "../../assets/contributors.json"
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
import {LayerConfigJson} from "../../Models/ThemeConfig/Json/LayerConfigJson"
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson"
import usersettings from "../../assets/generated/layers/usersettings.json"
import Locale from "../../UI/i18n/Locale"
import LinkToWeblate from "../../UI/Base/LinkToWeblate"
import FeatureSwitchState from "./FeatureSwitchState"
import Constants from "../../Models/Constants";
import Constants from "../../Models/Constants"
/**
* The part of the state which keeps track of user-related stuff, e.g. the OSM-connection,
@ -34,8 +34,8 @@ export default class UserRelatedState {
public readonly mangroveIdentity: MangroveIdentity
public readonly installedUserThemes: Store<string[]>
public readonly showAllQuestionsAtOnce: UIEventSource<boolean>
public static readonly SHOW_TAGS_VALUES = ["always","yes","full"] as const
public readonly showTags: UIEventSource<"no" | undefined | "always" | "yes" | "full">;
public static readonly SHOW_TAGS_VALUES = ["always", "yes", "full"] as const
public readonly showTags: UIEventSource<"no" | undefined | "always" | "yes" | "full">
public readonly homeLocation: FeatureSource
public readonly language: UIEventSource<string>
/**
@ -102,26 +102,22 @@ export default class UserRelatedState {
}
private static initUserRelatedState(): LayerConfig {
try{
return new LayerConfig(
<LayerConfigJson>usersettings,
"userinformationpanel"
)
}catch(e){
try {
return new LayerConfig(<LayerConfigJson>usersettings, "userinformationpanel")
} catch (e) {
return undefined
}
}
public GetUnofficialTheme(id: string):
| {
id: string
icon: string
title: any
shortDescription: any
definition?: any
isOfficial: boolean
}
id: string
icon: string
title: any
shortDescription: any
definition?: any
isOfficial: boolean
}
| undefined {
console.log("GETTING UNOFFICIAL THEME")
const pref = this.osmConnection.GetLongPreference("unofficial-theme-" + id)
@ -146,8 +142,8 @@ export default class UserRelatedState {
} catch (e) {
console.warn(
"Removing theme " +
id +
" as it could not be parsed from the preferences; the content is:",
id +
" as it could not be parsed from the preferences; the content is:",
str
)
pref.setData(null)
@ -184,7 +180,7 @@ export default class UserRelatedState {
}
private InitializeLanguage(availableLanguages?: string[]) {
this.language.addCallbackAndRunD(language => Locale.language.setData(language))
this.language.addCallbackAndRunD((language) => Locale.language.setData(language))
Locale.language.addCallback((currentLanguage) => {
if (Locale.showLinkToWeblate.data) {
return true // Disable auto switching as we are in translators mode
@ -262,7 +258,8 @@ export default class UserRelatedState {
_theme: layout?.id,
_backend: this.osmConnection.Backend(),
_applicationOpened: new Date().toISOString(),
_supports_sharing: (typeof window === "undefined") ? "no" : (window.navigator.share ? "yes" : "no")
_supports_sharing:
typeof window === "undefined" ? "no" : window.navigator.share ? "yes" : "no",
})
for (const key in Constants.userJourney) {
@ -297,13 +294,13 @@ export default class UserRelatedState {
const zenLinks: { link: string; id: string }[] = Utils.NoNull([
hasMissingTheme
? {
id: "theme:" + layout.id,
link: LinkToWeblate.hrefToWeblateZen(
language,
"themes",
layout.id
),
}
id: "theme:" + layout.id,
link: LinkToWeblate.hrefToWeblateZen(
language,
"themes",
layout.id
),
}
: undefined,
...missingLayers.map((id) => ({
id: "layer:" + id,
@ -375,7 +372,7 @@ export default class UserRelatedState {
// Language is managed seperately
continue
}
this.osmConnection.GetPreference(key, undefined, {prefix: ""}).setData(tags[key])
this.osmConnection.GetPreference(key, undefined, { prefix: "" }).setData(tags[key])
}
})

View file

@ -1,5 +1,5 @@
import {Tag} from "./Tag"
import {TagsFilter} from "./TagsFilter"
import { Tag } from "./Tag"
import { TagsFilter } from "./TagsFilter"
export class RegexTag extends TagsFilter {
public readonly key: RegExp | string
@ -39,7 +39,6 @@ export class RegexTag extends TagsFilter {
return fromTag === possibleRegex
}
return possibleRegex.test(fromTag)
}
private static source(r: string | RegExp) {
@ -155,7 +154,7 @@ export class RegexTag extends TagsFilter {
matchesProperties(tags: Record<string, string | number | boolean>): boolean {
if (typeof this.key === "string") {
let value = tags[this.key]
if(!value || value === ""){
if (!value || value === "") {
// No tag is known, so we assume the empty string
// If this regexTag matches the empty string, we return true, otherwise false
// (Note: if inverted, we must reverse this)
@ -176,7 +175,7 @@ export class RegexTag extends TagsFilter {
return !this.invert
}
}
if(typeof value !== "string"){
if (typeof value !== "string") {
value = JSON.stringify(value)
}
return RegexTag.doesMatch(value, this.value) != this.invert
@ -188,7 +187,7 @@ export class RegexTag extends TagsFilter {
}
if (RegexTag.doesMatch(key, this.key)) {
let value = tags[key] ?? ""
if(typeof value !== "string"){
if (typeof value !== "string") {
value = JSON.stringify(value)
}
return RegexTag.doesMatch(value, this.value) != this.invert

View file

@ -47,14 +47,14 @@ export class Tag extends TagsFilter {
// and it shouldn't be found!
return true
}
if(typeof foundValue !== "string"){
if(foundValue === true && (this.value === "true" || this.value === "yes" )){
if (typeof foundValue !== "string") {
if (foundValue === true && (this.value === "true" || this.value === "yes")) {
return true
}
if(foundValue === false && (this.value === "false" || this.value === "no" )){
if (foundValue === false && (this.value === "false" || this.value === "no")) {
return true
}
foundValue = ""+foundValue
foundValue = "" + foundValue
}
return foundValue === this.value
}

View file

@ -22,7 +22,7 @@ export class TagUtils {
]
static KVtoProperties(tags: Tag[]): Record<string, string> {
const properties : Record<string, string> = {}
const properties: Record<string, string> = {}
for (const tag of tags) {
properties[tag.key] = tag.value
}

View file

@ -416,7 +416,7 @@ class MappedStore<TIn, T> extends Store<T> {
this._upstreamPingCount = upstreamListenerHandler?.pingCount
this._extraStores = extraStores
this.registerCallbacksToUpstream()
if(onDestroy !== undefined){
if (onDestroy !== undefined) {
onDestroy(() => this.unregisterFromUpstream())
}
}
@ -698,7 +698,11 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
* srcSeen // => 21
* lastSeen // => 42
*/
public map<J>(f: (t: T) => J, extraSources: Store<any>[] = [], onDestroy?: (f : () => void ) => void): Store<J> {
public map<J>(
f: (t: T) => J,
extraSources: Store<any>[] = [],
onDestroy?: (f: () => void) => void
): Store<J> {
return new MappedStore(this, f, extraSources, this._callbacks, f(this.data), onDestroy)
}
/**

View file

@ -76,7 +76,8 @@ export default class FeatureReviews {
) {
const centerLonLat = GeoOperations.centerpointCoordinates(feature)
;[this._lon, this._lat] = centerLonLat
this._identity = mangroveIdentity ?? new MangroveIdentity(new UIEventSource<string>(undefined))
this._identity =
mangroveIdentity ?? new MangroveIdentity(new UIEventSource<string>(undefined))
const nameKey = options?.nameKey ?? "name"
if (feature.geometry.type === "Point") {
@ -103,7 +104,7 @@ export default class FeatureReviews {
this._uncertainty = options?.uncertaintyRadius ?? maxDistance
}
this._name = tagsSource .map((tags) => tags[nameKey] ?? options?.fallbackName)
this._name = tagsSource.map((tags) => tags[nameKey] ?? options?.fallbackName)
this.subjectUri = this.ConstructSubjectUri()

View file

@ -1,8 +1,8 @@
import ThemeViewState from "../../Models/ThemeViewState";
import Hash from "./Hash";
import ThemeViewState from "../../Models/ThemeViewState"
import Hash from "./Hash"
export default class ThemeViewStateHashActor {
private readonly _state: ThemeViewState;
private readonly _state: ThemeViewState
/**
* Converts the hash to the appropriate themeview state and, vice versa, sets the hash.
@ -15,27 +15,27 @@ export default class ThemeViewStateHashActor {
* @param state
*/
constructor(state: ThemeViewState) {
this._state = state;
this._state = state
// First of all, try to recover the selected element
if (Hash.hash.data) {
const hash = Hash.hash.data
this.loadStateFromHash(hash)
Hash.hash.setData(hash) // reapply the previous hash
state.indexedFeatures.featuresById.addCallbackAndRunD(_ => {
let unregister = this.loadSelectedElementFromHash(hash);
state.indexedFeatures.featuresById.addCallbackAndRunD((_) => {
let unregister = this.loadSelectedElementFromHash(hash)
// once that we have found a matching element, we can be sure the indexedFeaturesource was popuplated and that the job is done
return unregister
})
}
// Register a hash change listener to correctly handle the back button
Hash.hash.addCallback(hash => {
Hash.hash.addCallback((hash) => {
if (!!hash) {
// There is still a hash
// We _only_ have to (at most) close the overlays in this case
const parts = hash.split(";")
if(parts.indexOf("background") < 0){
if (parts.indexOf("background") < 0) {
state.guistate.backgroundLayerSelectionIsOpened.setData(false)
}
this.loadSelectedElementFromHash(hash)
@ -46,16 +46,14 @@ export default class ThemeViewStateHashActor {
// At last, register callbacks on the state to update the hash when they change.
// Note: these should use 'addCallback', not 'addCallbackAndRun'
state.selectedElement.addCallback(_ => this.setHash())
state.guistate.allToggles.forEach(({toggle, submenu}) => {
submenu?.addCallback(_ => this.setHash())
toggle.addCallback(_ => this.setHash());
state.selectedElement.addCallback((_) => this.setHash())
state.guistate.allToggles.forEach(({ toggle, submenu }) => {
submenu?.addCallback((_) => this.setHash())
toggle.addCallback((_) => this.setHash())
})
// When all is done, set the hash. This must happen last to give the code above correct info
this.setHash()
}
/**
@ -103,8 +101,7 @@ export default class ThemeViewStateHashActor {
private loadStateFromHash(hash: string) {
const state = this._state
const parts = hash.split(";")
outer: for (const {toggle, name, showOverOthers, submenu} of state.guistate.allToggles) {
outer: for (const { toggle, name, showOverOthers, submenu } of state.guistate.allToggles) {
for (const part of parts) {
if (part === name) {
toggle.setData(true)
@ -125,17 +122,15 @@ export default class ThemeViewStateHashActor {
// If we arrive here, the loop above has not found any match
toggle.setData(false)
}
}
private setHash() {
const s = this._state
let h = ""
for (const {toggle, showOverOthers, name, submenu} of s.guistate.allToggles) {
for (const { toggle, showOverOthers, name, submenu } of s.guistate.allToggles) {
if (showOverOthers || !toggle.data) {
continue;
continue
}
h = name
if (submenu?.data) {
@ -147,9 +142,9 @@ export default class ThemeViewStateHashActor {
h = s.selectedElement.data.properties.id
}
for (const {toggle, showOverOthers, name, submenu} of s.guistate.allToggles) {
for (const { toggle, showOverOthers, name, submenu } of s.guistate.allToggles) {
if (!showOverOthers || !toggle.data) {
continue;
continue
}
if (h) {
h += ";" + name
@ -161,7 +156,6 @@ export default class ThemeViewStateHashActor {
}
}
Hash.hash.setData(h)
}
private back() {
@ -176,5 +170,4 @@ export default class ThemeViewStateHashActor {
return
}
}
}