forked from MapComplete/MapComplete
First working version with multi-rendering
This commit is contained in:
parent
0c0ef48a96
commit
20fa5028d9
5 changed files with 129 additions and 21 deletions
|
@ -26,7 +26,7 @@ export default class SimpleMetaTagger {
|
||||||
"_last_edit:changeset",
|
"_last_edit:changeset",
|
||||||
"_last_edit:timestamp",
|
"_last_edit:timestamp",
|
||||||
"_version_number",
|
"_version_number",
|
||||||
"_backend"],
|
"_backend"],
|
||||||
doc: "Information about the last edit of this object."
|
doc: "Information about the last edit of this object."
|
||||||
},
|
},
|
||||||
(feature) => {/*Note: also called by 'UpdateTagsFromOsmAPI'*/
|
(feature) => {/*Note: also called by 'UpdateTagsFromOsmAPI'*/
|
||||||
|
@ -67,17 +67,100 @@ export default class SimpleMetaTagger {
|
||||||
private static layerInfo = new SimpleMetaTagger(
|
private static layerInfo = new SimpleMetaTagger(
|
||||||
{
|
{
|
||||||
doc: "The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined.",
|
doc: "The layer-id to which this feature belongs. Note that this might be return any applicable if `passAllFeatures` is defined.",
|
||||||
keys:["_layer"],
|
keys: ["_layer"],
|
||||||
includesDates: false,
|
includesDates: false,
|
||||||
},
|
},
|
||||||
(feature, freshness, layer) => {
|
(feature, freshness, layer) => {
|
||||||
if(feature.properties._layer === layer.id){
|
if (feature.properties._layer === layer.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
feature.properties._layer = layer.id
|
feature.properties._layer = layer.id
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
private static noBothButLeftRight = new SimpleMetaTagger(
|
||||||
|
{
|
||||||
|
keys: ["sidewalk:left", "sidewalk:right", "generic_key:left:property", "generic_key:right:property"],
|
||||||
|
doc: "Rewrites tags from 'generic_key:both:property' as 'generic_key:left:property' and 'generic_key:right:property' (and similar for sidewalk tagging). Note that this rewritten tags _will be reuploaded on a change_. To prevent to much unrelated retagging, this is only enabled if the layer has at least some lineRenderings with offset defined",
|
||||||
|
includesDates: false,
|
||||||
|
cleanupRetagger: true
|
||||||
|
},
|
||||||
|
((feature, state, layer) => {
|
||||||
|
|
||||||
|
if(!layer.lineRendering.some(lr => lr.leftRightSensitive)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tgs = feature.properties;
|
||||||
|
let somethingChanged = false
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key onto the properties (but doesn't overwrite if already existing)
|
||||||
|
*/
|
||||||
|
function set(key, value) {
|
||||||
|
if (tgs[key] === undefined || tgs[key] === "") {
|
||||||
|
tgs[key] = value
|
||||||
|
somethingChanged = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgs["sidewalk"]) {
|
||||||
|
|
||||||
|
const v = tgs["sidewalk"]
|
||||||
|
switch (v) {
|
||||||
|
case "none":
|
||||||
|
case "no":
|
||||||
|
set("sidewalk:left", "no");
|
||||||
|
set("sidewalk:right", "no");
|
||||||
|
break
|
||||||
|
case "both":
|
||||||
|
set("sidewalk:left", "yes");
|
||||||
|
set("sidewalk:right", "yes");
|
||||||
|
break;
|
||||||
|
case "left":
|
||||||
|
set("sidewalk:left", "yes");
|
||||||
|
set("sidewalk:right", "no");
|
||||||
|
break;
|
||||||
|
case "right":
|
||||||
|
set("sidewalk:left", "no");
|
||||||
|
set("sidewalk:right", "yes");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set("sidewalk:left", v);
|
||||||
|
set("sidewalk:right", v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delete tgs["sidewalk"]
|
||||||
|
somethingChanged = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const regex = /\([^:]*\):both:\(.*\)/
|
||||||
|
for (const key in tgs) {
|
||||||
|
const v = tgs[key]
|
||||||
|
if (key.endsWith(":both")) {
|
||||||
|
const strippedKey = key.substring(0, key.length - ":both".length)
|
||||||
|
set(strippedKey + ":left", v)
|
||||||
|
set(strippedKey + ":right", v)
|
||||||
|
delete tgs[key]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = key.match(regex)
|
||||||
|
if (match !== null) {
|
||||||
|
const strippedKey = match[1]
|
||||||
|
const property = match[1]
|
||||||
|
set(strippedKey + ":left:" + property, v)
|
||||||
|
set(strippedKey + ":right:" + property, v)
|
||||||
|
console.log("Left-right rewritten " + key)
|
||||||
|
delete tgs[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return somethingChanged
|
||||||
|
})
|
||||||
|
)
|
||||||
private static surfaceArea = new SimpleMetaTagger(
|
private static surfaceArea = new SimpleMetaTagger(
|
||||||
{
|
{
|
||||||
keys: ["_surface", "_surface:ha"],
|
keys: ["_surface", "_surface:ha"],
|
||||||
|
@ -85,12 +168,12 @@ export default class SimpleMetaTagger {
|
||||||
isLazy: true
|
isLazy: true
|
||||||
},
|
},
|
||||||
(feature => {
|
(feature => {
|
||||||
|
|
||||||
Object.defineProperty(feature.properties, "_surface", {
|
Object.defineProperty(feature.properties, "_surface", {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get: () => {
|
get: () => {
|
||||||
const sqMeters = ""+ GeoOperations.surfaceAreaInSqMeters(feature);
|
const sqMeters = "" + GeoOperations.surfaceAreaInSqMeters(feature);
|
||||||
delete feature.properties["_surface"]
|
delete feature.properties["_surface"]
|
||||||
feature.properties["_surface"] = sqMeters;
|
feature.properties["_surface"] = sqMeters;
|
||||||
return sqMeters
|
return sqMeters
|
||||||
|
@ -108,7 +191,7 @@ export default class SimpleMetaTagger {
|
||||||
return sqMetersHa
|
return sqMetersHa
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -219,8 +302,8 @@ export default class SimpleMetaTagger {
|
||||||
// isOpen is irrelevant
|
// isOpen is irrelevant
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(feature.properties, "_isOpen",{
|
Object.defineProperty(feature.properties, "_isOpen", {
|
||||||
enumerable: false,
|
enumerable: false,
|
||||||
configurable: true,
|
configurable: true,
|
||||||
get: () => {
|
get: () => {
|
||||||
|
@ -247,7 +330,7 @@ export default class SimpleMetaTagger {
|
||||||
|
|
||||||
if (oldNextChange > (new Date()).getTime() &&
|
if (oldNextChange > (new Date()).getTime() &&
|
||||||
tags["_isOpen:oldvalue"] === tags["opening_hours"]
|
tags["_isOpen:oldvalue"] === tags["opening_hours"]
|
||||||
&& tags["_isOpen"] !== undefined) {
|
&& tags["_isOpen"] !== undefined) {
|
||||||
// Already calculated and should not yet be triggered
|
// Already calculated and should not yet be triggered
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +437,8 @@ export default class SimpleMetaTagger {
|
||||||
SimpleMetaTagger.isOpen,
|
SimpleMetaTagger.isOpen,
|
||||||
SimpleMetaTagger.directionSimplified,
|
SimpleMetaTagger.directionSimplified,
|
||||||
SimpleMetaTagger.currentTime,
|
SimpleMetaTagger.currentTime,
|
||||||
SimpleMetaTagger.objectMetaInfo
|
SimpleMetaTagger.objectMetaInfo,
|
||||||
|
SimpleMetaTagger.noBothButLeftRight
|
||||||
|
|
||||||
];
|
];
|
||||||
public static readonly lazyTags: string[] = [].concat(...SimpleMetaTagger.metatags.filter(tagger => tagger.isLazy)
|
public static readonly lazyTags: string[] = [].concat(...SimpleMetaTagger.metatags.filter(tagger => tagger.isLazy)
|
||||||
|
@ -365,22 +449,24 @@ export default class SimpleMetaTagger {
|
||||||
public readonly isLazy: boolean;
|
public readonly isLazy: boolean;
|
||||||
public readonly includesDates: boolean
|
public readonly includesDates: boolean
|
||||||
public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date, layer: LayerConfig) => boolean;
|
public readonly applyMetaTagsOnFeature: (feature: any, freshness: Date, layer: LayerConfig) => boolean;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* A function that adds some extra data to a feature
|
* A function that adds some extra data to a feature
|
||||||
* @param docs: what does this extra data do?
|
* @param docs: what does this extra data do?
|
||||||
* @param f: apply the changes. Returns true if something changed
|
* @param f: apply the changes. Returns true if something changed
|
||||||
*/
|
*/
|
||||||
constructor(docs: { keys: string[], doc: string, includesDates?: boolean, isLazy?: boolean },
|
constructor(docs: { keys: string[], doc: string, includesDates?: boolean, isLazy?: boolean, cleanupRetagger?: boolean },
|
||||||
f: ((feature: any, freshness: Date, layer: LayerConfig) => boolean)) {
|
f: ((feature: any, freshness: Date, layer: LayerConfig) => boolean)) {
|
||||||
this.keys = docs.keys;
|
this.keys = docs.keys;
|
||||||
this.doc = docs.doc;
|
this.doc = docs.doc;
|
||||||
this.isLazy = docs.isLazy
|
this.isLazy = docs.isLazy
|
||||||
this.applyMetaTagsOnFeature = f;
|
this.applyMetaTagsOnFeature = f;
|
||||||
this.includesDates = docs.includesDates ?? false;
|
this.includesDates = docs.includesDates ?? false;
|
||||||
for (const key of docs.keys) {
|
if (!docs.cleanupRetagger) {
|
||||||
if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) {
|
for (const key of docs.keys) {
|
||||||
throw `Incorrect metakey ${key}: it should start with underscore (_)`
|
if (!key.startsWith('_') && key.toLowerCase().indexOf("theme") < 0) {
|
||||||
|
throw `Incorrect metakey ${key}: it should start with underscore (_)`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,10 @@ export default interface LineRenderingConfigJson {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of pixels this line should be moved.
|
* The number of pixels this line should be moved.
|
||||||
* Use a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line)
|
* Use a positive numbe to move to the right, a negative to move to the left (left/right as defined by the drawing direction of the line).
|
||||||
|
*
|
||||||
|
* IMPORTANT: MapComplete will already normalize 'key:both:property' and 'key:both' into the corresponding 'key:left' and 'key:right' tagging (same for 'sidewalk=left/right/both' which is rewritten to 'sidewalk:left' and 'sidewalk:right')
|
||||||
|
* This simplifies programming. Refer to the CalculatedTags.md-documentation for more details
|
||||||
*/
|
*/
|
||||||
offset?: number | TagRenderingConfigJson
|
offset?: number | TagRenderingConfigJson
|
||||||
}
|
}
|
|
@ -12,12 +12,16 @@ export default class LineRenderingConfig extends WithContextLoader {
|
||||||
public readonly width: TagRenderingConfig;
|
public readonly width: TagRenderingConfig;
|
||||||
public readonly dashArray: TagRenderingConfig;
|
public readonly dashArray: TagRenderingConfig;
|
||||||
public readonly offset: TagRenderingConfig;
|
public readonly offset: TagRenderingConfig;
|
||||||
|
public readonly leftRightSensitive: boolean
|
||||||
|
|
||||||
constructor(json: LineRenderingConfigJson, context: string) {
|
constructor(json: LineRenderingConfigJson, context: string) {
|
||||||
super(json, context)
|
super(json, context)
|
||||||
this.color = this.tr("color", "#0000ff");
|
this.color = this.tr("color", "#0000ff");
|
||||||
this.width = this.tr("width", "7");
|
this.width = this.tr("width", "7");
|
||||||
this.dashArray = this.tr("dashArray", "");
|
this.dashArray = this.tr("dashArray", "");
|
||||||
|
|
||||||
|
this.leftRightSensitive = json.offset !== undefined && json.offset !== 0 && json.offset !== "0"
|
||||||
|
|
||||||
this.offset = this.tr("offset", "0");
|
this.offset = this.tr("offset", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default class TagRenderingConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(typeof json === "number"){
|
if(typeof json === "number"){
|
||||||
this.render =Translations.WT( ""+json)
|
this.render = Translations.WT( ""+json)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,23 @@
|
||||||
"width": 8
|
"width": 8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"color": "#888",
|
"color": {
|
||||||
"width": 8,
|
"render": "#888"
|
||||||
|
},
|
||||||
|
"width": {
|
||||||
|
"render": "8",
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"or": [
|
||||||
|
"sidewalk:left=no",
|
||||||
|
"sidewalk:left=separate"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"offset": -8
|
"offset": -8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -55,7 +70,7 @@
|
||||||
"offset": 8
|
"offset": 8
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"allowSplit": true
|
"allowSplit": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue