Themes: add validation for duplicate presets, fix #1582
This commit is contained in:
parent
fc6160c760
commit
2e8a3311e7
5 changed files with 83 additions and 18 deletions
|
@ -144,14 +144,7 @@
|
|||
"width": 5
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"tags": [
|
||||
"shop=yes",
|
||||
"dog=yes"
|
||||
]
|
||||
}
|
||||
],
|
||||
"=presets": [ ],
|
||||
"source": {
|
||||
"=osmTags": {
|
||||
"and": [
|
||||
|
@ -227,4 +220,4 @@
|
|||
}
|
||||
],
|
||||
"credits": "Niels Elgaard Larsen"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
"sameAs": "vending_machine"
|
||||
},
|
||||
"minzoom": 18,
|
||||
"=presets": [],
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"and": [
|
||||
|
@ -61,4 +62,4 @@
|
|||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRende
|
|||
import Validators from "../../../UI/InputElement/Validators"
|
||||
import TagRenderingConfig from "../TagRenderingConfig"
|
||||
import { parse as parse_html } from "node-html-parser"
|
||||
import PresetConfig from "../PresetConfig"
|
||||
import { TagsFilter } from "../../../Logic/Tags/TagsFilter"
|
||||
|
||||
class ValidateLanguageCompleteness extends DesugaringStep<any> {
|
||||
private readonly _languages: string[]
|
||||
|
@ -167,9 +169,9 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
json: LayoutConfigJson,
|
||||
context: string
|
||||
): { result: LayoutConfigJson; errors: string[]; warnings: string[]; information: string[] } {
|
||||
const errors = []
|
||||
const warnings = []
|
||||
const information = []
|
||||
const errors: string[] = []
|
||||
const warnings: string[] = []
|
||||
const information: string[] = []
|
||||
|
||||
const theme = new LayoutConfig(json, this._isBuiltin)
|
||||
|
||||
|
@ -245,7 +247,7 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
information
|
||||
)
|
||||
}
|
||||
const dups = Utils.Dupiclates(json.layers.map((layer) => layer["id"]))
|
||||
const dups = Utils.Duplicates(json.layers.map((layer) => layer["id"]))
|
||||
if (dups.length > 0) {
|
||||
errors.push(
|
||||
`The theme ${json.id} defines multiple layers with id ${dups.join(", ")}`
|
||||
|
@ -275,6 +277,10 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
errors.push(e)
|
||||
}
|
||||
|
||||
if (theme.id !== "personal") {
|
||||
new DetectDuplicatePresets().convertJoin(theme, context, errors, warnings, information)
|
||||
}
|
||||
|
||||
return {
|
||||
result: json,
|
||||
errors,
|
||||
|
@ -889,7 +895,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
|
|||
{
|
||||
// duplicate ids in tagrenderings check
|
||||
const duplicates = Utils.Dedup(
|
||||
Utils.Dupiclates(Utils.NoNull((json.tagRenderings ?? []).map((tr) => tr["id"])))
|
||||
Utils.Duplicates(Utils.NoNull((json.tagRenderings ?? []).map((tr) => tr["id"])))
|
||||
)
|
||||
if (duplicates.length > 0) {
|
||||
console.log(json.tagRenderings)
|
||||
|
@ -985,7 +991,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
|
|||
)
|
||||
}
|
||||
|
||||
const duplicateIds = Utils.Dupiclates(
|
||||
const duplicateIds = Utils.Duplicates(
|
||||
(json.tagRenderings ?? [])
|
||||
?.map((f) => f["id"])
|
||||
.filter((id) => id !== "questions")
|
||||
|
@ -1243,3 +1249,68 @@ export class DetectDuplicateFilters extends DesugaringStep<{
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class DetectDuplicatePresets extends DesugaringStep<LayoutConfig> {
|
||||
constructor() {
|
||||
super(
|
||||
"Detects mappings which have identical (english) names or identical mappings.",
|
||||
["presets"],
|
||||
"DetectDuplicatePresets"
|
||||
)
|
||||
}
|
||||
convert(
|
||||
json: LayoutConfig,
|
||||
context: string
|
||||
): {
|
||||
result: LayoutConfig
|
||||
errors?: string[]
|
||||
warnings?: string[]
|
||||
information?: string[]
|
||||
} {
|
||||
const presets: PresetConfig[] = [].concat(...json.layers.map((l) => l.presets))
|
||||
|
||||
const errors = []
|
||||
const enNames = presets.map((p) => p.title.textFor("en"))
|
||||
if (new Set(enNames).size != enNames.length) {
|
||||
const dups = Utils.Duplicates(enNames)
|
||||
const layersWithDup = json.layers.filter((l) =>
|
||||
l.presets.some((p) => dups.indexOf(p.title.textFor("en")) >= 0)
|
||||
)
|
||||
const layerIds = layersWithDup.map((l) => l.id)
|
||||
errors.push(
|
||||
`At ${context}: this themes has multiple presets which are named:${dups}, namely layers ${layerIds.join(
|
||||
", "
|
||||
)} this is confusing for contributors and is probably the result of reusing the same layer multiple times. Use \`{"override": {"=presets": []}}\` to remove some presets`
|
||||
)
|
||||
}
|
||||
|
||||
const optimizedTags = <TagsFilter[]>presets.map((p) => new And(p.tags).optimize())
|
||||
for (let i = 0; i < presets.length; i++) {
|
||||
const presetATags = optimizedTags[i]
|
||||
const presetA = presets[i]
|
||||
for (let j = i + 1; j < presets.length; j++) {
|
||||
const presetBTags = optimizedTags[j]
|
||||
const presetB = presets[j]
|
||||
if (
|
||||
Utils.SameObject(presetATags, presetBTags) &&
|
||||
Utils.sameList(
|
||||
presetA.preciseInput.snapToLayers,
|
||||
presetB.preciseInput.snapToLayers
|
||||
)
|
||||
) {
|
||||
errors.push(
|
||||
`At ${context}: this themes has multiple presets with the same tags: ${presetATags.asHumanString(
|
||||
false,
|
||||
false,
|
||||
{}
|
||||
)}, namely the preset '${presets[i].title.textFor("en")}' and '${presets[
|
||||
j
|
||||
].title.textFor("en")}'`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { errors, result: json }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -359,7 +359,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
{
|
||||
const duplicateIds = Utils.Dupiclates(this.filters.map((f) => f.id))
|
||||
const duplicateIds = Utils.Duplicates(this.filters.map((f) => f.id))
|
||||
if (duplicateIds.length > 0) {
|
||||
throw `Some filters have a duplicate id: ${duplicateIds} (at ${context}.filters)`
|
||||
}
|
||||
|
|
|
@ -387,7 +387,7 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
return newArr
|
||||
}
|
||||
|
||||
public static Dupiclates(arr: string[]): string[] {
|
||||
public static Duplicates(arr: string[]): string[] {
|
||||
if (arr === undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue