Merge develop

This commit is contained in:
Pieter Vander Vennet 2021-07-27 19:59:41 +02:00
commit 0162d52b68
127 changed files with 6609 additions and 15167 deletions

View file

@ -6,12 +6,13 @@ import {And} from "../../Logic/Tags/And";
import {Tag} from "../../Logic/Tags/Tag";
import {TagsFilter} from "../../Logic/Tags/TagsFilter";
import SubstitutingTag from "../../Logic/Tags/SubstitutingTag";
import ComparingTag from "../../Logic/Tags/ComparingTag";
export class FromJSON {
public static SimpleTag(json: string, context?: string): Tag {
const tag = Utils.SplitFirst(json, "=");
if(tag.length !== 2){
if (tag.length !== 2) {
throw `Invalid tag: no (or too much) '=' found (in ${context ?? "unkown context"})`
}
return new Tag(tag[0], tag[1]);
@ -26,6 +27,15 @@ export class FromJSON {
}
}
private static comparators
: [string, (a: number, b: number) => boolean][]
= [
["<=", (a, b) => a <= b],
[">=", (a, b) => a >= b],
["<", (a, b) => a < b],
[">", (a, b) => a > b],
]
private static TagUnsafe(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
if (json === undefined) {
@ -33,6 +43,27 @@ export class FromJSON {
}
if (typeof (json) == "string") {
const tag = json as string;
for (const [operator, comparator] of FromJSON.comparators) {
if (tag.indexOf(operator) >= 0) {
const split = Utils.SplitFirst(tag, operator);
const val = Number(split[1].trim())
if (isNaN(val)) {
throw `Error: not a valid value for a comparison: ${split[1]}, make sure it is a number and nothing more (at ${context})`
}
const f = (value: string | undefined) => {
const b = Number(value?.replace(/[^\d.]/g,''))
if (isNaN(b)) {
return false;
}
return comparator(b, val)
}
return new ComparingTag(split[0], f, operator + val)
}
}
if (tag.indexOf("!~") >= 0) {
const split = Utils.SplitFirst(tag, "!~");
if (split[1] === "*") {
@ -54,11 +85,11 @@ export class FromJSON {
new RegExp("^" + split[1] + "$")
);
}
if(tag.indexOf(":=") >= 0){
if (tag.indexOf(":=") >= 0) {
const split = Utils.SplitFirst(tag, ":=");
return new SubstitutingTag(split[0], split[1]);
}
if (tag.indexOf("!=") >= 0) {
const split = Utils.SplitFirst(tag, "!=");
if (split[1] === "*") {

View file

@ -55,7 +55,7 @@ export interface LayerConfigJson {
* Note that both geojson-options might set a flag 'isOsmCache' indicating that the data originally comes from OSM too
*
*
* NOTE: the previous format was 'overpassTags: AndOrTagCOnfigJson | string', which is interpreted as a shorthand for source: {osmTags: "key=value"}
* NOTE: the previous format was 'overpassTags: AndOrTagConfigJson | string', which is interpreted as a shorthand for source: {osmTags: "key=value"}
* While still supported, this is considered deprecated
*/
source: { osmTags: AndOrTagConfigJson | string } |
@ -82,7 +82,7 @@ export interface LayerConfigJson {
doNotDownload?: boolean;
/**
* This tagrendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.
* This tag rendering should either be 'yes' or 'no'. If 'no' is returned, then the feature will be hidden from view.
* This is useful to hide certain features from view. Important: hiding features does not work dynamically, but is only calculated when the data is first renders.
* This implies that it is not possible to hide a feature after a tagging change
*
@ -98,8 +98,8 @@ export interface LayerConfigJson {
minzoom?: number;
/**
* If zoomed out below this zoomlevel, the data will be hidden.
* Default: minzoom
* The zoom level at which point the data is hidden again
* Default: 100 (thus: always visible
*/
minzoomVisible?: number;
@ -121,9 +121,9 @@ export interface LayerConfigJson {
* Note that this also doubles as the icon for this layer (rendered with the overpass-tags) ánd the icon in the presets.
*
* The result of the icon is rendered as follows:
* the resulting string is interpreted as a _list_ of items, seperated by ";". The bottommost layer is the first layer.
* the resulting string is interpreted as a _list_ of items, separated by ";". The bottommost layer is the first layer.
* As a result, on could use a generic pin, then overlay it with a specific icon.
* To make things even more practical, one can use all svgs from the folder "assets/svg" and _substitute the color_ in it.
* To make things even more practical, one can use all SVG's from the folder "assets/svg" and _substitute the color_ in it.
* E.g. to draw a red pin, use "pin:#f00", to have a green circle with your icon on top, use `circle:#0f0;<path to my icon.svg>`
*
*/
@ -221,7 +221,7 @@ export interface LayerConfigJson {
/**
* If set, the user will prompted to confirm the location before actually adding the data.
* THis will be with a 'drag crosshair'-method.
* This will be with a 'drag crosshair'-method.
*
* If 'preferredBackgroundCategory' is set, the element will attempt to pick a background layer of that category.
*/
@ -236,7 +236,7 @@ export interface LayerConfigJson {
*
* Refer to the class `TagRenderingConfigJson` to see the possibilities.
*
* Note that we can also use a string here - where the string refers to a tagrenering defined in `assets/questions/questions.json`,
* Note that we can also use a string here - where the string refers to a tag rendering defined in `assets/questions/questions.json`,
* where a few very general questions are defined e.g. website, phone number, ...
*
* A special value is 'questions', which indicates the location of the questions box. If not specified, it'll be appended to the bottom of the featureInfobox.

View file

@ -95,7 +95,7 @@ export default class LayoutConfig {
}
);
this.defaultBackgroundId = json.defaultBackgroundId;
this.layers = LayoutConfig.ExtractLayers(json, this.units, official);
this.layers = LayoutConfig.ExtractLayers(json, this.units, official, context);
// ALl the layers are constructed, let them share tags in now!
const roaming: { r, source: LayerConfig }[] = []
@ -160,12 +160,12 @@ export default class LayoutConfig {
}
private static ExtractLayers(json: LayoutConfigJson, units: Unit[], official: boolean): LayerConfig[] {
private static ExtractLayers(json: LayoutConfigJson, units: Unit[], official: boolean, context: string): LayerConfig[] {
const result: LayerConfig[] = []
json.layers.forEach((layer, i) => {
if (typeof layer === "string") {
if (AllKnownLayers.sharedLayersJson[layer] !== undefined) {
if (AllKnownLayers.sharedLayersJson.get(layer) !== undefined) {
if (json.overrideAll !== undefined) {
let lyr = JSON.parse(JSON.stringify(AllKnownLayers.sharedLayersJson[layer]));
const newLayer = new LayerConfig(Utils.Merge(json.overrideAll, lyr), units, `${json.id}+overrideAll.layers[${i}]`, official)
@ -176,7 +176,8 @@ export default class LayoutConfig {
return
}
} else {
throw "Unknown fixed layer " + layer;
console.log("Layer ", layer," not kown, try one of", Array.from(AllKnownLayers.sharedLayers.keys()).join(", "))
throw `Unknown builtin layer ${layer} at ${context}.layers[${i}]`;
}
}
@ -195,9 +196,9 @@ export default class LayoutConfig {
names = [names]
}
names.forEach(name => {
const shared = AllKnownLayers.sharedLayersJson[name];
const shared = AllKnownLayers.sharedLayersJson.get(name);
if (shared === undefined) {
throw "Unknown fixed layer " + name;
throw `Unknown shared/builtin layer ${name} at ${context}.layers[${i}]. Available layers are ${Array.from(AllKnownLayers.sharedLayersJson.keys()).join(", ")}`;
}
// @ts-ignore
let newLayer: LayerConfigJson = Utils.Merge(layer.override, JSON.parse(JSON.stringify(shared))); // We make a deep copy of the shared layer, in order to protect it from changes