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 {