forked from MapComplete/MapComplete
Merge develop
This commit is contained in:
commit
0162d52b68
127 changed files with 6609 additions and 15167 deletions
|
@ -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] === "*") {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue