diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts
index ef17b80..6b9019e 100644
--- a/Customizations/JSON/FromJSON.ts
+++ b/Customizations/JSON/FromJSON.ts
@@ -8,14 +8,13 @@ import Translation from "../../UI/i18n/Translation";
import {LayerConfigJson} from "./LayerConfigJson";
import {LayerDefinition, Preset} from "../LayerDefinition";
import {TagDependantUIElementConstructor} from "../UIElementConstructor";
-import FixedText from "../Questions/FixedText";
-import Translations from "../../UI/i18n/Translations";
import Combine from "../../UI/Base/Combine";
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
import {ImageCarouselConstructor} from "../../UI/Image/ImageCarousel";
import * as drinkingWater from "../../assets/layers/drinking_water/drinking_water.json";
import * as ghostbikes from "../../assets/layers/ghost_bike/ghost_bike.json"
import * as viewpoint from "../../assets/layers/viewpoint/viewpoint.json"
+import * as bike_parking from "../../assets/layers/bike_parking/bike_parking.json"
import {Utils} from "../../Utils";
export class FromJSON {
@@ -29,6 +28,7 @@ export class FromJSON {
FromJSON.Layer(drinkingWater),
FromJSON.Layer(ghostbikes),
FromJSON.Layer(viewpoint),
+ FromJSON.Layer(bike_parking),
];
for (const layer of sharedLayersList) {
@@ -201,7 +201,7 @@ export class FromJSON {
if (tag.indexOf("!~") >= 0) {
const split = Utils.SplitFirst(tag, "!~");
if (split[1] === "*") {
- split[1] = ".*"
+ split[1] = "..*"
}
return new RegexTag(
split[0],
@@ -212,7 +212,7 @@ export class FromJSON {
if (tag.indexOf("!=") >= 0) {
const split = Utils.SplitFirst(tag, "!=");
if (split[1] === "*") {
- split[1] = ".*"
+ split[1] = "..*"
}
return new RegexTag(
split[0],
@@ -223,7 +223,7 @@ export class FromJSON {
if (tag.indexOf("~") >= 0) {
const split = Utils.SplitFirst(tag, "~");
if (split[1] === "*") {
- split[1] = ".*"
+ split[1] = "..*"
}
return new RegexTag(
split[0],
@@ -259,6 +259,8 @@ export class FromJSON {
const iconSize = FromJSON.TagRenderingWithDefault(json.iconSize, "iconSize", "40,40,center");
const color = FromJSON.TagRenderingWithDefault(json.color, "layercolor", "#0000ff");
const width = FromJSON.TagRenderingWithDefault(json.width, "layerwidth", "10");
+ const tagRenderings = json.tagRenderings?.map(FromJSON.TagRendering) ?? [];
+
const renderTags = {"id": "node/-1"}
const presets: Preset[] = json?.presets?.map(preset => {
return ({
@@ -317,12 +319,13 @@ export class FromJSON {
title: FromJSON.TagRendering(json.title),
minzoom: json.minzoom,
presets: presets,
- elementsToShow: json.tagRenderings?.map(FromJSON.TagRendering) ?? [],
+ elementsToShow: tagRenderings,
style: style,
wayHandling: json.wayHandling
}
);
+ console.log("Parsed layer is ", layer);
return layer;
}
diff --git a/Customizations/Layers/BikeParkings.ts b/Customizations/Layers/BikeParkings.ts
index 6fbe754..e934d97 100644
--- a/Customizations/Layers/BikeParkings.ts
+++ b/Customizations/Layers/BikeParkings.ts
@@ -1,52 +1,17 @@
import {LayerDefinition} from "../LayerDefinition";
import {Tag} from "../../Logic/Tags";
-import FixedText from "../Questions/FixedText";
-import ParkingType from "../Questions/bike/ParkingType";
-import ParkingCapacity from "../Questions/bike/ParkingCapacity";
-import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
-import Translations from "../../UI/i18n/Translations";
-import ParkingAccessCargo from "../Questions/bike/ParkingAccessCargo";
import ParkingCapacityCargo from "../Questions/bike/ParkingCapacityCargo";
export default class BikeParkings extends LayerDefinition {
- private readonly accessCargoDesignated = new Tag("cargo_bike", "designated");
+ private readonly accessCargoDesignated = new Tag();
constructor() {
- super("bikeparking");
- this.name = Translations.t.cyclofix.parking.name;
- this.icon = "./assets/bike/parking.svg";
- this.overpassFilter = new Tag("amenity", "bicycle_parking");
- this.presets = [{
- title: Translations.t.cyclofix.parking.title,
- tags: [
- new Tag("amenity", "bicycle_parking"),
- ]
- }];
-
- this.maxAllowedOverlapPercentage = 10;
-
- this.minzoom = 17;
- this.style = function () {
- return {
- color: "#00bb00",
- icon: {
- iconUrl: "./assets/bike/parking.svg",
- iconSize: [50, 50],
- iconAnchor: [25, 50]
- }
- };
- };
- this.title = new FixedText(Translations.t.cyclofix.parking.title)
+ super(undefined);
this.elementsToShow = [
- new ImageCarouselWithUploadConstructor(),
- //new ParkingOperator(),
- new ParkingType(),
- new ParkingCapacity(),
- new ParkingAccessCargo(),
new ParkingCapacityCargo().OnlyShowIf(this.accessCargoDesignated)
+ //new ParkingOperator(),
];
- this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY;
}
}
diff --git a/Customizations/Layouts/Cyclofix.ts b/Customizations/Layouts/Cyclofix.ts
index f10d203..867d6ad 100644
--- a/Customizations/Layouts/Cyclofix.ts
+++ b/Customizations/Layouts/Cyclofix.ts
@@ -14,7 +14,7 @@ export default class Cyclofix extends Layout {
"cyclofix",
["en", "nl", "fr","gl"],
Translations.t.cyclofix.title,
- [new BikeServices(), new BikeShops(), "drinking_water", new BikeParkings(), new BikeOtherShops(), new BikeCafes()],
+ [new BikeServices(), new BikeShops(), "drinking_water", "bike_parking", new BikeOtherShops(), new BikeCafes()],
16,
50.8465573,
4.3516970,
diff --git a/Customizations/Questions/bike/ParkingAccessCargo.ts b/Customizations/Questions/bike/ParkingAccessCargo.ts
deleted file mode 100644
index 9a188a5..0000000
--- a/Customizations/Questions/bike/ParkingAccessCargo.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { Tag } from "../../../Logic/Tags";
-import Translations from "../../../UI/i18n/Translations";
-import {TagRenderingOptions} from "../../TagRenderingOptions";
-
-
-export default class ParkingAccessCargo extends TagRenderingOptions {
- constructor() {
- const key = "cargo_bike"
- const to = Translations.t.cyclofix.parking.access_cargo
- super({
- priority: 15,
- question: to.question.Render(),
- mappings: [
- {k: new Tag(key, "yes"), txt: to.yes},
- {k: new Tag(key, "designated"), txt: to.designated},
- {k: new Tag(key, "no"), txt: to.no}
- ]
- });
- }
-}
diff --git a/Customizations/Questions/bike/ParkingCapacity.ts b/Customizations/Questions/bike/ParkingCapacity.ts
deleted file mode 100644
index 9d2f9df..0000000
--- a/Customizations/Questions/bike/ParkingCapacity.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import Translations from "../../../UI/i18n/Translations";
-import {TagRenderingOptions} from "../../TagRenderingOptions";
-
-
-export default class ParkingCapacity extends TagRenderingOptions {
- constructor() {
- const to = Translations.t.cyclofix.parking.capacity
- super({
- priority: 15,
- question: to.question,
- freeform: {
- key: "capacity",
- renderTemplate: to.render,
- template: to.template
- }
- });
- }
-}
diff --git a/Customizations/Questions/bike/ParkingCapacityCargo.ts b/Customizations/Questions/bike/ParkingCapacityCargo.ts
deleted file mode 100644
index 7841259..0000000
--- a/Customizations/Questions/bike/ParkingCapacityCargo.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import Translations from "../../../UI/i18n/Translations";
-import {TagRenderingOptions} from "../../TagRenderingOptions";
-
-
-export default class ParkingCapacityCargo extends TagRenderingOptions {
- constructor() {
- const to = Translations.t.cyclofix.parking.capacity_cargo
- super({
- priority: 10,
- question: to.question,
- freeform: {
- key: "capacity:cargo_bike",
- renderTemplate: to.render,
- template: to.template
- }
- });
- }
-}
diff --git a/Customizations/Questions/bike/ParkingType.ts b/Customizations/Questions/bike/ParkingType.ts
deleted file mode 100644
index d0c9b0f..0000000
--- a/Customizations/Questions/bike/ParkingType.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import {Tag} from "../../../Logic/Tags";
-import Translations from "../../../UI/i18n/Translations";
-import Combine from "../../../UI/Base/Combine";
-import {TagRenderingOptions} from "../../TagRenderingOptions";
-
-class ParkingTypeHelper {
- static GenerateMappings() {
- const images = {
- stands: "assets/bike/parking_staple.svg",
- wall_loops: "assets/bike/parking_wall_loops.svg",
- handlebar_holder: "assets/bike/parking_handlebar_holder.svg",
- rack: "assets/bike/parking_rack.svg",
- shed: "assets/bike/parking_shed.svg"
- };
-
-
- const toImg = (url) => `
`
- const mappings = [];
- const to = Translations.t.cyclofix.parking.type
-
- for (const imagesKey in images) {
- const mapping =
- {
- k: new Tag("bicycle_parking", imagesKey),
- txt: new Combine([
- to[imagesKey],
- to.eg,
- toImg(images[imagesKey])
- ])
- };
-
- mappings.push(mapping);
-
- }
-
- return mappings;
- }
-}
-
-export default class ParkingType extends TagRenderingOptions {
- constructor() {
-
- const to = Translations.t.cyclofix.parking.type
-
-
- super({
- priority: 5,
- question: to.question,
- freeform: {
- key: "bicycle_parking",
- extraTags: new Tag("fixme", "Freeform bicycle_parking= tag used: possibly a wrong value"),
- template: to.template.txt,
- renderTemplate: to.render.txt,
- placeholder: Translations.t.cyclofix.freeFormPlaceholder,
- },
- mappings: ParkingTypeHelper.GenerateMappings()
-
- });
- }
-}
diff --git a/Customizations/TagRendering.ts b/Customizations/TagRendering.ts
index 8a204c1..644474b 100644
--- a/Customizations/TagRendering.ts
+++ b/Customizations/TagRendering.ts
@@ -205,7 +205,13 @@ TagRendering extends UIElement implements TagDependantUIElement {
InputElement {
const elements = [];
+
+ let freeformElement = undefined;
+ if (options.freeform !== undefined) {
+ freeformElement = this.InputForFreeForm(options.freeform);
+ }
+
if (options.mappings !== undefined) {
const previousTexts= [];
@@ -221,10 +227,11 @@ TagRendering extends UIElement implements TagDependantUIElement {
elements.push(this.InputElementForMapping(mapping));
}
}
-
- if (options.freeform !== undefined) {
- elements.push(this.InputForFreeForm(options.freeform));
+
+ if(freeformElement !== undefined) {
+ elements.push(freeformElement);
}
+
if (elements.length == 0) {
@@ -239,7 +246,7 @@ TagRendering extends UIElement implements TagDependantUIElement {
}
- private InputElementForMapping(mapping: { k: TagsFilter, txt: string | Translation }) {
+ private InputElementForMapping(mapping: { k: TagsFilter, txt: (string | Translation) }) {
return new FixedInputElement(this.ApplyTemplate(mapping.txt),
mapping.k.substituteValues(this.currentTags.data)
);
@@ -454,8 +461,6 @@ TagRendering extends UIElement implements TagDependantUIElement {
""]).Render();
}
- console.log("No rendering for",this)
-
return "";
}
@@ -466,7 +471,6 @@ TagRendering extends UIElement implements TagDependantUIElement {
private ApplyTemplate(template: string | Translation): UIElement {
if (template === undefined || template === null) {
- console.warn("Applying template which is undefined by ",this); // TODO THis error msg can probably be removed
return undefined;
}
return new VariableUiElement(this.currentTags.map(tags => {
diff --git a/Logic/Tags.ts b/Logic/Tags.ts
index 882e963..414b92b 100644
--- a/Logic/Tags.ts
+++ b/Logic/Tags.ts
@@ -14,37 +14,50 @@ export abstract class TagsFilter {
export class RegexTag extends TagsFilter {
- private readonly key: RegExp;
- private readonly value: RegExp;
+ private readonly key: RegExp | string;
+ private readonly value: RegExp | string;
private readonly invert: boolean;
- constructor(key: string | RegExp, value: RegExp, invert: boolean = false) {
+ constructor(key: string | RegExp, value: RegExp | string, invert: boolean = false) {
super();
- this.key = typeof (key) === "string" ? new RegExp(key) : key;
+ this.key = key;
this.value = value;
this.invert = invert;
}
asOverpass(): string[] {
- return [`['${this.key.source}'${this.invert ? "!" : ""}~'${this.value.source}']`];
+ return [`['${RegexTag.source(this.key)}'${this.invert ? "!" : ""}~'${RegexTag.source(this.value)}']`];
+ }
+
+ private static doesMatch(fromTag: string, possibleRegex: string | RegExp): boolean {
+ if(typeof possibleRegex === "string"){
+ return fromTag === possibleRegex;
+ }
+ return fromTag.match(possibleRegex) !== null;
+ }
+
+ private static source(r: string | RegExp) {
+ if (typeof (r) === "string") {
+ return r;
+ }
+ return r.source;
}
matches(tags: { k: string; v: string }[]): boolean {
for (const tag of tags) {
- if (tag.k.match(this.key)) {
- return tag.v.match(this.value) !== null;
+ if (RegexTag.doesMatch(tag.k, this.key)){
+ return RegexTag.doesMatch(tag.v, this.value);
}
}
return false;
}
substituteValues(tags: any) : TagsFilter{
- console.warn("Not substituting values on regex tags");
return this;
}
asHumanString() {
- return `${this.key.source}${this.invert ? "!" : ""}~${this.value.source}`;
+ return `${RegexTag.source(this.key)}${this.invert ? "!" : ""}~${RegexTag.source(this.value)}`;
}
}
diff --git a/UI/CustomGenerator/GenerateEmpty.ts b/UI/CustomGenerator/GenerateEmpty.ts
index d835be8..f07518e 100644
--- a/UI/CustomGenerator/GenerateEmpty.ts
+++ b/UI/CustomGenerator/GenerateEmpty.ts
@@ -27,7 +27,9 @@ export class GenerateEmpty {
startLat: 0,
startLon: 0,
startZoom: 1,
+ widenFactor: 0.05,
socialImage: "",
+
layers: []
}
}
diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts
index a0218e1..51f1cdf 100644
--- a/UI/i18n/Translations.ts
+++ b/UI/i18n/Translations.ts
@@ -12,23 +12,6 @@ export default class Translations {
static t = {
- climbingTrees: {
- layer: {
-
- title: new T({
- nl: "Klimbomen"
- }),
- description: new T({
- nl: "Een klimboom is een mooie boom waar men in kan klimmen, al dan niet officieel"
- })
- },
- layout: {
- title: new T({nl: "Open Klimbomenkaart"}),
- welcome: new T({nl: "Markeer je favoriete klimboom"})
- }
-
- },
-
cyclofix: {
title: new T({
@@ -59,49 +42,10 @@ export default class Translations {
"Todas as modificacións que fagas serán gardadas de xeito automático na base de datos global do OpenStreetMap e outros poderán reutilizalos libremente.
" +
"Para máis información sobre o proxecto cyclofix, vai a cyclofix.osm.be."
}),
- freeFormPlaceholder: new T({en: 'specify', nl: 'specifieer', fr: 'Specifiéz', gl: 'especificar'}),
parking: {
- name: new T({en: 'bike parking', nl: 'fietsparking', fr: 'parking à vélo'}),
- title: new T({
- en: 'Bike parking', nl: 'Fietsparking', fr: 'Parking à vélo',
- gl: 'Aparcadoiro de bicicletas'
- }),
+
type: {
- render: new T({
- en: 'This is a bicycle parking of the type: {bicycle_parking}',
- nl: 'Dit is een fietsparking van het type: {bicycle_parking}',
- fr: 'Ceci est un parking à vélo de type {bicycle_parking}',
- gl: 'Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}'
- }),
- template: new T({
- en: 'Some other type: $$$',
- nl: 'Een ander type: $$$',
- fr: "D'autres types: $$$",
- gl: "Algún outro tipo:: $$$"
- }),
- question: new T({
- en: 'What is the type of this bicycle parking?',
- nl: 'Van welk type is deze fietsparking?',
- fr: 'Quelle type de parking s\'agit il? ',
- gl: 'Que tipo de aparcadoiro de bicicletas é?'
- }),
- eg: new T({en: ", for example", nl: ", bijvoorbeeld", fr: ",par example", gl: ", por exemplo"}),
- stands: new T({en: 'Staple racks', nl: 'Nietjes', fr: 'Arceaux', gl: 'De roda (Stands)'}),
- wall_loops: new T({en: 'Wheel rack/loops', nl: 'Wielrek/lussen', fr: 'Pinces-roues', gl: 'Aros'}),
- handlebar_holder: new T({
- en: 'Handlebar holder',
- nl: 'Stuurhouder',
- fr: 'Support guidon',
- gl: 'Cadeado para guiador'
- }),
- shed: new T({en: 'Shed', nl: 'Schuur', fr: 'Abri', gl: 'Abeiro'}),
- rack: new T({en: 'Rack', nl: 'Rek', fr: 'Râtelier', gl: 'Cremalleira'}),
- "two-tier": new T({
- en: 'Two-tiered',
- nl: 'Dubbel (twee verdiepingen)',
- fr: 'Superposé',
- gl: 'Dobre cremalleira'
- }),
+ "two-tier": new T(),
},
operator: {
render: new T({
@@ -124,86 +68,7 @@ export default class Translations {
gl: 'Operado por unha persoa privada'
}),
},
- covered: {
- question: new T({
- en: 'Is this parking covered? Also select "covered" for indoor parkings.',
- nl: 'Is deze parking overdekt? Selecteer ook "overdekt" voor fietsparkings binnen een gebouw.',
- gl: 'Este aparcadoiro está cuberto? Tamén escolle "cuberto" para aparcadoiros interiores.'
- }),
- yes: new T({
- en: 'This parking is covered (it has a roof)',
- nl: 'Deze parking is overdekt (er is een afdak)',
- gl: 'Este aparcadoiro está cuberto (ten un teito)'
- }),
- no: new T({
- en: 'This parking is not covered',
- nl: 'Deze parking is niet overdekt',
- gl: 'Este aparcadoiro non está cuberto'
- })
- },
- capacity: {
- question: new T({
- en: "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?",
- nl: "Voor hoeveel fietsen is er bij deze fietsparking plaats (inclusief potentiëel bakfietsen)?",
- gl: "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?"
- }),
- template: new T({
- en: "This parking fits $nat$ bikes",
- nl: "Deze parking heeft plaats voor $nat$ fietsen",
- gl: "Neste aparcadoiro caben $nat$ bicicletas"
- }),
- render: new T({
- en: "Place for {capacity} bikes (in total)",
- nl: "Plaats voor {capacity} fietsen (in totaal)",
- gl: "Lugar para {capacity} bicicletas (en total)"
- }),
- },
- capacity_cargo: {
- question: new T({
- en: "How many cargo bicycles fit in this bicycle parking?",
- nl: "Voor hoeveel bakfietsen heeft deze fietsparking plaats?",
- fr: "TODO: fr",
- gl: "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?"
- }),
- template: new T({
- en: "This parking fits $nat$ cargo bikes",
- nl: "Deze parking heeft plaats voor $nat$ fietsen",
- fr: "TODO: fr",
- gl: "Neste aparcadoiro caben $nat$ bicicletas de carga"
- }),
- render: new T({
- en: "Place for {capacity:cargo_bike} cargo bikes",
- nl: "Plaats voor {capacity:cargo_bike} bakfietsen",
- fr: "TODO: fr",
- gl: "Lugar para {capacity:cargo_bike} bicicletas de carga"
- }),
- },
- access_cargo: {
- question: new T({
- en: "Does this bicycle parking have spots for cargo bikes?",
- nl: "Heeft deze fietsparking plaats voor bakfietsen?",
- fr: "TODO: fr",
- gl: "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?"
- }),
- yes: new T({
- en: "This parking has room for cargo bikes",
- nl: "Deze parking heeft plaats voor bakfietsen",
- fr: "TODO: fr",
- gl: "Este aparcadoiro ten espazo para bicicletas de carga."
- }),
- designated: new T({
- en: "This parking has designated (official) spots for cargo bikes.",
- nl: "Er zijn speciale plaatsen voorzien voor bakfietsen",
- fr: "TODO: fr",
- gl: "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga."
- }),
- no: new T({
- en: "You're not allowed to park cargo bikes",
- nl: "Je mag hier geen bakfietsen parkeren",
- fr: "TODO: fr",
- gl: "Non está permitido aparcar bicicletas de carga"
- })
- }
+
},
station: {
name: new T({
diff --git a/assets/layers/bike_parking/bike_parking.json b/assets/layers/bike_parking/bike_parking.json
new file mode 100644
index 0000000..efbecff
--- /dev/null
+++ b/assets/layers/bike_parking/bike_parking.json
@@ -0,0 +1,222 @@
+{
+ "id": "bike_parking",
+ "name": {
+ "en": "Bike parking",
+ "nl": "Fietsparking",
+ "fr": "Parking à vélo",
+ "gl": "Aparcadoiro de bicicletas"
+ },
+ "minzoom": 17,
+ "overpassTags": {
+ "and": [
+ "amenity=bicycle_parking"
+ ]
+ },
+ "icon": "./assets/layers/bike_parking/parking.svg",
+ "size": {
+ "render": "50,50,bottom"
+ },
+ "color": "#00f",
+ "stroke": "4",
+ "wayHandling": 1,
+ "presets": [
+ {
+ "title": {
+ "en": "Bike parking",
+ "nl": "Fietsparking",
+ "fr": "Parking à vélo",
+ "gl": "Aparcadoiro de bicicletas"
+ },
+ "tags": [
+ "amenity=bicycle_parking"
+ ]
+ }
+ ],
+ "title": {
+ "render": {
+ "en": "Bike parking",
+ "nl": "Fietsparking",
+ "fr": "Parking à vélo",
+ "gl": "Aparcadoiro de bicicletas"
+ }
+ },
+ "tagRenderings": [
+ "images",
+ {
+ "question": {
+ "en": "What is the type of this bicycle parking?",
+ "nl": "Van welk type is deze fietsparking?",
+ "fr": "Quelle type de parking s'agit il?",
+ "gl": "Que tipo de aparcadoiro de bicicletas é?"
+ },
+ "render": {
+ "en": "This is a bicycle parking of the type: {bicycle_parking}",
+ "nl": "Dit is een fietsparking van het type: {bicycle_parking}",
+ "fr": "Ceci est un parking à vélo de type {bicycle_parking}",
+ "gl": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}"
+ },
+ "freeform": {
+ "key": "bicycle_parking",
+ "extraTags": [
+ "fixme=Freeform used on 'bicycle_parking'-tag: possibly a wrong value"
+ ]
+ },
+ "mappings": [
+ {
+ "if": "bicycle_parking=stands",
+ "then": {
+ "en": "Staple racks ",
+ "nl": "Nietjes ",
+ "fr": "Arceaux ",
+ "gl": "De roda (Stands) "
+ }
+ },
+ {
+ "if": "bicycle_parking=wall_loops",
+ "then": {
+ "en": "Wheel rack/loops ",
+ "nl": "Wielrek/lussen ",
+ "fr": "Pinces-roues ",
+ "gl": "Aros "
+ }
+ },
+ {
+ "if": "bicycle_parking=handlebar_holder",
+ "then": {
+ "en": "Handlebar holder ",
+ "nl": "Stuurhouder ",
+ "fr": "Support guidon ",
+ "gl": "Cadeado para guiador "
+ }
+ },
+ {
+ "if": "bicycle_parking=rack",
+ "then": {
+ "en": "Rack ",
+ "nl": "Rek ",
+ "fr": "Râtelier ",
+ "gl": "Cremalleira "
+ }
+ },
+ {
+ "if": "bicycle_parking=two_tier",
+ "then": {
+ "en": "Two-tiered ",
+ "nl": "Dubbel (twee verdiepingen) ",
+ "fr": "Superposé ",
+ "gl": "Dobre cremalleira "
+ }
+ },
+ {
+ "if": "bicycle_parking=shed",
+ "then": {
+ "en": "Shed ",
+ "nl": "Schuur ",
+ "fr": "Abri ",
+ "gl": "Abeiro "
+ }
+ }
+ ]
+ },
+ {
+ "question": {
+ "en": "Is this parking covered? Also select \"covered\" for indoor parkings.",
+ "nl": "Is deze parking overdekt? Selecteer ook \"overdekt\" voor fietsparkings binnen een gebouw.",
+ "gl": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores."
+ },
+ "condition": "bicycle_parking!=shed",
+ "mappings": [
+ {
+ "if": "covered=yes",
+ "then": {
+ "en": "This parking is covered (it has a roof)",
+ "nl": "Deze parking is overdekt (er is een afdak)",
+ "gl": "Este aparcadoiro está cuberto (ten un teito)"
+ }
+ },
+ {
+ "if": "covered=no",
+ "then": {
+ "en": "This parking is not covered",
+ "nl": "Deze parking is niet overdekt",
+ "gl": "Este aparcadoiro non está cuberto"
+ }
+ }
+ ]
+ },
+ {
+ "question": {
+ "en": "How many bicycles fit in this bicycle parking (including possible cargo bicycles)?",
+ "fr": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?",
+ "nl": "Hoeveel fietsen kunnen in deze fietsparking (inclusief potentiëel bakfietsen)?",
+ "gl": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?"
+ },
+ "render": {
+ "en": "Place for {capacity} bikes",
+ "fr": "Place pour {capacity} vélos",
+ "nl": "Plaats voor {capacity} fietsen",
+ "gl": "Lugar para {capacity} bicicletas"
+ },
+ "freeform": {
+ "key": "capacity",
+ "type": "nat"
+ }
+ },
+ {
+ "question": {
+ "en": "Does this bicycle parking have spots for cargo bikes?",
+ "nl": "Heeft deze fietsparking plaats voor bakfietsen?",
+ "fr": "TODO: fr",
+ "gl": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?"
+ },
+ "mappings": [
+ {
+ "if": "cargo_bike=yes",
+ "then": {
+ "en": "This parking has room for cargo bikes",
+ "nl": "Deze parking heeft plaats voor bakfietsen",
+ "fr": "TODO: fr",
+ "gl": "Este aparcadoiro ten espazo para bicicletas de carga."
+ }
+ },
+ {
+ "if": "cargo_bike=designated",
+ "then": {
+ "en": "This parking has designated (official) spots for cargo bikes.",
+ "nl": "Er zijn speciale plaatsen voorzien voor bakfietsen",
+ "fr": "TODO: fr",
+ "gl": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga."
+ }
+ },
+ {
+ "if": "cargo_bike=no",
+ "then": {
+ "en": "You're not allowed to park cargo bikes",
+ "nl": "Je mag hier geen bakfietsen parkeren",
+ "fr": "TODO: fr",
+ "gl": "Non está permitido aparcar bicicletas de carga"
+ }
+ }
+ ]
+ },
+ {
+ "question": {
+ "en": "How many cargo bicycles fit in this bicycle parking?",
+ "nl": "Voor hoeveel bakfietsen heeft deze fietsparking plaats?",
+ "fr": "Combien de vélos de transport entrent dans ce parking à vélos ?",
+ "gl": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?"
+ },
+ "render": {
+ "en": "This parking fits {capacity:cargo_bike} cargo bikes",
+ "nl": "Deze parking heeft plaats voor {capacity:cargo_bike} fietsen",
+ "fr": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport.",
+ "gl": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga"
+ },
+ "condition": "cargo_bike~designated|yes",
+ "freeform": {
+ "key": "capacity:cargo_bike",
+ "type": "nat"
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/assets/layers/bike_parking/parking.svg b/assets/layers/bike_parking/parking.svg
new file mode 100644
index 0000000..ee2fb72
--- /dev/null
+++ b/assets/layers/bike_parking/parking.svg
@@ -0,0 +1,18 @@
+
diff --git a/assets/layers/bike_parking/parking_old.svg b/assets/layers/bike_parking/parking_old.svg
new file mode 100644
index 0000000..b095bc1
--- /dev/null
+++ b/assets/layers/bike_parking/parking_old.svg
@@ -0,0 +1,93 @@
+
diff --git a/assets/themes/artwork/artwork.json b/assets/themes/artwork/artwork.json
index 18daa4f..9e8c48d 100644
--- a/assets/themes/artwork/artwork.json
+++ b/assets/themes/artwork/artwork.json
@@ -33,7 +33,17 @@
"en": "Artwork",
"nl": "Kunstwerk",
"fr": "Oeuvre d'art"
- }
+ },
+ "mappings": [
+ {
+ "if": "name~*",
+ "then": {
+ "en": "Artwork {name}",
+ "nl": "Kunstwerk {name}",
+ "fr": "Oeuvre d'art {name}"
+ }
+ }
+ ]
},
"icon": {
"render": "./assets/themes/artwork/artwork.svg"
@@ -177,22 +187,6 @@
}
]
},
- {
- "question": {
- "en": "Which wikidata-entry corresponds with this artwork?",
- "fr": "Quelle entrée wikidata correspond à cette œuvre d'art ?",
- "nl": "Welk wikidata-item beschrijft dit kunstwerk?"
- },
- "render": {
- "en": "Corresponds with {wikidata}",
- "nl": "Komt overeen met {wikidata}",
- "fr": "Correspond à {wikidata}"
- },
- "freeform": {
- "key": "wikidata",
- "type": "wikidata"
- }
- },
{
"question": {
"en": "Which artist created this?",
@@ -223,6 +217,22 @@
"key": "website",
"type": "url"
}
+ },
+ {
+ "question": {
+ "en": "Which wikidata-entry corresponds with this artwork?",
+ "fr": "Quelle entrée wikidata correspond à cette œuvre d'art ?",
+ "nl": "Welk wikidata-item beschrijft dit kunstwerk?"
+ },
+ "render": {
+ "en": "Corresponds with {wikidata}",
+ "nl": "Komt overeen met {wikidata}",
+ "fr": "Correspond à {wikidata}"
+ },
+ "freeform": {
+ "key": "wikidata",
+ "type": "wikidata"
+ }
}
]
}
diff --git a/customGenerator.ts b/customGenerator.ts
index c195cee..75dec57 100644
--- a/customGenerator.ts
+++ b/customGenerator.ts
@@ -10,11 +10,10 @@ import {GenerateEmpty} from "./UI/CustomGenerator/GenerateEmpty";
import PageSplit from "./UI/Base/PageSplit";
import HelpText from "./Customizations/HelpText";
import {TagRendering} from "./Customizations/TagRendering";
-import {FromJSON} from "./Customizations/JSON/FromJSON";
import {LayoutConfigJson} from "./Customizations/JSON/LayoutConfigJson";
-let layout = GenerateEmpty.createTestLayout();
+let layout = GenerateEmpty.createEmptyLayout();
if(window.location.hash.length > 10){
layout = JSON.parse(atob(window.location.hash.substr(1))) as LayoutConfigJson;
}
@@ -66,6 +65,6 @@ new TabbedComponent([
header: "",
content: new SharePanel(es, liveUrl)
}
-], 1).SetClass("main-tabs")
+]).SetClass("main-tabs")
.AttachTo("maindiv");
diff --git a/deploy.sh b/deploy.sh
index 789e889..c966e49 100755
--- a/deploy.sh
+++ b/deploy.sh
@@ -8,7 +8,7 @@ rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/*
cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/
cd /home/pietervdvn/git/pietervdvn.github.io/MapComplete/
-# git add . && git commit -m "New mapcomplete version" &&git push
+git add . && git commit -m "New mapcomplete version" &&git push
cd -
# clean up the mess we made
# rm *.js
diff --git a/index.css b/index.css
index 46a4f0e..2fe3ab9 100644
--- a/index.css
+++ b/index.css
@@ -1235,6 +1235,7 @@
padding: 1em;
display: inline-block;
width: 100%;
+ box-sizing: border-box;
}
.tab-single-header {