Merge branch 'develop' of github.com:pietervdvn/MapComplete into develop
This commit is contained in:
commit
2310b23219
13 changed files with 112 additions and 91 deletions
|
@ -50,6 +50,22 @@ export class ChangesetHandler {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new list which contains every key at most once
|
||||||
|
*/
|
||||||
|
public static removeDuplicateMetaTags(extraMetaTags: ChangesetTag[]): ChangesetTag[]{
|
||||||
|
const r : ChangesetTag[] = []
|
||||||
|
const seen = new Set<string>()
|
||||||
|
for (const extraMetaTag of extraMetaTags) {
|
||||||
|
if(seen.has(extraMetaTag.key)){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
r.push(extraMetaTag)
|
||||||
|
seen.add(extraMetaTag.key)
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inplace rewrite of extraMetaTags
|
* Inplace rewrite of extraMetaTags
|
||||||
* If the metatags contain a special motivation of the format "<change-type>:node/-<number>", this method will rewrite this negative number to the actual ID
|
* If the metatags contain a special motivation of the format "<change-type>:node/-<number>", this method will rewrite this negative number to the actual ID
|
||||||
|
@ -95,7 +111,7 @@ export class ChangesetHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
extraMetaTags = [...extraMetaTags, ...this.defaultChangesetTags()]
|
extraMetaTags = [...extraMetaTags, ...this.defaultChangesetTags()]
|
||||||
|
extraMetaTags = ChangesetHandler.removeDuplicateMetaTags(extraMetaTags)
|
||||||
if (this.userDetails.data.csCount == 0) {
|
if (this.userDetails.data.csCount == 0) {
|
||||||
// The user became a contributor!
|
// The user became a contributor!
|
||||||
this.userDetails.data.csCount = 1;
|
this.userDetails.data.csCount = 1;
|
||||||
|
@ -316,6 +332,7 @@ export class ChangesetHandler {
|
||||||
private async UpdateTags(
|
private async UpdateTags(
|
||||||
csId: number,
|
csId: number,
|
||||||
tags: ChangesetTag[]) {
|
tags: ChangesetTag[]) {
|
||||||
|
tags = ChangesetHandler.removeDuplicateMetaTags(tags)
|
||||||
|
|
||||||
console.trace("Updating tags of " + csId)
|
console.trace("Updating tags of " + csId)
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
|
@ -31,6 +31,15 @@ export default class ComparingTag implements TagsFilter {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the properties match
|
||||||
|
*
|
||||||
|
* const t = new ComparingTag("key", (x => Number(x) < 42))
|
||||||
|
* t.matchesProperties({key: 42}) // => false
|
||||||
|
* t.matchesProperties({key: 41}) // => true
|
||||||
|
* t.matchesProperties({key: 0}) // => true
|
||||||
|
* t.matchesProperties({differentKey: 42}) // => false
|
||||||
|
*/
|
||||||
matchesProperties(properties: any): boolean {
|
matchesProperties(properties: any): boolean {
|
||||||
return this._predicate(properties[this._key]);
|
return this._predicate(properties[this._key]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ export class Tag extends TagsFilter {
|
||||||
* isEmpty.matchesProperties({"key": ""}) // => true
|
* isEmpty.matchesProperties({"key": ""}) // => true
|
||||||
* isEmpty.matchesProperties({"other_key": ""}) // => true
|
* isEmpty.matchesProperties({"other_key": ""}) // => true
|
||||||
* isEmpty.matchesProperties({"other_key": "value"}) // => true
|
* isEmpty.matchesProperties({"other_key": "value"}) // => true
|
||||||
|
* isEmpty.matchesProperties({"key": undefined}) // => true
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
matchesProperties(properties: any): boolean {
|
matchesProperties(properties: any): boolean {
|
||||||
const foundValue = properties[this.key]
|
const foundValue = properties[this.key]
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
||||||
|
|
||||||
export default class Constants {
|
export default class Constants {
|
||||||
|
|
||||||
public static vNumber = "0.17.0-alpha-2";
|
public static vNumber = "0.17.0-alpha-3";
|
||||||
|
|
||||||
public static ImgurApiKey = '7070e7167f0a25a'
|
public static ImgurApiKey = '7070e7167f0a25a'
|
||||||
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
||||||
|
|
|
@ -220,6 +220,23 @@ export class OH {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an OH-syntax rule into an object
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* const rules = OH.ParsePHRule("PH 12:00-17:00")
|
||||||
|
* rules.mode // => " "
|
||||||
|
* rules.start // => "12:00"
|
||||||
|
* rules.end // => "17:00"
|
||||||
|
*
|
||||||
|
* OH.ParseRule("PH 12:00-17:00") // => null
|
||||||
|
* OH.ParseRule("Th[-1] off") // => null
|
||||||
|
*
|
||||||
|
* const rules = OH.Parse("24/7");
|
||||||
|
* rules.length // => 7
|
||||||
|
* rules[0].startHour // => 0
|
||||||
|
* OH.ToString(rules) // => "24/7"
|
||||||
|
*/
|
||||||
public static ParseRule(rule: string): OpeningHour[] {
|
public static ParseRule(rule: string): OpeningHour[] {
|
||||||
try {
|
try {
|
||||||
if (rule.trim() == "24/7") {
|
if (rule.trim() == "24/7") {
|
||||||
|
|
|
@ -43,6 +43,14 @@ export default class Translations {
|
||||||
return new Translation(t, context);
|
return new Translation(t, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 'Wrap Translation': given an object containing translations OR a string, returns a translation object
|
||||||
|
*
|
||||||
|
* const json: any = {"en": "English", "nl": "Nederlands"};
|
||||||
|
* const translation = Translations.WT(new Translation(json));
|
||||||
|
* translation.textFor("en") // => "English"
|
||||||
|
* translation.textFor("nl") // => "Nederlands"
|
||||||
|
*/
|
||||||
public static WT(s: string | Translation): Translation {
|
public static WT(s: string | Translation): Translation {
|
||||||
if (s === undefined || s === null) {
|
if (s === undefined || s === null) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
17
Utils.ts
17
Utils.ts
|
@ -109,7 +109,22 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
||||||
return "" + i;
|
return "" + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Round(i: number) {
|
/**
|
||||||
|
* Converts a number to a string with one number after the comma
|
||||||
|
*
|
||||||
|
* Utils.Round(15) // => "15.0"
|
||||||
|
* Utils.Round(1) // => "1.0"
|
||||||
|
* Utils.Round(1.5) // => "1.5"
|
||||||
|
* Utils.Round(0.5) // => "0.5"
|
||||||
|
* Utils.Round(1.6) // => "1.6"
|
||||||
|
* Utils.Round(-15) // => "-15.0"
|
||||||
|
* Utils.Round(-1) // => "-1.0"
|
||||||
|
* Utils.Round(-1.5) // => "-1.5"
|
||||||
|
* Utils.Round(-0.5) // => "-0.5"
|
||||||
|
* Utils.Round(-1.6) // => "-1.6"
|
||||||
|
* Utils.Round(-1531.63543) // =>"-1531.6"
|
||||||
|
*/
|
||||||
|
public static Round(i: number): string {
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return "-" + Utils.Round(-i);
|
return "-" + Utils.Round(-i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3370,18 +3370,6 @@
|
||||||
"nl": "Moet men betalen om dit oplaadpunt te gebruiken?"
|
"nl": "Moet men betalen om dit oplaadpunt te gebruiken?"
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"and": [
|
|
||||||
"fee=no"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"nl": "Gratis te gebruiken",
|
|
||||||
"en": "Free to use"
|
|
||||||
},
|
|
||||||
"hideInAnswer": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"and": [
|
"and": [
|
||||||
|
@ -3410,6 +3398,18 @@
|
||||||
"en": "Free to use, but one has to authenticate"
|
"en": "Free to use, but one has to authenticate"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"and": [
|
||||||
|
"fee=no"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"nl": "Gratis te gebruiken",
|
||||||
|
"en": "Free to use"
|
||||||
|
},
|
||||||
|
"hideInAnswer": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"and": [
|
"and": [
|
||||||
|
|
|
@ -224,18 +224,6 @@
|
||||||
"nl": "Moet men betalen om dit oplaadpunt te gebruiken?"
|
"nl": "Moet men betalen om dit oplaadpunt te gebruiken?"
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
|
||||||
"if": {
|
|
||||||
"and": [
|
|
||||||
"fee=no"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"then": {
|
|
||||||
"nl": "Gratis te gebruiken",
|
|
||||||
"en": "Free to use"
|
|
||||||
},
|
|
||||||
"hideInAnswer": true
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"and": [
|
"and": [
|
||||||
|
@ -264,6 +252,18 @@
|
||||||
"en": "Free to use, but one has to authenticate"
|
"en": "Free to use, but one has to authenticate"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"if": {
|
||||||
|
"and": [
|
||||||
|
"fee=no"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"then": {
|
||||||
|
"nl": "Gratis te gebruiken",
|
||||||
|
"en": "Free to use"
|
||||||
|
},
|
||||||
|
"hideInAnswer": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"if": {
|
"if": {
|
||||||
"and": [
|
"and": [
|
||||||
|
|
|
@ -379,6 +379,14 @@
|
||||||
"then": "isOpen"
|
"then": "isOpen"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"label": {
|
||||||
|
"mappings": [
|
||||||
|
{
|
||||||
|
"if": "name~*",
|
||||||
|
"then": "<div style='background: white; padding: 0.25em; border-radius:0.5em'>{name}</div>"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"iconSize": {
|
"iconSize": {
|
||||||
"render": "40,40,center"
|
"render": "40,40,center"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1797,14 +1797,14 @@
|
||||||
"fee": {
|
"fee": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Free to use"
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"then": "Free to use (without authenticating)"
|
"then": "Free to use (without authenticating)"
|
||||||
},
|
},
|
||||||
"2": {
|
"1": {
|
||||||
"then": "Free to use, but one has to authenticate"
|
"then": "Free to use, but one has to authenticate"
|
||||||
},
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Free to use"
|
||||||
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"then": "Paid use, but free for customers of the hotel/pub/hospital/... who operates the charging station"
|
"then": "Paid use, but free for customers of the hotel/pub/hospital/... who operates the charging station"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1806,14 +1806,14 @@
|
||||||
"fee": {
|
"fee": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Gratis te gebruiken"
|
|
||||||
},
|
|
||||||
"1": {
|
|
||||||
"then": "Gratis te gebruiken (zonder aan te melden)"
|
"then": "Gratis te gebruiken (zonder aan te melden)"
|
||||||
},
|
},
|
||||||
"2": {
|
"1": {
|
||||||
"then": "Gratis te gebruiken, maar aanmelden met een applicatie is verplicht"
|
"then": "Gratis te gebruiken, maar aanmelden met een applicatie is verplicht"
|
||||||
},
|
},
|
||||||
|
"2": {
|
||||||
|
"then": "Gratis te gebruiken"
|
||||||
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"then": "Betalend te gebruiken, maar gratis voor klanten van het bijhorende hotel/café/ziekenhuis/..."
|
"then": "Betalend te gebruiken, maar gratis voor klanten van het bijhorende hotel/café/ziekenhuis/..."
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import {Utils} from "../Utils";
|
|
||||||
import {equal} from "assert";
|
import {equal} from "assert";
|
||||||
import T from "./TestHelper";
|
import T from "./TestHelper";
|
||||||
import Locale from "../UI/i18n/Locale";
|
import Locale from "../UI/i18n/Locale";
|
||||||
import Translations from "../UI/i18n/Translations";
|
|
||||||
import {Translation} from "../UI/i18n/Translation";
|
|
||||||
import {OH, OpeningHour} from "../UI/OpeningHours/OpeningHours";
|
import {OH, OpeningHour} from "../UI/OpeningHours/OpeningHours";
|
||||||
import {Tag} from "../Logic/Tags/Tag";
|
import {Tag} from "../Logic/Tags/Tag";
|
||||||
import {And} from "../Logic/Tags/And";
|
import {And} from "../Logic/Tags/And";
|
||||||
|
@ -97,15 +94,6 @@ export default class TagSpec extends T {
|
||||||
equal(false, t2.isEquivalent(t0))
|
equal(false, t2.isEquivalent(t0))
|
||||||
equal(false, t2.isEquivalent(t1))
|
equal(false, t2.isEquivalent(t1))
|
||||||
})],
|
})],
|
||||||
["Parse translation map", (() => {
|
|
||||||
|
|
||||||
const json: any = {"en": "English", "nl": "Nederlands"};
|
|
||||||
const translation = Translations.WT(new Translation(json));
|
|
||||||
Locale.language.setData("en");
|
|
||||||
equal(translation.txt, "English");
|
|
||||||
Locale.language.setData("nl");
|
|
||||||
equal(translation.txt, "Nederlands");
|
|
||||||
})],
|
|
||||||
["Parse tag rendering", (() => {
|
["Parse tag rendering", (() => {
|
||||||
Locale.language.setData("nl");
|
Locale.language.setData("nl");
|
||||||
const tr = new TagRenderingConfig({
|
const tr = new TagRenderingConfig({
|
||||||
|
@ -130,13 +118,6 @@ export default class TagSpec extends T {
|
||||||
equal(undefined, tr.GetRenderValue({"foo": "bar"}));
|
equal(undefined, tr.GetRenderValue({"foo": "bar"}));
|
||||||
|
|
||||||
})],
|
})],
|
||||||
[
|
|
||||||
"Empty match test",
|
|
||||||
() => {
|
|
||||||
const t = new Tag("key", "");
|
|
||||||
equal(false, t.matchesProperties({"key": "somevalue"}))
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"Test not with overpass",
|
"Test not with overpass",
|
||||||
() => {
|
() => {
|
||||||
|
@ -385,42 +366,6 @@ export default class TagSpec extends T {
|
||||||
]));
|
]));
|
||||||
equal(rules, "Tu 23:00-00:00");
|
equal(rules, "Tu 23:00-00:00");
|
||||||
}],
|
}],
|
||||||
["OH 24/7", () => {
|
|
||||||
const rules = OH.Parse("24/7");
|
|
||||||
equal(rules.length, 7);
|
|
||||||
equal(rules[0].startHour, 0);
|
|
||||||
const asStr = OH.ToString(rules);
|
|
||||||
equal(asStr, "24/7");
|
|
||||||
}],
|
|
||||||
["OH Th[-1] off", () => {
|
|
||||||
const rules = OH.ParseRule("Th[-1] off");
|
|
||||||
equal(rules, null);
|
|
||||||
}],
|
|
||||||
["OHNo parsePH 12:00-17:00", () => {
|
|
||||||
const rules = OH.ParseRule("PH 12:00-17:00");
|
|
||||||
equal(rules, null);
|
|
||||||
}],
|
|
||||||
["OH Parse PH 12:00-17:00", () => {
|
|
||||||
const rules = OH.ParsePHRule("PH 12:00-17:00");
|
|
||||||
equal(rules.mode, " ");
|
|
||||||
equal(rules.start, "12:00")
|
|
||||||
equal(rules.end, "17:00")
|
|
||||||
}],
|
|
||||||
["Round", () => {
|
|
||||||
equal(Utils.Round(15), "15.0")
|
|
||||||
equal(Utils.Round(1), "1.0")
|
|
||||||
equal(Utils.Round(1.5), "1.5")
|
|
||||||
equal(Utils.Round(0.5), "0.5")
|
|
||||||
equal(Utils.Round(1.6), "1.6")
|
|
||||||
|
|
||||||
equal(Utils.Round(-15), "-15.0")
|
|
||||||
equal(Utils.Round(-1), "-1.0")
|
|
||||||
equal(Utils.Round(-1.5), "-1.5")
|
|
||||||
equal(Utils.Round(-0.5), "-0.5")
|
|
||||||
equal(Utils.Round(-1.6), "-1.6")
|
|
||||||
|
|
||||||
}
|
|
||||||
],
|
|
||||||
["Regression", () => {
|
["Regression", () => {
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
|
|
Loading…
Reference in a new issue