Refactoring of conversion

This commit is contained in:
Pieter Vander Vennet 2022-02-04 01:05:35 +01:00
parent 5dffb3c5e7
commit 7eeffc2305
12 changed files with 389 additions and 97 deletions

View file

@ -0,0 +1,286 @@
bicycle_rental
================
<img src='https://mapcomplete.osm.be/./assets/themes/bicycle_rental/logo.svg' height="100px">
Bicycle rental stations
## Table of contents
1. [bicycle_rental](#bicycle_rental)
* [Themes using this layer](#themes-using-this-layer)
- [Basic tags for this layer](#basic-tags-for-this-layer)
- [Supported attributes](#supported-attributes)
+ [bicycle_rental_type](#bicycle_rental_type)
+ [website](#website)
+ [email](#email)
+ [phone](#phone)
+ [opening_hours](#opening_hours)
+ [payment-options](#payment-options)
+ [payment-options-advanced](#payment-options-advanced)
+ [bicycle-types](#bicycle-types)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
+ [rental-capacity-bicycle-type](#rental-capacity-bicycle-type)
+ [questions](#questions)
#### Themes using this layer
- [bicycle_rental](https://mapcomplete.osm.be/bicycle_rental)
- [personal](https://mapcomplete.osm.be/personal)
[Go to the source code](../assets/layers/bicycle_rental/bicycle_rental.json)
Basic tags for this layer
---------------------------
Elements must have the all of following tags to be shown on this layer:
- <a href='https://wiki.openstreetmap.org/wiki/Key:amenity' target='_blank'>amenity</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:amenity%3Dbicycle_rental' target='_blank'>bicycle_rental</a>
|bicycle_rental~^..*$|<a href='https://wiki.openstreetmap.org/wiki/Key:service:bicycle:rental' target='_blank'>
service:bicycle:rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:service:bicycle:rental%3Dyes' target='_blank'>yes</a>|rental~^.*
bicycle.*$
Supported attributes
----------------------
**Warning** This quick overview is incomplete
attribute | type | values which are supported by this layer
----------- | ------ | ------------------------------------------
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/website#values) [website](https://wiki.openstreetmap.org/wiki/Key:website) | [url](../SpecialInputElements.md#url) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/email#values) [email](https://wiki.openstreetmap.org/wiki/Key:email) | [email](../SpecialInputElements.md#email) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/phone#values) [phone](https://wiki.openstreetmap.org/wiki/Key:phone) | [phone](../SpecialInputElements.md#phone) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/opening_hours#values) [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours) | [opening_hours](../SpecialInputElements.md#opening_hours) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/rental#values) [rental](https://wiki.openstreetmap.org/wiki/Key:rental) | [string](../SpecialInputElements.md#string) | [city_bike](https://wiki.openstreetmap.org/wiki/Tag:rental%3Dcity_bike) [ebike](https://wiki.openstreetmap.org/wiki/Tag:rental%3Debike) [bmx](https://wiki.openstreetmap.org/wiki/Tag:rental%3Dbmx) [mtb](https://wiki.openstreetmap.org/wiki/Tag:rental%3Dmtb) [kid_bike](https://wiki.openstreetmap.org/wiki/Tag:rental%3Dkid_bike)
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:city_bike#values) [capacity:city_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:city_bike) | [pnat](../SpecialInputElements.md#pnat) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:ebike#values) [capacity:ebike](https://wiki.openstreetmap.org/wiki/Key:capacity:ebike) | [pnat](../SpecialInputElements.md#pnat) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:kid_bike#values) [capacity:kid_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:kid_bike) | [pnat](../SpecialInputElements.md#pnat) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:bmx#values) [capacity:bmx](https://wiki.openstreetmap.org/wiki/Key:capacity:bmx) | [pnat](../SpecialInputElements.md#pnat) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:mtb#values) [capacity:mtb](https://wiki.openstreetmap.org/wiki/Key:capacity:mtb) | [pnat](../SpecialInputElements.md#pnat) |
[<img src='https://mapcomplete.osm.be/assets/svg/statistics.svg' height='18px'>](https://taginfo.openstreetmap.org/keys/capacity:bicycle_pannier#values) [capacity:bicycle_pannier](https://wiki.openstreetmap.org/wiki/Key:capacity:bicycle_pannier) | [pnat](../SpecialInputElements.md#pnat) |
### bicycle_rental_type
The question is **What kind of bicycle rental is this?**
- **This is a shop whose main focus is bicycle rental** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:shop' target='_blank'>shop</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:shop%3Dbicycle_rental' target='_blank'>bicycle_rental</a>
&<a href='https://wiki.openstreetmap.org/wiki/Key:bicycle_rental' target='_blank'>bicycle_rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:bicycle_rental%3Dshop' target='_blank'>shop</a>
- **This is a rental buisiness which rents out various objects and/or vehicles. It rents out bicycles too, but this is
not the main focus** corresponds with <a href='https://wiki.openstreetmap.org/wiki/Key:shop' target='_blank'>shop</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:shop%3Drental' target='_blank'>rental</a>_This option cannot be
chosen as answer_
- **This is a shop which sells or repairs bicycles, but also rents out bicycles** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:service:bicycle:rental' target='_blank'>service:bicycle:
rental</a>=<a href='https://wiki.openstreetmap.org/wiki/Tag:service:bicycle:rental%3Dyes' target='_blank'>yes</a>
&<a href='https://wiki.openstreetmap.org/wiki/Key:shop' target='_blank'>shop</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:shop%3Dbicycle' target='_blank'>bicycle</a>
- **This is an automated docking station, where a bicycle is mechanically locked into a structure** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:bicycle_rental' target='_blank'>bicycle_rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:bicycle_rental%3Ddocking_station' target='_blank'>
docking_station</a>
- **A machine is present which dispenses and accepts keys, eventually after authentication and/or payment. The bicycles
are parked nearby** corresponds with <a href='https://wiki.openstreetmap.org/wiki/Key:bicycle_rental' target='_blank'>
bicycle_rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:bicycle_rental%3Dkey_dispensing_machine' target='_blank'>
key_dispensing_machine</a>
- **This is a dropoff point: a designated bicycle parking for this cycle rental** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:bicycle_rental' target='_blank'>bicycle_rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:bicycle_rental%3Ddropoff_point' target='_blank'>dropoff_point</a>
### website
The question is **What is the website of {name}?**
This rendering asks information about the property [website](https://wiki.openstreetmap.org/wiki/Key:website)
This is rendered with `<a href='{website}' target='_blank'>{website}</a>`
- **<a href='{contact:website}' target='_blank'>{contact:website}</a>** corresponds with contact:website~^..*$_This
option cannot be chosen as answer_
### email
The question is **What is the email address of {name}?**
This rendering asks information about the property [email](https://wiki.openstreetmap.org/wiki/Key:email)
This is rendered with `<a href='mailto:{email}' target='_blank'>{email}</a>`
- **<a href='mailto:{contact:email}' target='_blank'>{contact:email}</a>** corresponds with contact:email~^..*$_This
option cannot be chosen as answer_
### phone
The question is **What is the phone number of {name}?**
This rendering asks information about the property [phone](https://wiki.openstreetmap.org/wiki/Key:phone)
This is rendered with `<a href='tel:{phone}'>{phone}</a>`
- **<a href='tel:{contact:phone}'>{contact:phone}</a>** corresponds with contact:phone~^..*$_This option cannot be
chosen as answer_
### opening_hours
The question is **What are the opening hours of {name}?**
This rendering asks information about the
property [opening_hours](https://wiki.openstreetmap.org/wiki/Key:opening_hours)
This is rendered with `<h3>Opening hours</h3>{opening_hours_table(opening_hours)}`
### payment-options
The question is **Which methods of payment are accepted here?**
- **Cash is accepted here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cash' target='_blank'>payment:cash</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cash%3Dyes' target='_blank'>yes</a>Unselecting this answer
will add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cash' target='_blank'>payment:cash</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cash%3Dno' target='_blank'>no</a>
- **Payment cards are accepted here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cards' target='_blank'>payment:cards</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cards%3Dyes' target='_blank'>yes</a>Unselecting this answer
will add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cards' target='_blank'>payment:cards</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cards%3Dno' target='_blank'>no</a>
### payment-options-advanced
The question is **Which methods of payment are accepted here?**
- **Cash is accepted here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cash' target='_blank'>payment:cash</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cash%3Dyes' target='_blank'>yes</a>Unselecting this answer
will add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cash' target='_blank'>payment:cash</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cash%3Dno' target='_blank'>no</a>
- **Payment cards are accepted here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cards' target='_blank'>payment:cards</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cards%3Dyes' target='_blank'>yes</a>Unselecting this answer
will add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:cards' target='_blank'>payment:cards</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:cards%3Dno' target='_blank'>no</a>
- **Payment is done using a dedicated app** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:app' target='_blank'>payment:app</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:app%3Dyes' target='_blank'>yes</a>Unselecting this answer
will add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:app' target='_blank'>payment:app</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:app%3Dno' target='_blank'>no</a>
- **Payment is done using a membership card** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:payment:membership_card' target='_blank'>payment:
membership_card</a>=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:membership_card%3Dyes' target='_blank'>
yes</a>Unselecting this answer will
add <a href='https://wiki.openstreetmap.org/wiki/Key:payment:membership_card' target='_blank'>payment:
membership_card</a>=<a href='https://wiki.openstreetmap.org/wiki/Tag:payment:membership_card%3Dno' target='_blank'>
no</a>
### bicycle-types
The question is **What kind of bicycles and accessories are rented here?**
This rendering asks information about the property [rental](https://wiki.openstreetmap.org/wiki/Key:rental)
This is rendered with `{rental} is rented here`
- **Normal city bikes can be rented here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:rental' target='_blank'>rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:rental%3Dcity_bike' target='_blank'>city_bike</a>
- **Electrical bikes can be rented here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:rental' target='_blank'>rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:rental%3Debike' target='_blank'>ebike</a>
- **BMX bikes can be rented here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:rental' target='_blank'>rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:rental%3Dbmx' target='_blank'>bmx</a>
- **Mountainbikes can be rented here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:rental' target='_blank'>rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:rental%3Dmtb' target='_blank'>mtb</a>
- **Bikes for childs can be rented here** corresponds
with <a href='https://wiki.openstreetmap.org/wiki/Key:rental' target='_blank'>rental</a>
=<a href='https://wiki.openstreetmap.org/wiki/Tag:rental%3Dkid_bike' target='_blank'>kid_bike</a>
### rental-capacity-bicycle-type
The question is **How much city bikes can be rented here? **
This rendering asks information about the
property [capacity:city_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:city_bike)
This is rendered with `{capacity:city_bike} city bikes can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
### rental-capacity-bicycle-type
The question is **How much electrical bikes can be rented here? **
This rendering asks information about the
property [capacity:ebike](https://wiki.openstreetmap.org/wiki/Key:capacity:ebike)
This is rendered with `{capacity:ebike} electrical bikes can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
### rental-capacity-bicycle-type
The question is **How much bikes for children can be rented here? **
This rendering asks information about the
property [capacity:kid_bike](https://wiki.openstreetmap.org/wiki/Key:capacity:kid_bike)
This is rendered with `{capacity:kid_bike} bikes for children can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
### rental-capacity-bicycle-type
The question is **How much BMX bikes can be rented here? **
This rendering asks information about the property [capacity:bmx](https://wiki.openstreetmap.org/wiki/Key:capacity:bmx)
This is rendered with `{capacity:bmx} BMX bikes can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
### rental-capacity-bicycle-type
The question is **How much mountainbike can be rented here? **
This rendering asks information about the property [capacity:mtb](https://wiki.openstreetmap.org/wiki/Key:capacity:mtb)
This is rendered with `{capacity:mtb} mountainbike can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
### rental-capacity-bicycle-type
The question is **How much bicycle panniers can be rented here? **
This rendering asks information about the
property [capacity:bicycle_pannier](https://wiki.openstreetmap.org/wiki/Key:capacity:bicycle_pannier)
This is rendered with `{capacity:bicycle_pannier} bicycle panniers can be rented here`
### questions
_This tagrendering has no question and is thus read-only_
This document is autogenerated from assets/layers/bicycle_rental/bicycle_rental.json

View file

@ -26,14 +26,14 @@ export abstract class Conversion<TIn, TOut> {
return fixed.result; return fixed.result;
} }
public convertStrict(state: DesugaringContext, json: TIn, context: string): TOut { public convertStrict(json: TIn, context: string): TOut {
const fixed = this.convert(state, json, context) const fixed = this.convert(json, context)
return DesugaringStep.strict(fixed) return DesugaringStep.strict(fixed)
} }
abstract convert(state: DesugaringContext, json: TIn, context: string): { result: TOut, errors?: string[], warnings?: string[] } abstract convert(json: TIn, context: string): { result: TOut, errors?: string[], warnings?: string[] }
public convertAll(state: DesugaringContext, jsons: TIn[], context: string): { result: TOut[], errors: string[], warnings: string[] } { public convertAll(jsons: TIn[], context: string): { result: TOut[], errors: string[], warnings: string[] } {
if(jsons === undefined){ if(jsons === undefined){
throw "convertAll received undefined - don't do this (at "+context+")" throw "convertAll received undefined - don't do this (at "+context+")"
} }
@ -42,7 +42,7 @@ export abstract class Conversion<TIn, TOut> {
const warnings = [] const warnings = []
for (let i = 0; i < jsons.length; i++) { for (let i = 0; i < jsons.length; i++) {
const json = jsons[i]; const json = jsons[i];
const r = this.convert(state, json, context + "[" + i + "]") const r = this.convert(json, context + "[" + i + "]")
result.push(r.result) result.push(r.result)
errors.push(...r.errors ?? []) errors.push(...r.errors ?? [])
warnings.push(...r.warnings ?? []) warnings.push(...r.warnings ?? [])
@ -69,11 +69,11 @@ export class OnEvery<X, T> extends DesugaringStep<T> {
this.key = key; this.key = key;
} }
convert(state: DesugaringContext, json: T, context: string): { result: T; errors?: string[]; warnings?: string[] } { convert(json: T, context: string): { result: T; errors?: string[]; warnings?: string[] } {
json = {...json} json = {...json}
const step = this.step const step = this.step
const key = this.key; const key = this.key;
const r = step.convertAll(state, (<X[]>json[key]), context + "." + key) const r = step.convertAll((<X[]>json[key]), context + "." + key)
json[key] = r.result json[key] = r.result
return { return {
result: json, result: json,
@ -94,7 +94,7 @@ export class OnEveryConcat<X, T> extends DesugaringStep<T> {
this.key = key; this.key = key;
} }
convert(state: DesugaringContext, json: T, context: string): { result: T; errors: string[]; warnings: string[] } { convert(json: T, context: string): { result: T; errors: string[]; warnings: string[] } {
json = {...json} json = {...json}
const step = this.step const step = this.step
const key = this.key; const key = this.key;
@ -107,7 +107,7 @@ export class OnEveryConcat<X, T> extends DesugaringStep<T> {
warnings: [] warnings: []
} }
} }
const r = step.convertAll(state, (<X[]>values), context + "." + key) const r = step.convertAll((<X[]>values), context + "." + key)
const vals: X[][] = r.result const vals: X[][] = r.result
json[key] = [].concat(...vals) json[key] = [].concat(...vals)
return { return {
@ -129,12 +129,12 @@ export class Fuse<T> extends DesugaringStep<T> {
this.steps = steps; this.steps = steps;
} }
convert(state: DesugaringContext, json: T, context: string): { result: T; errors: string[]; warnings: string[] } { convert(json: T, context: string): { result: T; errors: string[]; warnings: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
for (let i = 0; i < this.steps.length; i++) { for (let i = 0; i < this.steps.length; i++) {
const step = this.steps[i]; const step = this.steps[i];
let r = step.convert(state, json, "While running step " +step.name + ": " + context) let r = step.convert(json, "While running step " +step.name + ": " + context)
errors.push(...r.errors ?? []) errors.push(...r.errors ?? [])
warnings.push(...r.warnings ?? []) warnings.push(...r.warnings ?? [])
json = r.result json = r.result
@ -163,7 +163,7 @@ export class SetDefault<T> extends DesugaringStep<T> {
this._overrideEmptyString = overrideEmptyString; this._overrideEmptyString = overrideEmptyString;
} }
convert(state: DesugaringContext, json: T, context: string): { result: T; errors: string[]; warnings: string[] } { convert(json: T, context: string): { result: T; errors: string[]; warnings: string[] } {
if (json[this.key] === undefined || (json[this.key] === "" && this._overrideEmptyString)) { if (json[this.key] === undefined || (json[this.key] === "" && this._overrideEmptyString)) {
json = {...json} json = {...json}
json[this.key] = this.value json[this.key] = this.value

View file

@ -1,4 +1,4 @@
import {Conversion, DesugaringContext} from "./Conversion"; import {Conversion} from "./Conversion";
import LayerConfig from "../LayerConfig"; import LayerConfig from "../LayerConfig";
import {LayerConfigJson} from "../Json/LayerConfigJson"; import {LayerConfigJson} from "../Json/LayerConfigJson";
import Translations from "../../../UI/i18n/Translations"; import Translations from "../../../UI/i18n/Translations";
@ -20,7 +20,7 @@ export default class CreateNoteImportLayer extends Conversion<LayerConfigJson, L
this._includeClosedNotesDays = includeClosedNotesDays; this._includeClosedNotesDays = includeClosedNotesDays;
} }
convert(state: DesugaringContext, layerJson: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } { convert(layerJson: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
const t = Translations.t.importLayer; const t = Translations.t.importLayer;

View file

@ -11,7 +11,7 @@ export class UpdateLegacyLayer extends DesugaringStep<LayerConfigJson | string |
["overpassTags", "source.osmtags", "tagRenderings[*].id", "mapRendering"]); ["overpassTags", "source.osmtags", "tagRenderings[*].id", "mapRendering"]);
} }
convert(state: {}, json: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } { convert(json: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } {
const warnings = [] const warnings = []
if (typeof json === "string" || json["builtin"] !== undefined) { if (typeof json === "string" || json["builtin"] !== undefined) {
// Reuse of an already existing layer; return as-is // Reuse of an already existing layer; return as-is
@ -123,7 +123,7 @@ class UpdateLegacyTheme extends DesugaringStep<LayoutConfigJson> {
super("Small fixes in the theme config", ["roamingRenderings"]); super("Small fixes in the theme config", ["roamingRenderings"]);
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
const oldThemeConfig = {...json} const oldThemeConfig = {...json}
if (oldThemeConfig["roamingRenderings"] !== undefined) { if (oldThemeConfig["roamingRenderings"] !== undefined) {

View file

@ -6,21 +6,24 @@ import Translations from "../../../UI/i18n/Translations";
import {Translation} from "../../../UI/i18n/Translation"; import {Translation} from "../../../UI/i18n/Translation";
class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | { builtin: string | string[], override: any }, TagRenderingConfigJson[]> { class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | { builtin: string | string[], override: any }, TagRenderingConfigJson[]> {
constructor() { private readonly _state: DesugaringContext;
constructor(state: DesugaringContext) {
super("Converts a tagRenderingSpec into the full tagRendering", []); super("Converts a tagRenderingSpec into the full tagRendering", []);
this._state = state;
} }
convert(state: DesugaringContext, json: string | TagRenderingConfigJson | { builtin: string | string[]; override: any }, context: string): { result: TagRenderingConfigJson[]; errors: string[]; warnings: string[] } { convert(json: string | TagRenderingConfigJson | { builtin: string | string[]; override: any }, context: string): { result: TagRenderingConfigJson[]; errors: string[]; warnings: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
return { return {
result: this.convertUntilStable(state, json, warnings, errors, context), result: this.convertUntilStable(json, warnings, errors, context),
errors, warnings errors, warnings
}; };
} }
private lookup(state: DesugaringContext, name: string): TagRenderingConfigJson[] { private lookup(name: string): TagRenderingConfigJson[] {
const state = this._state;
if (state.tagRenderings.has(name)) { if (state.tagRenderings.has(name)) {
return [state.tagRenderings.get(name)] return [state.tagRenderings.get(name)]
} }
@ -61,7 +64,8 @@ class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | {
return undefined; return undefined;
} }
private convertOnce(state: DesugaringContext, tr: string | any, warnings: string[], errors: string[], ctx: string): TagRenderingConfigJson[] { private convertOnce(tr: string | any, warnings: string[], errors: string[], ctx: string): TagRenderingConfigJson[] {
const state = this._state
if (tr === "questions") { if (tr === "questions") {
return [{ return [{
id: "questions" id: "questions"
@ -70,7 +74,7 @@ class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | {
if (typeof tr === "string") { if (typeof tr === "string") {
const lookup = this.lookup(state, tr); const lookup = this.lookup(tr);
if (lookup !== undefined) { if (lookup !== undefined) {
return lookup return lookup
} }
@ -96,7 +100,7 @@ class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | {
const trs: TagRenderingConfigJson[] = [] const trs: TagRenderingConfigJson[] = []
for (const name of names) { for (const name of names) {
const lookup = this.lookup(state, name) const lookup = this.lookup(name)
if (lookup === undefined) { if (lookup === undefined) {
errors.push(ctx + ": The tagRendering with identifier " + name + " was not found.\n\tDid you mean one of " + Array.from(state.tagRenderings.keys()).join(", ") + "?") errors.push(ctx + ": The tagRendering with identifier " + name + " was not found.\n\tDid you mean one of " + Array.from(state.tagRenderings.keys()).join(", ") + "?")
continue continue
@ -113,13 +117,13 @@ class ExpandTagRendering extends Conversion<string | TagRenderingConfigJson | {
return [tr] return [tr]
} }
private convertUntilStable(state: DesugaringContext, spec: string | any, warnings: string[], errors: string[], ctx: string): TagRenderingConfigJson[] { private convertUntilStable(spec: string | any, warnings: string[], errors: string[], ctx: string): TagRenderingConfigJson[] {
const trs = this.convertOnce(state, spec, warnings, errors, ctx); const trs = this.convertOnce(spec, warnings, errors, ctx);
const result = [] const result = []
for (const tr of trs) { for (const tr of trs) {
if (tr["builtin"] !== undefined) { if (tr["builtin"] !== undefined) {
const stable = this.convertUntilStable(state, tr, warnings, errors, ctx + "(RECURSIVE RESOLVE)") const stable = this.convertUntilStable(tr, warnings, errors, ctx + "(RECURSIVE RESOLVE)")
result.push(...stable) result.push(...stable)
} else { } else {
result.push(tr) result.push(tr)
@ -139,15 +143,16 @@ class ExpandGroupRewrite extends Conversion<{
} | TagRenderingConfigJson, TagRenderingConfigJson[]> { } | TagRenderingConfigJson, TagRenderingConfigJson[]> {
private static expandSubTagRenderings = new ExpandTagRendering() private _expandSubTagRenderings;
constructor() { constructor(state: DesugaringContext) {
super( super(
"Converts a rewrite config for tagRenderings into the expanded form" "Converts a rewrite config for tagRenderings into the expanded form"
); );
this._expandSubTagRenderings = new ExpandTagRendering(state)
} }
convert(state: DesugaringContext, json: convert( json:
{ {
rewrite: rewrite:
{ sourceString: string; into: string[] }[]; renderings: (string | { builtin: string; override: any } | TagRenderingConfigJson)[] { sourceString: string; into: string[] }[]; renderings: (string | { builtin: string; override: any } | TagRenderingConfigJson)[]
@ -186,7 +191,7 @@ class ExpandGroupRewrite extends Conversion<{
} }
} }
const subRenderingsRes = <{ result: TagRenderingConfigJson[][], errors, warnings }> ExpandGroupRewrite.expandSubTagRenderings.convertAll(state, config.renderings, context); const subRenderingsRes = <{ result: TagRenderingConfigJson[][], errors, warnings }> this._expandSubTagRenderings.convertAll(config.renderings, context);
const subRenderings: TagRenderingConfigJson[] = [].concat(...subRenderingsRes.result); const subRenderings: TagRenderingConfigJson[] = [].concat(...subRenderingsRes.result);
const errors = subRenderingsRes.errors; const errors = subRenderingsRes.errors;
const warnings = subRenderingsRes.warnings; const warnings = subRenderingsRes.warnings;
@ -279,13 +284,13 @@ class ExpandGroupRewrite extends Conversion<{
export class PrepareLayer extends Fuse<LayerConfigJson> { export class PrepareLayer extends Fuse<LayerConfigJson> {
constructor() { constructor(state: DesugaringContext) {
super( super(
"Fully prepares and expands a layer for the LayerConfig.", "Fully prepares and expands a layer for the LayerConfig.",
new OnEveryConcat("tagRenderings", new ExpandGroupRewrite()), new OnEveryConcat("tagRenderings", new ExpandGroupRewrite(state)),
new OnEveryConcat("tagRenderings", new ExpandTagRendering()), new OnEveryConcat("tagRenderings", new ExpandTagRendering(state)),
new SetDefault("titleIcons", ["defaults"]), new SetDefault("titleIcons", ["defaults"]),
new OnEveryConcat("titleIcons", new ExpandTagRendering()) new OnEveryConcat("titleIcons", new ExpandTagRendering(state))
); );
} }
} }

View file

@ -13,14 +13,17 @@ import DependencyCalculator from "../DependencyCalculator";
import {ValidateThemeAndLayers} from "./Validation"; import {ValidateThemeAndLayers} from "./Validation";
class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfigJson[]> { class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfigJson[]> {
constructor() { private readonly _state: DesugaringContext;
constructor(
state: DesugaringContext,
) {
super("Converts the identifier of a builtin layer into the actual layer, or converts a 'builtin' syntax with override in the fully expanded form", []); super("Converts the identifier of a builtin layer into the actual layer, or converts a 'builtin' syntax with override in the fully expanded form", []);
this._state = state;
} }
convert(state: DesugaringContext, json: string | LayerConfigJson, context: string): { result: LayerConfigJson[]; errors: string[]; warnings: string[] } { convert(json: string | LayerConfigJson, context: string): { result: LayerConfigJson[]; errors: string[] } {
const errors = [] const errors = []
const warnings = [] const state= this._state
function reportNotFound(name: string){ function reportNotFound(name: string){
const knownLayers = Array.from(state.sharedLayers.keys()) const knownLayers = Array.from(state.sharedLayers.keys())
const withDistance = knownLayers.map(lname => [lname, Utils.levenshteinDistance(name, lname)]) const withDistance = knownLayers.map(lname => [lname, Utils.levenshteinDistance(name, lname)])
@ -39,12 +42,11 @@ class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfig
return { return {
result: null, result: null,
errors, errors,
warnings
} }
} }
return { return {
result: [found], result: [found],
errors, warnings errors
} }
} }
@ -72,28 +74,31 @@ class SubstituteLayer extends Conversion<(string | LayerConfigJson), LayerConfig
} }
return { return {
result: layers, result: layers,
errors, warnings errors
} }
} }
return { return {
result: [json], result: [json],
errors, warnings errors
}; };
} }
} }
class AddDefaultLayers extends DesugaringStep<LayoutConfigJson> { class AddDefaultLayers extends DesugaringStep<LayoutConfigJson> {
private _state: DesugaringContext;
constructor() { constructor(state: DesugaringContext) {
super("Adds the default layers, namely: " + Constants.added_by_default.join(", "), ["layers"]); super("Adds the default layers, namely: " + Constants.added_by_default.join(", "), ["layers"]);
this._state = state;
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
const state = this._state
json.layers = [...json.layers] json.layers = [...json.layers]
const alreadyLoaded = new Set(json.layers.map(l => l["id"])) const alreadyLoaded = new Set(json.layers.map(l => l["id"]))
@ -141,7 +146,7 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> {
super("For every layer in the 'layers'-list, create a new layer which'll import notes. (Note that priviliged layers and layers which have a geojson-source set are ignored)", ["layers"]); super("For every layer in the 'layers'-list, create a new layer which'll import notes. (Note that priviliged layers and layers which have a geojson-source set are ignored)", ["layers"]);
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
@ -176,11 +181,10 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> {
try { try {
const importLayerResult = creator.convert(state, layer, context + ".(noteimportlayer)[" + i1 + "]") const importLayerResult = creator.convert(layer, context + ".(noteimportlayer)[" + i1 + "]")
errors.push(...importLayerResult.errors) errors.push(...importLayerResult.errors)
warnings.push(...importLayerResult.warnings) warnings.push(...importLayerResult.warnings)
if (importLayerResult.result !== undefined) { if (importLayerResult.result !== undefined) {
warnings.push("Added an import layer to theme " + json.id + ", namely " + importLayerResult.result.id)
json.layers.push(importLayerResult.result) json.layers.push(importLayerResult.result)
} }
} catch (e) { } catch (e) {
@ -199,8 +203,10 @@ class AddImportLayers extends DesugaringStep<LayoutConfigJson> {
export class AddMiniMap extends DesugaringStep<LayerConfigJson> { export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
constructor() { private readonly _state: DesugaringContext;
constructor(state: DesugaringContext, ) {
super("Adds a default 'minimap'-element to the tagrenderings if none of the elements define such a minimap", ["tagRenderings"]); super("Adds a default 'minimap'-element to the tagrenderings if none of the elements define such a minimap", ["tagRenderings"]);
this._state = state;
} }
/** /**
@ -229,9 +235,9 @@ export class AddMiniMap extends DesugaringStep<LayerConfigJson> {
return false; return false;
} }
convert(state: DesugaringContext, layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } { convert(layerConfig: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings: string[] } {
const state = this._state;
const hasMinimap = layerConfig.tagRenderings?.some(tr => AddMiniMap.hasMinimap(<TagRenderingConfigJson>tr)) ?? true const hasMinimap = layerConfig.tagRenderings?.some(tr => AddMiniMap.hasMinimap(<TagRenderingConfigJson>tr)) ?? true
if (!hasMinimap) { if (!hasMinimap) {
layerConfig = {...layerConfig} layerConfig = {...layerConfig}
@ -255,7 +261,7 @@ class ApplyOverrideAll extends DesugaringStep<LayoutConfigJson> {
super("Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", ["overrideAll", "layers"]); super("Applies 'overrideAll' onto every 'layer'. The 'overrideAll'-field is removed afterwards", ["overrideAll", "layers"]);
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
const overrideAll = json.overrideAll; const overrideAll = json.overrideAll;
if (overrideAll === undefined) { if (overrideAll === undefined) {
@ -280,8 +286,10 @@ class ApplyOverrideAll extends DesugaringStep<LayoutConfigJson> {
} }
class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> { class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
constructor() { private readonly _state: DesugaringContext;
constructor(state: DesugaringContext, ) {
super("If a layer has a dependency on another layer, these layers are added automatically on the theme. (For example: defibrillator depends on 'walls_and_buildings' to snap onto. This layer is added automatically)", ["layers"]); super("If a layer has a dependency on another layer, these layers are added automatically on the theme. (For example: defibrillator depends on 'walls_and_buildings' to snap onto. This layer is added automatically)", ["layers"]);
this._state = state;
} }
private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map<string, LayerConfigJson>, themeId: string): LayerConfigJson[] { private static CalculateDependencies(alreadyLoaded: LayerConfigJson[], allKnownLayers: Map<string, LayerConfigJson>, themeId: string): LayerConfigJson[] {
@ -326,7 +334,8 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
return dependenciesToAdd; return dependenciesToAdd;
} }
convert(state: DesugaringContext, theme: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(theme: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } {
const state = this._state
const allKnownLayers: Map<string, LayerConfigJson> = state.sharedLayers; const allKnownLayers: Map<string, LayerConfigJson> = state.sharedLayers;
const knownTagRenderings: Map<string, TagRenderingConfigJson> = state.tagRenderings; const knownTagRenderings: Map<string, TagRenderingConfigJson> = state.tagRenderings;
const errors = []; const errors = [];
@ -357,18 +366,18 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
export class PrepareTheme extends Fuse<LayoutConfigJson> { export class PrepareTheme extends Fuse<LayoutConfigJson> {
constructor() { constructor(state: DesugaringContext) {
super( super(
"Fully prepares and expands a theme", "Fully prepares and expands a theme",
new OnEveryConcat("layers", new SubstituteLayer()), new OnEveryConcat("layers", new SubstituteLayer(state)),
new SetDefault("socialImage", "assets/SocialImage.png", true), new SetDefault("socialImage", "assets/SocialImage.png", true),
new OnEvery("layers", new PrepareLayer()), new OnEvery("layers", new PrepareLayer(state)),
new ApplyOverrideAll(), new ApplyOverrideAll(),
new AddDefaultLayers(), new AddDefaultLayers(state),
new AddDependencyLayersToTheme(), new AddDependencyLayersToTheme(state),
new AddImportLayers(), new AddImportLayers(),
new OnEvery("layers", new AddMiniMap()) new OnEvery("layers", new AddMiniMap(state))
); );
} }
} }

View file

@ -1,4 +1,4 @@
import {DesugaringContext, DesugaringStep, Fuse, OnEvery} from "./Conversion"; import {DesugaringStep, Fuse, OnEvery} from "./Conversion";
import {LayerConfigJson} from "../Json/LayerConfigJson"; import {LayerConfigJson} from "../Json/LayerConfigJson";
import LayerConfig from "../LayerConfig"; import LayerConfig from "../LayerConfig";
import {Utils} from "../../../Utils"; import {Utils} from "../../../Utils";
@ -8,7 +8,6 @@ import {LayoutConfigJson} from "../Json/LayoutConfigJson";
import LayoutConfig from "../LayoutConfig"; import LayoutConfig from "../LayoutConfig";
import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson"; import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson";
import {TagUtils} from "../../../Logic/Tags/TagUtils"; import {TagUtils} from "../../../Logic/Tags/TagUtils";
import {parseString} from "xml2js";
class ValidateLanguageCompleteness extends DesugaringStep<any> { class ValidateLanguageCompleteness extends DesugaringStep<any> {
@ -19,7 +18,7 @@ class ValidateLanguageCompleteness extends DesugaringStep<any> {
this._languages = languages; this._languages = languages;
} }
convert(state: DesugaringContext, obj: any, context: string): { result: LayerConfig; errors: string[]; warnings: string[] } { convert(obj: any, context: string): { result: LayerConfig; errors: string[] } {
const errors = [] const errors = []
const translations = Translation.ExtractAllTranslationsFrom( const translations = Translation.ExtractAllTranslationsFrom(
obj obj
@ -34,7 +33,7 @@ class ValidateLanguageCompleteness extends DesugaringStep<any> {
return { return {
result: obj, result: obj,
warnings: [], errors errors
}; };
} }
} }
@ -55,9 +54,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
this._isBuiltin = isBuiltin; this._isBuiltin = isBuiltin;
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[]; warnings: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors: string[] } {
const errors = [] const errors = []
const warnings = []
{ {
// Legacy format checks // Legacy format checks
if (this._isBuiltin) { if (this._isBuiltin) {
@ -89,9 +87,8 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
} }
if (json["mustHaveLanguage"] !== undefined) { if (json["mustHaveLanguage"] !== undefined) {
const checked = new ValidateLanguageCompleteness(...json["mustHaveLanguage"]) const checked = new ValidateLanguageCompleteness(...json["mustHaveLanguage"])
.convert(state, theme, theme.id) .convert(theme, theme.id)
errors.push(...checked.errors) errors.push(...checked.errors)
warnings.push(...checked.warnings)
} }
} catch (e) { } catch (e) {
@ -100,8 +97,7 @@ class ValidateTheme extends DesugaringStep<LayoutConfigJson> {
return { return {
result: json, result: json,
errors, errors
warnings
}; };
} }
} }
@ -122,7 +118,7 @@ class OverrideShadowingCheck extends DesugaringStep<LayoutConfigJson>{
super("Checks that an 'overrideAll' does not override a single override"); super("Checks that an 'overrideAll' does not override a single override");
} }
convert(state: DesugaringContext, json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors?: string[]; warnings?: string[] } { convert(json: LayoutConfigJson, context: string): { result: LayoutConfigJson; errors?: string[]; warnings?: string[] } {
const overrideAll = json.overrideAll; const overrideAll = json.overrideAll;
if(overrideAll === undefined){ if(overrideAll === undefined){
@ -144,12 +140,10 @@ class OverrideShadowingCheck extends DesugaringStep<LayoutConfigJson>{
return {result: json, errors} return {result: json, errors}
} }
} }
export class PrevalidateTheme extends Fuse<LayoutConfigJson>{ export class PrevalidateTheme extends Fuse<LayoutConfigJson>{
constructor() { constructor() {
super("Various consistency checks on the raw JSON", super("Various consistency checks on the raw JSON",
new OverrideShadowingCheck() new OverrideShadowingCheck()
@ -157,7 +151,6 @@ export class PrevalidateTheme extends Fuse<LayoutConfigJson>{
} }
} }
export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson>{ export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJson>{
@ -165,7 +158,7 @@ export class DetectShadowedMappings extends DesugaringStep<TagRenderingConfigJso
super("Checks that the mappings don't shadow each other"); super("Checks that the mappings don't shadow each other");
} }
convert(state: DesugaringContext, json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[] } { convert(json: TagRenderingConfigJson, context: string): { result: TagRenderingConfigJson; errors?: string[]; warnings?: string[] } {
const errors = [] const errors = []
if(json.mappings === undefined || json.mappings.length === 0){ if(json.mappings === undefined || json.mappings.length === 0){
return {result: json} return {result: json}
@ -218,7 +211,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
this._isBuiltin = isBuiltin; this._isBuiltin = isBuiltin;
} }
convert(state: DesugaringContext, json: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings?: string[] } { convert(json: LayerConfigJson, context: string): { result: LayerConfigJson; errors: string[]; warnings?: string[] } {
const errors = [] const errors = []
const warnings = [] const warnings = []
@ -315,7 +308,7 @@ export class ValidateLayer extends DesugaringStep<LayerConfigJson> {
} }
} }
if(json.tagRenderings !== undefined){ if(json.tagRenderings !== undefined){
new DetectShadowedMappings().convertAll(state, <TagRenderingConfigJson[]> json.tagRenderings, context+".tagRenderings") new DetectShadowedMappings().convertAll(<TagRenderingConfigJson[]> json.tagRenderings, context+".tagRenderings")
} }
} catch (e) { } catch (e) {

View file

@ -10,13 +10,14 @@
"osmTags": { "osmTags": {
"and": [ "and": [
{ {
"or": [ "or": [
"amenity=charging_station", "amenity=charging_station",
"disused:amenity=charging_station", "disused:amenity=charging_station",
"planned:amenity=charging_station", "planned:amenity=charging_station",
"construction:amenity=charging_station" "construction:amenity=charging_station"
]
}
] ]
} ]
} }
}, },
"title": { "title": {

View file

@ -53,6 +53,7 @@ WriteFile("./Docs/SpecialInputElements.md", ValidatedTextField.HelpText(), ["Val
WriteFile("./Docs/BuiltinLayers.md", AllKnownLayouts.GenLayerOverviewText(), ["AllKnownLayers.ts"]) WriteFile("./Docs/BuiltinLayers.md", AllKnownLayouts.GenLayerOverviewText(), ["AllKnownLayers.ts"])
{ {
// Generate the builtinIndex which shows interlayer dependencies
var layers = ScriptUtils.getLayerFiles().map(f => f.parsed) var layers = ScriptUtils.getLayerFiles().map(f => f.parsed)
var builtinsPerLayer= new Map<string, string[]>(); var builtinsPerLayer= new Map<string, string[]>();
var layersUsingBuiltin = new Map<string /* Builtin */, string[]>(); var layersUsingBuiltin = new Map<string /* Builtin */, string[]>();

View file

@ -138,16 +138,16 @@ class LayerOverviewUtils {
const sharedTagRenderings = this.getSharedTagRenderings(); const sharedTagRenderings = this.getSharedTagRenderings();
const layerFiles = ScriptUtils.getLayerFiles(); const layerFiles = ScriptUtils.getLayerFiles();
const sharedLayers = new Map<string, LayerConfigJson>() const sharedLayers = new Map<string, LayerConfigJson>()
const prepLayer = new PrepareLayer();
const state: DesugaringContext = { const state: DesugaringContext = {
tagRenderings: sharedTagRenderings, tagRenderings: sharedTagRenderings,
sharedLayers sharedLayers
} }
const prepLayer = new PrepareLayer(state);
for (const sharedLayerJson of layerFiles) { for (const sharedLayerJson of layerFiles) {
const context = "While building builtin layer " + sharedLayerJson.path const context = "While building builtin layer " + sharedLayerJson.path
const fixed = prepLayer.convertStrict(state, sharedLayerJson.parsed, context) const fixed = prepLayer.convertStrict(sharedLayerJson.parsed, context)
const validator = new ValidateLayer(knownImagePaths, sharedLayerJson.path, true); const validator = new ValidateLayer(knownImagePaths, sharedLayerJson.path, true);
validator.convertStrict(state, fixed, context) validator.convertStrict(fixed, context)
if (sharedLayers.has(fixed.id)) { if (sharedLayers.has(fixed.id)) {
throw "There are multiple layers with the id " + fixed.id throw "There are multiple layers with the id " + fixed.id
@ -174,11 +174,11 @@ class LayerOverviewUtils {
let themeFile = themeInfo.parsed let themeFile = themeInfo.parsed
const themePath = themeInfo.path const themePath = themeInfo.path
new PrevalidateTheme().convertStrict(convertState, themeFile, themePath) new PrevalidateTheme().convertStrict(themeFile, themePath)
themeFile = new PrepareTheme().convertStrict(convertState, themeFile, themePath) themeFile = new PrepareTheme(convertState).convertStrict(themeFile, themePath)
new ValidateThemeAndLayers(knownImagePaths, themePath, true) new ValidateThemeAndLayers(knownImagePaths, themePath, true)
.convertStrict(convertState, themeFile, themePath) .convertStrict(themeFile, themePath)
this.writeTheme(themeFile) this.writeTheme(themeFile)
fixed.set(themeFile.id, themeFile) fixed.set(themeFile.id, themeFile)

View file

@ -357,10 +357,7 @@ export default class LegacyThemeLoaderSpec extends T {
["Walking_node_theme", () => { ["Walking_node_theme", () => {
const config = LegacyThemeLoaderSpec.walking_node_theme const config = LegacyThemeLoaderSpec.walking_node_theme
const fixed = new FixLegacyTheme().convert({ const fixed = new FixLegacyTheme().convert(
tagRenderings: new Map<string, TagRenderingConfigJson>(),
sharedLayers: new Map<string, LayerConfigJson>()
},
// @ts-ignore // @ts-ignore
config, config,
"While testing") "While testing")
@ -414,7 +411,7 @@ export default class LegacyThemeLoaderSpec extends T {
}], }],
["Shadowed mappings are detected", ["Shadowed mappings are detected",
() => { () => {
const r = new DetectShadowedMappings().convert(undefined, { const r = new DetectShadowedMappings().convert({
mappings: [ mappings: [
{ {
if: {or: ["key=value", "x=y"]}, if: {or: ["key=value", "x=y"]},
@ -428,7 +425,7 @@ export default class LegacyThemeLoaderSpec extends T {
}, "test"); }, "test");
T.isTrue(r.errors.length > 0, "Failing case is not detected") T.isTrue(r.errors.length > 0, "Failing case is not detected")
const r0 = new DetectShadowedMappings().convert(undefined, { const r0 = new DetectShadowedMappings().convert( {
mappings: [ mappings: [
{ {
if: {or: ["key=value", "x=y"]}, if: {or: ["key=value", "x=y"]},

View file

@ -40,10 +40,10 @@ export default class ThemeSpec extends T {
Constants.added_by_default.splice(0, Constants.added_by_default.length) Constants.added_by_default.splice(0, Constants.added_by_default.length)
const sharedLayers = new Map<string, LayerConfigJson>() const sharedLayers = new Map<string, LayerConfigJson>()
sharedLayers.set("public_bookcase", bookcaseLayer["default"]) sharedLayers.set("public_bookcase", bookcaseLayer["default"])
themeConfigJson = new PrepareTheme().convertStrict({ themeConfigJson = new PrepareTheme({
tagRenderings: new Map<string, TagRenderingConfigJson>(), tagRenderings: new Map<string, TagRenderingConfigJson>(),
sharedLayers: sharedLayers sharedLayers: sharedLayers
}, themeConfigJson, "test") }).convertStrict( themeConfigJson, "test")
const themeConfig = new LayoutConfig(themeConfigJson); const themeConfig = new LayoutConfig(themeConfigJson);
assert.equal("xyz", themeConfig.layers[0].source.geojsonSource) assert.equal("xyz", themeConfig.layers[0].source.geojsonSource)