diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index 9a8728e..7f1c558 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -1,22 +1,24 @@ -import {Groen} from "./Layouts/Groen"; -import {Toilets} from "./Layouts/Toilets"; -import {GRB} from "./Layouts/GRB"; -import {Statues} from "./Layouts/Statues"; -import {Bookcases} from "./Layouts/Bookcases"; +import { Groen } from "./Layouts/Groen"; +import { Toilets } from "./Layouts/Toilets"; +import { GRB } from "./Layouts/GRB"; +import { Statues } from "./Layouts/Statues"; +import { Bookcases } from "./Layouts/Bookcases"; import Cyclofix from "./Layouts/Cyclofix"; -import {All} from "./Layouts/All"; -import {Layout} from "./Layout"; +import { WalkByBrussels } from "./Layouts/WalkByBrussels"; +import { All } from "./Layouts/All"; +import { Layout } from "./Layout"; export class AllKnownLayouts { public static allSets: any = AllKnownLayouts.AllLayouts(); - private static AllLayouts() : any{ + private static AllLayouts(): any { const all = new All(); - const layouts : Layout[] = [ + const layouts: Layout[] = [ new Groen(), new GRB(), new Cyclofix(), new Bookcases(), + new WalkByBrussels(), all /*new Toilets(), new Statues(), @@ -29,4 +31,13 @@ export class AllKnownLayouts { } return allSets; } + + public static GetSets(layoutNames): any { + const all = new All(); + for (const name of layoutNames) { + all.layers = all.layers.concat(AllKnownLayouts.allSets[name].layers); + } + + return all; + } } diff --git a/Customizations/Layers/DrinkingWater.ts b/Customizations/Layers/DrinkingWater.ts new file mode 100644 index 0000000..56984a3 --- /dev/null +++ b/Customizations/Layers/DrinkingWater.ts @@ -0,0 +1,61 @@ +import { LayerDefinition } from "../LayerDefinition"; +import { And, Or, Tag } from "../../Logic/TagsFilter"; +import { OperatorTag } from "../Questions/OperatorTag"; +import * as L from "leaflet"; +import FixedText from "../Questions/FixedText"; +import { BikeParkingType } from "../Questions/BikeParkingType"; +import { TagRenderingOptions } from "../TagRendering"; +import { ImageCarouselWithUploadConstructor } from "../../UI/Image/ImageCarouselWithUpload"; + +export class DrinkingWaterLayer extends LayerDefinition { + + constructor() { + super(); + this.name = "drinking_water"; + this.icon = "./assets/bug.svg"; + + this.overpassFilter = new Or([ + new And([ + new Tag("amenity", "drinking_water") + ]) + ]); + + + this.newElementTags = [ + new Tag("amenity", "drinking_water"), + ]; + this.maxAllowedOverlapPercentage = 10; + + this.minzoom = 13; + this.style = this.generateStyleFunction(); + this.title = new FixedText("Drinking water"); + this.elementsToShow = [ + new OperatorTag(), + new BikeParkingType() + ]; + this.elementsToShow = [new ImageCarouselWithUploadConstructor(), new TagRenderingOptions({ + question: "How easy is it to fill water bottles?", + mappings: [ + { k: new Tag("bottle", "yes"), txt: "It is easy to refill water bottles" }, + { k: new Tag("bottle", "no"), txt: "Water bottles may not fit" } + ], + })]; + + } + + + private generateStyleFunction() { + const self = this; + return function (properties: any) { + + return { + color: "#00bb00", + icon: new L.icon({ + iconUrl: self.icon, + iconSize: [40, 40] + }) + }; + }; + } + +} \ No newline at end of file diff --git a/Customizations/Layouts/WalkByBrussels.ts b/Customizations/Layouts/WalkByBrussels.ts new file mode 100644 index 0000000..88126a1 --- /dev/null +++ b/Customizations/Layouts/WalkByBrussels.ts @@ -0,0 +1,29 @@ +import { Layout } from "../Layout"; +import { DrinkingWaterLayer } from "../Layers/DrinkingWater"; +import { NatureReserves } from "../Layers/NatureReserves"; +import { Park } from "../Layers/Park"; +import { BikeParkings } from "../Layers/BikeParkings"; + +export class WalkByBrussels extends Layout { + constructor() { + super("walkbybrussels", + "Drinking Water Spots", + [new DrinkingWaterLayer(), new BikeParkings(), new Park(), new NatureReserves()], + 10, + 50.8435, + 4.3688, + + + "

Drinking water

\n" + + "\n" + + "

" + + "Help with creating a map of drinking water points!" + + , + "

Start by creating an account\n" + + " or by " + + " logging in.

", + "Start by clicking a pin and answering the questions"); + } + +} \ No newline at end of file diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index 87ba7c6..ee936f7 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -1,11 +1,11 @@ -import {Basemap} from "./Basemap"; -import {TagsFilter, TagUtils} from "./TagsFilter"; -import {UIEventSource} from "../UI/UIEventSource"; -import {ElementStorage} from "./ElementStorage"; -import {Changes} from "./Changes"; +import { Basemap } from "./Basemap"; +import { TagsFilter, TagUtils } from "./TagsFilter"; +import { UIEventSource } from "../UI/UIEventSource"; +import { ElementStorage } from "./ElementStorage"; +import { Changes } from "./Changes"; import L from "leaflet" -import {GeoOperations} from "./GeoOperations"; -import {UIElement} from "../UI/UIElement"; +import { GeoOperations } from "./GeoOperations"; +import { UIElement } from "../UI/UIElement"; /*** * A filtered layer is a layer which offers a 'set-data' function @@ -20,6 +20,7 @@ export class FilteredLayer { public readonly name: string; public readonly filters: TagsFilter; + public readonly isDisplayed: UIEventSource = new UIEventSource(true); private readonly _map: Basemap; private readonly _maxAllowedOverlap: number; @@ -65,6 +66,16 @@ export class FilteredLayer { this._style = style; this._storage = storage; this._maxAllowedOverlap = maxAllowedOverlap; + const self = this; + this.isDisplayed.addCallback(function (isDisplayed) { + if (self._geolayer !== undefined && self._geolayer !== null) { + if (isDisplayed) { + self._geolayer.addTo(self._map.map); + } else { + self._map.map.removeLayer(self._geolayer); + } + } + }) } @@ -174,7 +185,7 @@ export class FilteredLayer { radius: 25, color: style.color }); - + } else { marker = L.marker(latLng, { icon: style.icon @@ -206,7 +217,9 @@ export class FilteredLayer { } }); - this._geolayer.addTo(this._map.map); + if (this.isDisplayed.data) { + this._geolayer.addTo(this._map.map); + } } diff --git a/index.ts b/index.ts index 6696d39..9b4b0f2 100644 --- a/index.ts +++ b/index.ts @@ -24,14 +24,12 @@ import {AllKnownLayouts} from "./Customizations/AllKnownLayouts"; import {All} from "./Customizations/Layouts/All"; - - // --------------------- Read the URL parameters ----------------- // @ts-ignore -if(location.href.startsWith("http://buurtnatuur.be")){ +if (location.href.startsWith("http://buurtnatuur.be")) { // Reload the https version. This is important for the 'locate me' button - window.location.replace("https://buurtnatuur.be"); + window.location.replace("https://buurtnatuur.be"); } @@ -40,7 +38,7 @@ let dryRun = false; if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { // Set to true if testing and changes should NOT be saved - // dryRun = true; + dryRun = true; // If you have a testfile somewhere, enable this to spoof overpass // This should be hosted independantly, e.g. with `cd assets; webfsd -p 8080` + a CORS plugin to disable cors rules Overpass.testUrl = null; // "http://127.0.0.1:8080/test.json"; @@ -75,8 +73,6 @@ if (window.location.search) { var kv = param.split("="); paramDict[kv[0]] = kv[1]; } - - } if (paramDict.layout) { @@ -141,7 +137,7 @@ const bm = new Basemap("leafletDiv", locationControl, new VariableUiElement( // ------------- Setup the layers ------------------------------- - +const controls = {}; const addButtons: { name: string, icon: string, @@ -171,6 +167,8 @@ for (const layer of layoutToUse.layers) { const flayer = layer.asLayer(bm, allElements, changes, osmConnection.userDetails, selectedElement, generateInfo); + controls[layer.name] = flayer.isDisplayed; + const addButton = { name: layer.name, icon: layer.icon, @@ -253,7 +251,9 @@ leftMessage.setData(welcomeMessage); welcomeMessage().AttachTo("messagesbox"); -var messageBox = new MessageBoxHandler(leftMessage, () => {selectedElement.setData(undefined)}); +var messageBox = new MessageBoxHandler(leftMessage, () => { + selectedElement.setData(undefined) +}); new CenterMessageBox( minZoom, @@ -276,4 +276,4 @@ new GeoLocationHandler(bm).AttachTo("geolocate-button"); // --------------- Send a ping to start various action -------- locationControl.ping(); -messageBox.update(); +messageBox.update(); \ No newline at end of file