forked from MapComplete/MapComplete
New question system
This commit is contained in:
parent
1738fc4252
commit
d1f8080c24
45 changed files with 1391 additions and 689 deletions
|
@ -51,11 +51,10 @@ export class Basemap {
|
|||
|
||||
|
||||
private baseLayers = {
|
||||
"OpenStreetMap Be": this.osmBeLayer,
|
||||
"OpenStreetMap": this.osmLayer,
|
||||
"Luchtfoto AIV Vlaanderen (2013-2015)": this.aivLucht2013Layer,
|
||||
"Luchtfoto AIV Vlaanderen (laatste)": this.aivLuchtLatestLayer,
|
||||
"GRB Vlaanderen": this.grbLayer
|
||||
"Luchtfoto Vlaanderen (recentste door AIV)": this.aivLuchtLatestLayer,
|
||||
"Luchtfoto Vlaanderen (2013-2015, door AIV)": this.aivLucht2013Layer,
|
||||
"Kaart van OpenStreetMap": this.osmLayer,
|
||||
"Kaart Grootschalig ReferentieBestand Vlaanderen (GRB) door AIV": this.grbLayer
|
||||
};
|
||||
|
||||
constructor(leafletElementId: string,
|
||||
|
|
|
@ -7,7 +7,7 @@ import {OsmNode, OsmObject} from "./OsmObject";
|
|||
import {ElementStorage} from "./ElementStorage";
|
||||
import {UIEventSource} from "../UI/UIEventSource";
|
||||
import {Question, QuestionDefinition} from "./Question";
|
||||
import {Tag} from "./TagsFilter";
|
||||
import {And, Tag, TagsFilter} from "./TagsFilter";
|
||||
|
||||
export class Changes {
|
||||
|
||||
|
@ -22,19 +22,34 @@ export class Changes {
|
|||
public readonly pendingChangesES = new UIEventSource<number>(this._pendingChanges.length);
|
||||
public readonly isSaving = new UIEventSource(false);
|
||||
private readonly _changesetComment: string;
|
||||
private readonly _centerMessage: UIEventSource<string>;
|
||||
|
||||
constructor(
|
||||
changesetComment: string,
|
||||
login: OsmConnection,
|
||||
allElements: ElementStorage,
|
||||
centerMessage: UIEventSource<string>) {
|
||||
allElements: ElementStorage) {
|
||||
this._changesetComment = changesetComment;
|
||||
this.login = login;
|
||||
this._allElements = allElements;
|
||||
this._centerMessage = centerMessage;
|
||||
}
|
||||
|
||||
addTag(elementId: string, tagsFilter : TagsFilter){
|
||||
if(tagsFilter instanceof Tag){
|
||||
const tag = tagsFilter as Tag;
|
||||
this.addChange(elementId, tag.key, tag.value);
|
||||
return;
|
||||
}
|
||||
|
||||
if(tagsFilter instanceof And){
|
||||
const and = tagsFilter as And;
|
||||
for (const tag of and.and) {
|
||||
this.addTag(elementId, tag);
|
||||
}
|
||||
return;
|
||||
}
|
||||
console.log("Unsupported tagsfilter element to addTag", tagsFilter);
|
||||
throw "Unsupported tagsFilter element";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a change to the pending changes
|
||||
* @param elementId
|
||||
|
@ -42,23 +57,7 @@ export class Changes {
|
|||
* @param value
|
||||
*/
|
||||
addChange(elementId: string, key: string, value: string) {
|
||||
|
||||
if (!this.login.userDetails.data.loggedIn) {
|
||||
this._centerMessage.setData(
|
||||
"<p>Bedankt voor je antwoord!</p>" +
|
||||
"<p>Gelieve <span class='activate-osm-authentication'>in te loggen op OpenStreetMap</span> om dit op te slaan.</p>" +
|
||||
"<p>Nog geen account? <a href=\'https://www.openstreetmap.org/user/new\' target=\'_blank\'>Registreer hier</a></p>"
|
||||
);
|
||||
const self = this;
|
||||
this.login.userDetails.addCallback(() => {
|
||||
if (self.login.userDetails.data.loggedIn) {
|
||||
self._centerMessage.setData("");
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
console.log("Received change",key, value)
|
||||
if (key === undefined || key === null) {
|
||||
console.log("Invalid key");
|
||||
return;
|
||||
|
|
|
@ -106,7 +106,6 @@ export class OsmConnection {
|
|||
|
||||
/**
|
||||
* All elements with class 'activate-osm-authentication' are loaded and get an 'onclick' to authenticate
|
||||
* @param osmConnection
|
||||
*/
|
||||
registerActivateOsmAUthenticationClass() {
|
||||
|
||||
|
@ -144,6 +143,10 @@ export class OsmConnection {
|
|||
}
|
||||
|
||||
public SetPreference(k:string, v:string) {
|
||||
if(!this.userDetails.data.loggedIn){
|
||||
console.log("Not saving preference: user not logged in");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.preferences.data[k] === v) {
|
||||
return;
|
||||
|
@ -239,7 +242,6 @@ export class OsmConnection {
|
|||
private AddChange(changesetId: string,
|
||||
changesetXML: string,
|
||||
continuation: ((changesetId: string, idMapping: any) => void)){
|
||||
const self = this;
|
||||
this.auth.xhr({
|
||||
method: 'POST',
|
||||
options: { header: { 'Content-Type': 'text/xml' } },
|
||||
|
|
|
@ -32,6 +32,19 @@ export abstract class OsmObject {
|
|||
|
||||
abstract SaveExtraData(element);
|
||||
|
||||
/**
|
||||
* Replaces all '"' (double quotes) by '"'
|
||||
* Bugfix where names containing '"' were not uploaded, such as '"Het Zwin" nature reserve'
|
||||
* @param string
|
||||
* @constructor
|
||||
*/
|
||||
private Escape(string: string) {
|
||||
while (string.indexOf('"') >= 0) {
|
||||
string = string.replace('"', '"');
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the changeset-XML for tags
|
||||
* @constructor
|
||||
|
@ -41,7 +54,7 @@ export abstract class OsmObject {
|
|||
for (const key in this.tags) {
|
||||
const v = this.tags[key];
|
||||
if (v !== "") {
|
||||
tags += ' <tag k="' + key + '" v="' + this.tags[key] + '"/>\n'
|
||||
tags += ' <tag k="' + this.Escape(key) + '" v="' + this.Escape(this.tags[key]) + '"/>\n'
|
||||
}
|
||||
}
|
||||
return tags;
|
||||
|
|
|
@ -29,6 +29,10 @@ export class Regex implements TagsFilter {
|
|||
return false;
|
||||
}
|
||||
|
||||
substituteValues(tags: any) : TagsFilter{
|
||||
throw "Substituting values is not supported on regex tags"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Tag implements TagsFilter {
|
||||
|
@ -42,11 +46,10 @@ export class Tag implements TagsFilter {
|
|||
|
||||
matches(tags: { k: string; v: string }[]): boolean {
|
||||
for (const tag of tags) {
|
||||
|
||||
if (tag.k === this.key) {
|
||||
if (tag.v === "") {
|
||||
// This tag has been removed
|
||||
return false;
|
||||
return this.value === "";
|
||||
}
|
||||
if (this.value === "*") {
|
||||
// Any is allowed
|
||||
|
@ -56,6 +59,10 @@ export class Tag implements TagsFilter {
|
|||
return this.value === tag.v;
|
||||
}
|
||||
}
|
||||
if(this.value === ""){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -70,6 +77,10 @@ export class Tag implements TagsFilter {
|
|||
return ['["' + this.key + '"="' + this.value + '"]'];
|
||||
}
|
||||
|
||||
substituteValues(tags: any) {
|
||||
return new Tag(this.key, TagUtils.ApplyTemplate(this.value, tags));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Or implements TagsFilter {
|
||||
|
@ -104,6 +115,14 @@ export class Or implements TagsFilter {
|
|||
return choices;
|
||||
}
|
||||
|
||||
substituteValues(tags: any): TagsFilter {
|
||||
const newChoices = [];
|
||||
for (const c of this.or) {
|
||||
newChoices.push(c.substituteValues(tags));
|
||||
}
|
||||
return new Or(newChoices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class And implements TagsFilter {
|
||||
|
@ -154,12 +173,22 @@ export class And implements TagsFilter {
|
|||
}
|
||||
return allChoices;
|
||||
}
|
||||
|
||||
substituteValues(tags: any): TagsFilter {
|
||||
const newChoices = [];
|
||||
for (const c of this.and) {
|
||||
newChoices.push(c.substituteValues(tags));
|
||||
}
|
||||
return new And(newChoices);
|
||||
}
|
||||
}
|
||||
|
||||
export interface TagsFilter {
|
||||
matches(tags: { k: string, v: string }[]): boolean
|
||||
|
||||
asOverpass(): string[]
|
||||
|
||||
substituteValues(tags: any) : TagsFilter;
|
||||
}
|
||||
|
||||
export class TagUtils {
|
||||
|
@ -172,4 +201,13 @@ export class TagUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
static ApplyTemplate(template: string, tags: any): string {
|
||||
for (const k in tags) {
|
||||
while (template.indexOf("{" + k + "}") >= 0) {
|
||||
template = template.replace("{" + k + "}", tags[k]);
|
||||
}
|
||||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue