forked from MapComplete/MapComplete
Merge master
This commit is contained in:
commit
470e9acc64
66 changed files with 10798 additions and 414 deletions
|
@ -65,6 +65,8 @@ Instead of using `{"render": {"en": "{some_special_visualisation(some_arg, some
|
|||
* [Example usage of export_as_geojson](#example-usage-of-export_as_geojson)
|
||||
+ [open_in_iD](#open_in_id)
|
||||
* [Example usage of open_in_iD](#example-usage-of-open_in_id)
|
||||
+ [open_in_josm](#open_in_josm)
|
||||
* [Example usage of open_in_josm](#example-usage-of-open_in_josm)
|
||||
+ [clear_location_history](#clear_location_history)
|
||||
* [Example usage of clear_location_history](#example-usage-of-clear_location_history)
|
||||
+ [close_note](#close_note)
|
||||
|
@ -562,6 +564,16 @@ id_of_object_to_apply_this_one | _undefined_ | If specified, applies the the tag
|
|||
|
||||
|
||||
|
||||
### open_in_josm
|
||||
|
||||
Opens the current view in the JOSM-editor
|
||||
|
||||
#### Example usage of open_in_josm
|
||||
|
||||
`{open_in_josm()}`
|
||||
|
||||
|
||||
|
||||
### clear_location_history
|
||||
|
||||
A button to remove the travelled track information from the device
|
||||
|
|
|
@ -9,7 +9,6 @@ import BaseUIElement from "../UI/BaseUIElement";
|
|||
import {UIEventSource} from "./UIEventSource";
|
||||
import {LocalStorageSource} from "./Web/LocalStorageSource";
|
||||
import LZString from "lz-string";
|
||||
import * as personal from "../assets/themes/personal/personal.json";
|
||||
import {FixLegacyTheme} from "../Models/ThemeConfig/Conversion/LegacyJsonConvert";
|
||||
import {LayerConfigJson} from "../Models/ThemeConfig/Json/LayerConfigJson";
|
||||
import SharedTagRenderings from "../Customizations/SharedTagRenderings";
|
||||
|
@ -52,17 +51,7 @@ export default class DetermineLayout {
|
|||
console.log("Using layout", layoutId);
|
||||
}
|
||||
layoutId = QueryParameters.GetQueryParameter("layout", layoutId, "The layout to load into MapComplete").data;
|
||||
const layoutToUse: LayoutConfig = AllKnownLayouts.allKnownLayouts.get(layoutId?.toLowerCase());
|
||||
|
||||
if (layoutToUse?.id === personal.id) {
|
||||
layoutToUse.layers = AllKnownLayouts.AllPublicLayers()
|
||||
for (const layer of layoutToUse.layers) {
|
||||
layer.minzoomVisible = Math.max(layer.minzoomVisible, layer.minzoom)
|
||||
layer.minzoom = Math.max(16, layer.minzoom)
|
||||
}
|
||||
}
|
||||
|
||||
return layoutToUse
|
||||
return AllKnownLayouts.allKnownLayouts.get(layoutId?.toLowerCase())
|
||||
}
|
||||
|
||||
public static LoadLayoutFromHash(
|
||||
|
@ -161,7 +150,8 @@ export default class DetermineLayout {
|
|||
}
|
||||
const converState = {
|
||||
tagRenderings: SharedTagRenderings.SharedTagRenderingJson,
|
||||
sharedLayers: knownLayersDict
|
||||
sharedLayers: knownLayersDict,
|
||||
publicLayers: new Set<string>()
|
||||
}
|
||||
json = new FixLegacyTheme().convertStrict(json, "While loading a dynamic theme")
|
||||
const raw = json;
|
||||
|
|
|
@ -79,7 +79,7 @@ export default class GeoJsonSource implements FeatureSourceForLayer, Tiled {
|
|||
private LoadJSONFrom(url: string) {
|
||||
const eventSource = this.features;
|
||||
const self = this;
|
||||
Utils.downloadJson(url)
|
||||
Utils.downloadJsonCached(url, 60 * 60)
|
||||
.then(json => {
|
||||
self.state.setData("loaded")
|
||||
if (json.features === undefined || json.features === null) {
|
||||
|
|
|
@ -34,7 +34,7 @@ export default class GenericImageProvider extends ImageProvider {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
protected DownloadAttribution(url: string) {
|
||||
public DownloadAttribution(url: string) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {Store, Stores, UIEventSource} from "../UIEventSource";
|
||||
import {Store, UIEventSource} from "../UIEventSource";
|
||||
import BaseUIElement from "../../UI/BaseUIElement";
|
||||
import {LicenseInfo} from "./LicenseInfo";
|
||||
import {Utils} from "../../Utils";
|
||||
|
@ -13,18 +13,6 @@ export default abstract class ImageProvider {
|
|||
|
||||
public abstract readonly defaultKeyPrefixes: string[]
|
||||
|
||||
private _cache = new Map<string, Store<LicenseInfo>>()
|
||||
|
||||
GetAttributionFor(url: string): Store<LicenseInfo> {
|
||||
const cached = this._cache.get(url);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
const src = Stores.FromPromise(this.DownloadAttribution(url))
|
||||
this._cache.set(url, src)
|
||||
return src;
|
||||
}
|
||||
|
||||
public abstract SourceIcon(backlinkSource?: string): BaseUIElement;
|
||||
|
||||
/**
|
||||
|
@ -75,6 +63,6 @@ export default abstract class ImageProvider {
|
|||
|
||||
public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>;
|
||||
|
||||
protected abstract DownloadAttribution(url: string): Promise<LicenseInfo>;
|
||||
public abstract DownloadAttribution(url: string): Promise<LicenseInfo>;
|
||||
|
||||
}
|
|
@ -99,11 +99,23 @@ export class Imgur extends ImageProvider {
|
|||
return []
|
||||
}
|
||||
|
||||
protected DownloadAttribution: (url: string) => Promise<LicenseInfo> = async (url: string) => {
|
||||
/**
|
||||
* Download the attribution from attribution
|
||||
*
|
||||
* const data = {"data":{"id":"I9t6B7B","title":"Station Knokke","description":"author:Pieter Vander Vennet\r\nlicense:CC-BY 4.0\r\nosmid:node\/9812712386","datetime":1655052078,"type":"image\/jpeg","animated":false,"width":2400,"height":1795,"size":910872,"views":2,"bandwidth":1821744,"vote":null,"favorite":false,"nsfw":false,"section":null,"account_url":null,"account_id":null,"is_ad":false,"in_most_viral":false,"has_sound":false,"tags":[],"ad_type":0,"ad_url":"","edited":"0","in_gallery":false,"link":"https:\/\/i.imgur.com\/I9t6B7B.jpg","ad_config":{"safeFlags":["not_in_gallery","share"],"highRiskFlags":[],"unsafeFlags":["sixth_mod_unsafe"],"wallUnsafeFlags":[],"showsAds":false,"showAdLevel":1}},"success":true,"status":200}
|
||||
* Utils.injectJsonDownloadForTests("https://api.imgur.com/3/image/E0RuAK3", data)
|
||||
* const licenseInfo = await Imgur.singleton.DownloadAttribution("https://i.imgur.com/E0RuAK3.jpg")
|
||||
* const expected = new LicenseInfo()
|
||||
* expected.licenseShortName = "CC-BY 4.0"
|
||||
* expected.artist = "Pieter Vander Vennet"
|
||||
* licenseInfo // => expected
|
||||
*/
|
||||
public async DownloadAttribution (url: string) : Promise<LicenseInfo> {
|
||||
const hash = url.substr("https://i.imgur.com/".length).split(".jpg")[0];
|
||||
|
||||
const apiUrl = 'https://api.imgur.com/3/image/' + hash;
|
||||
const response = await Utils.downloadJson(apiUrl, {Authorization: 'Client-ID ' + Constants.ImgurApiKey})
|
||||
const response = await Utils.downloadJsonCached(apiUrl, 365*24*60*60,
|
||||
{Authorization: 'Client-ID ' + Constants.ImgurApiKey})
|
||||
|
||||
const descr: string = response.data.description ?? "";
|
||||
const data: any = {};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export class LicenseInfo {
|
||||
title: string = ""
|
||||
artist: string = "";
|
||||
license: string = "";
|
||||
license: string = undefined;
|
||||
licenseShortName: string = "";
|
||||
usageTerms: string = "";
|
||||
attributionRequired: boolean = false;
|
||||
|
|
|
@ -4,7 +4,6 @@ import Svg from "../../Svg";
|
|||
import {Utils} from "../../Utils";
|
||||
import {LicenseInfo} from "./LicenseInfo";
|
||||
import Constants from "../../Models/Constants";
|
||||
import * as Console from "console";
|
||||
|
||||
export class Mapillary extends ImageProvider {
|
||||
|
||||
|
@ -82,7 +81,7 @@ export class Mapillary extends ImageProvider {
|
|||
return [this.PrepareUrlAsync(key, value)]
|
||||
}
|
||||
|
||||
protected async DownloadAttribution(url: string): Promise<LicenseInfo> {
|
||||
public async DownloadAttribution(url: string): Promise<LicenseInfo> {
|
||||
const license = new LicenseInfo()
|
||||
license.artist = "Contributor name unavailable";
|
||||
license.license = "CC BY-SA 4.0";
|
||||
|
@ -98,7 +97,7 @@ export class Mapillary extends ImageProvider {
|
|||
}
|
||||
|
||||
const metadataUrl = 'https://graph.mapillary.com/' + mapillaryId + '?fields=thumb_1024_url&&access_token=' + Constants.mapillary_client_token_v4;
|
||||
const response = await Utils.downloadJson(metadataUrl)
|
||||
const response = await Utils.downloadJsonCached(metadataUrl,60*60)
|
||||
const url = <string>response["thumb_1024_url"];
|
||||
return {
|
||||
url: url,
|
||||
|
|
|
@ -46,7 +46,7 @@ export class WikidataImageProvider extends ImageProvider {
|
|||
return allImages
|
||||
}
|
||||
|
||||
protected DownloadAttribution(url: string): Promise<any> {
|
||||
public DownloadAttribution(url: string): Promise<any> {
|
||||
throw new Error("Method not implemented; shouldn't be needed!");
|
||||
}
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
return [Promise.resolve(this.UrlForImage("File:" + value))]
|
||||
}
|
||||
|
||||
protected async DownloadAttribution(filename: string): Promise<LicenseInfo> {
|
||||
public async DownloadAttribution(filename: string): Promise<LicenseInfo> {
|
||||
filename = WikimediaImageProvider.ExtractFileName(filename)
|
||||
|
||||
if (filename === "") {
|
||||
|
@ -123,7 +123,7 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
"api.php?action=query&prop=imageinfo&iiprop=extmetadata&" +
|
||||
"titles=" + filename +
|
||||
"&format=json&origin=*";
|
||||
const data = await Utils.downloadJson(url)
|
||||
const data = await Utils.downloadJsonCached(url,365*24*60*60)
|
||||
const licenseInfo = new LicenseInfo();
|
||||
const pageInfo = data.query.pages[-1]
|
||||
if (pageInfo === undefined) {
|
||||
|
|
|
@ -222,6 +222,11 @@ export class Changes {
|
|||
}
|
||||
|
||||
console.log("Got the fresh objects!", osmObjects, "pending: ", pending)
|
||||
if(pending.length == 0){
|
||||
console.log("No pending changes...")
|
||||
return true;
|
||||
}
|
||||
|
||||
const perType = Array.from(
|
||||
Utils.Hist(pending.filter(descr => descr.meta.changeType !== undefined && descr.meta.changeType !== null)
|
||||
.map(descr => descr.meta.changeType)), ([key, count]) => (
|
||||
|
|
|
@ -216,11 +216,19 @@ export class TagUtils {
|
|||
*
|
||||
* TagUtils.Tag("xyz<5").matchesProperties({xyz: 4}) // => true
|
||||
* TagUtils.Tag("xyz<5").matchesProperties({xyz: 5}) // => false
|
||||
<<<<<<< HEAD
|
||||
*
|
||||
* // RegexTags must match values with newlines
|
||||
* TagUtils.Tag("note~.*aed.*").matchesProperties({note: "Hier bevindt zich wss een defibrillator. \\n\\n De aed bevindt zich op de 5de verdieping"}) // => true
|
||||
* TagUtils.Tag("note~i~.*aed.*").matchesProperties({note: "Hier bevindt zich wss een defibrillator. \\n\\n De AED bevindt zich op de 5de verdieping"}) // => true
|
||||
*
|
||||
=======
|
||||
*
|
||||
* // RegexTags must match values with newlines
|
||||
* TagUtils.Tag("note~.*aed.*").matchesProperties({note: "Hier bevindt zich wss een defibrillator. \\n\\n De aed bevindt zich op de 5de verdieping"}) // => true
|
||||
* TagUtils.Tag("note~i~.*aed.*").matchesProperties({note: "Hier bevindt zich wss een defibrillator. \\n\\n De AED bevindt zich op de 5de verdieping"}) // => true
|
||||
*
|
||||
>>>>>>> master
|
||||
* // Must match case insensitive
|
||||
* TagUtils.Tag("name~i~somename").matchesProperties({name: "SoMeName"}) // => true
|
||||
*/
|
||||
|
@ -286,7 +294,7 @@ export class TagUtils {
|
|||
private static TagUnsafe(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter {
|
||||
|
||||
if (json === undefined) {
|
||||
throw `Error while parsing a tag: 'json' is undefined in ${context}. Make sure all the tags are defined and at least one tag is present in a complex expression`
|
||||
throw new Error(`Error while parsing a tag: 'json' is undefined in ${context}. Make sure all the tags are defined and at least one tag is present in a complex expression`)
|
||||
}
|
||||
if (typeof (json) != "string") {
|
||||
if (json.and !== undefined && json.or !== undefined) {
|
||||
|
@ -346,9 +354,8 @@ export class TagUtils {
|
|||
new RegExp("^" + split[1] + "$", "s")
|
||||
);
|
||||
}
|
||||
|
||||
const withRegex = TagUtils.parseRegexOperator(tag)
|
||||
if(withRegex != null) {
|
||||
if (withRegex != null) {
|
||||
if (withRegex.value === "*" && withRegex.invert) {
|
||||
throw `Don't use 'key!~*' - use 'key=' instead (empty string as value (in the tag ${tag} while parsing ${context})`
|
||||
}
|
||||
|
@ -362,7 +369,7 @@ export class TagUtils {
|
|||
}
|
||||
return new RegexTag(
|
||||
withRegex.key,
|
||||
new RegExp("^"+value+"$", "s"+withRegex.modifier),
|
||||
new RegExp("^" + value + "$", "s" + withRegex.modifier),
|
||||
withRegex.invert
|
||||
);
|
||||
}
|
||||
|
@ -468,26 +475,26 @@ export class TagUtils {
|
|||
* TagUtils.ContainsOppositeTags([new Tag("key", "value"), new RegexTag("key", "value", true)]) // => true
|
||||
* TagUtils.ContainsOppositeTags([new Tag("key", "value"), new RegexTag("key", /value/, true)]) // => true
|
||||
*/
|
||||
public static ContainsOppositeTags(tags: (TagsFilter)[]) : boolean{
|
||||
for (let i = 0; i < tags.length; i++){
|
||||
public static ContainsOppositeTags(tags: (TagsFilter)[]): boolean {
|
||||
for (let i = 0; i < tags.length; i++) {
|
||||
const tag = tags[i];
|
||||
if(!(tag instanceof Tag || tag instanceof RegexTag)){
|
||||
if (!(tag instanceof Tag || tag instanceof RegexTag)) {
|
||||
continue
|
||||
}
|
||||
for (let j = i + 1; j < tags.length; j++){
|
||||
for (let j = i + 1; j < tags.length; j++) {
|
||||
const guard = tags[j];
|
||||
if(!(guard instanceof Tag || guard instanceof RegexTag)){
|
||||
if (!(guard instanceof Tag || guard instanceof RegexTag)) {
|
||||
continue
|
||||
}
|
||||
if(guard.key !== tag.key) {
|
||||
if (guard.key !== tag.key) {
|
||||
// Different keys: they can _never_ be opposites
|
||||
continue
|
||||
}
|
||||
if((guard.value["source"] ?? guard.value) !== (tag.value["source"] ?? tag.value)){
|
||||
if ((guard.value["source"] ?? guard.value) !== (tag.value["source"] ?? tag.value)) {
|
||||
// different values: the can _never_ be opposites
|
||||
continue
|
||||
}
|
||||
if( (guard["invert"] ?? false) !== (tag["invert"] ?? false) ) {
|
||||
if ((guard["invert"] ?? false) !== (tag["invert"] ?? false)) {
|
||||
// The 'invert' flags are opposite, the key and value is the same for both
|
||||
// This means we have found opposite tags!
|
||||
return true
|
||||
|
@ -505,7 +512,7 @@ export class TagUtils {
|
|||
*
|
||||
* TagUtils.removeShadowedElementsFrom([new Tag("key","value")], [new Tag("key","value"), new Tag("other_key","value")]) // => [new Tag("other_key","value")]
|
||||
*/
|
||||
public static removeShadowedElementsFrom(blacklist: TagsFilter[], listToFilter: TagsFilter[] ) : TagsFilter[] {
|
||||
public static removeShadowedElementsFrom(blacklist: TagsFilter[], listToFilter: TagsFilter[]): TagsFilter[] {
|
||||
return listToFilter.filter(tf => !blacklist.some(guard => guard.shadows(tf)))
|
||||
}
|
||||
|
||||
|
@ -514,16 +521,16 @@ export class TagUtils {
|
|||
*
|
||||
* TagUtils.removeEquivalents([new RegexTag("key", /^..*$/), new Tag("key","value")]) // => [new Tag("key", "value")]
|
||||
*/
|
||||
public static removeEquivalents( listToFilter: (Tag | RegexTag)[]) : TagsFilter[] {
|
||||
public static removeEquivalents(listToFilter: (Tag | RegexTag)[]): TagsFilter[] {
|
||||
const result: TagsFilter[] = []
|
||||
outer: for (let i = 0; i < listToFilter.length; i++){
|
||||
outer: for (let i = 0; i < listToFilter.length; i++) {
|
||||
const tag = listToFilter[i];
|
||||
for (let j = 0; j < listToFilter.length; j++){
|
||||
if(i === j){
|
||||
for (let j = 0; j < listToFilter.length; j++) {
|
||||
if (i === j) {
|
||||
continue
|
||||
}
|
||||
const guard = listToFilter[j];
|
||||
if(guard.shadows(tag)) {
|
||||
if (guard.shadows(tag)) {
|
||||
// the guard 'kills' the tag: we continue the outer loop without adding the tag
|
||||
continue outer;
|
||||
}
|
||||
|
@ -540,7 +547,7 @@ export class TagUtils {
|
|||
* TagUtils.containsEquivalents([new Tag("key","value")], [ new Tag("other_key","value")]) // => false
|
||||
* TagUtils.containsEquivalents([new Tag("key","value")], [ new Tag("key","other_value")]) // => false
|
||||
*/
|
||||
public static containsEquivalents( guards: TagsFilter[], listToFilter: TagsFilter[] ) : boolean {
|
||||
public static containsEquivalents(guards: TagsFilter[], listToFilter: TagsFilter[]): boolean {
|
||||
return listToFilter.some(tf => guards.some(guard => guard.shadows(tf)))
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Utils} from "../../Utils";
|
|||
export class QueryParameters {
|
||||
|
||||
static defaults = {}
|
||||
static documentation = {}
|
||||
static documentation: Map<string, string> = new Map<string, string>()
|
||||
private static order: string [] = ["layout", "test", "z", "lat", "lon"];
|
||||
private static _wasInitialized: Set<string> = new Set()
|
||||
private static knownSources = {};
|
||||
|
@ -18,7 +18,7 @@ export class QueryParameters {
|
|||
if (!this.initialized) {
|
||||
this.init();
|
||||
}
|
||||
QueryParameters.documentation[key] = documentation;
|
||||
QueryParameters.documentation.set(key, documentation);
|
||||
if (deflt !== undefined) {
|
||||
QueryParameters.defaults[key] = deflt;
|
||||
}
|
||||
|
|
|
@ -121,13 +121,14 @@ export default class Wikipedia {
|
|||
* @param searchTerm
|
||||
*/
|
||||
public async searchViaIndex(searchTerm: string): Promise<{ title: string, snippet: string, url: string } []> {
|
||||
const url = `${this.backend}/w/index.php?search=${encodeURIComponent(searchTerm)}`
|
||||
const url = `${this.backend}/w/index.php?search=${encodeURIComponent(searchTerm)}&ns0=1`
|
||||
const result = await Utils.downloadAdvanced(url);
|
||||
if(result["redirect"] ){
|
||||
const targetUrl = result["redirect"]
|
||||
// This is an exact match
|
||||
return [{
|
||||
title: this.extractPageName(result["redirect"]).trim(),
|
||||
url: result["redirect"],
|
||||
title: this.extractPageName(targetUrl)?.trim(),
|
||||
url: targetUrl,
|
||||
snippet: ""
|
||||
}]
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import {Utils} from "../Utils";
|
|||
|
||||
export default class Constants {
|
||||
|
||||
public static vNumber = "0.20.1";
|
||||
public static vNumber = "0.21.0";
|
||||
|
||||
public static ImgurApiKey = '7070e7167f0a25a'
|
||||
public static readonly mapillary_client_token_v4 = "MLY|4441509239301885|b40ad2d3ea105435bd40c7e76993ae85"
|
||||
|
@ -23,7 +23,7 @@ export default class Constants {
|
|||
/**
|
||||
* Layer IDs of layers which have special properties through built-in hooks
|
||||
*/
|
||||
public static readonly priviliged_layers: string[] = [...Constants.added_by_default, "type_node", "note", "import_candidate", ...Constants.no_include]
|
||||
public static readonly priviliged_layers: string[] = [...Constants.added_by_default, "type_node", "note", "import_candidate", "direction", ...Constants.no_include]
|
||||
|
||||
|
||||
// The user journey states thresholds when a new feature gets unlocked
|
||||
|
|
|
@ -4,7 +4,8 @@ import {Utils} from "../../../Utils";
|
|||
|
||||
export interface DesugaringContext {
|
||||
tagRenderings: Map<string, TagRenderingConfigJson>
|
||||
sharedLayers: Map<string, LayerConfigJson>
|
||||
sharedLayers: Map<string, LayerConfigJson>,
|
||||
publicLayers?: Set<string>
|
||||
}
|
||||
|
||||
export abstract class Conversion<TIn, TOut> {
|
||||
|
@ -226,7 +227,7 @@ export class Fuse<T> extends DesugaringStep<T> {
|
|||
break;
|
||||
}
|
||||
}catch(e){
|
||||
console.error("Step "+step.name+" failed due to "+e);
|
||||
console.error("Step "+step.name+" failed due to ",e,e.stack);
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
|
|
@ -454,8 +454,15 @@ class PreparePersonalTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
return {result: json}
|
||||
}
|
||||
|
||||
json.layers = Array.from(this._state.sharedLayers.keys()).filter(l => Constants.priviliged_layers.indexOf(l) < 0)
|
||||
return {result: json};
|
||||
// The only thing this _really_ does, is adding the layer-ids into 'layers'
|
||||
// All other preparations are done by the 'override-all'-block in personal.json
|
||||
|
||||
json.layers = Array.from(this._state.sharedLayers.keys())
|
||||
.filter(l => Constants.priviliged_layers.indexOf(l) < 0)
|
||||
.filter(l => this._state.publicLayers.has(l))
|
||||
return {result: json, information: [
|
||||
"The personal theme has "+json.layers.length+" public layers"
|
||||
]};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -321,8 +321,9 @@ export class DetectShadowedMappings extends DesugaringStep<QuestionableTagRender
|
|||
for (const calculatedTagName of this._calculatedTagNames) {
|
||||
defaultProperties[calculatedTagName] = "some_calculated_tag_value_for_"+calculatedTagName
|
||||
}
|
||||
const parsedConditions = json.mappings.map(m => {
|
||||
const ifTags = TagUtils.Tag(m.if);
|
||||
const parsedConditions = json.mappings.map((m,i) => {
|
||||
const ctx = `${context}.mappings[${i}]`
|
||||
const ifTags = TagUtils.Tag(m.if, ctx);
|
||||
if(m.hideInAnswer !== undefined && m.hideInAnswer !== false && m.hideInAnswer !== true){
|
||||
let conditionTags = TagUtils.Tag( m.hideInAnswer)
|
||||
// Merge the condition too!
|
||||
|
@ -407,7 +408,7 @@ export class DetectMappingsWithImages extends DesugaringStep<TagRenderingConfigJ
|
|||
|
||||
const mapping = json.mappings[i]
|
||||
const ignore = mapping["#"]?.indexOf(ignoreToken) >=0
|
||||
const images = Utils.Dedup(Translations.T(mapping.then).ExtractImages())
|
||||
const images = Utils.Dedup(Translations.T(mapping.then)?.ExtractImages() ?? [])
|
||||
const ctx = `${context}.mappings[${i}]`
|
||||
if (images.length > 0) {
|
||||
if(!ignore){
|
||||
|
|
|
@ -41,7 +41,7 @@ export interface DeleteConfigJson {
|
|||
* The tags that will be given to the object.
|
||||
* This must remove tags so that the 'source/osmTags' won't match anymore
|
||||
*/
|
||||
if: AndOrTagConfigJson,
|
||||
if: string | AndOrTagConfigJson,
|
||||
/**
|
||||
* The human explanation for the options
|
||||
*/
|
||||
|
|
|
@ -287,7 +287,7 @@ export interface LayerConfigJson {
|
|||
*/
|
||||
tagRenderings?:
|
||||
(string
|
||||
| { builtin: string, override: any }
|
||||
| { builtin: string | string[], override: any }
|
||||
| QuestionableTagRenderingConfigJson
|
||||
| RewritableConfigJson<(string | { builtin: string, override: any } | QuestionableTagRenderingConfigJson)[]>
|
||||
) [],
|
||||
|
@ -426,7 +426,7 @@ export interface LayerConfigJson {
|
|||
units?: UnitConfigJson[]
|
||||
|
||||
/**
|
||||
* If set, synchronizes wether or not this layer is selected.
|
||||
* If set, synchronizes whether or not this layer is enabled.
|
||||
*
|
||||
* no: Do not sync at all, always revert to default
|
||||
* local: keep selection on local storage
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*
|
||||
* [
|
||||
* {
|
||||
* // The first pair: key --> X, a|b|c --> 0
|
||||
* # The first pair: key --> X, a|b|c --> 0
|
||||
* "X": 0
|
||||
* },
|
||||
* {
|
||||
|
|
|
@ -65,7 +65,8 @@ export default class LayerConfig extends WithContextLoader {
|
|||
public readonly filterIsSameAs: string;
|
||||
public readonly forceLoad: boolean;
|
||||
|
||||
public readonly syncSelection: "no" | "local" | "theme-only" | "global"
|
||||
public static readonly syncSelectionAllowed = ["no" , "local" , "theme-only" , "global"] as const;
|
||||
public readonly syncSelection: (typeof LayerConfig.syncSelectionAllowed)[number] // this is a trick to conver a constant array of strings into a type union of these values
|
||||
|
||||
constructor(
|
||||
json: LayerConfigJson,
|
||||
|
@ -97,7 +98,10 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
this.maxAgeOfCache = json.source.maxCacheAge ?? 24 * 60 * 60 * 30
|
||||
this.syncSelection = json.syncSelection;
|
||||
if(json.syncSelection !== undefined && LayerConfig.syncSelectionAllowed.indexOf(json.syncSelection) < 0){
|
||||
throw context+ " Invalid sync-selection: must be one of "+LayerConfig.syncSelectionAllowed.map(v => `'${v}'`).join(", ")+" but got '"+json.syncSelection+"'"
|
||||
}
|
||||
this.syncSelection = json.syncSelection ?? "no";
|
||||
const osmTags = TagUtils.Tag(
|
||||
json.source.osmTags,
|
||||
context + "source.osmTags"
|
||||
|
|
|
@ -111,6 +111,10 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
const type = json.freeform.type ?? "string"
|
||||
|
||||
if(ValidatedTextField.AvailableTypes().indexOf(type ) < 0){
|
||||
throw "At "+context+".freeform.type is an unknown type: "+type+"; try one of "+ValidatedTextField.AvailableTypes().join(", ")
|
||||
}
|
||||
|
||||
let placeholder: Translation = Translations.T(json.freeform.placeholder)
|
||||
if (placeholder === undefined) {
|
||||
const typeDescription = Translations.t.validation[type]?.description
|
||||
|
@ -172,15 +176,21 @@ export default class TagRenderingConfig {
|
|||
this.mappings = json.mappings.map((mapping, i) => {
|
||||
|
||||
const ctx = `${translationKey}.mappings.${i}`
|
||||
if (mapping.if === undefined) {
|
||||
throw `${ctx}: Invalid mapping: "if" is not defined in ${JSON.stringify(mapping)}`
|
||||
}
|
||||
if (mapping.then === undefined) {
|
||||
throw `${ctx}: Invalid mapping: if without body`
|
||||
if(mapping["render"] !== undefined){
|
||||
throw `${ctx}: Invalid mapping: no 'then'-clause found. You might have typed 'render' instead of 'then', change it in ${JSON.stringify(mapping)}`
|
||||
}
|
||||
throw `${ctx}: Invalid mapping: no 'then'-clause found in ${JSON.stringify(mapping)}`
|
||||
}
|
||||
if (mapping.ifnot !== undefined && !this.multiAnswer) {
|
||||
throw `${ctx}: Invalid mapping: ifnot defined, but the tagrendering is not a multianswer`
|
||||
throw `${ctx}: Invalid mapping: 'ifnot' is defined, but the tagrendering is not a multianswer. Either remove ifnot or set 'multiAnswer:true' to enable checkboxes instead of radiobuttons`
|
||||
}
|
||||
|
||||
if (mapping.if === undefined) {
|
||||
throw `${ctx}: Invalid mapping: "if" is not defined, but the tagrendering is not a multianswer`
|
||||
if(mapping["render"] !== undefined){
|
||||
throw `${ctx}: Invalid mapping: a 'render'-key is present, this is probably a bug: ${JSON.stringify(mapping)}`
|
||||
}
|
||||
if (typeof mapping.if !== "string" && mapping.if["length"] !== undefined) {
|
||||
throw `${ctx}: Invalid mapping: "if" is defined as an array. Use {"and": <your conditions>} or {"or": <your conditions>} instead`
|
||||
|
|
|
@ -26,9 +26,7 @@ export default class Title extends BaseUIElement {
|
|||
} else if (embedded instanceof FixedUiElement) {
|
||||
innerText = embedded.content
|
||||
} else {
|
||||
if (Utils.runningFromConsole) {
|
||||
console.log("Not constructing an anchor for title with embedded content of " + embedded)
|
||||
} else {
|
||||
if (!Utils.runningFromConsole) {
|
||||
innerText = embedded.ConstructElement()?.innerText
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,10 @@ import FilteredLayer from "../../Models/FilteredLayer";
|
|||
import {TagUtils} from "../../Logic/Tags/TagUtils";
|
||||
import Svg from "../../Svg";
|
||||
|
||||
/**
|
||||
* The icon with the 'plus'-sign and the preset icons spinning
|
||||
*
|
||||
*/
|
||||
export default class AddNewMarker extends Combine {
|
||||
|
||||
constructor(filteredLayers: UIEventSource<FilteredLayer[]>) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import Combine from "../Base/Combine";
|
||||
import Attribution from "./Attribution";
|
||||
import Img from "../Base/Img";
|
||||
import ImageProvider, {ProvidedImage} from "../../Logic/ImageProviders/ImageProvider";
|
||||
import ImageProvider from "../../Logic/ImageProviders/ImageProvider";
|
||||
import BaseUIElement from "../BaseUIElement";
|
||||
import {Mapillary} from "../../Logic/ImageProviders/Mapillary";
|
||||
import {UIEventSource} from "../../Logic/UIEventSource";
|
||||
|
||||
|
||||
export class AttributedImage extends Combine {
|
||||
|
@ -21,7 +22,7 @@ export class AttributedImage extends Combine {
|
|||
|
||||
let attr: BaseUIElement = undefined
|
||||
if(imageInfo.provider !== undefined){
|
||||
attr = new Attribution(imageInfo.provider?.GetAttributionFor(imageInfo.url),
|
||||
attr = new Attribution(UIEventSource.FromPromise( imageInfo.provider?.DownloadAttribution(imageInfo.url)),
|
||||
imageInfo.provider?.SourceIcon(),
|
||||
imageInfo.date
|
||||
)
|
||||
|
|
|
@ -24,7 +24,7 @@ export default class Attribution extends VariableUiElement {
|
|||
new Combine([
|
||||
Translations.W(license?.title).SetClass("block"),
|
||||
Translations.W(license?.artist ?? "").SetClass("block font-bold"),
|
||||
Translations.W((license?.license ?? "") === "" ? "CC0" : (license?.license ?? "")),
|
||||
Translations.W(license?.license ?? license?.licenseShortName),
|
||||
date === undefined ? undefined : new FixedUiElement(date.toLocaleDateString())
|
||||
]).SetClass("flex flex-col")
|
||||
]).SetClass("flex flex-row bg-black text-white text-sm absolute bottom-0 left-0 p-0.5 pl-5 pr-3 rounded-lg no-images")
|
||||
|
|
|
@ -547,7 +547,7 @@ class LengthTextField extends TextFieldDef {
|
|||
|
||||
constructor() {
|
||||
super(
|
||||
"decimal", "A geographical length in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]"
|
||||
"length", "A geographical length in meters (rounded at two points). Will give an extra minimap with a measurement tool. Arguments: [ zoomlevel, preferredBackgroundMapType (comma separated) ], e.g. `[\"21\", \"map,photo\"]"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -734,6 +734,7 @@ class EmailTextField extends TextFieldDef {
|
|||
if (str === undefined) {
|
||||
return false
|
||||
}
|
||||
str = str.trim()
|
||||
if (str.startsWith("mailto:")) {
|
||||
str = str.substring("mailto:".length)
|
||||
}
|
||||
|
@ -744,6 +745,7 @@ class EmailTextField extends TextFieldDef {
|
|||
if (str === undefined) {
|
||||
return undefined
|
||||
}
|
||||
str = str.trim()
|
||||
if (str.startsWith("mailto:")) {
|
||||
str = str.substring("mailto:".length)
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ export default class ConfirmLocationOfPoint extends Combine {
|
|||
bounds: mapBounds
|
||||
})
|
||||
preciseInput.installBounds(preset.boundsFactor ?? 0.25, true)
|
||||
preciseInput.SetClass("h-40 rounded-xl overflow-hidden border border-gray").SetStyle("height: 12rem;")
|
||||
preciseInput.SetClass("rounded-xl overflow-hidden border border-gray").SetStyle("height: 18rem; max-height: 50vh")
|
||||
|
||||
|
||||
if (preset.preciseInput.snapToLayers && preset.preciseInput.snapToLayers.length > 0) {
|
||||
|
|
|
@ -223,7 +223,9 @@ export default class FeatureInfoBox extends ScrollableFullScreen {
|
|||
|
||||
return new Combine([new TagRenderingAnswer(tags, config_all_tags, state),
|
||||
new TagRenderingAnswer(tags, config_download, state),
|
||||
new TagRenderingAnswer(tags, config_id, state)])
|
||||
new TagRenderingAnswer(tags, config_id, state),
|
||||
"This is layer "+layerConfig.id
|
||||
])
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
|
@ -54,11 +54,13 @@ abstract class AbstractImportButton implements SpecialVisualizations {
|
|||
public readonly docs: string
|
||||
public readonly args: { name: string, defaultValue?: string, doc: string }[]
|
||||
private readonly showRemovedTags: boolean;
|
||||
private readonly cannotBeImportedMessage: BaseUIElement | undefined;
|
||||
|
||||
constructor(funcName: string, docsIntro: string, extraArgs: { name: string, doc: string, defaultValue?: string, required?: boolean }[], showRemovedTags = true) {
|
||||
constructor(funcName: string, docsIntro: string, extraArgs: { name: string, doc: string, defaultValue?: string, required?: boolean }[],
|
||||
options?: {showRemovedTags? : true | boolean, cannotBeImportedMessage?: BaseUIElement}) {
|
||||
this.funcName = funcName
|
||||
this.showRemovedTags = showRemovedTags;
|
||||
|
||||
this.showRemovedTags = options?.showRemovedTags ?? true;
|
||||
this.cannotBeImportedMessage = options?.cannotBeImportedMessage
|
||||
this.docs = `${docsIntro}
|
||||
|
||||
Note that the contributor must zoom to at least zoomlevel 18 to be able to use this functionality.
|
||||
|
@ -200,7 +202,7 @@ ${Utils.special_visualizations_importRequirementDocs}
|
|||
pleaseLoginButton,
|
||||
state
|
||||
),
|
||||
t.wrongType,
|
||||
this.cannotBeImportedMessage ?? t.wrongType,
|
||||
new UIEventSource(this.canBeImported(feature)))
|
||||
|
||||
}
|
||||
|
@ -304,7 +306,10 @@ export class ConflateButton extends AbstractImportButton {
|
|||
[{
|
||||
name: "way_to_conflate",
|
||||
doc: "The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag"
|
||||
}]
|
||||
}],
|
||||
{
|
||||
cannotBeImportedMessage: Translations.t.general.add.import.wrongTypeToConflate
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -393,7 +398,7 @@ export class ImportWayButton extends AbstractImportButton implements AutoAction
|
|||
doc: "Distance to distort the geometry to snap to this layer",
|
||||
defaultValue: "0.1"
|
||||
}],
|
||||
false
|
||||
{ showRemovedTags: false}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -548,7 +553,7 @@ export class ImportPointButton extends AbstractImportButton {
|
|||
{name:"location_picker",
|
||||
defaultValue: "photo",
|
||||
doc: "Chooses the background for the precise location picker, options are 'map', 'photo' or 'osmbasedmap' or 'none' if the precise input picker should be disabled"}],
|
||||
false
|
||||
{ showRemovedTags: false}
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import Translations from "./i18n/Translations";
|
|||
import {QueryParameters} from "../Logic/Web/QueryParameters";
|
||||
import FeatureSwitchState from "../Logic/State/FeatureSwitchState";
|
||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig";
|
||||
import {DefaultGuiState} from "./DefaultGuiState";
|
||||
|
||||
export default class QueryParameterDocumentation {
|
||||
|
||||
|
@ -26,12 +27,12 @@ export default class QueryParameterDocumentation {
|
|||
"Finally, the URL-hash is the part after the `#`. It is `node/1234` in this case."
|
||||
])
|
||||
|
||||
public static UrlParamDocs(): object{
|
||||
public static UrlParamDocs(): Map<string, string> {
|
||||
const dummyLayout = new LayoutConfig({
|
||||
id: ">theme<",
|
||||
maintainer: "pietervdvn",
|
||||
version: "0",
|
||||
title: {en:"<theme>"},
|
||||
title: {en: "<theme>"},
|
||||
description: "A theme to generate docs with",
|
||||
socialImage: "./assets/SocialImage.png",
|
||||
startLat: 0,
|
||||
|
@ -50,7 +51,7 @@ export default class QueryParameterDocumentation {
|
|||
]
|
||||
|
||||
})
|
||||
|
||||
new DefaultGuiState(); // Init a featureSwitchState to init all the parameters
|
||||
new FeatureSwitchState(dummyLayout)
|
||||
|
||||
QueryParameters.GetQueryParameter("layer-<layer-id>", "true", "Wether or not the layer with id <layer-id> is shown")
|
||||
|
@ -58,16 +59,18 @@ export default class QueryParameterDocumentation {
|
|||
}
|
||||
|
||||
public static GenerateQueryParameterDocs(): BaseUIElement {
|
||||
|
||||
|
||||
const docs: (string | BaseUIElement)[] = [...QueryParameterDocumentation.QueryParamDocsIntro];
|
||||
for (const key in QueryParameters.documentation) {
|
||||
this.UrlParamDocs().forEach((value, key) => {
|
||||
const c = new Combine([
|
||||
new Title(key, 2),
|
||||
QueryParameters.documentation[key],
|
||||
value,
|
||||
QueryParameters.defaults[key] === undefined ? "No default value set" : `The default value is _${QueryParameters.defaults[key]}_`
|
||||
|
||||
])
|
||||
docs.push(c)
|
||||
}
|
||||
})
|
||||
return new Combine(docs).SetClass("flex flex-col")
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ import {ConflateButton, ImportPointButton, ImportWayButton} from "./Popup/Import
|
|||
import TagApplyButton from "./Popup/TagApplyButton";
|
||||
import AutoApplyButton from "./Popup/AutoApplyButton";
|
||||
import * as left_right_style_json from "../assets/layers/left_right_style/left_right_style.json";
|
||||
import {OpenIdEditor} from "./BigComponents/CopyrightPanel";
|
||||
import {OpenIdEditor, OpenJosm} from "./BigComponents/CopyrightPanel";
|
||||
import Toggle from "./Input/Toggle";
|
||||
import Img from "./Base/Img";
|
||||
import NoteCommentElement from "./Popup/NoteCommentElement";
|
||||
|
@ -207,10 +207,12 @@ class NearbyImageVis implements SpecialVisualization {
|
|||
const nearby = new Lazy(() => {
|
||||
const towardsCenter = new CheckBox(t.onlyTowards, false)
|
||||
|
||||
const radiusValue= state?.osmConnection?.GetPreference("nearby-images-radius","300").sync(s => Number(s), [], i => ""+i) ?? new UIEventSource(300);
|
||||
const radiusValue = state?.osmConnection?.GetPreference("nearby-images-radius","300").sync(s => Number(s), [], i => ""+i) ?? new UIEventSource(300);
|
||||
|
||||
const radius = new Slider(25, 500, {value:
|
||||
radiusValue, step: 25})
|
||||
const radius = new Slider(25, 500, {
|
||||
value:
|
||||
radiusValue, step: 25
|
||||
})
|
||||
const alreadyInTheImage = AllImageProviders.LoadImagesFor(tagSource)
|
||||
const options: NearbyImageOptions & { value } = {
|
||||
lon, lat,
|
||||
|
@ -283,10 +285,8 @@ export default class SpecialVisualizations {
|
|||
|
||||
public static specialVisualizations: SpecialVisualization[] = SpecialVisualizations.init()
|
||||
|
||||
public static HelpMessage() {
|
||||
|
||||
const helpTexts =
|
||||
SpecialVisualizations.specialVisualizations.map(viz => new Combine(
|
||||
public static DocumentationFor(viz: SpecialVisualization): BaseUIElement {
|
||||
return new Combine(
|
||||
[
|
||||
new Title(viz.funcName, 3),
|
||||
viz.docs,
|
||||
|
@ -304,8 +304,12 @@ export default class SpecialVisualizations {
|
|||
viz.example ?? "`{" + viz.funcName + "(" + viz.args.map(arg => arg.defaultValue).join(",") + ")}`"
|
||||
).SetClass("literal-code"),
|
||||
|
||||
]
|
||||
));
|
||||
])
|
||||
}
|
||||
|
||||
public static HelpMessage() {
|
||||
|
||||
const helpTexts = SpecialVisualizations.specialVisualizations.map(viz => SpecialVisualizations.DocumentationFor(viz));
|
||||
|
||||
return new Combine([
|
||||
new Combine([
|
||||
|
@ -886,7 +890,14 @@ export default class SpecialVisualizations {
|
|||
return new OpenIdEditor(state, undefined, feature.data.id)
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
funcName: "open_in_josm",
|
||||
docs: "Opens the current view in the JOSM-editor",
|
||||
args: [],
|
||||
constr: (state, feature) => {
|
||||
return new OpenJosm(state)
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
funcName: "clear_location_history",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"contributors": [
|
||||
{
|
||||
"commits": 3823,
|
||||
"commits": 3854,
|
||||
"contributor": "Pieter Vander Vennet"
|
||||
},
|
||||
{
|
||||
|
@ -44,6 +44,10 @@
|
|||
"commits": 19,
|
||||
"contributor": "Niels Elgaard Larsen"
|
||||
},
|
||||
{
|
||||
"commits": 19,
|
||||
"contributor": "yopaseopor"
|
||||
},
|
||||
{
|
||||
"commits": 19,
|
||||
"contributor": "Sebastian Kürten"
|
||||
|
@ -78,11 +82,11 @@
|
|||
},
|
||||
{
|
||||
"commits": 10,
|
||||
"contributor": "LiamSimons"
|
||||
"contributor": "dependabot[bot]"
|
||||
},
|
||||
{
|
||||
"commits": 9,
|
||||
"contributor": "dependabot[bot]"
|
||||
"commits": 10,
|
||||
"contributor": "LiamSimons"
|
||||
},
|
||||
{
|
||||
"commits": 8,
|
||||
|
@ -104,10 +108,6 @@
|
|||
"commits": 7,
|
||||
"contributor": "Binnette"
|
||||
},
|
||||
{
|
||||
"commits": 7,
|
||||
"contributor": "yopaseopor"
|
||||
},
|
||||
{
|
||||
"commits": 6,
|
||||
"contributor": "danieldegroot2"
|
||||
|
@ -116,17 +116,21 @@
|
|||
"commits": 6,
|
||||
"contributor": "pelderson"
|
||||
},
|
||||
{
|
||||
"commits": 5,
|
||||
"contributor": "Thibault Molleman"
|
||||
},
|
||||
{
|
||||
"commits": 5,
|
||||
"contributor": "David Haberthür"
|
||||
},
|
||||
{
|
||||
"commits": 4,
|
||||
"contributor": "Ward Beyens"
|
||||
"contributor": "Codain"
|
||||
},
|
||||
{
|
||||
"commits": 3,
|
||||
"contributor": "Codain"
|
||||
"commits": 4,
|
||||
"contributor": "Ward Beyens"
|
||||
},
|
||||
{
|
||||
"commits": 3,
|
||||
|
@ -268,10 +272,6 @@
|
|||
"commits": 1,
|
||||
"contributor": "Schouppe Joost"
|
||||
},
|
||||
{
|
||||
"commits": 1,
|
||||
"contributor": "Thibault Molleman"
|
||||
},
|
||||
{
|
||||
"commits": 1,
|
||||
"contributor": "Noémie"
|
||||
|
|
|
@ -383,6 +383,26 @@
|
|||
],
|
||||
"id": "Takeaway"
|
||||
},
|
||||
{
|
||||
"id": "delivery",
|
||||
"question": {
|
||||
"en": "Delivers {title()} their food at home?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "delivery=yes",
|
||||
"then": {
|
||||
"en": "This business does home delivery (eventually via a third party)"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "delivery=no",
|
||||
"then": {
|
||||
"en": "This business does not deliver at home"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"question": {
|
||||
"nl": "Heeft deze eetgelegenheid een vegetarische optie?",
|
||||
|
|
|
@ -348,7 +348,13 @@
|
|||
"fr": "Non accessible",
|
||||
"de": "Der Spielplatz ist nicht öffentlich zugänglich"
|
||||
}
|
||||
}
|
||||
},
|
||||
{"if": "leisure=playground",
|
||||
"then":
|
||||
{
|
||||
"en": "This is a schoolyard - an outdoor area where the pupils can play during their breaks; but it is not accessible to the general public",
|
||||
"nl": "Dit is een schoolplein - een zone waar de leerlingen kunnen spelen tijdens de pauze. Dit schoolplein is niet toegankelijk voor het publiek"
|
||||
}}
|
||||
]
|
||||
},
|
||||
"website",
|
||||
|
@ -510,6 +516,15 @@
|
|||
}
|
||||
],
|
||||
"deletion": {
|
||||
"nonDeleteMappings": [
|
||||
{
|
||||
"if": "leisure=schoolyard",
|
||||
"then": {
|
||||
"en": "This is a schoolyard - an (outdoor) area where pupils of a school can play during recess and which is not publicly accessible",
|
||||
"nl": "Dit is een schoolplein - een ruimte waar de leerlingen van een school kunnen spelen tijdens de pauze maar die niet publiek toegankelijk is"
|
||||
}
|
||||
}
|
||||
],
|
||||
"softDeletionTags": {
|
||||
"and": [
|
||||
"disused:leisure=playground",
|
||||
|
|
|
@ -467,7 +467,8 @@
|
|||
"osmTags": "payment:cash=yes",
|
||||
"question": {
|
||||
"en": "Accepts cash",
|
||||
"de": "Akzeptiert Bargeld"
|
||||
"de": "Akzeptiert Bargeld",
|
||||
"nl": "Accepteert cash"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -479,7 +480,8 @@
|
|||
"osmTags": "payment:cards=yes",
|
||||
"question": {
|
||||
"en": "Accepts payment cards",
|
||||
"de": "Akzeptiert Kartenzahlung"
|
||||
"de": "Akzeptiert Kartenzahlung",
|
||||
"nl": "Accepteert betaalkaarten"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
{
|
||||
"id": "ref",
|
||||
"render": {
|
||||
|
|
|
@ -50,6 +50,35 @@
|
|||
"drinking_water",
|
||||
"bike_themed_object",
|
||||
"bike_cleaning",
|
||||
"bike_parking"
|
||||
"bike_parking",
|
||||
{
|
||||
"builtin": [
|
||||
"charging_station"
|
||||
],
|
||||
"override": {
|
||||
"id": "charging_station_ebikes",
|
||||
"minzoom": 14,
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"and+": [
|
||||
"bicycle=yes"
|
||||
]
|
||||
}
|
||||
},
|
||||
"filter": null,
|
||||
"=presets": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"#": "All charging stations at a high zoom level, to avoid duplicates",
|
||||
"builtin": "charging_station",
|
||||
"override": {
|
||||
"name": null,
|
||||
"filter": {
|
||||
"sameAs": "charging_station_ebike"
|
||||
},
|
||||
"minzoom": 18
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -498,6 +498,19 @@
|
|||
"de": "Metatags noch nicht berechnet... Dieses Fenster erneut öffnen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"id~relation/*",
|
||||
"_overlap_percentage>50",
|
||||
"_reverse_overlap_percentage>50",
|
||||
"_overlaps_with!="
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"en": "This building has holes and is modeled as a relation. As such, it cannot be conflated. Conflate it manually via <a href='https://buildings.osm.be/#/'>the building export site</a> {open_in_josm()}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"#": "Actually the same as below, except that the text shows 'add the address' too",
|
||||
"if": {
|
||||
|
|
|
@ -41,8 +41,9 @@
|
|||
"overpassMaxZoom": 15,
|
||||
"overrideAll": {
|
||||
"minzoom": 17,
|
||||
"syncSelection": "theme",
|
||||
"syncSelection": "theme-only",
|
||||
"shownByDefault": false
|
||||
},
|
||||
"enableNoteImports": false,
|
||||
"layers": []
|
||||
}
|
|
@ -70,6 +70,7 @@
|
|||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
{
|
||||
"id": "lit",
|
||||
"question": {
|
||||
|
@ -189,6 +190,7 @@
|
|||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
{
|
||||
"id": "lit",
|
||||
"question": {
|
||||
|
|
|
@ -85,7 +85,8 @@
|
|||
"filter": {
|
||||
"sameAs": "charging_station_ebike"
|
||||
},
|
||||
"minzoom": 18
|
||||
"minzoom": 18,
|
||||
"=presets": []
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -261,7 +261,8 @@
|
|||
"en": "What is the sub-unit for this address? <div class='subtle'>Some named building or large complexes are split into sub-units (e.g. \"1\", \"Flat 2\", \"Unit C\")</div>"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "addr:unit"
|
||||
"key": "addr:unit",
|
||||
"addExtraTags": ["not:addr:unit="]
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -390,7 +391,8 @@
|
|||
"freeform": {
|
||||
"key": "addr:substreet",
|
||||
"addExtraTags": [
|
||||
"addr:street="
|
||||
"addr:street=",
|
||||
"not:addr:substreet="
|
||||
]
|
||||
},
|
||||
"mappings": [
|
||||
|
@ -469,7 +471,8 @@
|
|||
"en": "What is the parent street name for this address?<div class='subtle'>This street name will appear after the place name or first street name in the address</div>"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "addr:parentstreet"
|
||||
"key": "addr:parentstreet",
|
||||
"addExtraTags": ["not:addr:parentstreet="]
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
|
|
@ -281,13 +281,13 @@
|
|||
"isDeleted": "Gelöscht",
|
||||
"nearbyPictures": {
|
||||
"allFiltered": "Keine Bilder passen zu Ihrem Filter",
|
||||
"browseNearby": "Bilder in der Nähe durchsuchen...",
|
||||
"browseNearby": "Bilder in der Nähe durchsuchen…",
|
||||
"confirm": "Das ausgewählte Bild zeigt {title()}",
|
||||
"hasMatchingPicture": "Passt ein Bild zum Objekt? Wählen Sie es unten aus",
|
||||
"loadMore": "Weitere Bilder laden",
|
||||
"loading": "Bilder in der Nähe laden...",
|
||||
"loading": "Bilder in der Nähe laden…",
|
||||
"noImageSelected": "Wählen Sie ein Bild aus, um es mit dem Objekt zu verknüpfen",
|
||||
"nothingFound": "Keine Bilder in der Nähe gefunden...",
|
||||
"nothingFound": "Keine Bilder in der Nähe gefunden…",
|
||||
"onlyTowards": "Nur Bilder anzeigen, die in Richtung dieses Objekts aufgenommen wurden",
|
||||
"removeFilters": "Hier klicken, um die Filter zu entfernen",
|
||||
"title": "Bilder in der Nähe",
|
||||
|
@ -449,18 +449,43 @@
|
|||
},
|
||||
"matrixbot": {
|
||||
"commandFailed": "Es tut uns leid, beim Ausführen von <code>{cmd}</code> ist etwas schiefgegangen",
|
||||
"commandNotFound": "Ihre Anfrage wurde nicht verstanden. Meinten Sie vielleicht {0}, {1}, {2} oder ${2}? <p>Geben Sie <code>help</code> ein, um eine Übersicht über alle Befehle zu sehen</p>",
|
||||
"commandNotFound": "Ihre Anfrage wurde nicht verstanden. Meinten Sie vielleicht {0}, {1}, {2} oder {2}? <p>Geben Sie <code>help</code> ein, um eine Übersicht über alle Befehle zu sehen</p>",
|
||||
"commands": {
|
||||
"documentation": {
|
||||
"didYouMean": " Vielleicht meinten Sie einen von: ",
|
||||
"docs": "Ruft die Dokumentation zu einer MapComplete-Ebene, einem Thema oder einem URL-Parameter ab",
|
||||
"notFound": "Kein {singular} mit Namen <code>{id}</code> gefunden.",
|
||||
"urlParam": "URL-Parameter <code>{id}<code></code></code>"
|
||||
},
|
||||
"dream": {
|
||||
"docs": "Sendet einen computergenerierten Text",
|
||||
"generatedBy": "Dieser Text wurde von {bot} erstellt, einem auf maschinellem Lernen basierenden Bot, der auf Reddit aktiv ist."
|
||||
},
|
||||
"help": {
|
||||
"argcmd": "Der Befehl, über den Sie mehr Informationen wünschen",
|
||||
"askRights": "Bitten Sie {admins}, Ihnen ausreichende Berechtigungen zu erteilen",
|
||||
"docs": "Druckt Informationen über unterstützte Befehle",
|
||||
"docs": "Gibt Informationen über unterstützte Befehle aus",
|
||||
"insufficientRights": "Sie haben derzeit nicht genügend Berechtigungen, um diesen Befehl auszuführen.",
|
||||
"notFound": "Ich habe <code>{cmd}</code> nicht gefunden. Vielleicht meinten Sie einen von {closest}?",
|
||||
"p0": "Hallo! Ich bin MapComplete-bot {bot_version} (basierend auf MapComplete {mc_version}).",
|
||||
"p1": "Senden Sie mir einen Befehl und ich antworte mit etwas Nützlichem: Geben Sie mir einen Befehl über eine private Nachricht oder setzen Sie <code>!</code> vor dem Befehl in einem öffentlichen Raum.",
|
||||
"priviligedComand": "Privilegierter Befehl",
|
||||
"supported": "Meine unterstützten Befehle sind:"
|
||||
},
|
||||
"info": {
|
||||
"closed": "Geschlossen",
|
||||
"closedTodayAndTomorrow": "Heute und morgen geschlossen",
|
||||
"couldNotDownload": "<code>{id}</code> konnte nicht heruntergeladen werden",
|
||||
"editWith": "Dieses Element mit {title} bearbeiten",
|
||||
"fetchingInfoAbout": "Daten über {id} abrufen…",
|
||||
"foundResults": "{total} Ergebnisse gefunden für <code>{search}</code>, rufe Details ab…",
|
||||
"noEditPossible": "Keine MapComplete-Themen unterstützen dieses Element",
|
||||
"noInfo": "Noch keine relevanten Informationen",
|
||||
"noOpeningHours": "Es sind keine Öffnungszeiten bekannt.",
|
||||
"nothingFound": "Nichts gefunden für <code>{_}</code>",
|
||||
"searchingWorldwide": "Durchsuche OpenStreetMap.org nach Ihrer Suche <code>{_}</code>",
|
||||
"provideSearch": "Bitte geben Sie einen Suchbegriff der id an, um diesen Befehl zu verwenden"
|
||||
},
|
||||
"language": {
|
||||
"arglang": "Die von nun an zu verwendende Sprache",
|
||||
"currentLanguage": "Die Sprache im aktuellen Raum ist {language}",
|
||||
|
@ -470,12 +495,50 @@
|
|||
"knownLanguages": "Sie können eine der folgenden Sprachen wählen:",
|
||||
"notFound": "Die Sprache {language} wurde nicht gefunden"
|
||||
},
|
||||
"role": {
|
||||
"allRevoked": "Alle Rechte von <b>{user}</b> wurden widerrufen",
|
||||
"allRolesIntro": "Alle Benutzer, die Rechte haben, sind:",
|
||||
"argrole": "Welche Rolle hinzugefügt werden soll; muss ein Befehlsname sein",
|
||||
"arguser": "Für wen die Rolle geändert werden soll. Wird standardmäßig auf denjenigen übertragen, der nach einigen Befehlen fragt",
|
||||
"argverb": "<code>add</code> oder <code>remove</code> verwenden, um eine Rolle von einem Benutzer hinzuzufügen oder zu entfernen. <code>list</code> verwenden, um alle Rollen eines Benutzers anzuzeigen",
|
||||
"docs": "Ändern, was ein Benutzer tun oder nicht tun darf",
|
||||
"noPreviousRoles": "<b>{user}</b> hatte keine vorherigen Rollen",
|
||||
"noRightsNeeded": "Der Befehl <code>{role}</code> kann von jedem ausgeführt werden, Sie müssen keine Rechte dafür festlegen",
|
||||
"noRolesYet": "<b>{user}</b> hat derzeit keine Rollen.",
|
||||
"noSuchRole": "Die Rolle <code>{role}</code> kann nicht an <code>{user}</code> vergeben werden. Eine Rolle ist dasselbe wie ein Befehlsname, geben Sie <code>help</code> ein, um alle Befehle zu sehen.",
|
||||
"userHasRoles": "<b>{user}</b> hat derzeit die folgenden Rollen:"
|
||||
},
|
||||
"shutdown": {
|
||||
"argmode": "Gibt an, ob der Dienst neu gestartet werden soll, muss einer der folgenden Werte sein: {verbs}",
|
||||
"docs": "Schaltet den Bot ab",
|
||||
"goodbye": "Ich schließe… Bis später!",
|
||||
"notYetShuttingDown": "Ich starte noch nicht neu, da ich erst vor {uptime} Sekunden gebootet habe. Ich werde mindestens {min_uptime} warten, bevor ich neu starte."
|
||||
},
|
||||
"welcome": {
|
||||
"p0": "Hallo! Ich bin MapComplete-bot. Ich bin ein Computerprogramm, das OpenStreetMap durchsucht und einige Informationen über <a href=\"https://mapcomplete.osm.be\">MapComplete</a> geben kann, eine Webseite und App, die thematische Karten zeigt. Wenn Informationen fehlen, können Sie sie dort leicht hinzufügen.",
|
||||
"p1": "Senden Sie mir <code>info [searchterm]</code> und ich werde OpenStreetMap für Sie durchsuchen. Ich zeige Ihnen dann die Informationen über das, was ich gefunden habe.",
|
||||
"p2": "Alternativ können auch <code>search [ojecttype] near [placename]</code> oder <code>search [objecttype] in [placename]</code> verwendet werden, um nach weiteren Orten zu suchen. Unterstützte Objekttypen sind diejenigen, die in MapComplete gefunden werden können. Weitere Kategorien werden in Zukunft hinzugefügt - und wenn Sie der Herausforderung gewachsen sind, <a href=\"https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Making_Your_Own_Theme.md\">können Sie Ihre thematische Karte und damit auch eine Kategorie erstellen</a>",
|
||||
"p3": "Es gibt noch einige weitere Befehle, senden Sie <code>help</code>, um sie alle zu sehen."
|
||||
},
|
||||
"wiki": {
|
||||
"docs": "Gibt (einen Teil) der angegebenen Seite von {backend} aus. In öffentlichen Räumen wird der erste Absatz angezeigt; in einer Direktnachricht wird die gesamte Seite gesendet."
|
||||
},
|
||||
"dm": {
|
||||
"failed": "Ich konnte <code>{cmd}</code> aufgrund von {message} nicht ausführen",
|
||||
"sendReason": "Ich habe Ihnen diese Nachricht geschickt, weil <b>{sender}</b> mich gebeten hat, diese mit <code>{cmd}</code> zu senden"
|
||||
},
|
||||
"tags": {
|
||||
"announceSearch": "<code>{id}</code> scheint keine gültige OSM-id zu sein - suche stattdessen weltweit nach {search}…"
|
||||
},
|
||||
"search": {
|
||||
"searching": "Suche {layerTitle} {mode} <code>{search}</code>…"
|
||||
}
|
||||
}
|
||||
},
|
||||
"decryptionFailed": "Es tut mir leid, ich konnte die Nachricht nicht entschlüsseln. Sie können versuchen, diesen Kanal zu verlassen und sich erneut zu verbinden",
|
||||
"noSufficientRights": "Dieser Befehl ist nur für Administratoren oder Benutzer mit dieser Rolle verfügbar",
|
||||
"subcommanNotFound": "Ich habe die Anfrage nicht verstanden. Dieser Befehl braucht ein Verb, um ausgeführt zu werden, aber <code>{verb}</code> ist kein Verb, das ich kenne. Ich kenne aber die Verben {known_verbs}",
|
||||
"subcommandNotGiven": "Ich habe die Anfrage nicht verstanden. Dieser Befehl braucht ein Verb, um ausgeführt zu werden, aber Sie haben keins angegeben. Versuchen Sie eines der {known_verbs}",
|
||||
"tooLongForPublic": "Leider ist diese Nachricht zu lang für einen öffentlichen Raum - senden Sie mir stattdessen eine Direktnachricht"
|
||||
},
|
||||
"move": {
|
||||
"cancel": "Verschieben abbrechen",
|
||||
|
|
124
langs/en.json
124
langs/en.json
|
@ -56,6 +56,7 @@
|
|||
"importTags": "The element will receive {tags}",
|
||||
"officialThemesOnly": "The import button is disabled for unofficial themes to prevent accidents",
|
||||
"wrongType": "This element is not a point or a way and can not be imported",
|
||||
"wrongTypeToConflate": "This element is not a point or a way and can not be conflated",
|
||||
"zoomInMore": "Zoom in more to import this feature"
|
||||
},
|
||||
"importTags": "The element will receive {tags}",
|
||||
|
@ -282,13 +283,13 @@
|
|||
"isDeleted": "Deleted",
|
||||
"nearbyPictures": {
|
||||
"allFiltered": "No images matched your filter",
|
||||
"browseNearby": "Browse nearby images...",
|
||||
"browseNearby": "Browse nearby images…",
|
||||
"confirm": "The selected image shows {title()}",
|
||||
"hasMatchingPicture": "Does a picture match the object? Select it below",
|
||||
"loadMore": "Load more images",
|
||||
"loading": "Loading nearby images...",
|
||||
"loading": "Loading nearby images…",
|
||||
"noImageSelected": "Select an image to link it to the object",
|
||||
"nothingFound": "No nearby images found...",
|
||||
"nothingFound": "No nearby images found…",
|
||||
"onlyTowards": "Only show pictures which are taken towards this object",
|
||||
"removeFilters": "Click here to remove the filters",
|
||||
"title": "Nearby pictures",
|
||||
|
@ -450,16 +451,53 @@
|
|||
},
|
||||
"matrixbot": {
|
||||
"commandFailed": "Sorry, something went wrong while running <code>{cmd}</code>",
|
||||
"commandNotFound": "I didn't understand your request. Did you perhaps mean to type {0}, {1}, {2} or ${2}? <p>Type <code>help</code> to see an overview of all commands</p>",
|
||||
"commandNotFound": "I didn't understand your request. Did you perhaps mean to type {0}, {1}, {2} or {2}? <p>Type <code>help</code> to see an overview of all commands</p>",
|
||||
"commands": {
|
||||
"dm": {
|
||||
"argbody": "The actual command body of the command",
|
||||
"argto": "The ID of whom to send the output to",
|
||||
"commandNotFound": "Command {key} not found - see <code>help</code> for all commands",
|
||||
"docs": "Executes a command and send the output to someone else",
|
||||
"executing": "Executing <code>{_}</code> and sending the result to <b>{to}</b>…",
|
||||
"failed": "I couldn't execute <code>{cmd}</code> due to {message}",
|
||||
"noDm": "I couldn't create a room with {to}",
|
||||
"receipt": "I delivered the message to {to}",
|
||||
"selectValidCommand": "Specify a valid command",
|
||||
"selectValidUser": "Specify a valid target user",
|
||||
"sendReason": "I sent you this message because <b>{sender}</b> requested me to send this with <code>{cmd}</code>"
|
||||
},
|
||||
"documentation": {
|
||||
"argid": "The ID of the layer, theme or URL-parameter for which documentation is needed",
|
||||
"docs": "Gets documentation about a mapcomplete layer, theme or URL-parameter",
|
||||
"noIdIntro": "Give a layer id to get information about a layer. Known layers are:",
|
||||
"noLayerFound": "No layer found with name <code>{id}</code>. Perhaps you meant one of: ",
|
||||
"noThemeFound": "No theme found with name <code>{id}</code>. Perhaps you meant one of: ",
|
||||
"noUrlParameterFound": "No URL-parameter found with name <code>{id}</code>. Perhaps you meant one of: ",
|
||||
"urlParam": "URL-parameter <code>{id}<code>"
|
||||
"argid": "The id of a {list} or {list_end} of which the docs are needed. Alternatively, write one of {coded_list} to see available ids.",
|
||||
"didYouMean": "Did you mean",
|
||||
"docs": "Gets documentation about a MapComplete layer, theme or URL-parameter",
|
||||
"file": {
|
||||
"plural": "files",
|
||||
"singular": "file"
|
||||
},
|
||||
"inputElement": {
|
||||
"plural": "input elements",
|
||||
"singular": "input element"
|
||||
},
|
||||
"layer": {
|
||||
"plural": "layers",
|
||||
"singular": "layer"
|
||||
},
|
||||
"noIdIntro": "Give an id to get more information about a MapComplete programming related item. Known types are {list}",
|
||||
"notFound": "No {singular} found with name <code>{id}</code>",
|
||||
"overview": "The following {plural} exist:",
|
||||
"theme": {
|
||||
"plural": "themes",
|
||||
"singular": "theme"
|
||||
},
|
||||
"urlParam": "URL-parameter <code>{id}<code>",
|
||||
"url_parameter": {
|
||||
"plural": "url-parameters",
|
||||
"singular": "url-parameter"
|
||||
},
|
||||
"visualisation": {
|
||||
"plural": "visualisations",
|
||||
"singular": "visualisation"
|
||||
}
|
||||
},
|
||||
"dream": {
|
||||
"docs": "Sends a computer-generated text",
|
||||
|
@ -477,18 +515,20 @@
|
|||
"supported": "My supported commands are:"
|
||||
},
|
||||
"info": {
|
||||
"argsearch": "The ID of the OSM-object or a search query",
|
||||
"closed": "Closed",
|
||||
"closedTodayAndTomorrow": "Closed today and tomorrow",
|
||||
"couldNotDownload": "Could not download <code>{id}</code>",
|
||||
"editWith": "Edit this elemen with {title}",
|
||||
"fetchingInfoAbout": "Fetching data about {id}...",
|
||||
"foundResults": "Found {total} results for <code>${search}</code>, fetching details about them...",
|
||||
"docs": "Gets info about an OSM-object. Either give an id OR a search string; the objects are interpreted and known values are shown.",
|
||||
"editWith": "Edit this element with {title}",
|
||||
"fetchingInfoAbout": "Fetching data about {id}…",
|
||||
"foundResults": "Found {total} results for <code>{search}</code>, fetching details about them…",
|
||||
"noEditPossible": "No MapComplete themes support this element",
|
||||
"noInfo": "No relevant information yet",
|
||||
"noOpeningHours": "No opening hours are known.",
|
||||
"nothingFound": "Nothing found for <code>{_}</code>",
|
||||
"provideSearch": "Please, provide a search term of id to use this command",
|
||||
"searchingWorldwide": "Searhing OpenStreetMap.org for your search <code>{_}</code>"
|
||||
"searchingWorldwide": "Searching OpenStreetMap.org for your search <code>{_}</code>"
|
||||
},
|
||||
"language": {
|
||||
"arglang": "The language to be used from now on",
|
||||
|
@ -510,22 +550,63 @@
|
|||
"noRightsNeeded": "The command <code>{role}</code> can be executed by anyone, you don't need to set rights for it",
|
||||
"noRolesYet": "<b>{user}</b> currently has no roles.",
|
||||
"noSuchRole": "The role <code>{role}</code> cannot be given to <code>{user}</code>. A role is the same as a command name, type <code>help</code> to see all commands.",
|
||||
"userHasRoles": "<b>{user}</b> currently has the following roles:"
|
||||
"userHasRoles": "<b>{user}</b> currently has the following roles:",
|
||||
"verbadd": "Adds a role to the specified user",
|
||||
"verbdefault": "List the roles of the user",
|
||||
"verblist": "List all the user roles of the specified user",
|
||||
"verbremove": "Removes a role from the specified uer",
|
||||
"verbrevoke": "Revokes all rights of a user"
|
||||
},
|
||||
"scheme": {
|
||||
"argkey": "The name of the key",
|
||||
"docs": "Gives information about a key in a theme-config-file",
|
||||
"noMatchingLayer": "No matching keys found, maybe you meant one of:",
|
||||
"notype": "no type specificied",
|
||||
"title": "{key} (used at <code>{path}</code>, {type})"
|
||||
},
|
||||
"search": {
|
||||
"announceLimited": "<p><i>I'm only showing the {cutoff} items closest to the <a href='{href}' target='_blank'>searched location</a>.</i></p>",
|
||||
"arglayerid": "The name of a layer OR a single search term",
|
||||
"argsearch": "The search term",
|
||||
"argverb": "Either search in a geographical area (e.g. a city) or search near a POI",
|
||||
"docs": "Searches for POI in or near a location",
|
||||
"noMatchingLayer": "I didn't find a matching layer",
|
||||
"noNearOrIn": "Sorry, I didn't understand your command as I didn't find a <code>near</code> or <code>in</code> in your search query.\n Try something as <code>search drinking water in London</code>, <code>search friture in Brussels</code></p>\n <p>Alternatively, try <code>info {cmd}</code> to get info about a single object.",
|
||||
"nothingFound": "Sorry, I couldn't find anything for <code>{search}</code>, so I can't search for {layerTitle}",
|
||||
"overview": "I found {length} matching items.",
|
||||
"searching": "Searching {layerTitle} {mode} <code>{search}</code>…"
|
||||
},
|
||||
"shutdown": {
|
||||
"argmode": "Indicates if the service should be restarted, must be one of {verbs}",
|
||||
"docs": "Shuts down the bot",
|
||||
"goodbye": "Shutting down... See you later!",
|
||||
"notYetShuttingDown": "I'm not restarting yet as I just booted only {uptime} seconds ago. I'll wait at least {min_uptime} before rebooting."
|
||||
"goodbye": "Shutting down… See you later!",
|
||||
"notYetShuttingDown": "I'm not restarting yet as I just booted only {uptime} seconds ago. I'll wait at least {min_uptime} before rebooting.",
|
||||
"verbshutdown": "Shuts down the bot",
|
||||
"verbupdate": "Attempts to update the embedded MapComplete-codebase, shuts down afterwards"
|
||||
},
|
||||
"tags": {
|
||||
"announceSearch": "<code>{id}</code> doesn't seem to be a valid OSM-id - searching worldwide instead for {search}…",
|
||||
"argsearch": "The ID of the OSM-object or a search query",
|
||||
"docs": "Show the tags of an OSM-object. Either give an id OR a search string; the objects are interpreted and known values are shown.",
|
||||
"noSearchGiven": "Please, provide a search term of id to use this command",
|
||||
"nothingFound": "Nothing found for {_}"
|
||||
},
|
||||
"welcome": {
|
||||
"docs": "Gives a friendly welcome message",
|
||||
"p0": "Hi! I'm MapComplete-bot. I'm a computer program which searches OpenStreetMap and which can give some information about <a href='https://mapcomplete.osm.be'>MapComplete</a>, which is a website and app that shows thematic maps. If information is missing, you can add it easily over there.",
|
||||
"p1": "Send me <code>info [searchterm]</code> and I'll search OpenStreetMap for you. I'll show you the information on what I found.",
|
||||
"p2": "Alternatively, use <code>search [ojecttype] near [placename]</code> or <code>search [objecttype] in [placename]</code> to search for more places. Supported object types are those that can be found in MapComplete. More categories will be added in the future - and if you are up to the challenge, <a href='https://github.com/pietervdvn/MapComplete/blob/develop/Docs/Making_Your_Own_Theme.md'>you can create your thematic map and thus category too</a>",
|
||||
"p3": "There are a few more commands, send <code>help</code> to see all of them."
|
||||
},
|
||||
"wiki": {
|
||||
"docs": "Prints (a part of) the specified page from wiki.osm.org. In public rooms, it'll print the first paragraph; in a DM the entire page will be sent."
|
||||
"argsearch": "The title of the page or the search term",
|
||||
"docs": "Searches and prints (a part of) the specified page from {backend}. In public rooms, it'll print the first paragraph; in a DM the entire page will be sent.",
|
||||
"foundMatching": "Found a matching wiki page, namely {title}",
|
||||
"gotResults": "Got {count} results for search query <code>{search}</code>:",
|
||||
"loadingFailed": "Sorry, the page <code>{pagename}</code> could not be loaded",
|
||||
"noWiki": "Please, specify a wiki page to search for",
|
||||
"nothingFound": "I couldn't find anything on {backend} for {search}",
|
||||
"searching": "Searching on {backend}…"
|
||||
}
|
||||
},
|
||||
"decryptionFailed": "Sorry, I couldn't decrypt your message. You can try to leave this channel and to connect again",
|
||||
|
@ -625,7 +706,7 @@
|
|||
"aboutOsm": {
|
||||
"aboutOsm": {
|
||||
"intro": "OpenStreetMap is a shared, global database, built by volunteers. All geodata can be contributed to OpenStreetMap, as long as <b>it can be verified on the ground</b>.<br/> OpenStreetMap has grown to be a very broad and deep dataset as it contains data over thousands of categories of objects.An individual object might also have a ton of attributes, bringing a lot of nuance, e.g.:",
|
||||
"li0": "Streets have geometry, but might also have information about the maxspeed, surface, wether they are lit, their name, a link to Wikipedia, a link to what they are named after, which hiking-, cycle- and busroutes run there, …",
|
||||
"li0": "Streets have geometry, but might also have information about the speed limit, surface, whether they are lit, their name, a link to Wikipedia, a link to what they are named after, which hiking-, cycle- and bus routes run there, …",
|
||||
"li1": "Shops and other amenities might have opening hours, a phone number, a link to the website, which payment methods are supported, what they sell, which services they offer, …",
|
||||
"li2": "Toilets might have information about wheelchair accessibility, a changing table, if payment is needed, …",
|
||||
"li3": "and much, much more…",
|
||||
|
@ -765,6 +846,9 @@
|
|||
"int": {
|
||||
"description": "a whole number"
|
||||
},
|
||||
"length": {
|
||||
"description": "a length measurement in meter"
|
||||
},
|
||||
"nat": {
|
||||
"description": "a positive, whole number or zero",
|
||||
"mustBePositive": "This number should be positive",
|
||||
|
|
|
@ -1106,6 +1106,9 @@
|
|||
},
|
||||
"5": {
|
||||
"then": "Fahrradwerkstatt/geschäft <i>{name}</i>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Geschäfte"
|
||||
}
|
||||
},
|
||||
"render": "Fahrradwerkstatt/geschäft"
|
||||
|
@ -3723,10 +3726,10 @@
|
|||
"friture-oil": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Pflanzliches Fett"
|
||||
"then": "Es wird pflanzliches Fett zum Frittieren verwendet"
|
||||
},
|
||||
"1": {
|
||||
"then": "Tierisches Fett"
|
||||
"then": "Es wird tierisches Fett zum Frittieren verwendet"
|
||||
}
|
||||
},
|
||||
"question": "Wird in dieser Pommesbude pflanzliches oder tierisches Fett zum Frittieren verwendet?"
|
||||
|
|
|
@ -3687,7 +3687,7 @@
|
|||
"then": "Take-away is not possible here"
|
||||
}
|
||||
},
|
||||
"question": "Does this place offer takea-way?"
|
||||
"question": "Does this place offer take-away?"
|
||||
},
|
||||
"Vegan (no friture)": {
|
||||
"mappings": {
|
||||
|
@ -3726,13 +3726,13 @@
|
|||
"friture-oil": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Vegetable oil"
|
||||
"then": "The frying is done with vegetable oil"
|
||||
},
|
||||
"1": {
|
||||
"then": "Animal oil"
|
||||
"then": "The frying is done with animal oil"
|
||||
}
|
||||
},
|
||||
"question": "Does this fries shop use vegetable or animal cooking?"
|
||||
"question": "Does this fries shop use vegetable or animal oil for cooking?"
|
||||
},
|
||||
"friture-take-your-container": {
|
||||
"mappings": {
|
||||
|
|
1399
langs/layers/es.json
1399
langs/layers/es.json
File diff suppressed because it is too large
Load diff
|
@ -435,7 +435,72 @@
|
|||
"presets": {
|
||||
"0": {
|
||||
"description": "Un magasin qui priorise la location de vélos",
|
||||
"title": "une magasin de location de vélos"
|
||||
"title": "un magasin de location de vélos"
|
||||
},
|
||||
"1": {
|
||||
"title": "une location de vélos"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"bicycle-types": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Des vélos de ville peuvent être loués ici"
|
||||
},
|
||||
"1": {
|
||||
"then": "Des vélos électriques peuvent être loués ici"
|
||||
},
|
||||
"2": {
|
||||
"then": "Des BMX peuvent être loués ici"
|
||||
},
|
||||
"3": {
|
||||
"then": "Des vélos de montagne peuvent être loués ici"
|
||||
},
|
||||
"7": {
|
||||
"then": "Des casques de vélos peuvent être loués ici"
|
||||
},
|
||||
"4": {
|
||||
"then": "Des vélos d'enfants peuvent être loués ici"
|
||||
},
|
||||
"5": {
|
||||
"then": "Des tandems peuvent être loués ici"
|
||||
},
|
||||
"6": {
|
||||
"then": "Des vélos de course peuvent être loués ici"
|
||||
}
|
||||
},
|
||||
"question": "Quels types de vélos et d’accessoires peuvent être loués ici ?",
|
||||
"render": "{rental} est louable ici"
|
||||
},
|
||||
"9": {
|
||||
"rewrite": {
|
||||
"into": {
|
||||
"3": {
|
||||
"1": "BMX"
|
||||
},
|
||||
"4": {
|
||||
"1": "vélos de montagne"
|
||||
},
|
||||
"0": {
|
||||
"1": "vélos de ville"
|
||||
},
|
||||
"1": {
|
||||
"1": "vélos électriques"
|
||||
},
|
||||
"2": {
|
||||
"1": "vélos d'enfants"
|
||||
},
|
||||
"6": {
|
||||
"1": "tandem"
|
||||
}
|
||||
}
|
||||
},
|
||||
"renderings": {
|
||||
"0": {
|
||||
"render": "{capacity:bicycle_type} type_plural peuvent être loués ici",
|
||||
"question": "Combien de type_plural peuvent être loués ici ?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -2726,5 +2791,36 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"etymology": {
|
||||
"tagRenderings": {
|
||||
"etymology_multi_apply": {
|
||||
"render": "{multi_apply(_same_name_ids, name:etymology:wikidata;name:etymology, Appliquer automatiquement aux segments avec le même nom, true)}"
|
||||
},
|
||||
"simple etymology": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "L'origine de ce nom est inconnu"
|
||||
}
|
||||
},
|
||||
"question": "En référence à quoi cet objet est-il nommé ?<br/><span class='subtle'>Cela peut être indiqué sur le panneau de la rue</span>",
|
||||
"render": "Nommé en référence à {name:etymology}"
|
||||
},
|
||||
"wikipedia-etymology": {
|
||||
"render": "<h3>Article Wikipedia de la référence au nom</h3>{wikipedia(name:etymology:wikidata):max-height:20rem}",
|
||||
"question": "Quel est l'Item Wikidata auquel l'objet fait référence ?"
|
||||
},
|
||||
"zoeken op inventaris onroerend erfgoed": {
|
||||
"render": "<a href='https://inventaris.onroerenderfgoed.be/erfgoedobjecten?tekst={name}' target='_blank'>Chercher sur inventaris onroerend erfgoed</a>"
|
||||
},
|
||||
"wikipedia": {
|
||||
"render": "Un article Wikipédia à propos de cette <b>rue</b> existe :<br/>{wikipedia():max-height:25rem}"
|
||||
},
|
||||
"street-name-sign-image": {
|
||||
"render": "{image_carousel(image:streetsign)}<br/>{image_upload(image:streetsign, Ajouter une photo de la plaque de rue)}"
|
||||
}
|
||||
},
|
||||
"description": "Tous les objets dont le nom ont une étymologie connue",
|
||||
"name": "A une étymologie"
|
||||
}
|
||||
}
|
|
@ -74,7 +74,7 @@
|
|||
}
|
||||
},
|
||||
"artwork": {
|
||||
"description": "Verschillende soorten kunstwerken",
|
||||
"description": "Een vrije kaart met standbeelden, bustes, graffiti en andere kunstwerken van over de hele wereld",
|
||||
"name": "Kunstwerken",
|
||||
"presets": {
|
||||
"0": {
|
||||
|
@ -4753,6 +4753,20 @@
|
|||
"question": "Toon enkel winkels met naam {search}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Accepteert cash"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Accepteert betaalkaarten"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Winkel",
|
||||
|
|
|
@ -449,27 +449,81 @@
|
|||
},
|
||||
"matrixbot": {
|
||||
"commandFailed": "Sorry, er ging iets mis toen ik probeerde om <code>{cmd}</code> uit te voeren.",
|
||||
"commandNotFound": "Sorry, ik heb je commando niet verstaan. Zou het kunnen dat je {0}, {1}, {2} of ${2} bedoelt? <p>Je kan ook <code>help</code> sturen om een overzicht van alle commando's te zien</p>",
|
||||
"commandNotFound": "Sorry, ik heb je commando niet verstaan. Zou het kunnen dat je {0}, {1}, {2} of {2} bedoelt? <p>Je kan ook <code>help</code> sturen om een overzicht van alle commando's te zien</p>",
|
||||
"commands": {
|
||||
"dm": {
|
||||
"failed": "I kon <code>{cmd}</code> niet uitvoeren doordag {message}",
|
||||
"sendReason": "Ik stuurde jou dit bericht omdat <b>{sender}</b> mij gevraagd heeft om je het resultaat van <code>{cmd}</code> te sturen"
|
||||
},
|
||||
"documentation": {
|
||||
"didYouMean": "Bedoelde je misschien één van onderstaande URL-parameters? ",
|
||||
"docs": "Vraag documentatie over een MapComplete-laag, -thema of URL-parameter",
|
||||
"notFound": "Ik kong geen {singular} vinden met naam <code>{id}</code>.",
|
||||
"urlParam": "URL-parameter <code>{id}</code>"
|
||||
},
|
||||
"dream": {
|
||||
"docs": "Stuurt een dromerige, computer-gegenereerde tekst",
|
||||
"generatedBy": "Deze text is gemaakt door {bot} die Machine-Learning gebruikt om op Reddit te posten."
|
||||
},
|
||||
"help": {
|
||||
"argcmd": "The command you want more information about",
|
||||
"argcmd": "Het commando waarvoor je meer informatie wilt",
|
||||
"askRights": "Vraag aan {admins} om je toegang te geven",
|
||||
"docs": "Prints info about supported commands",
|
||||
"docs": "Geeft informatie over de gekende commando's",
|
||||
"insufficientRights": "Je hebt geen toegang tot dit commando.",
|
||||
"notFound": "Ik kon het commando <code>{cmd}</code> niet vinden. Bedoelde je misschien {closest}?",
|
||||
"p0": "Hallo! Ik ben MapComplete-bot {bot_version} (gebouwd met MapComplete {mc_version}).",
|
||||
"p1": "Je kan me een commando sturen en dan zal ik dat commando opvolgen. Dit kan door me een privé-bericht te sturen. In een publieke ruimte zal ik antwoorden als een bericht begint met <code>!</code> of een mention.",
|
||||
"priviligedComand": "Commando waar je rechten voor nodig hebt",
|
||||
"supported": "De commando's die ik ken zijn:"
|
||||
},
|
||||
"info": {
|
||||
"closed": "Gesloten",
|
||||
"closedTodayAndTomorrow": "Vandaag en morgen gesloten",
|
||||
"couldNotDownload": "Ik kon <code>{id}</code> niet downloaden",
|
||||
"editWith": "Bewerk dit element op {title}",
|
||||
"fetchingInfoAbout": "Data over {id} aan het ophalen...",
|
||||
"foundResults": "Ik vond {total} resultaten voor <code>{search}</code>, ik ben informatie erover aan het ophalen...",
|
||||
"noEditPossible": "Geen enkel MapComplete-thema bevat dit soort objecten...",
|
||||
"noInfo": "Nog geen relevante informatie",
|
||||
"noOpeningHours": "Geen openingsuren gekend",
|
||||
"nothingFound": "Ik kon niets vinden voor <code>{_}</code>",
|
||||
"provideSearch": "Gelieve een zoekterm of id te geven",
|
||||
"searchingWorldwide": "OpenStreetMap aan het doorzoeken voor <code>{_}</code>"
|
||||
},
|
||||
"language": {
|
||||
"arglang": "De taal die ik vanaf nu in deze ruimte ga spreken",
|
||||
"currentLanguage": "Momenteel praat ik {language} in deze ruimte",
|
||||
"docs": "Stelt in welke taal ik in deze ruimte spreek",
|
||||
"hasBeenSet": "De taal is ingesteld op <b>{language}</b>.",
|
||||
"helpTranslating": "Help mee met het vertalen van mijn teksten om Weblate.",
|
||||
"helpTranslating": "Help mee met het vertalen van mijn teksten op Weblate.",
|
||||
"knownLanguages": "Je kan een van de volgende talen kiezen:",
|
||||
"notFound": "De taal {language} heb ik niet gevonden"
|
||||
},
|
||||
"role": {
|
||||
"allRevoked": "Alle rechten van <b>{user}</b> werden ingetrokken",
|
||||
"allRolesIntro": "Alle gebruikers met rechten zijn:",
|
||||
"argrole": "Welke rechten de persoon krijgt, dit is de naam van het commando die deze gebruiker mag uitvoeren",
|
||||
"arguser": "De gebruikersnaam van wie de rechten verandert moeten worden.",
|
||||
"argverb": "Ofdat een rol toegevoegd (<code>add</code>) of verwijderd (<code>remove</code>) moet worden. Gebruik <code>list</code> om een oplijsting te krijgen van alle rollen van de gebruiker",
|
||||
"docs": "Verander wat een gebruiker mag uitvoeren",
|
||||
"noPreviousRoles": "<b>{user}</b> heeft geen rollen",
|
||||
"noRightsNeeded": "Het comand <code>{role}</code> mag door iedereen uitgevoerd worden, je hoeft die rechten niet toe te kennen",
|
||||
"noRolesYet": "<b>{user}</b> heeft op dit moment geen rechten.",
|
||||
"noSuchRole": "De rechten voor <code>{role}</code> kunnen niet gegeven worden aan <code>{user}</code>. Geef de commandonaam waarvoor je de rechten wilt toekennen. (Typ <code>help</code> voor een overzicht van alle commando's).",
|
||||
"userHasRoles": "<b>{user}</b> heeft op dit moment de volgende rechten:"
|
||||
},
|
||||
"search": {
|
||||
"searching": "Aan het zoeken naar {layerTitle} {mode} <code>{search}</code>..."
|
||||
},
|
||||
"shutdown": {
|
||||
"argmode": "Geeft aan op welke manier ik moet afsluiten. Dit moet één van de volgende woorden zijn: {verbs}",
|
||||
"docs": "Sluit de robot af",
|
||||
"goodbye": "Aan het afsluiten… Tot later!",
|
||||
"notYetShuttingDown": "Ik ga nog niet afsluiten want ik ben nog maar net opgestart. Ik wacht minimaal {min_uptime} seconden voordat ik terug afsluit, momenteel ben ik nog maar {uptime} aan het lopen."
|
||||
},
|
||||
"tags": {
|
||||
"announceSearch": "<code>{id}</code> is geen OpenStreetMap-ID - ik ben wereldwijd aan het zoeken naar {search}..."
|
||||
},
|
||||
"welcome": {
|
||||
"p0": "Hallo! Ik ben MapComplete-bot. Ik ben een computer-programma die voor jou OpenStreetMap doorzoekt en die documentatie geeft van <a href=\"https://mapcomplete.osm.be\">MapComplete</a>, een website die themakaarten toont waar je ook eenvoudig zelf data aan kan toevoegen.",
|
||||
"p1": "Stuur me <code>info [zoekterm]</code> en ik ga OpenStreetMap voor je doorzoeken en het resultaat aan je tonen.",
|
||||
|
@ -477,12 +531,14 @@
|
|||
"p3": "Er zijn nog meer commando's, stuur me <code>help</code> om ze allemaal te zien."
|
||||
},
|
||||
"wiki": {
|
||||
"docs": "Stuurt een (deel van) de gevraagde pagina van wiki.osm.org. In een publieke ruimte stuur ik enkel de eerste paragraaf, in een privaat bericht krijg je de volledige pagina."
|
||||
"docs": "Stuurt een (deel van) de gevraagde pagina van {backend}. In een publieke ruimte stuur ik enkel de eerste paragraaf, in een privaat bericht krijg je de volledige pagina."
|
||||
}
|
||||
},
|
||||
"decryptionFailed": "Sorry, I couldn't decrypt your message. You can try to leave this channel and to connect again",
|
||||
"noSufficientRights": "This command is only available to administrators or users who have this role",
|
||||
"tooLongForPublic": "Sorry, this message is too long for a public room - send me a direct message instead"
|
||||
"decryptionFailed": "Sorry, ik kon je bericht niet ontcijferen. Probeer om deze kamer te verlaten en opnieuw te connecteren",
|
||||
"noSufficientRights": "Dit commando is enkel beschikbaar voor administrators en wie rechten heeft gekregen",
|
||||
"subcommanNotFound": "Sorry, ik heb je vraag niet verstaan. Dit commando heeft een extra werkwoord nodig, maar <code>{verb}</code> is geen werkwoord dat ik ken. Ik ken wel de volgende werkwoorden: {known_verbs}",
|
||||
"subcommandNotGiven": "Ik heb je commando niet verstaan. Dit commando heeft een extra werkwoord nodig, maar je hebt er geen geven. Voeg één van {known_verbs} toe",
|
||||
"tooLongForPublic": "Sorry, dit bericht is te lang voor een publieke ruimte - stuur me een privébericht"
|
||||
},
|
||||
"move": {
|
||||
"cancel": "Annuleer verplaatsing",
|
||||
|
|
|
@ -612,6 +612,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Metatags noch nicht berechnet... Dieses Fenster erneut öffnen"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Gebäude hat Löcher und ist als Relation modelliert. Als solches kann es nicht zusammengeführt werden. Es kann manuell zusammengeführt werden über die <a href='https://buildings.osm.be/#/'>Gebäudeexportseite</a> {open_in_josm()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -612,6 +612,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Did not yet calculate the metatags... Reopen this popup"
|
||||
},
|
||||
"1": {
|
||||
"then": "This building has holes and is modeled as a relation. As such, it cannot be conflated. Conflate it manually via <a href='https://buildings.osm.be/#/'>the building export site</a> {open_in_josm()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"title": "Mapa abierto de desfibriladores (DEA)"
|
||||
},
|
||||
"artwork": {
|
||||
"description": "Bienvenido a Open Artwork Map, un mapa de estatuas, bustos, grafitis y otras obras de arte de todo el mundo"
|
||||
"description": "Un mapa abierto de estatus, bustos, grafitis y otras obras de arte en todo el mundo"
|
||||
},
|
||||
"benches": {
|
||||
"description": "Este mapa muestra todos los bancos que están grabados en OpenStreetMap: Bancos individuales, bancos que pertenecen a paradas o marquesinas del transporte público. Con una cuenta de OpenStreetMap, puedes mapear nuevos bancos o editar detalles de bancos existentes.",
|
||||
|
@ -127,12 +127,61 @@
|
|||
"1": {
|
||||
"then": "Este lugar no tiene sanitarios"
|
||||
}
|
||||
},
|
||||
"question": "¿Este lugar tiene baños?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"render": "Sitio web oficial: <a href='{website}'>{website}</a>",
|
||||
"question": "¿Este lugar tiene un sitio web?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"tagRenderings": {
|
||||
"dumpstations-fee": {
|
||||
"mappings": {
|
||||
"1": {
|
||||
"then": "Se puede utilizar gratis"
|
||||
},
|
||||
"0": {
|
||||
"then": "Tienes que pagar por el uso"
|
||||
}
|
||||
},
|
||||
"question": "¿Este lugar cobra una tasa?"
|
||||
},
|
||||
"dumpstations-charge": {
|
||||
"question": "¿Cuánto cobra este lugar?",
|
||||
"render": "Este lugar cobra {charge}"
|
||||
},
|
||||
"dumpstations-network": {
|
||||
"question": "¿A qué red forma parte este lugar? (saltar si a ninguna)",
|
||||
"render": "Esta estación forma parte de la red {network}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"overrideAll": {
|
||||
"tagRenderings+": {
|
||||
"1": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este lugar tiene suministro eléctrico"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este lugar no tiene suministro eléctrico"
|
||||
}
|
||||
},
|
||||
"question": "¿Tiene suministro eléctrico este lugar?"
|
||||
},
|
||||
"0": {
|
||||
"render": "Este lugar lo opera {operator}",
|
||||
"question": "¿Quién opera este lugar?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "Encuentra sitios para pasar la noche con tu caravana",
|
||||
"title": "Campings"
|
||||
},
|
||||
"cycle_infra": {
|
||||
"description": "Un mapa en el que puedes ver y editar cosas relacionadas con la infraestructura ciclista. Hecho durante #osoc21.",
|
||||
"shortDescription": "Un mapa en el que puedes ver y editar cosas relacionadas con la infraestructura ciclista.",
|
||||
|
@ -162,7 +211,8 @@
|
|||
"name": "nodos",
|
||||
"tagRenderings": {
|
||||
"node-expected_rcn_route_relations": {
|
||||
"question": "¿A cuántos otros nodos ciclistas enlaza este nodo?"
|
||||
"question": "¿A cuántos otros nodos ciclistas enlaza este nodo?",
|
||||
"render": "Este nodo enlaza a {expected_rcn_route_relations} otros nodos ciclistas."
|
||||
},
|
||||
"node-survey:date": {
|
||||
"question": "¿Cuándo fue sondeado este nodo ciclista por última vez?",
|
||||
|
@ -228,7 +278,8 @@
|
|||
}
|
||||
},
|
||||
"shortDescription": "Un mapa de ciclocalles",
|
||||
"title": "Ciclocalles"
|
||||
"title": "Ciclocalles",
|
||||
"description": "Una ciclocalle es una calle donde <b>el tráfico motorizado no puede adelantar a ciclistas</b>. Están señalizadas por una señal de tráfico especial. Las ciclocalles se pueden encontrar en los Países Bajos y Bélgica, pero también en Alemania y Francia. "
|
||||
},
|
||||
"cyclofix": {
|
||||
"description": "El objetivo de este mapa es presentar a los ciclistas con una solución fácil de utilizar para encontrar la infraestructura apropiada para sus necesidades. <br><br>Puedes seguir tu localización precisa (móvil solo) y seleccionar las capas que son relevantes para ti en la esquina inferior izquierda. Tgambién puedes utilizar esta herramienta para editar o añadir pines (puntos de interés) al mapa y proveer más datos respondiendo a preguntas.<br><br>Todos los cambios que hagas se guardarán de manera automática en la base de datos global de OpenStreetMap y podrán ser utilizados libremente por otros. <br><br>Para más información sobre el proyecto cyclofix, ve a <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a>.",
|
||||
|
@ -244,7 +295,39 @@
|
|||
"title": "Entradas"
|
||||
},
|
||||
"etymology": {
|
||||
"shortDescription": "¿Cual es el origen de un topónimo?"
|
||||
"shortDescription": "¿Cual es el origen de un topónimo?",
|
||||
"layers": {
|
||||
"1": {
|
||||
"override": {
|
||||
"=name": "Calles sin información etimológica"
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"override": {
|
||||
"=name": "Parques y bosques sin información etimológica"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"override": {
|
||||
"=name": "Instituciones educacionales sin información etimológica"
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"override": {
|
||||
"=name": "Lugares deportivos sin información etimológica"
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"override": {
|
||||
"=name": "Lugares turísticos sin información etimológica"
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"override": {
|
||||
"=name": "Lugares culturales sin información etimológica"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"facadegardens": {
|
||||
"layers": {
|
||||
|
@ -270,10 +353,15 @@
|
|||
"question": "¿Hay alguna planta comestible?"
|
||||
},
|
||||
"facadegardens-plants": {
|
||||
"question": "¿Qué tipo de plantas crecen aquí?"
|
||||
"question": "¿Qué tipo de plantas crecen aquí?",
|
||||
"mappings": {
|
||||
"2": {
|
||||
"then": "Hay arbustos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"facadegardens-start_date": {
|
||||
"question": "¿Cuándo se construyó el jardín? (un año es suficiente)",
|
||||
"question": "¿Cuándo se construyó el jardín? (el año es suficiente)",
|
||||
"render": "Fecha de construcción del jardín: {start_date}"
|
||||
},
|
||||
"facadegardens-sunshine": {
|
||||
|
@ -290,10 +378,23 @@
|
|||
},
|
||||
"question": "¿El jardín está al sol o a la sombra?"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Jardín de fachada"
|
||||
},
|
||||
"description": "Jardines de fachada",
|
||||
"name": "Jardines de fachada",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "Añadir un jardín de fachada",
|
||||
"title": "un jardín de fachada"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Jardines de fachada",
|
||||
"shortDescription": "Este mapa muestra jardines de fachada con fotografías e información útil sobre la orientación, la luz del sol y los tipos de plantas."
|
||||
},
|
||||
"food": {
|
||||
"description": "Restaurantes y comida rápida",
|
||||
"title": "Restaurantes y comida rápida"
|
||||
|
@ -313,9 +414,9 @@
|
|||
}
|
||||
},
|
||||
"hailhydrant": {
|
||||
"description": "",
|
||||
"shortDescription": "Mapa para mostrar hidrantes, extintores, parques de bomberos y parques de ambulancias.",
|
||||
"title": "Hidrantes, Extintores, Parques de bomberos y Parques de ambulancias"
|
||||
"description": "En este mapa puedes encontrar y actualizar bocas de incendios, parques de bomberos, parques de ambulancias y extintores en tus vecindarios favoritos.\n\nPuedes rastrear tu localización precisa (solo móvil) y seleccionar las capas que son relevantes para ti en la esquina inferior izquierda. También puedes utilizar esta herramienta para añadir o editar pines (puntos de interés) al mapa y proveer detalles adicionales contestando a preguntas disponibles.\n\nTodos los cambios que hagas se guardarán automáticamente en la base de datos global de OpenStreetMap y podrán ser reutilizados libremente por otros.",
|
||||
"shortDescription": "Mapa para mostrar bocas de incendios, extintores, parques de bomberos y parques de ambulancias.",
|
||||
"title": "Bocas de incendios, Extintores, Parques de bomberos y Parques de ambulancias"
|
||||
},
|
||||
"mapcomplete-changes": {
|
||||
"description": "Este mapa muestra todos los cambios hechos con MapComplete",
|
||||
|
@ -336,6 +437,13 @@
|
|||
"question": "<b>No</b> hecho por contributor/a {search}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Nombre del tema contiene {search}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Centros de conjuntos de cambios",
|
||||
|
@ -345,6 +453,14 @@
|
|||
},
|
||||
"render_id": {
|
||||
"render": "Conjunto de cambios <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
|
||||
},
|
||||
"theme": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Cambio con tema <b>no oficial</b> <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
|
||||
}
|
||||
},
|
||||
"render": "Cambio con tema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
|
@ -365,7 +481,7 @@
|
|||
"title": "Cambios hechos con MapComplete"
|
||||
},
|
||||
"maps": {
|
||||
"description": "En este mapa puedes encontrar todos los mapas que OpenStreetMap conoce - típicamente un mapa grande con un tablero que muestra el área, la ciudad o la región, ej. un mapa turista detrás de una vaya publicitaria, un mapa de una reserva natura, un mapa de redes ciclistas en la región, ...)<br/><br/>Si falta un mapa, puedes mapear este mapa fácilmente en OpenStreetMap.",
|
||||
"description": "En este mapa puedes encontrar todos los mapas que OpenStreetMap conoce - típicamente un mapa grande con un tablero que muestra el área, la ciudad o la región, ej. un mapa turista detrás de una vaya publicitaria, un mapa de una reserva natural, un mapa de redes ciclistas en la región, ...)<br/><br/>Si falta un mapa, puedes mapear este mapa fácilmente en OpenStreetMap.",
|
||||
"shortDescription": "Este tema muestra todos los mapas (turísticos) que OpenStreetMap conoce",
|
||||
"title": "Un mapa de mapas"
|
||||
},
|
||||
|
@ -547,5 +663,83 @@
|
|||
"description": "Mapa de todos los Árboles",
|
||||
"shortDescription": "Mapa de los Árboles",
|
||||
"title": "Árboles"
|
||||
},
|
||||
"charging_stations": {
|
||||
"description": "En este mapa, uno puede encontrar y marcar información sobre estaciones de carga",
|
||||
"title": "Estaciones de carga",
|
||||
"shortDescription": "Un mapa mundial de estaciones de carga"
|
||||
},
|
||||
"grb": {
|
||||
"layers": {
|
||||
"1": {
|
||||
"tagRenderings": {
|
||||
"building type": {
|
||||
"question": "¿Qué tipo de edificio es este?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"tagRenderings": {
|
||||
"Import-button": {
|
||||
"mappings": {
|
||||
"1": {
|
||||
"then": "Este edificio tiene agujeros y está modelado como una relación. Por lo tanto, no se puede combinar. Combínalo manualmente a través <a href='https://buildings.osm.be/#/'>el sitio de exportación de edificios</a> {open_in_josm()}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"climbing": {
|
||||
"layers": {
|
||||
"0": {
|
||||
"override": {
|
||||
"tagRenderings+": {
|
||||
"1": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Accesible públicamente a cualquiera"
|
||||
},
|
||||
"2": {
|
||||
"then": "Solo clientes"
|
||||
},
|
||||
"1": {
|
||||
"then": "Necesitas un permiso para acceder aquí"
|
||||
},
|
||||
"3": {
|
||||
"then": "Solo miembros del club"
|
||||
}
|
||||
},
|
||||
"question": "¿Quién puede acceder aquí?"
|
||||
}
|
||||
},
|
||||
"units+": {
|
||||
"0": {
|
||||
"applicableUnits": {
|
||||
"1": {
|
||||
"human": " pies"
|
||||
},
|
||||
"0": {
|
||||
"human": " metro"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cycle_highways": {
|
||||
"description": "Este mapa muestra carriles bici",
|
||||
"layers": {
|
||||
"0": {
|
||||
"name": "carriles bici",
|
||||
"title": {
|
||||
"render": "carril bici"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Carriles bici"
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
"title": "Open AED-kaart - Brugge edition"
|
||||
},
|
||||
"artwork": {
|
||||
"description": "Welkom op de open kunstwerken-kaart, een kaart met standbeelden, bustes, graffiti en andere kunstwerken van over de hele wereld",
|
||||
"description": "Een vrije kaart met standbeelden, bustes, graffiti en andere kunstwerken van over de hele wereld",
|
||||
"title": "Open kunstwerken-kaart"
|
||||
},
|
||||
"benches": {
|
||||
|
@ -600,6 +600,31 @@
|
|||
"override": {
|
||||
"=name": "Parken en bossen zonder etymologische informatie"
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"override": {
|
||||
"=name": "Culturele plaatsen zonder etymologische informatie"
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"override": {
|
||||
"=name": "Toeristische plaatsen zonder etymologische informatie"
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"override": {
|
||||
"=name": "Gezondheidsinstellingen en maatschappelijke plaatsen zonder etymologische informatie"
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"override": {
|
||||
"=name": "Sportplekken zonder etymologische informatie"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"override": {
|
||||
"=name": "Onderwijsinstelling zonder etymologische informatie"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "Wat is de oorsprong van een plaatsnaam?",
|
||||
|
@ -794,6 +819,9 @@
|
|||
},
|
||||
"grb-unit": {
|
||||
"render": "De wooneenheid-aanduiding is <b>{addr:unit}</b> "
|
||||
},
|
||||
"building type": {
|
||||
"question": "Wat voor soort gebouw is dit?"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -821,6 +849,17 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"tagRenderings": {
|
||||
"Import-button": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Metatags nog niet berekend... Heropen deze pop-up"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "Grb import helper tool",
|
||||
|
@ -859,6 +898,9 @@
|
|||
},
|
||||
"grb-unit": {
|
||||
"render": "De wooneenheid-aanduiding is <b>{addr:unit}</b> "
|
||||
},
|
||||
"building type": {
|
||||
"question": "Wat voor soort gebouw is dit?"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -867,15 +909,19 @@
|
|||
"title": "GRB Fixup"
|
||||
},
|
||||
"hackerspaces": {
|
||||
"title": "Hackerspaces"
|
||||
"title": "Hackerspaces",
|
||||
"shortDescription": "Een kaart van hackerspaces",
|
||||
"description": "Op deze kaart kan je hackerspaces zien, toevoegen en updaten"
|
||||
},
|
||||
"hailhydrant": {
|
||||
"title": "Brandkranen, brandblussers, brandweerposten en ambulanceposten"
|
||||
"title": "Brandkranen, brandblussers, brandweerposten en ambulanceposten",
|
||||
"shortDescription": "Kaart om hydranten, brandblussers, brandweerkazernes en ambulanceposten weer te geven.",
|
||||
"description": "Op deze kaart kan je hydranten, brandblussers, brandweerkazernes en stalplaatsen voor ambulances vinden en updaten.\n\nJe kan je exacte locatie bepalen (enkel via GSM) en relevante lagen selecteren in de linkeronderhoek. Je kan deze applicatie ook gebruiken om pins (points of interest) op de kaart te zetten en om extra details toe te voegen door vragen te beantwoorden.\n\nAlle wijzigingen die je maakt zullen automatisch worden opgeslagen in de globale database van OpenStreetMap en kunnen vrij door anderen gebruikt worden."
|
||||
},
|
||||
"maps": {
|
||||
"description": "Op deze kaart kan je alle kaarten zien die OpenStreetMap kent.<br/><br/>Ontbreekt er een kaart, dan kan je die kaart hier ook gemakelijk aan deze kaart toevoegen.",
|
||||
"shortDescription": "Een kaart met alle kaarten die OpenStreetMap kent",
|
||||
"title": "Een kaart met Kaarten"
|
||||
"shortDescription": "Dit thema toont alle (toeristische) kaarten die OpenStreetMap kent",
|
||||
"title": "Een kaart van kaarten"
|
||||
},
|
||||
"missing_streets": {
|
||||
"description": "Dit thema voegt automatisch straatnamen toe aan gebouwen met huisnummer en overeenkomstig CRAB-adres.",
|
||||
|
@ -885,7 +931,7 @@
|
|||
"nature": {
|
||||
"description": "Op deze kaart vind je informatie voor natuurliefhebbers, zoals info over het natuurgebied waar je inzit, vogelkijkhutten, informatieborden, ...",
|
||||
"shortDescription": "Deze kaart bevat informatie voor natuurliefhebbers",
|
||||
"title": "De Natuur in"
|
||||
"title": "De natuur in"
|
||||
},
|
||||
"notes": {
|
||||
"description": "Een kaartnota bevat tekst op een specifieke locatie om aan te duiden dat er iets mis is of ontbreekt.<br/><br/>Bekijk ook het <a href='#filters'>filtermenu</a> om de notas te filteren op tekst, gebruiker, datum, ...",
|
||||
|
@ -919,9 +965,9 @@
|
|||
},
|
||||
"2": {
|
||||
"override": {
|
||||
"name": "hondvriendelijke winkels",
|
||||
"name": "Hondvriendelijke winkels",
|
||||
"title": {
|
||||
"render": "hondvriendelijke winkels"
|
||||
"render": "Hondvriendelijke winkels"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -981,17 +1027,47 @@
|
|||
},
|
||||
"title": {
|
||||
"render": "Postkantoor"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"OH": {
|
||||
"render": "Openingsuren: {opening_hours_table()}",
|
||||
"question": "Wat zijn de openingsuren voor dit postkantoor?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "24/7 open (ook tijdens feestdagen)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Brievenbussen en postkantoren"
|
||||
"title": "Brievenbussen en postkantoren",
|
||||
"shortDescription": "Een kaart die brievenbussen en postkantoren toont",
|
||||
"description": "Op deze kaart kan je informatie over brievenbussen en postkantoren vinden en toevoegen. Je kan deze kaart gebruiken om te achterhalen waar je je volgende postkaart naar kan sturen! :)<br/>Zie je een fout of ontbreekt een brievenbus? Dan kan je deze kaart aanpassen met een gratis OpenStreetMap account. "
|
||||
},
|
||||
"shops": {
|
||||
"shortDescription": "Een bewerkbare kaart met simpele informatie over winkels",
|
||||
"title": "Winkels"
|
||||
"title": "Winkels",
|
||||
"description": "Op deze kaart kan men algemene informatie over winkels toevoegen, evenals openingsuren en telefoonnummers"
|
||||
},
|
||||
"sidewalks": {
|
||||
"title": "Voetpaden"
|
||||
"title": "Voetpaden",
|
||||
"description": "Experimenteel thema",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "Laag die voetpaden naast wegen toont",
|
||||
"name": "Voetpaden",
|
||||
"tagRenderings": {
|
||||
"streetname": {
|
||||
"render": "Deze straat heet {name}"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "{name}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shortDescription": "Voetpaden in kaart brengen"
|
||||
},
|
||||
"speelplekken": {
|
||||
"description": "<h3>Welkom bij de Groendoener!</h3>De Zuidrand dat is spelen, ravotten, chillen, wandelen,… in het groen. Meer dan <b>200 grote en kleine speelplekken</b> liggen er in parken, in bossen en op pleintjes te wachten om ontdekt te worden. De verschillende speelplekken werden getest én goedgekeurd door kinder- en jongerenreporters uit de Zuidrand. Met leuke challenges dagen de reporters jou uit om ook op ontdekking te gaan. Klik op een speelplek op de kaart, bekijk het filmpje en ga op verkenning!<br/><br/>Het project groendoener kadert binnen het strategisch project <a href='https://www.provincieantwerpen.be/aanbod/dlm/samenwerkingsverbanden/zuidrand/projecten/strategisch-project-beleefbare-open-ruimte.html' target='_blank'>Beleefbare Open Ruimte in de Antwerpse Zuidrand</a> en is een samenwerking tussen het departement Leefmilieu van provincie Antwerpen, Sportpret vzw, een OpenStreetMap-België Consultent en Createlli vzw. Het project kwam tot stand met steun van Departement Omgeving van de Vlaamse Overheid.<br/><img class='w-full md:w-1/2' src='./assets/themes/speelplekken/provincie_antwerpen.jpg'/><img class='w-full md:w-1/2' src='./assets/themes/speelplekken/Departement_Omgeving_Vlaanderen.png'/>",
|
||||
|
@ -1125,5 +1201,90 @@
|
|||
"description": "Op deze kaart vind je vuilnisbakken waar je afval in kan smijten. Ontbreekt er een vuilnisbak? Dan kan je die zelf toevoegen",
|
||||
"shortDescription": "Een kaart met vuilnisbakken",
|
||||
"title": "Vuilnisbak"
|
||||
},
|
||||
"mapcomplete-changes": {
|
||||
"shortDescription": "Toont wijzigingen gemaakt met MapComplete",
|
||||
"description": "Deze kaart toont alle wijzigingen die met MapComplete werden gemaakt",
|
||||
"layers": {
|
||||
"0": {
|
||||
"description": "Toont alle wijzigingen met MapComplete",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Themanaam bevat {search}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Gemaakt door bijdrager {search}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "<b>Niet</b> gemaakt door bijdrager {search}"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"contributor": {
|
||||
"render": "Wijziging gemaakt door <a href='https://openstreetmap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a>"
|
||||
},
|
||||
"render_id": {
|
||||
"render": "Wijzigingset <a href='https://openstreetmap.org/changeset/{id}' target='_blank'>{id}</a>"
|
||||
},
|
||||
"theme": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Wijziging met <b>officieus</b> thema <a href='https://mapcomplete.osm.be/theme.html?userlayout={theme}'>{theme}</a>"
|
||||
}
|
||||
},
|
||||
"render": "Wijziging met thema <a href='https://mapcomplete.osm.be/{theme}'>{theme}</a>"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Wijzigingset voor {theme}"
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"override": {
|
||||
"tagRenderings": {
|
||||
"link_to_more": {
|
||||
"render": "Meer statistieken kunnen <a href='https://github.com/pietervdvn/MapComplete/tree/develop/Docs/Tools/graphs' target='_blank'>hier</a> gevonden worden"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Wijzigingen gemaakt met MapComplete"
|
||||
},
|
||||
"postal_codes": {
|
||||
"shortDescription": "Postcodes",
|
||||
"title": "Postcodes",
|
||||
"description": "Postcodes",
|
||||
"layers": {
|
||||
"0": {
|
||||
"name": "postcodes",
|
||||
"title": {
|
||||
"render": "Postcode {postal_code}"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"postal_code": {
|
||||
"render": "Deze postcode is {postal_code}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"name": "stadhuizen",
|
||||
"title": {
|
||||
"render": "Stadhuis {name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
package-lock.json
generated
30
package-lock.json
generated
|
@ -26,9 +26,9 @@
|
|||
"@types/prompt-sync": "^4.1.0",
|
||||
"@types/wikidata-sdk": "^6.1.0",
|
||||
"@types/xml2js": "^0.4.9",
|
||||
"core-js": "^3.22.8",
|
||||
"country-language": "^0.1.7",
|
||||
"doctest-ts-improved": "^0.8.6",
|
||||
"csv-parse": "^5.1.0",
|
||||
"doctest-ts-improved": "^0.8.8",
|
||||
"email-validator": "^2.0.4",
|
||||
"escape-html": "^1.0.3",
|
||||
"geojson2svg": "^1.3.1",
|
||||
|
@ -4899,6 +4899,7 @@
|
|||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz",
|
||||
"integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/core-js"
|
||||
|
@ -5490,6 +5491,11 @@
|
|||
"cssom": "0.3.x"
|
||||
}
|
||||
},
|
||||
"node_modules/csv-parse": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.1.0.tgz",
|
||||
"integrity": "sha512-JL+Q6YEikT2uoe57InjFFa6VejhSv0tDwOxeQ1bVQKeUC/NCnLAAZ8n3PzowPQQLuZ37fysDYZipB2UJkH9C6A=="
|
||||
},
|
||||
"node_modules/currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
||||
|
@ -6045,9 +6051,9 @@
|
|||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
|
||||
},
|
||||
"node_modules/doctest-ts-improved": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz",
|
||||
"integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==",
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.8.tgz",
|
||||
"integrity": "sha512-aEkS6go+DBz8atfQSAUoCXc0N+nI2YKFXOhS9j/Jrxv0rG0J+6e6xDxiZq0rP6sKybRF/zHSWqC2jjR9qzx2ZA==",
|
||||
"dependencies": {
|
||||
"@types/chai": "^4.3.0",
|
||||
"chai": "^4.3.6",
|
||||
|
@ -20602,7 +20608,8 @@
|
|||
"core-js": {
|
||||
"version": "3.22.8",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.22.8.tgz",
|
||||
"integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA=="
|
||||
"integrity": "sha512-UoGQ/cfzGYIuiq6Z7vWL1HfkE9U9IZ4Ub+0XSiJTCzvbZzgPA69oDF2f+lgJ6dFFLEdjW5O6svvoKzXX23xFkA==",
|
||||
"optional": true
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.12.0",
|
||||
|
@ -21070,6 +21077,11 @@
|
|||
"cssom": "0.3.x"
|
||||
}
|
||||
},
|
||||
"csv-parse": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.1.0.tgz",
|
||||
"integrity": "sha512-JL+Q6YEikT2uoe57InjFFa6VejhSv0tDwOxeQ1bVQKeUC/NCnLAAZ8n3PzowPQQLuZ37fysDYZipB2UJkH9C6A=="
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
||||
|
@ -21487,9 +21499,9 @@
|
|||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
|
||||
},
|
||||
"doctest-ts-improved": {
|
||||
"version": "0.8.6",
|
||||
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.6.tgz",
|
||||
"integrity": "sha512-J7fXMJ29ve6DUsUHKEO5bOwGmYjhNZd88L7NMVDKIiLIiUCJ9zkR2k7IZOGjMC0RXw/q788REawcMUgIj+7Muw==",
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/doctest-ts-improved/-/doctest-ts-improved-0.8.8.tgz",
|
||||
"integrity": "sha512-aEkS6go+DBz8atfQSAUoCXc0N+nI2YKFXOhS9j/Jrxv0rG0J+6e6xDxiZq0rP6sKybRF/zHSWqC2jjR9qzx2ZA==",
|
||||
"requires": {
|
||||
"@types/chai": "^4.3.0",
|
||||
"chai": "^4.3.6",
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
"weblate-add-upstream": "git remote add weblate-github git@github.com:weblate/MapComplete.git",
|
||||
"weblate-fix": "git remote update weblate-github ; git merge weblate-github/weblate-mapcomplete-core; git merge weblate-github/weblate-mapcomplete-layers ; git merge weblate-github/weblate-mapcomplete-layer-translations",
|
||||
"weblate-fix-heavy": "git remote rm weblate-layers; git remote add weblate-layers https://hosted.weblate.org/git/mapcomplete/layers/; git remote update weblate-layers; git merge weblate-layers/master",
|
||||
"housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && git commit assets/ langs/ Docs/ -m 'Housekeeping...'"
|
||||
"housekeeping": "npm run generate && npm run generate:docs && npm run generate:contributor-list && git commit assets/ langs/ Docs/ -m 'Housekeeping...'",
|
||||
"parseSchools": "cd scripts/schools && ts-node amendSchoolData.ts"
|
||||
},
|
||||
"keywords": [
|
||||
"OpenStreetMap",
|
||||
|
@ -83,7 +84,8 @@
|
|||
"@types/wikidata-sdk": "^6.1.0",
|
||||
"@types/xml2js": "^0.4.9",
|
||||
"country-language": "^0.1.7",
|
||||
"doctest-ts-improved": "^0.8.6",
|
||||
"csv-parse": "^5.1.0",
|
||||
"doctest-ts-improved": "^0.8.8",
|
||||
"email-validator": "^2.0.4",
|
||||
"escape-html": "^1.0.3",
|
||||
"geojson2svg": "^1.3.1",
|
||||
|
|
89
scripts/csvToGeojson.ts
Normal file
89
scripts/csvToGeojson.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import {parse} from 'csv-parse/sync';
|
||||
import {readFileSync} from "fs";
|
||||
|
||||
var lambert72toWGS84 = function(x, y){
|
||||
|
||||
var newLongitude, newLatitude;
|
||||
|
||||
var n = 0.77164219,
|
||||
F = 1.81329763,
|
||||
thetaFudge = 0.00014204,
|
||||
e = 0.08199189,
|
||||
a = 6378388,
|
||||
xDiff = 149910,
|
||||
yDiff = 5400150,
|
||||
theta0 = 0.07604294;
|
||||
|
||||
var xReal = xDiff - x,
|
||||
yReal = yDiff - y;
|
||||
|
||||
var rho = Math.sqrt(xReal * xReal + yReal * yReal),
|
||||
theta = Math.atan(xReal / -yReal);
|
||||
|
||||
newLongitude = (theta0 + (theta + thetaFudge) / n) * 180 / Math.PI;
|
||||
newLatitude = 0;
|
||||
|
||||
for (var i = 0; i < 5 ; ++i) {
|
||||
newLatitude = (2 * Math.atan(Math.pow(F * a / rho, 1 / n) * Math.pow((1 + e * Math.sin(newLatitude)) / (1 - e * Math.sin(newLatitude)), e / 2))) - Math.PI / 2;
|
||||
}
|
||||
newLatitude *= 180 / Math.PI;
|
||||
return [newLongitude, newLatitude];
|
||||
|
||||
}
|
||||
|
||||
function main(args: string[]): void {
|
||||
|
||||
|
||||
|
||||
if (args.length == 0) {
|
||||
/* args = ["/home/pietervdvn/Downloads/Scholen/aantallen.csv",
|
||||
"/home/pietervdvn/Downloads/Scholen/perschool.csv",
|
||||
"/home/pietervdvn/Downloads/Scholen/Vestigingsplaatsen-van-scholen-gewoon-secundair-onderwijs-cleaned.csv"]
|
||||
*/
|
||||
console.log("Usage: csvToGeojson input.csv name-of-lat-field name-of-lon-field")
|
||||
return
|
||||
}
|
||||
|
||||
let file = args[0]
|
||||
if(file.startsWith("file://")){
|
||||
file = file.substr("file://".length)
|
||||
}
|
||||
const latField = args[1]
|
||||
const lonField = args[2]
|
||||
|
||||
const csvOptions = {
|
||||
columns: true,
|
||||
skip_empty_lines: true,
|
||||
trim: true
|
||||
}
|
||||
|
||||
const csv: Record<any, string>[] = parse(readFileSync(file), csvOptions)
|
||||
|
||||
const features = csv.map((csvElement, i) => {
|
||||
const lat = Number(csvElement[latField])
|
||||
const lon = Number(csvElement[lonField])
|
||||
if(isNaN(lat) || isNaN(lon)){
|
||||
throw `Not a valid lat or lon for entry ${i}: ${JSON.stringify(csvElement)}`
|
||||
}
|
||||
|
||||
|
||||
|
||||
return {
|
||||
type: "Feature",
|
||||
properties: csvElement,
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: lambert72toWGS84(lon, lat)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
console.log(JSON.stringify({
|
||||
type: "FeatureCollection",
|
||||
features
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
main(process.argv.slice(2))
|
|
@ -13,8 +13,6 @@ import PointRenderingConfigJson from "../Models/ThemeConfig/Json/PointRenderingC
|
|||
import {PrepareLayer} from "../Models/ThemeConfig/Conversion/PrepareLayer";
|
||||
import {PrepareTheme} from "../Models/ThemeConfig/Conversion/PrepareTheme";
|
||||
import {DesugaringContext} from "../Models/ThemeConfig/Conversion/Conversion";
|
||||
import LayerConfig from "../Models/ThemeConfig/LayerConfig";
|
||||
import LayerConfigJsonJSC from "../Docs/Schemas/LayerConfigJsonJSC";
|
||||
import {Utils} from "../Utils";
|
||||
|
||||
// This scripts scans 'assets/layers/*.json' for layer definition files and 'assets/themes/*.json' for theme definition files.
|
||||
|
@ -211,14 +209,42 @@ class LayerOverviewUtils {
|
|||
return sharedLayers;
|
||||
}
|
||||
|
||||
private static publicLayerIdsFrom(themefiles: LayoutConfigJson[]): Set<string>{
|
||||
const publicLayers = [].concat(...themefiles
|
||||
.filter(th => !th.hideFromOverview)
|
||||
.map(th => th.layers))
|
||||
|
||||
const publicLayerIds = new Set<string>()
|
||||
for (const publicLayer of publicLayers) {
|
||||
if(typeof publicLayer === "string"){
|
||||
publicLayerIds.add(publicLayer)
|
||||
continue
|
||||
}
|
||||
if(publicLayer["builtin"] !== undefined){
|
||||
const bi = publicLayer["builtin"]
|
||||
if(typeof bi === "string"){
|
||||
publicLayerIds.add(bi)
|
||||
continue
|
||||
}
|
||||
bi.forEach(id=>publicLayerIds.add(id))
|
||||
continue
|
||||
}
|
||||
publicLayerIds.add(publicLayer.id)
|
||||
}
|
||||
return publicLayerIds
|
||||
}
|
||||
|
||||
private buildThemeIndex(knownImagePaths: Set<string>, sharedLayers: Map<string, LayerConfigJson>): Map<string, LayoutConfigJson> {
|
||||
console.log(" ---------- VALIDATING BUILTIN THEMES ---------")
|
||||
const themeFiles = ScriptUtils.getThemeFiles();
|
||||
const fixed = new Map<string, LayoutConfigJson>();
|
||||
|
||||
const publicLayers = LayerOverviewUtils.publicLayerIdsFrom(themeFiles.map(th => th.parsed))
|
||||
|
||||
const convertState: DesugaringContext = {
|
||||
sharedLayers,
|
||||
tagRenderings: this.getSharedTagRenderings()
|
||||
tagRenderings: this.getSharedTagRenderings(),
|
||||
publicLayers
|
||||
}
|
||||
for (const themeInfo of themeFiles) {
|
||||
let themeFile = themeInfo.parsed
|
||||
|
|
4098
scripts/schools/Onderwijsinstellingen.csv
Normal file
4098
scripts/schools/Onderwijsinstellingen.csv
Normal file
File diff suppressed because it is too large
Load diff
3
scripts/schools/README.md
Normal file
3
scripts/schools/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Little scripts to parse Belgian school data
|
||||
|
||||
|
152
scripts/schools/amendSchoolData.ts
Normal file
152
scripts/schools/amendSchoolData.ts
Normal file
|
@ -0,0 +1,152 @@
|
|||
import {parse} from 'csv-parse/sync';
|
||||
import {readFileSync, writeFileSync} from "fs";
|
||||
import {Utils} from "../../Utils";
|
||||
|
||||
function parseAndClean(filename: string): Record<any, string>[] {
|
||||
const csvOptions = {
|
||||
columns: true,
|
||||
skip_empty_lines: true,
|
||||
trim: true
|
||||
}
|
||||
const records: Record<any, string>[] = parse(readFileSync(filename), csvOptions)
|
||||
return records.map(r => {
|
||||
|
||||
for (const key of Object.keys(r)) {
|
||||
if (r[key].endsWith("niet van toepassing")) {
|
||||
delete r[key]
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
})
|
||||
}
|
||||
|
||||
const structuren = {
|
||||
"Voltijds Gewoon Secundair Onderwijs": "secondary",
|
||||
"Gewoon Lager Onderwijs": "primary",
|
||||
"Gewoon Kleuteronderwijs": "kindergarten",
|
||||
"Kleuteronderwijs": "kindergarten",
|
||||
"Buitengewoon Lager Onderwijs": "primary",
|
||||
"Buitengewoon Secundair Onderwijs": "secondary",
|
||||
"Buitengewoon Kleuteronderwijs": "kindergarten",
|
||||
"Deeltijds Beroepssecundair Onderwijs": "secondary"
|
||||
|
||||
}
|
||||
|
||||
const rmKeys = ["schoolnummer", "instellingstype",
|
||||
"adres", "begindatum","hoofdzetel","huisnummer","kbo-nummer",
|
||||
"beheerder(s)", "bestuur", "clb", "ingerichte hoofdstructuren", "busnummer", "crab-code", "crab-huisnr",
|
||||
"einddatum", "fax", "gemeente", "intern_vplnummer", "kbo_nummer", "lx", "ly", "niscode",
|
||||
"onderwijsniveau","onderwijsvorm","scholengemeenschap",
|
||||
"postcode", "provincie",
|
||||
"provinciecode", "soort instelling", "status erkenning", "straat", "VWO-vestigingsplaatscode", "taalstelsel",
|
||||
"net"]
|
||||
|
||||
const rename = {
|
||||
"e-mail":"email",
|
||||
"naam":"name",
|
||||
"telefoon":"phone"
|
||||
|
||||
}
|
||||
|
||||
function main() {
|
||||
const aantallen = "/home/pietervdvn/Downloads/Scholen/aantallen.csv"
|
||||
const perSchool = "/home/pietervdvn/Downloads/Scholen/perschool.csv"
|
||||
|
||||
const schoolfields = ["schoolnummer", "intern_vplnummer", "net", "naam", "hoofdzetel", "adres", "straat", "huisnummer", "busnummer", "postcode", "gemeente", "niscode", "provinciecode", "provincie", "VWO-vestigingsplaatscode", "crab-code", "crab-huisnr", "lx", "ly", "kbo-nummer", "telefoon", "fax", "e-mail", "website", "beheerder(s)", "soort instelling", "onderwijsniveau", "instellingstype", "begindatum", "einddatum", "status erkenning", "clb", "bestuur", "scholengemeenschap", "taalstelsel", "ingerichte hoofdstructuren"] as const
|
||||
|
||||
const schoolGeojson: {
|
||||
features: {
|
||||
properties: Record<(typeof schoolfields)[number], string>
|
||||
}[]
|
||||
} = JSON.parse(readFileSync("scholen.geojson", "utf8"))
|
||||
|
||||
const aantallenFields = ["schooljaar", "nr koepel", "koepel", "instellingscode", "intern volgnr vpl", "volgnr vpl", "naam instelling", "GON-school", "GOK-school", "instellingsnummer scholengemeenschap", "scholengemeenschap", "code schoolbestuur", "schoolbestuur", "type vestigingsplaats", "fusiegemeente hoofdvestigingsplaats", "straatnaam vestigingsplaats", "huisnr vestigingsplaats", "bus vestigingsplaats", "postcode vestigingsplaats", "deelgemeente vestigingsplaats", "fusiegemeente vestigingsplaats", "hoofdstructuur (code)", "hoofdstructuur", "administratieve groep (code)", "administratieve groep", "graad lager onderwijs", "pedagogische methode", "graad secundair onderwijs", "leerjaar", "A of B-stroom", "basisopties", "beroepenveld", "onderwijsvorm", "studiegebied", "studierichting", "stelsel", "okan cluster", "type buitengewoon onderwijs", "opleidingsvorm (code)", "opleidingsvorm", "fase", "opleidingen", "geslacht", "aantal inschrijvingen"] as const
|
||||
const aantallenParsed: Record<(typeof aantallenFields)[number], string>[] = parseAndClean(aantallen)
|
||||
const perschoolFields = ["schooljaar", "nr koepel", "koepel", "instellingscode", "naam instelling", "straatnaam", "huisnr", "bus", "postcode", "deelgemeente", "fusiegemeente", "aantal inschrijvingen"] as const
|
||||
const perschoolParsed: Record<(typeof perschoolFields)[number], string>[] = parseAndClean(perSchool)
|
||||
|
||||
schoolGeojson.features = schoolGeojson.features
|
||||
.filter(sch => sch.properties.lx != "0" && sch.properties.ly != "0")
|
||||
.filter(sch => sch.properties.instellingstype !== "Universiteit")
|
||||
|
||||
for (const feature of schoolGeojson.features) {
|
||||
|
||||
const props = feature.properties
|
||||
|
||||
const aantallen = aantallenParsed.filter(i => i.instellingscode == props.schoolnummer)
|
||||
|
||||
if (aantallen.length > 0) {
|
||||
|
||||
const fetch = (key: (typeof aantallenFields)[number]) => Utils.NoNull(Utils.Dedup(aantallen.map(x => x[key])))
|
||||
|
||||
props["onderwijsvorm"] = fetch("onderwijsvorm").join(";")
|
||||
|
||||
const gonSchool = aantallen.some(x => x["GON-school"] === "GON-school")
|
||||
const gokSchool = aantallen.some(x => x["GOK-school"] === "GON-school")
|
||||
const hoofdstructuur = fetch("hoofdstructuur")
|
||||
const onderwijsvorm = fetch("onderwijsvorm")
|
||||
const koepel = fetch("koepel")
|
||||
const stelsel = fetch("stelsel")
|
||||
const scholengemeenschap = fetch("scholengemeenschap")
|
||||
const graden =fetch("graad secundair onderwijs")
|
||||
graden.sort()
|
||||
let specialEducation = false
|
||||
const classification = hoofdstructuur.map(s => {
|
||||
const v = structuren[s]
|
||||
if (s.startsWith("Buitengewoon")) {
|
||||
specialEducation = true;
|
||||
}
|
||||
if (v === undefined) {
|
||||
console.error("Type not found: " + s)
|
||||
return ""
|
||||
}
|
||||
return v
|
||||
})
|
||||
props["school"] = Utils.Dedup(classification).join("; ")
|
||||
props["degrees"] = graden.join(";")
|
||||
props["koepel"] = koepel.join(";")
|
||||
props["scholengemeenschap"] = scholengemeenschap.join(";")
|
||||
props["stelsel"] = stelsel
|
||||
if (specialEducation) {
|
||||
props["school:for"] = "special_education"
|
||||
}
|
||||
if (props.taalstelsel === "Nederlandstalig") {
|
||||
props["language:nl"] = "yes"
|
||||
}
|
||||
|
||||
if(props.instellingstype === "Instelling voor deeltijds kunstonderwijs") {
|
||||
props["amenity"] = "college"
|
||||
props["school:subject"] = "art"
|
||||
}
|
||||
}
|
||||
|
||||
const schoolinfo = perschoolParsed.filter(i => i.instellingscode == props.schoolnummer)
|
||||
if (schoolinfo.length == 0) {
|
||||
// pass
|
||||
} else if (schoolinfo.length == 1) {
|
||||
props["capacity"] = schoolinfo[0]["aantal inschrijvingen"].split(";").map(i => Number(i)).reduce((sum, i) => sum + i, 0)
|
||||
} else {
|
||||
throw "Multiple schoolinfo's found for " + props.schoolnummer
|
||||
}
|
||||
|
||||
props["source:ref"] = props.schoolnummer
|
||||
|
||||
for (const renameKey in rename) {
|
||||
const into = rename[renameKey]
|
||||
if(props[renameKey] !== undefined){
|
||||
props[into] = props[renameKey]
|
||||
delete props[renameKey]
|
||||
}
|
||||
}
|
||||
|
||||
for (const rmKey of rmKeys) {
|
||||
delete props[rmKey]
|
||||
}
|
||||
|
||||
}
|
||||
writeFileSync("amended_schools.geojson", JSON.stringify(schoolGeojson), "utf8")
|
||||
|
||||
}
|
||||
|
||||
main()
|
1
scripts/schools/amended_schools.geojson
Normal file
1
scripts/schools/amended_schools.geojson
Normal file
File diff suppressed because one or more lines are too long
4098
scripts/schools/scholen.csv
Normal file
4098
scripts/schools/scholen.csv
Normal file
File diff suppressed because it is too large
Load diff
1
scripts/schools/scholen.geojson
Normal file
1
scripts/schools/scholen.geojson
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue