chore: automated housekeeping...

This commit is contained in:
Pieter Vander Vennet 2024-08-23 13:13:41 +02:00
parent 18e977db2a
commit 22a7a14880
111 changed files with 25070 additions and 1612 deletions

View file

@ -148,16 +148,19 @@ export class RasterLayerUtils {
ignoreLayer?: RasterLayerPolygon,
skipLayers: number = 0
): RasterLayerPolygon {
const inCategory = available.filter(l => l.properties.category === preferredCategory)
const best : RasterLayerPolygon[] = inCategory.filter(l => l.properties.best)
const others : RasterLayerPolygon[] = inCategory.filter(l => !l.properties.best)
const inCategory = available.filter((l) => l.properties.category === preferredCategory)
const best: RasterLayerPolygon[] = inCategory.filter((l) => l.properties.best)
const others: RasterLayerPolygon[] = inCategory.filter((l) => !l.properties.best)
let all = best.concat(others)
console.log("Selected layers are:", all.map(l => l.properties.id))
if(others.length > skipLayers){
console.log(
"Selected layers are:",
all.map((l) => l.properties.id)
)
if (others.length > skipLayers) {
all = all.slice(skipLayers)
}
return all.find(l => l !== ignoreLayer)
return all.find((l) => l !== ignoreLayer)
}
}

View file

@ -25,7 +25,7 @@ export class UpdateLegacyLayer extends DesugaringStep<
context = context.enter(json.id)
let config = { ...json }
if(config["credits"] === "Not logged in"){
if (config["credits"] === "Not logged in") {
delete config["credits"]
}
@ -146,7 +146,7 @@ export class UpdateLegacyLayer extends DesugaringStep<
delete config["wayHandling"]
delete config["hideUnderlayingFeaturesMinPercentage"]
const src = config.source
if(src){
if (src) {
delete src["isOsmCache"]
delete src["maxCacheAge"]
delete src["widenFactor"]

View file

@ -42,7 +42,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
super(
"Expands filters: replaces a shorthand by the value found in 'filters.json'. If the string is formatted 'layername.filtername, it will be looked up into that layer instead",
["filter"],
"ExpandFilter",
"ExpandFilter"
)
this._state = state
}
@ -112,7 +112,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
context
.enters("filter", i)
.err(
"Found a matching tagRendering to base a filter on, but this tagRendering does not contain any mappings",
"Found a matching tagRendering to base a filter on, but this tagRendering does not contain any mappings"
)
}
const options = matchingTr.mappings.map((mapping) => ({
@ -137,7 +137,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
const split = filter.split(".")
if (split.length > 2) {
context.err(
"invalid filter name: " + filter + ", expected `layername.filterid`",
"invalid filter name: " + filter + ", expected `layername.filterid`"
)
}
const layer = this._state.sharedLayers.get(split[0])
@ -146,7 +146,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
}
const expectedId = split[1]
const expandedFilter = (<(FilterConfigJson | string)[]>layer.filter).find(
(f) => typeof f !== "string" && f.id === expectedId,
(f) => typeof f !== "string" && f.id === expectedId
)
if (expandedFilter === undefined) {
context.err("Did not find filter with name " + filter)
@ -164,15 +164,15 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
const suggestions = Utils.sortedByLevenshteinDistance(
filter,
Array.from(ExpandFilter.predefinedFilters.keys()),
(t) => t,
(t) => t
)
context
.enter(filter)
.err(
"While searching for predefined filter " +
filter +
": this filter is not found. Perhaps you meant one of: " +
suggestions,
filter +
": this filter is not found. Perhaps you meant one of: " +
suggestions
)
}
newFilters.push(found)
@ -185,9 +185,9 @@ class ExpandTagRendering extends Conversion<
| string
| TagRenderingConfigJson
| {
builtin: string | string[]
override: any
},
builtin: string | string[]
override: any
},
TagRenderingConfigJson[]
> {
private readonly _state: DesugaringContext
@ -209,12 +209,12 @@ class ExpandTagRendering extends Conversion<
noHardcodedStrings?: false | boolean
// If set, a question will be added to the 'sharedTagRenderings'. Should only be used for 'questions.json'
addToContext?: false | boolean
},
}
) {
super(
"Converts a tagRenderingSpec into the full tagRendering, e.g. by substituting the tagRendering by the shared-question and reusing the builtins",
[],
"ExpandTagRendering",
"ExpandTagRendering"
)
this._state = state
this._self = self
@ -234,7 +234,7 @@ class ExpandTagRendering extends Conversion<
public convert(
spec: string | any,
ctx: ConversionContext,
ctx: ConversionContext
): QuestionableTagRenderingConfigJson[] {
const trs = this.convertOnce(spec, ctx)
@ -347,8 +347,8 @@ class ExpandTagRendering extends Conversion<
found,
ConversionContext.construct(
[layer.id, "tagRenderings", found["id"]],
["AddContextToTranslations"],
),
["AddContextToTranslations"]
)
)
matchingTrs[i] = found
}
@ -376,17 +376,17 @@ class ExpandTagRendering extends Conversion<
ctx.warn(
`A literal rendering was detected: ${tr}
Did you perhaps forgot to add a layer name as 'layername.${tr}'? ` +
Array.from(state.sharedLayers.keys()).join(", "),
Array.from(state.sharedLayers.keys()).join(", ")
)
}
if (this._options?.noHardcodedStrings && this._state?.sharedLayers?.size > 0) {
ctx.err(
"Detected an invocation to a builtin tagRendering, but this tagrendering was not found: " +
tr +
" \n Did you perhaps forget to add the layer as prefix, such as `icons." +
tr +
"`? ",
tr +
" \n Did you perhaps forget to add the layer as prefix, such as `icons." +
tr +
"`? "
)
}
@ -421,9 +421,9 @@ class ExpandTagRendering extends Conversion<
}
ctx.err(
"An object calling a builtin can only have keys `builtin` or `override`, but a key with name `" +
key +
"` was found. This won't be picked up! The full object is: " +
JSON.stringify(tr),
key +
"` was found. This won't be picked up! The full object is: " +
JSON.stringify(tr)
)
}
@ -442,39 +442,39 @@ class ExpandTagRendering extends Conversion<
const candidates = Utils.sortedByLevenshteinDistance(
layerName,
Array.from(state.sharedLayers.keys()),
(s) => s,
(s) => s
)
if (state.sharedLayers.size === 0) {
ctx.warn(
"BOOTSTRAPPING. Rerun generate layeroverview. While reusing tagrendering: " +
name +
": layer " +
layerName +
" not found for now, but ignoring as this is a bootstrapping run. ",
name +
": layer " +
layerName +
" not found for now, but ignoring as this is a bootstrapping run. "
)
} else {
ctx.err(
": While reusing tagrendering: " +
name +
": layer " +
layerName +
" not found. Maybe you meant one of " +
candidates.slice(0, 3).join(", "),
name +
": layer " +
layerName +
" not found. Maybe you meant one of " +
candidates.slice(0, 3).join(", ")
)
}
continue
}
candidates = Utils.NoNull(layer.tagRenderings.map((tr) => tr["id"])).map(
(id) => layerName + "." + id,
(id) => layerName + "." + id
)
}
candidates = Utils.sortedByLevenshteinDistance(name, candidates, (i) => i)
ctx.err(
"The tagRendering with identifier " +
name +
" was not found.\n\tDid you mean one of " +
candidates.join(", ") +
"?\n(Hint: did you add a new label and are you trying to use this label at the same time? Run 'reset:layeroverview' first",
name +
" was not found.\n\tDid you mean one of " +
candidates.join(", ") +
"?\n(Hint: did you add a new label and are you trying to use this label at the same time? Run 'reset:layeroverview' first"
)
continue
}
@ -499,13 +499,13 @@ class DetectInline extends DesugaringStep<QuestionableTagRenderingConfigJson> {
super(
"If no 'inline' is set on the freeform key, it will be automatically added. If no special renderings are used, it'll be set to true",
["freeform.inline"],
"DetectInline",
"DetectInline"
)
}
convert(
json: QuestionableTagRenderingConfigJson,
context: ConversionContext,
context: ConversionContext
): QuestionableTagRenderingConfigJson {
if (json.freeform === undefined) {
return json
@ -528,7 +528,7 @@ class DetectInline extends DesugaringStep<QuestionableTagRenderingConfigJson> {
if (json.freeform.inline === true) {
context.err(
"'inline' is set, but the rendering contains a special visualisation...\n " +
spec[key],
spec[key]
)
}
json = JSON.parse(JSON.stringify(json))
@ -551,7 +551,7 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
super(
"Adds a 'questions'-object if no question element is added yet",
["tagRenderings"],
"AddQuestionBox",
"AddQuestionBox"
)
}
@ -575,18 +575,18 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
json.tagRenderings = [...json.tagRenderings]
const allSpecials: Exclude<RenderingSpecification, string>[] = <any>(
ValidationUtils.getAllSpecialVisualisations(
<QuestionableTagRenderingConfigJson[]>json.tagRenderings,
<QuestionableTagRenderingConfigJson[]>json.tagRenderings
).filter((spec) => typeof spec !== "string")
)
const questionSpecials = allSpecials.filter((sp) => sp.func.funcName === "questions")
const noLabels = questionSpecials.filter(
(sp) => sp.args.length === 0 || sp.args[0].trim() === "",
(sp) => sp.args.length === 0 || sp.args[0].trim() === ""
)
if (noLabels.length > 1) {
context.err(
"Multiple 'questions'-visualisations found which would show _all_ questions. Don't do this",
"Multiple 'questions'-visualisations found which would show _all_ questions. Don't do this"
)
}
@ -594,9 +594,9 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
const allLabels = new Set(
[].concat(
...json.tagRenderings.map(
(tr) => (<QuestionableTagRenderingConfigJson>tr).labels ?? [],
),
),
(tr) => (<QuestionableTagRenderingConfigJson>tr).labels ?? []
)
)
)
const seen: Set<string> = new Set()
for (const questionSpecial of questionSpecials) {
@ -614,20 +614,20 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
if (blacklisted?.length > 0 && used?.length > 0) {
context.err(
"The {questions()}-special rendering only supports either a blacklist OR a whitelist, but not both." +
"\n Whitelisted: " +
used.join(", ") +
"\n Blacklisted: " +
blacklisted.join(", "),
"\n Whitelisted: " +
used.join(", ") +
"\n Blacklisted: " +
blacklisted.join(", ")
)
}
for (const usedLabel of used) {
if (!allLabels.has(usedLabel)) {
context.err(
"This layers specifies a special question element for label `" +
usedLabel +
"`, but this label doesn't exist.\n" +
" Available labels are " +
Array.from(allLabels).join(", "),
usedLabel +
"`, but this label doesn't exist.\n" +
" Available labels are " +
Array.from(allLabels).join(", ")
)
}
seen.add(usedLabel)
@ -660,7 +660,7 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
super(
"Add some editing elements, such as the delete button or the move button if they are configured. These used to be handled by the feature info box, but this has been replaced by special visualisation elements",
[],
"AddEditingElements",
"AddEditingElements"
)
this._desugaring = desugaring
this.builtinQuestions = Array.from(this._desugaring.tagRenderings?.values() ?? [])
@ -690,13 +690,13 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
json.tagRenderings = [...(json.tagRenderings ?? [])]
const allIds = new Set<string>(json.tagRenderings.map((tr) => tr["id"]))
const specialVisualisations = ValidationUtils.getAllSpecialVisualisations(
<any>json.tagRenderings,
<any>json.tagRenderings
)
const usedSpecialFunctions = new Set(
specialVisualisations.map((sv) =>
typeof sv === "string" ? undefined : sv.func.funcName,
),
typeof sv === "string" ? undefined : sv.func.funcName
)
)
/***** ADD TO TOP ****/
@ -764,7 +764,7 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
super(
"Converts a 'special' translation into a regular translation which uses parameters",
["special"],
"RewriteSpecial",
"RewriteSpecial"
)
}
@ -855,12 +855,12 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
private static convertIfNeeded(
input:
| (object & {
special: {
type: string
}
})
special: {
type: string
}
})
| any,
context: ConversionContext,
context: ConversionContext
): any {
const special = input["special"]
if (special === undefined) {
@ -870,7 +870,7 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
const type = special["type"]
if (type === undefined) {
context.err(
"A 'special'-block should define 'type' to indicate which visualisation should be used",
"A 'special'-block should define 'type' to indicate which visualisation should be used"
)
return undefined
}
@ -880,10 +880,10 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
const options = Utils.sortedByLevenshteinDistance(
type,
SpecialVisualizations.specialVisualizations,
(sp) => sp.funcName,
(sp) => sp.funcName
)
context.err(
`Special visualisation '${type}' not found. Did you perhaps mean ${options[0].funcName}, ${options[1].funcName} or ${options[2].funcName}?\n\tFor all known special visualisations, please see https://github.com/pietervdvn/MapComplete/blob/develop/Docs/SpecialRenderings.md`,
`Special visualisation '${type}' not found. Did you perhaps mean ${options[0].funcName}, ${options[1].funcName} or ${options[2].funcName}?\n\tFor all known special visualisations, please see https://github.com/pietervdvn/MapComplete/blob/develop/Docs/SpecialRenderings.md`
)
return undefined
}
@ -904,7 +904,7 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
const byDistance = Utils.sortedByLevenshteinDistance(
wrongArg,
argNamesList,
(x) => x,
(x) => x
)
return `Unexpected argument in special block at ${context} with name '${wrongArg}'. Did you mean ${
byDistance[0]
@ -923,8 +923,8 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
`Obligated parameter '${arg.name}' in special rendering of type ${
vis.funcName
} not found.\n The full special rendering specification is: '${JSON.stringify(
input,
)}'\n ${arg.name}: ${arg.doc}`,
input
)}'\n ${arg.name}: ${arg.doc}`
)
}
}
@ -1026,7 +1026,7 @@ export class RewriteSpecial extends DesugaringStep<TagRenderingConfigJson> {
continue
}
Utils.WalkPath(path.path, json, (leaf, travelled) =>
RewriteSpecial.convertIfNeeded(leaf, context.enter(travelled)),
RewriteSpecial.convertIfNeeded(leaf, context.enter(travelled))
)
}
@ -1060,7 +1060,7 @@ class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson> {
} = badgesJson[i]
const expanded = this._expand.convert(
<QuestionableTagRenderingConfigJson>iconBadge.then,
context.enters("iconBadges", i),
context.enters("iconBadges", i)
)
if (expanded === undefined) {
iconBadges.push(iconBadge)
@ -1071,7 +1071,7 @@ class ExpandIconBadges extends DesugaringStep<PointRenderingConfigJson> {
...expanded.map((resolved) => ({
if: iconBadge.if,
then: <MinimalTagRenderingConfigJson>resolved,
})),
}))
)
}
@ -1088,11 +1088,11 @@ class PreparePointRendering extends Fuse<PointRenderingConfigJson> {
new Each(
new On(
"icon",
new FirstOf(new ExpandTagRendering(state, layer, { applyCondition: false })),
),
),
new FirstOf(new ExpandTagRendering(state, layer, { applyCondition: false }))
)
)
),
new ExpandIconBadges(state, layer),
new ExpandIconBadges(state, layer)
)
}
}
@ -1102,7 +1102,7 @@ class SetFullNodeDatabase extends DesugaringStep<LayerConfigJson> {
super(
"sets the fullNodeDatabase-bit if needed",
["fullNodeDatabase"],
"SetFullNodeDatabase",
"SetFullNodeDatabase"
)
}
@ -1131,7 +1131,7 @@ class ExpandMarkerRenderings extends DesugaringStep<IconConfigJson> {
super(
"Expands tagRenderings in the icons, if needed",
["icon", "color"],
"ExpandMarkerRenderings",
"ExpandMarkerRenderings"
)
this._layer = layer
this._state = state
@ -1163,7 +1163,7 @@ class AddFavouriteBadges extends DesugaringStep<LayerConfigJson> {
super(
"Adds the favourite heart to the title and the rendering badges",
[],
"AddFavouriteBadges",
"AddFavouriteBadges"
)
}
@ -1188,7 +1188,7 @@ export class AddRatingBadge extends DesugaringStep<LayerConfigJson> {
super(
"Adds the 'rating'-element if a reviews-element is used in the tagRenderings",
["titleIcons"],
"AddRatingBadge",
"AddRatingBadge"
)
}
@ -1207,8 +1207,8 @@ export class AddRatingBadge extends DesugaringStep<LayerConfigJson> {
const specialVis: Exclude<RenderingSpecification, string>[] = <
Exclude<RenderingSpecification, string>[]
>ValidationUtils.getAllSpecialVisualisations(<any>json.tagRenderings).filter(
(rs) => typeof rs !== "string",
>ValidationUtils.getAllSpecialVisualisations(<any>json.tagRenderings).filter(
(rs) => typeof rs !== "string"
)
const funcs = new Set<string>(specialVis.map((rs) => rs.func.funcName))
@ -1224,12 +1224,12 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
super(
"The auto-icon creates a (non-clickable) title icon based on a tagRendering which has icons",
["titleIcons"],
"AutoTitleIcon",
"AutoTitleIcon"
)
}
private createTitleIconsBasedOn(
tr: QuestionableTagRenderingConfigJson,
tr: QuestionableTagRenderingConfigJson
): TagRenderingConfigJson | undefined {
const mappings: { if: TagConfigJson; then: string }[] = tr.mappings
?.filter((m) => m.icon !== undefined)
@ -1259,7 +1259,7 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
return undefined
}
return this.createTitleIconsBasedOn(<any>tr)
}),
})
)
json.titleIcons.splice(allAutoIndex, 1, ...generated)
return json
@ -1288,8 +1288,8 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
.enters("titleIcons", i)
.warn(
"TagRendering with id " +
trId +
" does not have any icons, not generating an icon for this",
trId +
" does not have any icons, not generating an icon for this"
)
continue
}
@ -1300,9 +1300,12 @@ export class AutoTitleIcon extends DesugaringStep<LayerConfigJson> {
}
class DeriveSource extends DesugaringStep<LayerConfigJson> {
constructor() {
super("If no source is given, automatically derives the osmTags by 'or'-ing all the preset tags", ["source"], "DeriveSource")
super(
"If no source is given, automatically derives the osmTags by 'or'-ing all the preset tags",
["source"],
"DeriveSource"
)
}
public convert(json: LayerConfigJson, context: ConversionContext): LayerConfigJson {
@ -1310,13 +1313,15 @@ class DeriveSource extends DesugaringStep<LayerConfigJson> {
return json
}
if (!json.presets) {
context.err("No source tags given. Trying to derive the source-tags based on the presets, but no presets are given")
context.err(
"No source tags given. Trying to derive the source-tags based on the presets, but no presets are given"
)
return json
}
json = { ...json }
const raw = { or: json.presets.map(pr => ({ and: pr.tags })) }
const raw = { or: json.presets.map((pr) => ({ and: pr.tags })) }
const osmTags = TagUtils.optimzeJson(raw)
if (osmTags === false) {
context.err("The preset-tags optimize to 'false' " + JSON.stringify(raw))
@ -1330,13 +1335,12 @@ class DeriveSource extends DesugaringStep<LayerConfigJson> {
json.source = { osmTags }
return json
}
}
export class PrepareLayer extends Fuse<LayerConfigJson> {
constructor(
state: DesugaringContext,
options?: { addTagRenderingsToContext?: false | boolean },
options?: { addTagRenderingsToContext?: false | boolean }
) {
super(
"Fully prepares and expands a layer for the LayerConfig.",
@ -1349,8 +1353,8 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
new Concat(
new ExpandTagRendering(state, layer, {
addToContext: options?.addTagRenderingsToContext ?? false,
}),
),
})
)
),
new On("tagRenderings", new Each(new DetectInline())),
new AddQuestionBox(),
@ -1363,11 +1367,11 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
new On<PointRenderingConfigJson[], LayerConfigJson>(
"pointRendering",
(layer) =>
new Each(new On("marker", new Each(new ExpandMarkerRenderings(state, layer)))),
new Each(new On("marker", new Each(new ExpandMarkerRenderings(state, layer))))
),
new On<PointRenderingConfigJson[], LayerConfigJson>(
"pointRendering",
(layer) => new Each(new PreparePointRendering(state, layer)),
(layer) => new Each(new PreparePointRendering(state, layer))
),
new SetDefault("titleIcons", ["icons.defaults"]),
new AddRatingBadge(),
@ -1376,9 +1380,9 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
new On(
"titleIcons",
(layer) =>
new Concat(new ExpandTagRendering(state, layer, { noHardcodedStrings: true })),
new Concat(new ExpandTagRendering(state, layer, { noHardcodedStrings: true }))
),
new ExpandFilter(state),
new ExpandFilter(state)
)
}
}

View file

@ -25,7 +25,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
path: string,
isBuiltin: boolean,
doesImageExist: DoesImageExist,
studioValidations: boolean,
studioValidations: boolean
) {
super("Runs various checks against common mistakes for a layer", [], "PrevalidateLayer")
this._path = path
@ -49,11 +49,10 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (json.source === undefined) {
if (json.presets?.length < 1) {
context
.enter("source")
.err(
"No source section is defined; please define one as data is not loaded otherwise",
"No source section is defined; please define one as data is not loaded otherwise"
)
}
} else {
@ -62,7 +61,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
context
.enters("source", "osmTags")
.err(
"No osmTags defined in the source section - these should always be present, even for geojson layer",
"No osmTags defined in the source section - these should always be present, even for geojson layer"
)
} else {
const osmTags = TagUtils.Tag(json.source["osmTags"], context + "source.osmTags")
@ -71,7 +70,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
.enters("source", "osmTags")
.err(
"The source states tags which give a very wide selection: it only uses negative expressions, which will result in too much and unexpected data. Add at least one required tag. The tags are:\n\t" +
osmTags.asHumanString(false, false, {}),
osmTags.asHumanString(false, false, {})
)
}
}
@ -97,10 +96,10 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
.enter("syncSelection")
.err(
"Invalid sync-selection: must be one of " +
LayerConfig.syncSelectionAllowed.map((v) => `'${v}'`).join(", ") +
" but got '" +
json.syncSelection +
"'",
LayerConfig.syncSelectionAllowed.map((v) => `'${v}'`).join(", ") +
" but got '" +
json.syncSelection +
"'"
)
}
if (json["pointRenderings"]?.length > 0) {
@ -119,7 +118,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
}
json.pointRendering?.forEach((pr, i) =>
this._validatePointRendering.convert(pr, context.enters("pointeRendering", i)),
this._validatePointRendering.convert(pr, context.enters("pointeRendering", i))
)
if (json["mapRendering"]) {
@ -136,8 +135,8 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (!Constants.priviliged_layers.find((x) => x == json.id)) {
context.err(
"Layer " +
json.id +
" uses 'special' as source.osmTags. However, this layer is not a privileged layer",
json.id +
" uses 'special' as source.osmTags. However, this layer is not a privileged layer"
)
}
}
@ -152,19 +151,19 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
context
.enter("title")
.err(
"This layer does not have a title defined but it does have tagRenderings. Not having a title will disable the popups, resulting in an unclickable element. Please add a title. If not having a popup is intended and the tagrenderings need to be kept (e.g. in a library layer), set `title: null` to disable this error.",
"This layer does not have a title defined but it does have tagRenderings. Not having a title will disable the popups, resulting in an unclickable element. Please add a title. If not having a popup is intended and the tagrenderings need to be kept (e.g. in a library layer), set `title: null` to disable this error."
)
}
if (json.title === null) {
context.info(
"Title is `null`. This results in an element that cannot be clicked - even though tagRenderings is set.",
"Title is `null`. This results in an element that cannot be clicked - even though tagRenderings is set."
)
}
{
// Check for multiple, identical builtin questions - usability for studio users
const duplicates = Utils.Duplicates(
<string[]>json.tagRenderings.filter((tr) => typeof tr === "string"),
<string[]>json.tagRenderings.filter((tr) => typeof tr === "string")
)
for (let i = 0; i < json.tagRenderings.length; i++) {
const tagRendering = json.tagRenderings[i]
@ -194,7 +193,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
{
// duplicate ids in tagrenderings check
const duplicates = Utils.NoNull(
Utils.Duplicates(Utils.NoNull((json.tagRenderings ?? []).map((tr) => tr["id"]))),
Utils.Duplicates(Utils.NoNull((json.tagRenderings ?? []).map((tr) => tr["id"])))
)
if (duplicates.length > 0) {
// It is tempting to add an index to this warning; however, due to labels the indices here might be different from the index in the tagRendering list
@ -202,11 +201,11 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
.enter("tagRenderings")
.err(
"Some tagrenderings have a duplicate id: " +
duplicates.join(", ") +
"\n" +
JSON.stringify(
json.tagRenderings.filter((tr) => duplicates.indexOf(tr["id"]) >= 0),
),
duplicates.join(", ") +
"\n" +
JSON.stringify(
json.tagRenderings.filter((tr) => duplicates.indexOf(tr["id"]) >= 0)
)
)
}
}
@ -239,8 +238,8 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (json["overpassTags"] !== undefined) {
context.err(
"Layer " +
json.id +
"still uses the old 'overpassTags'-format. Please use \"source\": {\"osmTags\": <tags>}' instead of \"overpassTags\": <tags> (note: this isn't your fault, the custom theme generator still spits out the old format)",
json.id +
'still uses the old \'overpassTags\'-format. Please use "source": {"osmTags": <tags>}\' instead of "overpassTags": <tags> (note: this isn\'t your fault, the custom theme generator still spits out the old format)'
)
}
const forbiddenTopLevel = [
@ -260,7 +259,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
}
if (json["hideUnderlayingFeaturesMinPercentage"] !== undefined) {
context.err(
"Layer " + json.id + " contains an old 'hideUnderlayingFeaturesMinPercentage'",
"Layer " + json.id + " contains an old 'hideUnderlayingFeaturesMinPercentage'"
)
}
@ -277,9 +276,9 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (this._path != undefined && this._path.indexOf(expected) < 0) {
context.err(
"Layer is in an incorrect place. The path is " +
this._path +
", but expected " +
expected,
this._path +
", but expected " +
expected
)
}
}
@ -297,13 +296,13 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
.enter(["tagRenderings", ...emptyIndexes])
.err(
`Some tagrendering-ids are empty or have an emtpy string; this is not allowed (at ${emptyIndexes.join(
",",
)}])`,
","
)}])`
)
}
const duplicateIds = Utils.Duplicates(
(json.tagRenderings ?? [])?.map((f) => f["id"]).filter((id) => id !== "questions"),
(json.tagRenderings ?? [])?.map((f) => f["id"]).filter((id) => id !== "questions")
)
if (duplicateIds.length > 0 && !Utils.runningFromConsole) {
context
@ -327,7 +326,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
if (json.tagRenderings !== undefined) {
new On(
"tagRenderings",
new Each(new ValidateTagRenderings(json, this._doesImageExist)),
new Each(new ValidateTagRenderings(json, this._doesImageExist))
).convert(json, context)
}
@ -354,7 +353,7 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
context
.enters("pointRendering", i, "marker", indexM, "icon", "condition")
.err(
"Don't set a condition in a marker as this will result in an invisible but clickable element. Use extra filters in the source instead.",
"Don't set a condition in a marker as this will result in an invisible but clickable element. Use extra filters in the source instead."
)
}
}
@ -389,16 +388,16 @@ export class PrevalidateLayer extends DesugaringStep<LayerConfigJson> {
for (const tag of tags.asChange({ id: "node/-1" })) {
properties[tag.k] = tag.v
}
if(baseTags) {
if (baseTags) {
const doMatch = baseTags.matchesProperties(properties)
if (!doMatch) {
context
.enters("presets", i, "tags")
.err(
"This preset does not match the required tags of this layer. This implies that a newly added point will not show up.\n A newly created point will have properties: " +
tags.asHumanString(false, false, {}) +
"\n The required tags are: " +
baseTags.asHumanString(false, false, {}),
tags.asHumanString(false, false, {}) +
"\n The required tags are: " +
baseTags.asHumanString(false, false, {})
)
}
}

View file

@ -81,11 +81,11 @@ export default class LayerConfig extends WithContextLoader {
}
this.syncSelection = json.syncSelection ?? "no"
if(!json.source){
if (!json.source) {
this.source = new SourceConfig({
osmTags: TagUtils.Tag({or: json.presets.map(pr => ({and:pr.tags}))})
osmTags: TagUtils.Tag({ or: json.presets.map((pr) => ({ and: pr.tags })) }),
})
}else if (typeof json.source !== "string") {
} else if (typeof json.source !== "string") {
this.maxAgeOfCache = json.source["maxCacheAge"] ?? 24 * 60 * 60 * 30
this.source = new SourceConfig(
{
@ -97,7 +97,7 @@ export default class LayerConfig extends WithContextLoader {
mercatorCrs: json.source["mercatorCrs"],
idKey: json.source["idKey"],
},
json.id,
json.id
)
}
@ -116,7 +116,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.calculatedTags !== undefined) {
if (!official) {
console.warn(
`Unofficial theme ${this.id} with custom javascript! This is a security risk`,
`Unofficial theme ${this.id} with custom javascript! This is a security risk`
)
}
this.calculatedTags = []
@ -186,7 +186,7 @@ export default class LayerConfig extends WithContextLoader {
tags: pr.tags.map((t) => TagUtils.SimpleTag(t)),
description: Translations.T(
pr.description,
`${translationContext}.presets.${i}.description`,
`${translationContext}.presets.${i}.description`
),
preciseInput: preciseInput,
exampleImages: pr.exampleImages,
@ -200,7 +200,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.lineRendering) {
this.lineRendering = Utils.NoNull(json.lineRendering).map(
(r, i) => new LineRenderingConfig(r, `${context}[${i}]`),
(r, i) => new LineRenderingConfig(r, `${context}[${i}]`)
)
} else {
this.lineRendering = []
@ -208,7 +208,7 @@ export default class LayerConfig extends WithContextLoader {
if (json.pointRendering) {
this.mapRendering = Utils.NoNull(json.pointRendering).map(
(r, i) => new PointRenderingConfig(r, `${context}[${i}](${this.id})`),
(r, i) => new PointRenderingConfig(r, `${context}[${i}](${this.id})`)
)
} else {
this.mapRendering = []
@ -220,7 +220,7 @@ export default class LayerConfig extends WithContextLoader {
r.location.has("centroid") ||
r.location.has("projected_centerpoint") ||
r.location.has("start") ||
r.location.has("end"),
r.location.has("end")
)
if (
@ -242,7 +242,7 @@ export default class LayerConfig extends WithContextLoader {
Constants.priviliged_layers.indexOf(<any>this.id) < 0 &&
this.source !== null /*library layer*/ &&
!this.source?.geojsonSource?.startsWith(
"https://api.openstreetmap.org/api/0.6/notes.json",
"https://api.openstreetmap.org/api/0.6/notes.json"
)
) {
throw (
@ -261,7 +261,7 @@ export default class LayerConfig extends WithContextLoader {
typeof tr !== "string" &&
tr["builtin"] === undefined &&
tr["id"] === undefined &&
tr["rewrite"] === undefined,
tr["rewrite"] === undefined
) ?? []
if (missingIds?.length > 0 && official) {
console.error("Some tagRenderings of", this.id, "are missing an id:", missingIds)
@ -272,8 +272,8 @@ export default class LayerConfig extends WithContextLoader {
(tr, i) =>
new TagRenderingConfig(
<QuestionableTagRenderingConfigJson>tr,
this.id + ".tagRenderings[" + i + "]",
),
this.id + ".tagRenderings[" + i + "]"
)
)
if (json.units !== undefined && !Array.isArray(json.units)) {
throw (
@ -283,7 +283,7 @@ export default class LayerConfig extends WithContextLoader {
)
}
this.units = (json.units ?? []).flatMap((unitJson, i) =>
Unit.fromJson(unitJson, this.tagRenderings, `${context}.unit[${i}]`),
Unit.fromJson(unitJson, this.tagRenderings, `${context}.unit[${i}]`)
)
if (
@ -359,7 +359,7 @@ export default class LayerConfig extends WithContextLoader {
public GetBaseTags(): Record<string, string> {
return TagUtils.changeAsProperties(
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }],
this.source?.osmTags?.asChange({ id: "node/-1" }) ?? [{ k: "id", v: "node/-1" }]
)
}
@ -372,7 +372,7 @@ export default class LayerConfig extends WithContextLoader {
neededLayer: string
}[] = [],
addedByDefault = false,
canBeIncluded = true,
canBeIncluded = true
): string {
const extraProps: string[] = []
extraProps.push("This layer is shown at zoomlevel **" + this.minzoom + "** and higher")
@ -380,32 +380,32 @@ export default class LayerConfig extends WithContextLoader {
if (canBeIncluded) {
if (addedByDefault) {
extraProps.push(
"**This layer is included automatically in every theme. This layer might contain no points**",
"**This layer is included automatically in every theme. This layer might contain no points**"
)
}
if (this.shownByDefault === false) {
extraProps.push(
"This layer is not visible by default and must be enabled in the filter by the user. ",
"This layer is not visible by default and must be enabled in the filter by the user. "
)
}
if (this.title === undefined) {
extraProps.push(
"Elements don't have a title set and cannot be toggled nor will they show up in the dashboard. If you import this layer in your theme, override `title` to make this toggleable.",
"Elements don't have a title set and cannot be toggled nor will they show up in the dashboard. If you import this layer in your theme, override `title` to make this toggleable."
)
}
if (this.name === undefined && this.shownByDefault === false) {
extraProps.push(
"This layer is not visible by default and the visibility cannot be toggled, effectively resulting in a fully hidden layer. This can be useful, e.g. to calculate some metatags. If you want to render this layer (e.g. for debugging), enable it by setting the URL-parameter layer-<id>=true",
"This layer is not visible by default and the visibility cannot be toggled, effectively resulting in a fully hidden layer. This can be useful, e.g. to calculate some metatags. If you want to render this layer (e.g. for debugging), enable it by setting the URL-parameter layer-<id>=true"
)
}
if (this.name === undefined) {
extraProps.push(
"Not visible in the layer selection by default. If you want to make this layer toggable, override `name`",
"Not visible in the layer selection by default. If you want to make this layer toggable, override `name`"
)
}
if (this.mapRendering.length === 0) {
extraProps.push(
"Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings`",
"Not rendered on the map by default. If you want to rendering this on the map, override `mapRenderings`"
)
}
@ -415,12 +415,12 @@ export default class LayerConfig extends WithContextLoader {
"<img src='../warning.svg' height='1rem'/>",
"This layer is loaded from an external source, namely ",
"`" + this.source.geojsonSource + "`",
].join("\n\n"),
].join("\n\n")
)
}
} else {
extraProps.push(
"This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data.",
"This layer can **not** be included in a theme. It is solely used by [special renderings](SpecialRenderings.md) showing a minimap with custom data."
)
}
@ -430,7 +430,7 @@ export default class LayerConfig extends WithContextLoader {
usingLayer = [
"## Themes using this layer",
MarkdownUtils.list(
(usedInThemes ?? []).map((id) => `[${id}](https://mapcomplete.org/${id})`),
(usedInThemes ?? []).map((id) => `[${id}](https://mapcomplete.org/${id})`)
),
]
} else if (this.source !== null) {
@ -446,15 +446,15 @@ export default class LayerConfig extends WithContextLoader {
" into the layout as it depends on it: ",
dep.reason,
"(" + dep.context + ")",
].join(" "),
].join(" ")
)
}
for (const revDep of Utils.Dedup(layerIsNeededBy?.get(this.id) ?? [])) {
extraProps.push(
["This layer is needed as dependency for layer", `[${revDep}](#${revDep})`].join(
" ",
),
" "
)
)
}
@ -465,10 +465,10 @@ export default class LayerConfig extends WithContextLoader {
.filter((values) => values.key !== "id")
.map((values) => {
const embedded: string[] = values.values?.map((v) =>
Link.OsmWiki(values.key, v, true).SetClass("mr-2").AsMarkdown(),
Link.OsmWiki(values.key, v, true).SetClass("mr-2").AsMarkdown()
) ?? ["_no preset options defined, or no values in them_"]
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(
values.key,
values.key
)}/`
const tagInfo = `https://taginfo.openstreetmap.org/keys/${values.key}#values`
return [
@ -483,7 +483,7 @@ export default class LayerConfig extends WithContextLoader {
: `[${values.type}](../SpecialInputElements.md#${values.type})`,
embedded.join(" "),
]
}),
})
)
let quickOverview: string[] = []
@ -493,7 +493,7 @@ export default class LayerConfig extends WithContextLoader {
"this quick overview is incomplete",
MarkdownUtils.table(
["attribute", "type", "values which are supported by this layer"],
tableRows,
tableRows
),
]
}
@ -527,19 +527,19 @@ export default class LayerConfig extends WithContextLoader {
const parts = neededTags["and"]
tagsDescription.push(
"Elements must match **all** of the following expressions:",
parts.map((p, i) => i + ". " + p.asHumanString(true, false, {})).join("\n"),
parts.map((p, i) => i + ". " + p.asHumanString(true, false, {})).join("\n")
)
} else if (neededTags["or"]) {
const parts = neededTags["or"]
tagsDescription.push(
"Elements must match **any** of the following expressions:",
parts.map((p) => " - " + p.asHumanString(true, false, {})).join("\n"),
parts.map((p) => " - " + p.asHumanString(true, false, {})).join("\n")
)
} else {
tagsDescription.push(
"Elements must match the expression **" +
neededTags.asHumanString(true, false, {}) +
"**",
neededTags.asHumanString(true, false, {}) +
"**"
)
}

View file

@ -973,11 +973,15 @@ export class TagRenderingConfigUtils {
}
const clone: TagRenderingConfig = Object.create(config)
// The original mappings get "priorityIf" set
const oldMappingsCloned = clone.mappings?.map((m) => (<Mapping> {
...m,
addExtraTags: [new Tag("nobrand","")],
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*"),
})) ?? [];
const oldMappingsCloned =
clone.mappings?.map(
(m) =>
<Mapping>{
...m,
addExtraTags: [new Tag("nobrand", "")],
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*"),
}
) ?? []
clone.mappings = [...oldMappingsCloned, ...extraMappings]
return clone
})

View file

@ -161,7 +161,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.featureSwitches = new FeatureSwitchState(layout)
this.guistate = new MenuState(
this.featureSwitches.featureSwitchWelcomeMessage.data,
layout.id,
layout.id
)
this.map = new UIEventSource<MlMap>(undefined)
const geolocationState = new GeoLocationState()
@ -177,14 +177,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
oauth_token: QueryParameters.GetQueryParameter(
"oauth_token",
undefined,
"Used to complete the login",
"Used to complete the login"
),
})
this.userRelatedState = new UserRelatedState(
this.osmConnection,
layout,
this.featureSwitches,
this.mapProperties,
this.mapProperties
)
this.userRelatedState.fixateNorth.addCallbackAndRunD((fixated) => {
this.mapProperties.allowRotating.setData(fixated !== "yes")
@ -195,20 +195,20 @@ export default class ThemeViewState implements SpecialVisualizationState {
geolocationState,
this.selectedElement,
this.mapProperties,
this.userRelatedState.gpsLocationHistoryRetentionTime,
this.userRelatedState.gpsLocationHistoryRetentionTime
)
this.geolocationControl = new GeolocationControlState(this.geolocation, this.mapProperties)
this.availableLayers = AvailableRasterLayers.layersAvailableAt(
this.mapProperties.location,
this.osmConnection.isLoggedIn,
this.osmConnection.isLoggedIn
)
this.layerState = new LayerState(
this.osmConnection,
layout.layers,
layout.id,
this.featureSwitches.featureSwitchLayerDefault,
this.featureSwitches.featureSwitchLayerDefault
)
{
@ -217,7 +217,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const isDisplayed = QueryParameters.GetBooleanQueryParameter(
"overlay-" + rasterInfo.id,
rasterInfo.defaultState ?? true,
"Whether or not overlay layer " + rasterInfo.id + " is shown",
"Whether or not overlay layer " + rasterInfo.id + " is shown"
)
const state = { isDisplayed }
overlayLayerStates.set(rasterInfo.id, state)
@ -242,7 +242,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.osmConnection.Backend(),
(id) => this.layerState.filteredLayers.get(id).isDisplayed,
mvtAvailableLayers,
this.fullNodeDatabase,
this.fullNodeDatabase
)
let currentViewIndex = 0
@ -260,7 +260,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
id: "current_view_" + currentViewIndex,
}),
]
}),
})
)
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
@ -278,19 +278,19 @@ export default class ThemeViewState implements SpecialVisualizationState {
featureSwitches: this.featureSwitches,
},
layout?.isLeftRightSensitive() ?? false,
(e) => this.reportError(e),
(e) => this.reportError(e)
)
this.historicalUserLocations = this.geolocation.historicalUserLocations
this.newFeatures = new NewGeometryFromChangesFeatureSource(
this.changes,
layoutSource,
this.featureProperties,
this.featureProperties
)
layoutSource.addSource(this.newFeatures)
const perLayer = new PerLayerFeatureSourceSplitter(
Array.from(this.layerState.filteredLayers.values()).filter(
(l) => l.layerDef?.source !== null,
(l) => l.layerDef?.source !== null
),
new ChangeGeometryApplicator(this.indexedFeatures, this.changes),
{
@ -301,10 +301,10 @@ export default class ThemeViewState implements SpecialVisualizationState {
"Got ",
features.length,
"leftover features, such as",
features[0].properties,
features[0].properties
)
},
},
}
)
this.perLayer = perLayer.perLayer
}
@ -344,12 +344,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.lastClickObject = new LastClickFeatureSource(
this.layout,
this.mapProperties.lastClickLocation,
this.userRelatedState.addNewFeatureMode,
this.userRelatedState.addNewFeatureMode
)
this.osmObjectDownloader = new OsmObjectDownloader(
this.osmConnection.Backend(),
this.changes,
this.changes
)
this.perLayerFiltered = this.showNormalDataOn(this.map)
@ -360,7 +360,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
currentZoom: this.mapProperties.zoom,
layerState: this.layerState,
bounds: this.visualFeedbackViewportBounds,
},
}
)
this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView
this.imageUploadManager = new ImageUploadManager(
@ -368,7 +368,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
Imgur.singleton,
this.featureProperties,
this.osmConnection,
this.changes,
this.changes
)
this.favourites = new FavouritesFeatureSource(this)
const longAgo = new Date()
@ -414,7 +414,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
LayoutSource.fromCacheZoomLevel,
fs,
this.featureProperties,
fs.layer.layerDef.maxAgeOfCache,
fs.layer.layerDef.maxAgeOfCache
)
toLocalStorage.set(layerId, storage)
})
@ -427,7 +427,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const doShowLayer = this.mapProperties.zoom.map(
(z) =>
(fs.layer.isDisplayed?.data ?? true) && z >= (fs.layer.layerDef?.minzoom ?? 0),
[fs.layer.isDisplayed],
[fs.layer.isDisplayed]
)
if (!doShowLayer.data && this.featureSwitches.featureSwitchFilter.data === false) {
@ -444,7 +444,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
fs.layer,
fs,
(id) => this.featureProperties.getStore(id),
this.layerState.globalFilters,
this.layerState.globalFilters
)
filteringFeatureSource.set(layerName, filtered)
@ -588,7 +588,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
return
}
this.selectClosestAtCenter(0)
},
}
)
for (let i = 1; i < 9; i++) {
@ -606,7 +606,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
onUp: true,
},
doc,
() => this.selectClosestAtCenter(i - 1),
() => this.selectClosestAtCenter(i - 1)
)
}
@ -623,7 +623,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
if (this.featureSwitches.featureSwitchBackgroundSelection.data) {
this.guistate.backgroundLayerSelectionIsOpened.setData(true)
}
},
}
)
Hotkeys.RegisterHotkey(
{
@ -635,7 +635,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
if (this.featureSwitches.featureSwitchFilter.data) {
this.guistate.openFilterView()
}
},
}
)
const setLayerCategory = (category: EliCategory, skipLayers: number = 0) => {
const timeOfCall = new Date()
@ -652,7 +652,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
current.data,
skipLayers
)
if(!best){
if (!best) {
return
}
console.log("Best layer for category", category, "is", best?.properties?.id)
@ -663,43 +663,43 @@ export default class ThemeViewState implements SpecialVisualizationState {
Hotkeys.RegisterHotkey(
{ nomod: "O" },
Translations.t.hotkeyDocumentation.selectOsmbasedmap,
() => setLayerCategory("osmbasedmap"),
() => setLayerCategory("osmbasedmap")
)
Hotkeys.RegisterHotkey(
{ nomod: "M" },
Translations.t.hotkeyDocumentation.selectMap,
() => setLayerCategory("map"),
() => setLayerCategory("map")
)
Hotkeys.RegisterHotkey(
{ nomod: "P" },
Translations.t.hotkeyDocumentation.selectAerial,
() => setLayerCategory("photo"),
() => setLayerCategory("photo")
)
Hotkeys.RegisterHotkey(
{ shift: "O" },
Translations.t.hotkeyDocumentation.selectOsmbasedmap,
() => setLayerCategory("osmbasedmap",2),
() => setLayerCategory("osmbasedmap", 2)
)
Hotkeys.RegisterHotkey(
{ shift: "M" },
Translations.t.hotkeyDocumentation.selectMap,
() => setLayerCategory("map",2),
() => setLayerCategory("map", 2)
)
Hotkeys.RegisterHotkey(
{ shift: "P" },
Translations.t.hotkeyDocumentation.selectAerial,
() => setLayerCategory("photo",2),
() => setLayerCategory("photo", 2)
)
Hotkeys.RegisterHotkey(
{ nomod: "L" },
Translations.t.hotkeyDocumentation.geolocate,
() => {
this.geolocationControl.handleClick()
},
}
)
return true
})
@ -711,7 +711,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
Translations.t.hotkeyDocumentation.translationMode,
() => {
Locale.showLinkToWeblate.setData(!Locale.showLinkToWeblate.data)
},
}
)
}
@ -722,7 +722,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
const normalLayers = this.layout.layers.filter(
(l) =>
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
!l.id.startsWith("note_import"),
!l.id.startsWith("note_import")
)
const maxzoom = Math.min(...normalLayers.map((l) => l.minzoom))
@ -730,7 +730,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
(l) =>
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
l.source.geojsonSource === undefined &&
l.doCount,
l.doCount
)
const summaryTileSource = new SummaryTileSource(
Constants.SummaryServer,
@ -739,7 +739,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties,
{
isActive: this.mapProperties.zoom.map((z) => z < maxzoom),
},
}
)
return new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers)
@ -760,12 +760,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
gps_location_history: this.geolocation.historicalUserLocations,
gps_track: this.geolocation.historicalUserLocationsTrack,
selected_element: new StaticFeatureSource(
this.selectedElement.map((f) => (f === undefined ? empty : [f])),
this.selectedElement.map((f) => (f === undefined ? empty : [f]))
),
range: new StaticFeatureSource(
this.mapProperties.maxbounds.map((bbox) =>
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })],
),
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })]
)
),
current_view: this.currentView,
favourite: this.favourites,
@ -780,7 +780,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
ShowDataLayer.showRange(
this.map,
new StaticFeatureSource([bbox.asGeoJson({ id: "range" })]),
this.featureSwitches.featureSwitchIsTesting,
this.featureSwitches.featureSwitchIsTesting
)
}
const currentViewLayer = this.layout.layers.find((l) => l.id === "current_view")
@ -794,7 +794,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
currentViewLayer,
this.layout,
this.osmObjectDownloader,
this.featureProperties,
this.featureProperties
)
})
}
@ -838,20 +838,20 @@ export default class ThemeViewState implements SpecialVisualizationState {
const lastClickLayerConfig = new LayerConfig(
<LayerConfigJson>last_click_layerconfig,
"last_click",
"last_click"
)
const lastClickFiltered =
lastClickLayerConfig.isShown === undefined
? specialLayers.last_click
: specialLayers.last_click.features.mapD((fs) =>
fs.filter((f) => {
const matches = lastClickLayerConfig.isShown.matchesProperties(
f.properties,
)
console.debug("LastClick ", f, "matches", matches)
return matches
}),
)
fs.filter((f) => {
const matches = lastClickLayerConfig.isShown.matchesProperties(
f.properties
)
console.debug("LastClick ", f, "matches", matches)
return matches
})
)
new ShowDataLayer(this.map, {
features: new StaticFeatureSource(lastClickFiltered),
layer: lastClickLayerConfig,
@ -898,7 +898,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.mapProperties.rasterLayer,
this.availableLayers,
this.featureSwitches.backgroundLayerId,
this.userRelatedState.preferredBackgroundLayer,
this.userRelatedState.preferredBackgroundLayer
)
}
@ -914,7 +914,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
? ">>> _Not_ reporting error to report server as testmode is on"
: ">>> Reporting error to",
Constants.ErrorReportServer,
message,
message
)
if (isTesting) {
return