diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 3c6e3c3..b0dd76a 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -10,6 +10,8 @@ import { Layout } from "./Layout"; import {MetaMap} from "./Layouts/MetaMap"; import {Widths} from "./Layers/Widths"; import {StreetWidth} from "./Layouts/StreetWidth"; +import {NatureReserves} from "./Layers/NatureReserves"; +import {Natuurpunt} from "./Layouts/Natuurpunt"; export class AllKnownLayouts { public static allSets: any = AllKnownLayouts.AllLayouts(); @@ -24,6 +26,7 @@ export class AllKnownLayouts { new WalkByBrussels(), new MetaMap(), new StreetWidth(), + new Natuurpunt(), all /*new Toilets(), new Statues(), diff --git a/Customizations/LayerDefinition.ts b/Customizations/LayerDefinition.ts index 8044374..1065f43 100644 --- a/Customizations/LayerDefinition.ts +++ b/Customizations/LayerDefinition.ts @@ -62,9 +62,9 @@ export class LayerDefinition { * icon is the Leaflet icon * Note that this is passed entirely to leaflet, so other leaflet attributes work too */ - style: (tags: any) => { - color: string, - icon: any , + style: (tags: any) => { + color: string, + icon: any, }; /** @@ -73,6 +73,36 @@ export class LayerDefinition { maxAllowedOverlapPercentage: number = undefined; + constructor(options: { + name: string, + newElementTags: Tag[], + icon: string, + minzoom: number, + overpassFilter: TagsFilter, + title?: TagRenderingOptions, + elementsToShow?: TagDependantUIElementConstructor[], + maxAllowedOverlapPercentage?: number, + style?: (tags: any) => { + color: string, + icon: any + } + } = undefined) { + if (options === undefined) { + console.log("No options!") + return; + } + this.name = options.name; + this.maxAllowedOverlapPercentage = options.maxAllowedOverlapPercentage ?? 0; + this.newElementTags = options.newElementTags; + this.icon = options.icon; + this.minzoom = options.minzoom; + this.overpassFilter = options.overpassFilter; + this.title = options.title; + this.elementsToShow = options.elementsToShow; + this.style = options.style; + console.log(this) + } + asLayer(basemap: Basemap, allElements: ElementStorage, changes: Changes, userDetails: UIEventSource, selectedElement: UIEventSource, showOnPopup: (tags: UIEventSource<(any)>) => UIElement): FilteredLayer { diff --git a/Customizations/Layers/Birdhide.ts b/Customizations/Layers/Birdhide.ts new file mode 100644 index 0000000..52ce774 --- /dev/null +++ b/Customizations/Layers/Birdhide.ts @@ -0,0 +1,146 @@ +import {LayerDefinition} from "../LayerDefinition"; +import {And, Or, Tag} from "../../Logic/TagsFilter"; +import {TagRenderingOptions} from "../TagRendering"; +import FixedText from "../Questions/FixedText"; +import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; +import L from "leaflet"; + +export class Birdhide extends LayerDefinition { + + private static readonly birdhide = new Tag("leisure", "bird_hide"); + + + constructor() { + super({ + name: "vogelkijkplaats", + overpassFilter: Birdhide.birdhide, + elementsToShow: [new FixedText("hi")], + icon: "assets/nature/birdhide.svg", + minzoom: 12, + newElementTags: [Birdhide.birdhide], + style(tags: any): { color: string; icon: any } { + return {color: "", icon: undefined}; + }, + }); + + function rmStart(toRemove: string, title: string): string { + if (title.toLowerCase().indexOf(toRemove.toLowerCase()) == 0) { + return title.substr(toRemove.length).trim(); + } + return title; + + } + + function rmStarts(toRemove: string[], title: string) { + for (const toRm of toRemove) { + title = rmStart(toRm, title); + } + return title; + } + + this.title = new TagRenderingOptions({ + tagsPreprocessor: (tags) => { + if (tags.name) { + const nm = + rmStarts( + ["Vogelkijkhut", "Vogelkijkwand", "Kijkwand", "Kijkhut"], + tags.name); + + tags.name = " '" + nm + "'"; + } else { + tags.name = ""; + } + }, + mappings: [ + { + k: new And([new Tag("shelter", "no"), new Tag("building", "")]), + txt: "Vogelkijkwand{name}" + }, + { + k: new And([new Tag("amenity", "shelter"), new Tag("building", "yes")]), + txt: "Vogelijkhut{name}" + }, + { + k: new Tag("amenity", "shelter"), + txt: "Vogelijkhut{name}" + }, + { + k: new Tag("building", "yes"), + txt: "Vogelijkhut{name}" + }, + {k: null, txt: "Vogelkijkplaats{name}"} + ] + }); + + + this.style = (properties) => { + let icon = "assets/nature/birdhide.svg"; + if (new Or([new Tag("amenity", "shelter"), new Tag("building", "yes"), new Tag("shelter", "yes")]).matchesProperties(properties)) { + icon = "assets/nature/birdshelter.svg"; + } + + return { + color: "#0000bb", + icon: L.icon({ + iconUrl: icon, + iconSize: [40,40], + iconAnchor: [20,20] + }) + } + } + + + this.elementsToShow = [ + new ImageCarouselWithUploadConstructor(), + + new TagRenderingOptions({ + question: "Is dit een kijkwand of kijkhut?", + mappings: [ + { + k: new And([new Tag("shelter", "no"), new Tag("building", ""), new Tag("amenity", "")]), + txt: "Vogelkijkwand" + }, + { + k: new And([new Tag("amenity", "shelter"), new Tag("building", "yes"), new Tag("shelter", "yes")]), + txt: "Vogelijkhut" + } + ] + }), + new TagRenderingOptions({ + question: "Is ze rolstoeltoegankelijk?", + mappings: [ + { + k: new Tag("wheelchair", "no"), + txt: "Niet rolstoeltoegankelijk" + }, + { + k: new Tag("wheelchair", "limited"), + txt: "Een rolstoel raakt er, maar het is niet makkelijk" + }, + { + k: new Tag("wheelchair", "yes"), + txt: "Een rolstoel raakt er gemakkelijk" + } + ] + }), + + new TagRenderingOptions({ + question: "Wie beheert deze?", + freeform: { + key: "operator", + template: "Beheer door $$$", + renderTemplate: "Beheer door {operator}", + placeholder: "organisatie" + }, + mappings: [ + {k: new Tag("operator", "Natuurpunt"), txt: "Natuurpunt"}, + {k: new Tag("operator", "Agentschap Natuur en Bos"), txt: "het Agentschap Natuur en Bos (ANB)"}, + + ] + }) + + + ]; + + } +} \ No newline at end of file diff --git a/Customizations/Layers/InformationBoard.ts b/Customizations/Layers/InformationBoard.ts new file mode 100644 index 0000000..34770df --- /dev/null +++ b/Customizations/Layers/InformationBoard.ts @@ -0,0 +1,112 @@ +import {LayerDefinition} from "../LayerDefinition"; +import FixedText from "../Questions/FixedText"; +import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload"; +import {TagRenderingOptions} from "../TagRendering"; +import {And, Tag} from "../../Logic/TagsFilter"; +import L from "leaflet"; + +export class InformationBoard extends LayerDefinition { + constructor() { + super({ + name: "Informatiebord", + minzoom: 12, + overpassFilter: new Tag("tourism", "information"), + newElementTags: [new Tag("tourism", "information")], + maxAllowedOverlapPercentage: 0, + icon: "assets/nature/info.png", + }); + + const isMap = new Tag("information", "map"); + const isOsmSource = new Tag("map_source", "OpenStreetMap"); + + this.title = new TagRenderingOptions({ + mappings: [ + {k: isMap, txt: "Kaart"}, + {k:null, txt: "Informatiebord"} + ] + }); + + this.style = (properties) => { + let icon = "assets/nature/info.png"; + if (isMap.matchesProperties(properties)) { + icon = "assets/map.svg"; + if (isOsmSource.matchesProperties(properties)) { + icon = "assets/osm-logo-white-bg.svg"; + + const attr = properties["map_source:attribution"]; + if (attr == "sticker") { + icon = "assets/map-stickered.svg" + } else if (attr == "no") { + icon = "assets/osm-logo-buggy-attr.svg" + } + } + } + + return { + color: "#000000", + icon: L.icon( + { + iconUrl: icon, + iconSize: [50, 50] + } + ) + }; + } + + + this.elementsToShow = [ + + new ImageCarouselWithUploadConstructor(), + + new TagRenderingOptions({ + question: "Heeft dit informatiebord een kaart?", + mappings: [ + {k: new Tag("information","board"), txt: "Dit is een informatiebord"}, + {k: isMap, txt: "Dit is een kaart"} + ] + }), + + new TagRenderingOptions({ + question: "Is this map based on OpenStreetMap?", + mappings: [ + { + k: isOsmSource, + txt: "This map is based on OpenStreetMap" + }, + ], + freeform: { + key: "map_source", + renderTemplate: "The map data is based on {map_source}", + template: "The map data is based on $$$" + } + }).OnlyShowIf(isMap), + new TagRenderingOptions({ + question: "Is the attribution present?", + mappings: [ + { + k: new Tag("map_source:attribution", "yes"), + txt: "OpenStreetMap is clearly attribute, including the ODBL-license" + }, + { + k: new Tag("map_source:attribution", "incomplete"), + txt: "OpenStreetMap is clearly attribute, but the license is not mentioned" + }, + { + k: new Tag("map_source:attribution", "sticker"), + txt: "OpenStreetMap wasn't mentioned, but someone put an OpenStreetMap-sticker on it" + }, + { + k: new Tag("map_source:attribution", "no"), + txt: "There is no attribution at all" + }, + { + k: new Tag("map_source:attribution", "none"), + txt: "There is no attribution at all" + } + ] + }).OnlyShowIf(new Tag("map_source", "OpenStreetMap")) + ] + + + } +} \ No newline at end of file diff --git a/Customizations/Layers/NatureReserves.ts b/Customizations/Layers/NatureReserves.ts index 5d49292..b430405 100644 --- a/Customizations/Layers/NatureReserves.ts +++ b/Customizations/Layers/NatureReserves.ts @@ -10,18 +10,18 @@ import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWi export class NatureReserves extends LayerDefinition { - constructor() { + constructor(moreQuests: boolean = false) { super(); this.name = "natuurgebied"; this.icon = "./assets/tree_white_background.svg"; this.overpassFilter = - new Or([new Tag("leisure", "nature_reserve"), new Tag("boundary","protected_area")]); + new Or([new Tag("leisure", "nature_reserve"), new Tag("boundary", "protected_area")]); this.maxAllowedOverlapPercentage = 10; this.newElementTags = [new Tag("leisure", "nature_reserve"), new Tag("fixme", "Toegevoegd met MapComplete, geometry nog uit te tekenen")] this.minzoom = 13; - this.title = new NameInline("natuurreservaat"); + this.title = new NameInline("natuurreservaat"); this.style = this.generateStyleFunction(); this.elementsToShow = [ new ImageCarouselWithUploadConstructor(), @@ -30,6 +30,67 @@ export class NatureReserves extends LayerDefinition { new OperatorTag(), new DescriptionQuestion("natuurgebied") ]; + + + const extraRenderings = [ + new TagRenderingOptions({ + question: "Mogen honden in dit natuurgebied?", + mappings: [ + {k: new Tag("dog", "leashed"), txt: "Honden moeten aan de leiband"}, + {k: new Tag("dog", "no"), txt: "Honden zijn niet toegestaan"}, + {k: new Tag("dog", "yes"), txt: "Honden zijn welkom"}, + ] + }).OnlyShowIf(new Tag("access", "yes")), + new TagRenderingOptions({ + question: "Op welke website kunnen we meer informatie vinden over dit natuurgebied?", + freeform: { + key:"website", + renderTemplate: "Meer informatie", + template: "$$$" + } + }), + new TagRenderingOptions({ + question: "Wie is de conservator van dit gebied?
" + + "Geef de naam van de conservator énkel als die duidelijk online staat gepubliceerd.", + freeform: { + renderTemplate: "De conservator van dit gebied is {curator}", + template: "$$$", + key: "curator" + } + }), + new TagRenderingOptions( + { + question: "Wat is het email-adres van de beheerder?
" + + "Geef bij voorkeur het emailadres van de Natuurpunt-afdeling; geef enkel een email-adres van de conservator als dit duidelijk is gepubliceerd", + freeform: { + renderTemplate: "Bij problemen of vragen, de {conservator} kan bereikt worden via " + + "{email}", + template: "$$$", + key: "email" + } + }), + new TagRenderingOptions( + { + question: "Wat is het telefoonnummer van de beheerder?
" + + "Geef bij voorkeur het telefoonnummer van de Natuurpunt-afdeling; geef enkel een email-adres van de conservator als dit duidelijk is gepubliceerd", + freeform: { + renderTemplate: "Bij problemen of vragen, de {conservator} kan bereikt worden via " + + "{phone}", + template: "$$$", + key: "phone" + } + + }), + + + ]; + + if (moreQuests) { + this.elementsToShow = + this.elementsToShow.concat(extraRenderings); + } + + } diff --git a/Customizations/Layers/Widths.ts b/Customizations/Layers/Widths.ts index a619699..c17329b 100644 --- a/Customizations/Layers/Widths.ts +++ b/Customizations/Layers/Widths.ts @@ -101,6 +101,7 @@ export class Widths extends LayerDefinition { this.carWidth = carWidth; this.cyclistWidth = cyclistWidth; this.pedestrianWidth = pedestrianWidth; + this.minzoom = 12; function r(n: number) { const pre = Math.floor(n); @@ -254,7 +255,7 @@ export class Widths extends LayerDefinition { new TagRenderingOptions({ mappings: [ {k:new Tag("highway","living_street"),txt: "Dit is een woonerf"}, - {k:new Tag("highway","pedestrian"),txt: "Hier mogen enkel voetgangers komen"} + {k:new Tag("highway","pedestrian"),txt: "Deze weg is autovrij"} ] }), diff --git a/Customizations/Layouts/Natuurpunt.ts b/Customizations/Layouts/Natuurpunt.ts new file mode 100644 index 0000000..8216fcb --- /dev/null +++ b/Customizations/Layouts/Natuurpunt.ts @@ -0,0 +1,20 @@ +import {Layout} from "../Layout"; +import {Birdhide} from "../Layers/Birdhide"; +import {InformationBoard} from "../Layers/InformationBoard"; +import {NatureReserves} from "../Layers/NatureReserves"; + +export class Natuurpunt extends Layout{ + constructor() { + super( + "natuurpunt", + "De natuur in", + [new Birdhide(), new InformationBoard(), new NatureReserves(true)], + 12, + 51.20875, + 3.22435, + "

Natuurpuntstuff

", + "", + "" + ); + } +} \ No newline at end of file diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index 03fdc05..76a9d9c 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -104,7 +104,7 @@ export class FilteredLayer { const notShadowed = []; for (const feature of leftoverFeatures) { - if (this._maxAllowedOverlap !== undefined && this._maxAllowedOverlap >= 0) { + if (this._maxAllowedOverlap !== undefined && this._maxAllowedOverlap > 0) { if (GeoOperations.featureIsContainedInAny(feature, selfFeatures, this._maxAllowedOverlap)) { // This feature is filtered away continue; diff --git a/assets/bike_pump.svg b/assets/bike_pump.svg deleted file mode 100644 index b4c7c96..0000000 --- a/assets/bike_pump.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/assets/ghost_bike.svg b/assets/ghost_bike.svg deleted file mode 100644 index 1befcb7..0000000 --- a/assets/ghost_bike.svg +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/assets/github.svg b/assets/github.svg deleted file mode 100644 index 93af7db..0000000 --- a/assets/github.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/assets/nature/ANB.jpg b/assets/nature/ANB.jpg new file mode 100644 index 0000000..9ac4776 Binary files /dev/null and b/assets/nature/ANB.jpg differ diff --git a/assets/nature/Natuurpunt.jpg b/assets/nature/Natuurpunt.jpg new file mode 100644 index 0000000..f91c493 Binary files /dev/null and b/assets/nature/Natuurpunt.jpg differ diff --git a/assets/nature/birdhide.png b/assets/nature/birdhide.png new file mode 100644 index 0000000..d1d5513 Binary files /dev/null and b/assets/nature/birdhide.png differ diff --git a/assets/nature/birdhide.svg b/assets/nature/birdhide.svg new file mode 100644 index 0000000..f08f667 --- /dev/null +++ b/assets/nature/birdhide.svg @@ -0,0 +1,65 @@ + + + + + + + + image/svg+xml + + + + + + + + diff --git a/assets/nature/birdhideMapnik.svg b/assets/nature/birdhideMapnik.svg new file mode 100644 index 0000000..5f1c248 --- /dev/null +++ b/assets/nature/birdhideMapnik.svg @@ -0,0 +1,14 @@ + + + + + + + image/svg+xml + + + + + + + \ No newline at end of file diff --git a/assets/nature/birdshelter.inkscape.svg b/assets/nature/birdshelter.inkscape.svg new file mode 100644 index 0000000..03bd90c --- /dev/null +++ b/assets/nature/birdshelter.inkscape.svg @@ -0,0 +1,82 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/assets/nature/birdshelter.png b/assets/nature/birdshelter.png new file mode 100644 index 0000000..d5b2303 Binary files /dev/null and b/assets/nature/birdshelter.png differ diff --git a/assets/nature/birdshelter.svg b/assets/nature/birdshelter.svg new file mode 100644 index 0000000..9143498 --- /dev/null +++ b/assets/nature/birdshelter.svg @@ -0,0 +1,35 @@ + + + + + + + image/svg+xml + + + + + + + + diff --git a/assets/nature/info.png b/assets/nature/info.png new file mode 100644 index 0000000..35a2cc1 Binary files /dev/null and b/assets/nature/info.png differ diff --git a/assets/nature/natuurpunt_logo_zwart.png b/assets/nature/natuurpunt_logo_zwart.png new file mode 100644 index 0000000..41dfab4 Binary files /dev/null and b/assets/nature/natuurpunt_logo_zwart.png differ diff --git a/assets/nature/shelter.svg b/assets/nature/shelter.svg new file mode 100644 index 0000000..57eb695 --- /dev/null +++ b/assets/nature/shelter.svg @@ -0,0 +1,14 @@ + + + + + + + image/svg+xml + + + + + + + \ No newline at end of file diff --git a/assets/tree.svg b/assets/tree.svg deleted file mode 100644 index 436c0ee..0000000 --- a/assets/tree.svg +++ /dev/null @@ -1,167 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/assets/tree_white_background.svg b/assets/tree_white_background.svg deleted file mode 100644 index 30473fb..0000000 --- a/assets/tree_white_background.svg +++ /dev/null @@ -1,1036 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -