Merge master
This commit is contained in:
commit
f20144a502
17 changed files with 420 additions and 56 deletions
|
@ -363,7 +363,7 @@ export class Changes {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
public CreateChangesetObjects(changes: ChangeDescription[], downloadedOsmObjects: OsmObject[]): {
|
||||||
newObjects: OsmObject[],
|
newObjects: OsmObject[],
|
||||||
modifiedObjects: OsmObject[]
|
modifiedObjects: OsmObject[]
|
||||||
deletedObjects: OsmObject[]
|
deletedObjects: OsmObject[]
|
||||||
|
|
|
@ -51,13 +51,14 @@ export class ChangesetHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* 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
|
||||||
* The key is changed _in place_; true will be returned if a change has been applied
|
* The key is changed _in place_; true will be returned if a change has been applied
|
||||||
* @param extraMetaTags
|
* @param extraMetaTags
|
||||||
* @param rewriteIds
|
* @param rewriteIds
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private static rewriteMetaTags(extraMetaTags: ChangesetTag[], rewriteIds: Map<string, string>) {
|
static rewriteMetaTags(extraMetaTags: ChangesetTag[], rewriteIds: Map<string, string>) {
|
||||||
let hasChange = false;
|
let hasChange = false;
|
||||||
for (const tag of extraMetaTags) {
|
for (const tag of extraMetaTags) {
|
||||||
const match = tag.key.match(/^([a-zA-Z0-9_]+):(node\/-[0-9])$/)
|
const match = tag.key.match(/^([a-zA-Z0-9_]+):(node\/-[0-9])$/)
|
||||||
|
@ -93,6 +94,8 @@ export class ChangesetHandler {
|
||||||
throw "The meta tags should at least contain a `comment` and a `theme`"
|
throw "The meta tags should at least contain a `comment` and a `theme`"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extraMetaTags = [...extraMetaTags, ...this.defaultChangesetTags()]
|
||||||
|
|
||||||
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;
|
||||||
|
@ -112,7 +115,7 @@ export class ChangesetHandler {
|
||||||
openChangeset.setData(csId);
|
openChangeset.setData(csId);
|
||||||
const changeset = generateChangeXML(csId);
|
const changeset = generateChangeXML(csId);
|
||||||
console.trace("Opened a new changeset (openChangeset.data is undefined):", changeset);
|
console.trace("Opened a new changeset (openChangeset.data is undefined):", changeset);
|
||||||
const changes = await this.AddChange(csId, changeset)
|
const changes = await this.UploadChange(csId, changeset)
|
||||||
const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes)
|
const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes)
|
||||||
if(hasSpecialMotivationChanges){
|
if(hasSpecialMotivationChanges){
|
||||||
// At this point, 'extraMetaTags' will have changed - we need to set the tags again
|
// At this point, 'extraMetaTags' will have changed - we need to set the tags again
|
||||||
|
@ -139,11 +142,12 @@ export class ChangesetHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rewritings = await this.AddChange(
|
const rewritings = await this.UploadChange(
|
||||||
csId,
|
csId,
|
||||||
generateChangeXML(csId))
|
generateChangeXML(csId))
|
||||||
|
|
||||||
await this.RewriteTagsOf(extraMetaTags, rewritings, oldChangesetMeta)
|
const rewrittenTags = this.RewriteTagsOf(extraMetaTags, rewritings, oldChangesetMeta)
|
||||||
|
await this.UpdateTags(csId, rewrittenTags)
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Could not upload, changeset is probably closed: ", e);
|
console.warn("Could not upload, changeset is probably closed: ", e);
|
||||||
|
@ -153,13 +157,13 @@ export class ChangesetHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the metatag of a changeset -
|
* Given an existing changeset with metadata and extraMetaTags to add, will fuse them to a new set of metatags
|
||||||
|
* Does not yet send data
|
||||||
* @param extraMetaTags: new changeset tags to add/fuse with this changeset
|
* @param extraMetaTags: new changeset tags to add/fuse with this changeset
|
||||||
|
* @param rewriteIds: the mapping of ids
|
||||||
* @param oldChangesetMeta: the metadata-object of the already existing changeset
|
* @param oldChangesetMeta: the metadata-object of the already existing changeset
|
||||||
* @constructor
|
|
||||||
* @private
|
|
||||||
*/
|
*/
|
||||||
private async RewriteTagsOf(extraMetaTags: ChangesetTag[],
|
public RewriteTagsOf(extraMetaTags: ChangesetTag[],
|
||||||
rewriteIds: Map<string, string>,
|
rewriteIds: Map<string, string>,
|
||||||
oldChangesetMeta: {
|
oldChangesetMeta: {
|
||||||
open: boolean,
|
open: boolean,
|
||||||
|
@ -167,9 +171,8 @@ export class ChangesetHandler {
|
||||||
uid: number, // User ID
|
uid: number, // User ID
|
||||||
changes_count: number,
|
changes_count: number,
|
||||||
tags: any
|
tags: any
|
||||||
}) {
|
}) : ChangesetTag[] {
|
||||||
|
|
||||||
const csId = oldChangesetMeta.id
|
|
||||||
|
|
||||||
// Note: extraMetaTags is where all the tags are collected into
|
// Note: extraMetaTags is where all the tags are collected into
|
||||||
|
|
||||||
|
@ -214,9 +217,7 @@ export class ChangesetHandler {
|
||||||
|
|
||||||
|
|
||||||
ChangesetHandler.rewriteMetaTags(extraMetaTags, rewriteIds)
|
ChangesetHandler.rewriteMetaTags(extraMetaTags, rewriteIds)
|
||||||
|
return extraMetaTags
|
||||||
await this.UpdateTags(csId, extraMetaTags)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,7 +296,7 @@ export class ChangesetHandler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async GetChangesetMeta(csId: number): Promise<{
|
async GetChangesetMeta(csId: number): Promise<{
|
||||||
id: number,
|
id: number,
|
||||||
open: boolean,
|
open: boolean,
|
||||||
uid: number,
|
uid: number,
|
||||||
|
@ -341,20 +342,29 @@ export class ChangesetHandler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private defaultChangesetTags() : ChangesetTag[]{
|
||||||
|
return [ ["created_by", `MapComplete ${Constants.vNumber}`],
|
||||||
|
["locale", Locale.language.data],
|
||||||
|
["host", `${window.location.origin}${window.location.pathname}`],
|
||||||
|
["source", this.changes.state["currentUserLocation"]?.features?.data?.length > 0 ? "survey" : undefined],
|
||||||
|
["imagery", this.changes.state["backgroundLayer"]?.data?.id]].map(([key, value]) => ({
|
||||||
|
key, value, aggretage: false
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens a changeset with the specified tags
|
||||||
|
* @param changesetTags
|
||||||
|
* @constructor
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
private OpenChangeset(
|
private OpenChangeset(
|
||||||
changesetTags: ChangesetTag[]
|
changesetTags: ChangesetTag[]
|
||||||
): Promise<number> {
|
): Promise<number> {
|
||||||
const self = this;
|
const self = this;
|
||||||
return new Promise<number>(function (resolve, reject) {
|
return new Promise<number>(function (resolve, reject) {
|
||||||
|
|
||||||
const metadata = [
|
const metadata = changesetTags.map(cstag => [cstag.key, cstag.value])
|
||||||
["created_by", `MapComplete ${Constants.vNumber}`],
|
|
||||||
["locale", Locale.language.data],
|
|
||||||
["host", `${window.location.origin}${window.location.pathname}`],
|
|
||||||
["source", self.changes.state["currentUserLocation"]?.features?.data?.length > 0 ? "survey" : undefined],
|
|
||||||
["imagery", self.changes.state["backgroundLayer"]?.data?.id],
|
|
||||||
...changesetTags.map(cstag => [cstag.key, cstag.value])
|
|
||||||
]
|
|
||||||
.filter(kv => (kv[1] ?? "") !== "")
|
.filter(kv => (kv[1] ?? "") !== "")
|
||||||
.map(kv => `<tag k="${kv[0]}" v="${escapeHtml(kv[1])}"/>`)
|
.map(kv => `<tag k="${kv[0]}" v="${escapeHtml(kv[1])}"/>`)
|
||||||
.join("\n")
|
.join("\n")
|
||||||
|
@ -382,7 +392,7 @@ export class ChangesetHandler {
|
||||||
/**
|
/**
|
||||||
* Upload a changesetXML
|
* Upload a changesetXML
|
||||||
*/
|
*/
|
||||||
private AddChange(changesetId: number,
|
private UploadChange(changesetId: number,
|
||||||
changesetXML: string): Promise<Map<string, string>> {
|
changesetXML: string): Promise<Map<string, string>> {
|
||||||
const self = this;
|
const self = this;
|
||||||
return new Promise(function (resolve, reject) {
|
return new Promise(function (resolve, reject) {
|
||||||
|
|
|
@ -291,7 +291,20 @@
|
||||||
"it": "Accessibile pubblicamente",
|
"it": "Accessibile pubblicamente",
|
||||||
"de": "Zugänglich für die Allgemeinheit",
|
"de": "Zugänglich für die Allgemeinheit",
|
||||||
"fr": "Accessible au public"
|
"fr": "Accessible au public"
|
||||||
}
|
},
|
||||||
|
"addExtraTags": [
|
||||||
|
"fee=no"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"if": "fee=yes",
|
||||||
|
"then": {
|
||||||
|
"en": "This is a <b>paid</b> playground",
|
||||||
|
"nl": "Er moet <b>betaald</b> worden om deze speeltuin te mogen gebruiken"
|
||||||
|
},
|
||||||
|
"addExtraTags": [
|
||||||
|
"access=customers"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "access=customers",
|
"if": "access=customers",
|
||||||
|
@ -301,7 +314,10 @@
|
||||||
"it": "Accessibile solamente ai clienti dell’attività che lo gestisce",
|
"it": "Accessibile solamente ai clienti dell’attività che lo gestisce",
|
||||||
"de": "Nur für Kunden des Betreibers zugänglich",
|
"de": "Nur für Kunden des Betreibers zugänglich",
|
||||||
"fr": "Réservée aux clients"
|
"fr": "Réservée aux clients"
|
||||||
}
|
},
|
||||||
|
"addExtraTags": [
|
||||||
|
"fee=no"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "access=students",
|
"if": "access=students",
|
||||||
|
@ -312,7 +328,10 @@
|
||||||
"de": "Nur für Schüler der Schule zugänglich",
|
"de": "Nur für Schüler der Schule zugänglich",
|
||||||
"fr": "Réservée aux élèves de l’école"
|
"fr": "Réservée aux élèves de l’école"
|
||||||
},
|
},
|
||||||
"hideInAnswer": true
|
"hideInAnswer": true,
|
||||||
|
"addExtraTags": [
|
||||||
|
"fee=no"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "access=private",
|
"if": "access=private",
|
||||||
|
|
|
@ -11,7 +11,8 @@
|
||||||
"delete": "Supprimer",
|
"delete": "Supprimer",
|
||||||
"explanations": {
|
"explanations": {
|
||||||
"hardDelete": "Ce point sera supprimé d’OpenStreetmap. Il pourra être restauré par des méthodes avancées",
|
"hardDelete": "Ce point sera supprimé d’OpenStreetmap. Il pourra être restauré par des méthodes avancées",
|
||||||
"selectReason": "Sélectionner pourquoi cet élément devrait être supprimé"
|
"selectReason": "Sélectionner pourquoi cet élément devrait être supprimé",
|
||||||
|
"softDelete": "Cet objet sera mis à jour et caché de l'application. <span class=\"subtle\">{reason}</span>"
|
||||||
},
|
},
|
||||||
"isDeleted": "Cet objet est supprimé",
|
"isDeleted": "Cet objet est supprimé",
|
||||||
"isntAPoint": "Seul les points peuvent être supprimés, l'objet sélectionné est une ligne, un polygone ou une relation.",
|
"isntAPoint": "Seul les points peuvent être supprimés, l'objet sélectionné est une ligne, un polygone ou une relation.",
|
||||||
|
@ -56,7 +57,12 @@
|
||||||
"title": "Ajouter un nouveau point ?",
|
"title": "Ajouter un nouveau point ?",
|
||||||
"warnVisibleForEveryone": "Votre ajout sera visible",
|
"warnVisibleForEveryone": "Votre ajout sera visible",
|
||||||
"zoomInFurther": "Rapprochez vous pour ajouter un point.",
|
"zoomInFurther": "Rapprochez vous pour ajouter un point.",
|
||||||
"zoomInMore": "Zoomez pour importer cet élément"
|
"zoomInMore": "Zoomez pour importer cet élément",
|
||||||
|
"import": {
|
||||||
|
"howToTest": "Pour essayer, ajouter <b>test=true</b> ou <b>backend=osm-test</b> à l'adresse de la page. Le groupe de modifications sera affiché dans la console. Merci d'ouvrir un PR pour officialiser ce thème et ainsi activer le bouton d'import.",
|
||||||
|
"importTags": "L'objet recevra {tags}",
|
||||||
|
"hasBeenImported": "Cet objet a été importé"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"attribution": {
|
"attribution": {
|
||||||
"attributionContent": "<p>Toutes les données sont fournies par <a href='https://osm.org' target='_blank'>OpenStreetMap</a>, librement réutilisables sous <a href='https://osm.org/copyright' target='_blank'>Open DataBase License</a>.</p>",
|
"attributionContent": "<p>Toutes les données sont fournies par <a href='https://osm.org' target='_blank'>OpenStreetMap</a>, librement réutilisables sous <a href='https://osm.org/copyright' target='_blank'>Open DataBase License</a>.</p>",
|
||||||
|
|
|
@ -2334,13 +2334,13 @@
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Zugänglich für die Allgemeinheit"
|
"then": "Zugänglich für die Allgemeinheit"
|
||||||
},
|
},
|
||||||
"1": {
|
"2": {
|
||||||
"then": "Nur für Kunden des Betreibers zugänglich"
|
"then": "Nur für Kunden des Betreibers zugänglich"
|
||||||
},
|
},
|
||||||
"2": {
|
"3": {
|
||||||
"then": "Nur für Schüler der Schule zugänglich"
|
"then": "Nur für Schüler der Schule zugänglich"
|
||||||
},
|
},
|
||||||
"3": {
|
"4": {
|
||||||
"then": "Nicht zugänglich"
|
"then": "Nicht zugänglich"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3944,12 +3944,15 @@
|
||||||
"then": "Accessible to the general public"
|
"then": "Accessible to the general public"
|
||||||
},
|
},
|
||||||
"1": {
|
"1": {
|
||||||
"then": "Only accessible for clients of the operating business"
|
"then": "This is a <b>paid</b> playground"
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Only accessible to students of the school"
|
"then": "Only accessible for clients of the operating business"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
|
"then": "Only accessible to students of the school"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
"then": "Not accessible"
|
"then": "Not accessible"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -210,7 +210,8 @@
|
||||||
"render": "Espace entre deux barrières successives : {width:separation} m"
|
"render": "Espace entre deux barrières successives : {width:separation} m"
|
||||||
},
|
},
|
||||||
"Width of opening (cyclebarrier)": {
|
"Width of opening (cyclebarrier)": {
|
||||||
"render": "Largeur de l'ouverture : {width:opening} m"
|
"render": "Largeur de l'ouverture : {width:opening} m",
|
||||||
|
"question": "Quelle est la largeur d'ouverture la plus petite près de la barrière ?"
|
||||||
},
|
},
|
||||||
"bicycle=yes/no": {
|
"bicycle=yes/no": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
|
@ -220,6 +221,17 @@
|
||||||
"1": {
|
"1": {
|
||||||
"then": "Un cycliste ne peut pas franchir ceci."
|
"then": "Un cycliste ne peut pas franchir ceci."
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"question": "Est-ce qu'un vélo peut franchir cette barrière ?"
|
||||||
|
},
|
||||||
|
"barrier_type": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "C'est un plot unique sur la route"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "C'est une barrière visant à ralentir les vélos"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -323,7 +335,8 @@
|
||||||
},
|
},
|
||||||
"title": {
|
"title": {
|
||||||
"render": "Banc"
|
"render": "Banc"
|
||||||
}
|
},
|
||||||
|
"description": "Un banc est une surface en bois, métal, pierre... sur laquelle un humain peut s'asseoir. Cette couche permet de les visualiser et pose des questions à leur sujet."
|
||||||
},
|
},
|
||||||
"bench_at_pt": {
|
"bench_at_pt": {
|
||||||
"name": "Bancs des arrêts de transport en commun",
|
"name": "Bancs des arrêts de transport en commun",
|
||||||
|
@ -339,7 +352,8 @@
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Il n'y a pas de banc ici"
|
"then": "Il n'y a pas de banc ici"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"question": "Quel type de banc est-ce ?"
|
||||||
},
|
},
|
||||||
"bench_at_pt-name": {
|
"bench_at_pt-name": {
|
||||||
"render": "{name}"
|
"render": "{name}"
|
||||||
|
@ -355,7 +369,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"render": "Banc"
|
"render": "Banc"
|
||||||
}
|
},
|
||||||
|
"description": "Une couche montrant tous les arrêts de transports publics qui ont un banc"
|
||||||
},
|
},
|
||||||
"bicycle_library": {
|
"bicycle_library": {
|
||||||
"description": "Un lieu où des vélos peuvent être empruntés pour un temps plus long",
|
"description": "Un lieu où des vélos peuvent être empruntés pour un temps plus long",
|
||||||
|
@ -1599,13 +1614,13 @@
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Accessible au public"
|
"then": "Accessible au public"
|
||||||
},
|
},
|
||||||
"1": {
|
"2": {
|
||||||
"then": "Réservée aux clients"
|
"then": "Réservée aux clients"
|
||||||
},
|
},
|
||||||
"2": {
|
"3": {
|
||||||
"then": "Réservée aux élèves de l’école"
|
"then": "Réservée aux élèves de l’école"
|
||||||
},
|
},
|
||||||
"3": {
|
"4": {
|
||||||
"then": "Non accessible"
|
"then": "Non accessible"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2381,5 +2396,18 @@
|
||||||
},
|
},
|
||||||
"watermill": {
|
"watermill": {
|
||||||
"name": "Moulin à eau"
|
"name": "Moulin à eau"
|
||||||
|
},
|
||||||
|
"bicycle_rental": {
|
||||||
|
"name": "Location de vélo",
|
||||||
|
"description": "Station de location de vélo",
|
||||||
|
"presets": {
|
||||||
|
"0": {
|
||||||
|
"description": "Un magasin avec employé(s) consacré à la location de vélos",
|
||||||
|
"title": "magasin de location de vélos"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"title": "location de vélos"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,8 +11,17 @@
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Bangunan ini tidak memiliki nomor rumah"
|
"then": "Bangunan ini tidak memiliki nomor rumah"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"question": "Berapa nomor rumah ini?",
|
||||||
|
"render": "Nomor rumah ini <b>{addr:housenumber}</b>"
|
||||||
|
},
|
||||||
|
"street": {
|
||||||
|
"question": "Alamat ini di jalan apa?",
|
||||||
|
"render": "Alamat ini ada di jalan <b>{addr:street}</b>"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"title": {
|
||||||
|
"render": "Alamat yang diketahui"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"artwork": {
|
"artwork": {
|
||||||
|
@ -377,5 +386,14 @@
|
||||||
},
|
},
|
||||||
"watermill": {
|
"watermill": {
|
||||||
"name": "Kincir Air"
|
"name": "Kincir Air"
|
||||||
|
},
|
||||||
|
"ambulancestation": {
|
||||||
|
"name": "Peta stasiun ambulans",
|
||||||
|
"presets": {
|
||||||
|
"0": {
|
||||||
|
"description": "Tambahkan stasiun ambulans ke peta",
|
||||||
|
"title": "Stasiun ambulans"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1287,13 +1287,13 @@
|
||||||
"0": {
|
"0": {
|
||||||
"then": "Accessibile pubblicamente"
|
"then": "Accessibile pubblicamente"
|
||||||
},
|
},
|
||||||
"1": {
|
"2": {
|
||||||
"then": "Accessibile solamente ai clienti dell’attività che lo gestisce"
|
"then": "Accessibile solamente ai clienti dell’attività che lo gestisce"
|
||||||
},
|
},
|
||||||
"2": {
|
"3": {
|
||||||
"then": "Accessibile solamente agli studenti della scuola"
|
"then": "Accessibile solamente agli studenti della scuola"
|
||||||
},
|
},
|
||||||
"3": {
|
"4": {
|
||||||
"then": "Non accessibile"
|
"then": "Non accessibile"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3753,12 +3753,15 @@
|
||||||
"then": "Vrij toegankelijk voor het publiek"
|
"then": "Vrij toegankelijk voor het publiek"
|
||||||
},
|
},
|
||||||
"1": {
|
"1": {
|
||||||
"then": "Enkel toegankelijk voor klanten van de bijhorende zaak"
|
"then": "Er moet <b>betaald</b> worden om deze speeltuin te mogen gebruiken"
|
||||||
},
|
},
|
||||||
"2": {
|
"2": {
|
||||||
"then": "Enkel toegankelijk voor scholieren van de bijhorende school"
|
"then": "Enkel toegankelijk voor klanten van de bijhorende zaak"
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
|
"then": "Enkel toegankelijk voor scholieren van de bijhorende school"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
"then": "Niet vrij toegankelijk"
|
"then": "Niet vrij toegankelijk"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1078,7 +1078,7 @@
|
||||||
},
|
},
|
||||||
"playground-access": {
|
"playground-access": {
|
||||||
"mappings": {
|
"mappings": {
|
||||||
"3": {
|
"4": {
|
||||||
"then": "Недоступно"
|
"then": "Недоступно"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
},
|
},
|
||||||
"3": {
|
"3": {
|
||||||
"then": "Premier étage"
|
"then": "Premier étage"
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"then": "Sous-sol"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "À quel étage se situe l’élément ?",
|
"question": "À quel étage se situe l’élément ?",
|
||||||
|
@ -111,6 +114,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"question": "Quel est l’élément Wikipédia correspondant ?"
|
"question": "Quel est l’élément Wikipédia correspondant ?"
|
||||||
|
},
|
||||||
|
"payment-options-advanced": {
|
||||||
|
"override": {
|
||||||
|
"mappings+": {
|
||||||
|
"0": {
|
||||||
|
"then": "Paiement via une application"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Paiement via une carte de membre"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -561,6 +561,26 @@
|
||||||
"override": {
|
"override": {
|
||||||
"=name": "Institutions d'éducation sans origine étymologique"
|
"=name": "Institutions d'éducation sans origine étymologique"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"5": {
|
||||||
|
"override": {
|
||||||
|
"=name": "Lieux touristiques sans origine étymologique"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"4": {
|
||||||
|
"override": {
|
||||||
|
"=name": "Lieux culturels sans origine étymologique"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"6": {
|
||||||
|
"override": {
|
||||||
|
"=name": "Établissements sociaux ou de soins sans origine étymologique"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"7": {
|
||||||
|
"override": {
|
||||||
|
"=name": "Lieux sportifs sans origine étymologique"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"shortDescription": "Quelle est l'origine de ce toponyme ?",
|
"shortDescription": "Quelle est l'origine de ce toponyme ?",
|
||||||
|
@ -778,5 +798,10 @@
|
||||||
"description": "Cartographions tous les arbres !",
|
"description": "Cartographions tous les arbres !",
|
||||||
"shortDescription": "Carte des arbres",
|
"shortDescription": "Carte des arbres",
|
||||||
"title": "Arbres"
|
"title": "Arbres"
|
||||||
|
},
|
||||||
|
"bicycle_rental": {
|
||||||
|
"shortDescription": "Une carte avec des stations et magasins de location de vélos",
|
||||||
|
"title": "Location de vélos",
|
||||||
|
"description": "Vous trouverez sur cette carte toutes les stations de location de vélo telles qu'elles sont référencées dans OpenStreetMap"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
"generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css",
|
"generate:css": "tailwindcss -i index.css -o css/index-tailwind-output.css",
|
||||||
"test": "ts-node test/TestAll.ts",
|
"test": "ts-node test/TestAll.ts",
|
||||||
"init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean",
|
"init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean",
|
||||||
"add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote update weblate-layers",
|
"add-weblate-upstream": "git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layer-translations/ ; git remote add weblate-core https://hosted.weblate.org/git/mapcomplete/layer-core/; git remote add weblate-themes https://hosted.weblate.org/git/mapcomplete/layer-themes/; git remote add weblate-github git@github.com:weblate/MapComplete.git",
|
||||||
"fix-weblate": "git remote update weblate-layers; git merge weblate-layers/master",
|
"fix-weblate": "git remote update weblate-layers; git merge weblate-layers/master",
|
||||||
"generate:editor-layer-index": "ts-node scripts/downloadFile.ts https://osmlab.github.io/editor-layer-index/imagery.geojson assets/editor-layer-index.json",
|
"generate:editor-layer-index": "ts-node scripts/downloadFile.ts https://osmlab.github.io/editor-layer-index/imagery.geojson assets/editor-layer-index.json",
|
||||||
"generate:polygon-features": "ts-node scripts/downloadFile.ts https://raw.githubusercontent.com/tyrasd/osm-polygon-features/master/polygon-features.json assets/polygon-features.json",
|
"generate:polygon-features": "ts-node scripts/downloadFile.ts https://raw.githubusercontent.com/tyrasd/osm-polygon-features/master/polygon-features.json assets/polygon-features.json",
|
||||||
|
|
51
test/Changes.spec.ts
Normal file
51
test/Changes.spec.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
import T from "./TestHelper";
|
||||||
|
import {Changes} from "../Logic/Osm/Changes";
|
||||||
|
import {ChangeDescription, ChangeDescriptionTools} from "../Logic/Osm/Actions/ChangeDescription";
|
||||||
|
|
||||||
|
export default class ChangesSpec extends T {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super([
|
||||||
|
["Generate preXML from changeDescriptions", () => {
|
||||||
|
const changeDescrs: ChangeDescription[] = [
|
||||||
|
{
|
||||||
|
type: "node",
|
||||||
|
id: -1,
|
||||||
|
changes: {
|
||||||
|
lat: 42,
|
||||||
|
lon: -8
|
||||||
|
},
|
||||||
|
tags: [{k: "someKey", v: "someValue"}],
|
||||||
|
meta: {
|
||||||
|
changeType: "create",
|
||||||
|
theme: "test"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "node",
|
||||||
|
id: -1,
|
||||||
|
tags: [{k: 'foo', v: 'bar'}],
|
||||||
|
meta: {
|
||||||
|
changeType: "answer",
|
||||||
|
theme: "test"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const c = new Changes()
|
||||||
|
const descr = c.CreateChangesetObjects(
|
||||||
|
changeDescrs,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
T.equals(0, descr.modifiedObjects.length)
|
||||||
|
T.equals(0, descr.deletedObjects.length)
|
||||||
|
T.equals(1, descr.newObjects.length)
|
||||||
|
const ch = descr.newObjects[0]
|
||||||
|
T.equals("bar", ch.tags["foo"])
|
||||||
|
T.equals("someValue", ch.tags["someKey"])
|
||||||
|
}]
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
181
test/ChangesetHandler.spec.ts
Normal file
181
test/ChangesetHandler.spec.ts
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
import T from "./TestHelper";
|
||||||
|
import {ChangesetHandler, ChangesetTag} from "../Logic/Osm/ChangesetHandler";
|
||||||
|
import {UIEventSource} from "../Logic/UIEventSource";
|
||||||
|
import {OsmConnection} from "../Logic/Osm/OsmConnection";
|
||||||
|
import {ElementStorage} from "../Logic/ElementStorage";
|
||||||
|
import {Changes} from "../Logic/Osm/Changes";
|
||||||
|
|
||||||
|
export default class ChangesetHandlerSpec extends T {
|
||||||
|
|
||||||
|
private static asDict(tags: {key: string, value: string | number}[]) : Map<string, string | number>{
|
||||||
|
const d= new Map<string, string | number>()
|
||||||
|
|
||||||
|
for (const tag of tags) {
|
||||||
|
d.set(tag.key, tag.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super([
|
||||||
|
[
|
||||||
|
"Test rewrite tags", () => {
|
||||||
|
const cs = new ChangesetHandler(new UIEventSource<boolean>(true),
|
||||||
|
new OsmConnection({}),
|
||||||
|
new ElementStorage(),
|
||||||
|
new Changes(),
|
||||||
|
new UIEventSource(undefined)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const oldChangesetMeta = {
|
||||||
|
"type": "changeset",
|
||||||
|
"id": 118443748,
|
||||||
|
"created_at": "2022-03-13T19:52:10Z",
|
||||||
|
"closed_at": "2022-03-13T20:54:35Z",
|
||||||
|
"open": false,
|
||||||
|
"user": "Pieter Vander Vennet",
|
||||||
|
"uid": 3818858,
|
||||||
|
"minlat": 51.0361902,
|
||||||
|
"minlon": 3.7092939,
|
||||||
|
"maxlat": 51.0364194,
|
||||||
|
"maxlon": 3.7099520,
|
||||||
|
"comments_count": 0,
|
||||||
|
"changes_count": 3,
|
||||||
|
"tags": {
|
||||||
|
"answer": "5",
|
||||||
|
"comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen",
|
||||||
|
"created_by": "MapComplete 0.16.6",
|
||||||
|
"host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html",
|
||||||
|
"imagery": "osm",
|
||||||
|
"locale": "nl",
|
||||||
|
"source": "survey",
|
||||||
|
"source:node/-1":"note/1234",
|
||||||
|
"theme": "toerisme_vlaanderen",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let rewritten = cs.RewriteTagsOf(
|
||||||
|
[{
|
||||||
|
key: "newTag",
|
||||||
|
value: "newValue",
|
||||||
|
aggregate: false
|
||||||
|
}],
|
||||||
|
new Map<string, string>(),
|
||||||
|
oldChangesetMeta)
|
||||||
|
let d = ChangesetHandlerSpec.asDict(rewritten)
|
||||||
|
T.equals(10, d.size)
|
||||||
|
T.equals("5", d.get("answer"))
|
||||||
|
T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment"))
|
||||||
|
T.equals("MapComplete 0.16.6", d.get("created_by"))
|
||||||
|
T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host"))
|
||||||
|
T.equals("osm", d.get("imagery"))
|
||||||
|
T.equals("survey", d.get("source"))
|
||||||
|
T.equals("note/1234", d.get("source:node/-1"))
|
||||||
|
T.equals("toerisme_vlaanderen", d.get("theme"))
|
||||||
|
|
||||||
|
T.equals("newValue", d.get("newTag"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rewritten = cs.RewriteTagsOf(
|
||||||
|
[{
|
||||||
|
key: "answer",
|
||||||
|
value: "37",
|
||||||
|
aggregate: true
|
||||||
|
}],
|
||||||
|
new Map<string, string>(),
|
||||||
|
oldChangesetMeta)
|
||||||
|
d = ChangesetHandlerSpec.asDict(rewritten)
|
||||||
|
|
||||||
|
T.equals(9, d.size)
|
||||||
|
T.equals("42", d.get("answer"))
|
||||||
|
T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment"))
|
||||||
|
T.equals("MapComplete 0.16.6", d.get("created_by"))
|
||||||
|
T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host"))
|
||||||
|
T.equals("osm", d.get("imagery"))
|
||||||
|
T.equals("survey", d.get("source"))
|
||||||
|
T.equals("note/1234", d.get("source:node/-1"))
|
||||||
|
T.equals("toerisme_vlaanderen", d.get("theme"))
|
||||||
|
|
||||||
|
rewritten = cs.RewriteTagsOf(
|
||||||
|
[],
|
||||||
|
new Map<string, string>([["node/-1", "node/42"]]),
|
||||||
|
oldChangesetMeta)
|
||||||
|
d = ChangesetHandlerSpec.asDict(rewritten)
|
||||||
|
|
||||||
|
T.equals(9, d.size)
|
||||||
|
T.equals("5", d.get("answer"))
|
||||||
|
T.equals("Adding data with #MapComplete for theme #toerisme_vlaanderen", d.get("comment"))
|
||||||
|
T.equals("MapComplete 0.16.6", d.get("created_by"))
|
||||||
|
T.equals("https://mapcomplete.osm.be/toerisme_vlaanderen.html", d.get("host"))
|
||||||
|
T.equals("osm", d.get("imagery"))
|
||||||
|
T.equals("survey", d.get("source"))
|
||||||
|
T.equals("note/1234", d.get("source:node/42"))
|
||||||
|
T.equals("toerisme_vlaanderen", d.get("theme"))
|
||||||
|
|
||||||
|
},
|
||||||
|
],[
|
||||||
|
"Test rewrite on special motivation", () => {
|
||||||
|
|
||||||
|
|
||||||
|
const cs = new ChangesetHandler(new UIEventSource<boolean>(true),
|
||||||
|
new OsmConnection({}),
|
||||||
|
new ElementStorage(),
|
||||||
|
new Changes(),
|
||||||
|
new UIEventSource(undefined)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const oldChangesetMeta = {
|
||||||
|
"type": "changeset",
|
||||||
|
"id": 118443748,
|
||||||
|
"created_at": "2022-03-13T19:52:10Z",
|
||||||
|
"closed_at": "2022-03-13T20:54:35Z",
|
||||||
|
"open": false,
|
||||||
|
"user": "Pieter Vander Vennet",
|
||||||
|
"uid": 3818858,
|
||||||
|
"minlat": 51.0361902,
|
||||||
|
"minlon": 3.7092939,
|
||||||
|
"maxlat": 51.0364194,
|
||||||
|
"maxlon": 3.7099520,
|
||||||
|
"comments_count": 0,
|
||||||
|
"changes_count": 3,
|
||||||
|
"tags": {
|
||||||
|
"answer": "5",
|
||||||
|
"comment": "Adding data with #MapComplete for theme #toerisme_vlaanderen",
|
||||||
|
"created_by": "MapComplete 0.16.6",
|
||||||
|
"host": "https://mapcomplete.osm.be/toerisme_vlaanderen.html",
|
||||||
|
"imagery": "osm",
|
||||||
|
"locale": "nl",
|
||||||
|
"source": "survey",
|
||||||
|
"source:-1":"note/1234",
|
||||||
|
"theme": "toerisme_vlaanderen",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const extraMetaTags : ChangesetTag[] = [
|
||||||
|
{
|
||||||
|
key: "created_by",
|
||||||
|
value:"mapcomplete"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: "source:node/-1",
|
||||||
|
value:"note/1234"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
const changes = new Map<string, string>([["node/-1","node/42"]])
|
||||||
|
const hasSpecialMotivationChanges = ChangesetHandler.rewriteMetaTags(extraMetaTags, changes)
|
||||||
|
T.isTrue(hasSpecialMotivationChanges, "Special rewrite did not trigger")
|
||||||
|
// Rewritten inline by rewriteMetaTags
|
||||||
|
T.equals("source:node/42", extraMetaTags[1].key)
|
||||||
|
T.equals("note/1234", extraMetaTags[1].value)
|
||||||
|
T.equals("created_by", extraMetaTags[0].key)
|
||||||
|
T.equals("mapcomplete", extraMetaTags[0].value)
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,11 +21,16 @@ import ValidatedTextFieldTranslationsSpec from "./ValidatedTextFieldTranslations
|
||||||
import CreateCacheSpec from "./CreateCache.spec";
|
import CreateCacheSpec from "./CreateCache.spec";
|
||||||
import CodeQualitySpec from "./CodeQuality.spec";
|
import CodeQualitySpec from "./CodeQuality.spec";
|
||||||
import ImportMultiPolygonSpec from "./ImportMultiPolygon.spec";
|
import ImportMultiPolygonSpec from "./ImportMultiPolygon.spec";
|
||||||
|
import {ChangesetHandler} from "../Logic/Osm/ChangesetHandler";
|
||||||
|
import ChangesetHandlerSpec from "./ChangesetHandler.spec";
|
||||||
|
import ChangesSpec from "./Changes.spec";
|
||||||
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
|
||||||
const allTests: T[] = [
|
const allTests: T[] = [
|
||||||
|
new ChangesSpec(),
|
||||||
|
new ChangesetHandlerSpec(),
|
||||||
new OsmObjectSpec(),
|
new OsmObjectSpec(),
|
||||||
new TagSpec(),
|
new TagSpec(),
|
||||||
new ImageAttributionSpec(),
|
new ImageAttributionSpec(),
|
||||||
|
@ -45,7 +50,7 @@ async function main() {
|
||||||
new ValidatedTextFieldTranslationsSpec(),
|
new ValidatedTextFieldTranslationsSpec(),
|
||||||
new CreateCacheSpec(),
|
new CreateCacheSpec(),
|
||||||
new CodeQualitySpec(),
|
new CodeQualitySpec(),
|
||||||
new ImportMultiPolygonSpec()
|
new ImportMultiPolygonSpec(),
|
||||||
]
|
]
|
||||||
ScriptUtils.fixUtils();
|
ScriptUtils.fixUtils();
|
||||||
const realDownloadFunc = Utils.externalDownloadFunction;
|
const realDownloadFunc = Utils.externalDownloadFunction;
|
||||||
|
|
Loading…
Reference in a new issue