diff --git a/Customizations/Layers/Widths.ts b/Customizations/Layers/Widths.ts index ef4d10f..185ad6c 100644 --- a/Customizations/Layers/Widths.ts +++ b/Customizations/Layers/Widths.ts @@ -8,6 +8,7 @@ export class Widths extends LayerDefinition { private cyclistWidth: number; private carWidth: number; + private pedestrianWidth: number; private readonly _bothSideParking = new Tag("parking:lane:both", "parallel"); private readonly _noSideParking = new Tag("parking:lane:both", "no_parking"); @@ -17,6 +18,13 @@ export class Widths extends LayerDefinition { private readonly _rightSideParking = new And([new Tag("parking:lane:right", "parallel"), new Tag("parking:lane:left", "no_parking")]); + + private _sidewalkBoth = new Tag("sidewalk", "both"); + private _sidewalkLeft = new Tag("sidewalk", "left"); + private _sidewalkRight = new Tag("sidewalk", "right"); + private _sidewalkNone = new Tag("sidewalk", "none"); + + private readonly _oneSideParking = new Or([this._leftSideParking, this._rightSideParking]); private readonly _carfree = new Or([new Tag("highway", "pedestrian"), new Tag("highway", "living_street")]) @@ -38,13 +46,25 @@ export class Widths extends LayerDefinition { } + let pedestrianFlowNeeded = 0; + + if (this._sidewalkBoth.matchesProperties(properties)) { + pedestrianFlowNeeded = 0; + } else if (this._sidewalkNone.matchesProperties(properties)) { + pedestrianFlowNeeded = 2; + } else if (this._sidewalkLeft.matchesProperties(properties) || this._sidewalkRight.matches(properties)) { + pedestrianFlowNeeded = 1; + } else { + pedestrianFlowNeeded = -1; + } + + let onewayCar = properties.oneway === "yes"; let onewayBike = properties["oneway:bicycle"] === "yes" || (onewayCar && properties["oneway:bicycle"] === undefined) let carWidth = (onewayCar ? 1 : 2) * this.carWidth; - let cyclistWidth = (onewayBike ? 1 : 2) * this.cyclistWidth; const width = parseFloat(properties["width:carriageway"]); @@ -53,6 +73,7 @@ export class Widths extends LayerDefinition { const targetWidth = carWidth + cyclistWidth + + Math.max(0, pedestrianFlowNeeded) * this.pedestrianWidth + parallelParkingCount * this.carWidth; return { @@ -60,16 +81,25 @@ export class Widths extends LayerDefinition { parkingStateKnown: parkingStateKnown, width: width, targetWidth: targetWidth, - onewayBike: onewayBike + onewayBike: onewayBike, + pedestrianFlowNeeded: pedestrianFlowNeeded, } } constructor(carWidth: number, - cyclistWidth: number) { + cyclistWidth: number, + pedestrianWidth: number) { super(); this.carWidth = carWidth; this.cyclistWidth = cyclistWidth; + this.pedestrianWidth = pedestrianWidth; + + function r(n: number) { + const pre = Math.floor(n); + const post = Math.floor((n * 10) % 10); + return "" + pre + "." + post; + } this.name = "widths"; this.overpassFilter = new Tag("width:carriageway", "*"); @@ -85,33 +115,35 @@ export class Widths extends LayerDefinition { const self = this; this.style = (properties) => { - let c = "#0c0"; + let c = "#f00"; const props = self.calcProps(properties); - - if (props.width < props.targetWidth) { - c = "#f00"; + if (props.pedestrianFlowNeeded > 0) { + c = "#fa0" + } + if (props.width >= props.targetWidth) { + c = "#0c0"; } - let dashArray = undefined; - - if (!props.parkingStateKnown) { + if (!props.parkingStateKnown && properties["note:width:carriageway"] === undefined) { c = "#f0f" } - + if (this._carfree.matchesProperties(properties)) { c = "#aaa"; } + + // Mark probably wrong data + if (props.width > 15) { + c = "#f0f" + } + + let dashArray = undefined; if (props.onewayBike) { dashArray = [20, 8] } - - if (props.width > 15) { - c = "#ffb72b" - } - return { icon: null, color: c, @@ -122,28 +154,56 @@ export class Widths extends LayerDefinition { this.elementsToShow = [ new TagRenderingOptions({ + question: "Mogen auto's hier parkeren?", mappings: [ { k: this._bothSideParking, - txt: "Auto's kunnen langs beide zijden parkeren.Dit gebruikt " + (this.carWidth * 2) + "m
" + txt: "Auto's kunnen langs beide zijden parkeren.Dit gebruikt " + r(this.carWidth * 2) + "m
" }, { k: this._oneSideParking, - txt: "Auto's kunnen langs één kant parkeren.
Dit gebruikt " + this.carWidth + "m
" + txt: "Auto's kunnen langs één kant parkeren.
Dit gebruikt " + r(this.carWidth) + "m
" }, {k: this._noSideParking, txt: "Auto's mogen hier niet parkeren"}, - {k: null, txt: "Nog geen parkeerinformatie bekend"} - ] + // {k: null, txt: "Nog geen parkeerinformatie bekend"} + ], + freeform: { + key: "note:width:carriageway", + renderTemplate: "{note:width:carriageway}", + template: "$$$", + } }).OnlyShowIf(this._notCarFree), + + + new TagRenderingOptions({ + mappings: [ + { + k: this._sidewalkNone, + txt: "Deze straat heeft geen voetpaden. Voetgangers hebben hier " + r(this.pedestrianWidth * 2) + "m nodig" + }, + { + k: new Or([this._sidewalkLeft, this._sidewalkRight]), + txt: "Deze straat heeft een voetpad aan één kant. Voetgangers hebben hier " + r(this.pedestrianWidth) + "m nodig" + }, + {k: this._sidewalkBoth, txt: "Deze straat heeft voetpad aan beide zijden."}, + ], + freeform: { + key: "note:width:carriageway", + renderTemplate: "{note:width:carriageway}", + template: "$$$", + } + }).OnlyShowIf(this._notCarFree), + + new TagRenderingOptions({ mappings: [ { k: new Tag("oneway:bicycle", "yes"), - txt: "Eenrichtingsverkeer, óók voor fietsers. Dit gebruikt " + (this.carWidth + this.cyclistWidth) + "m" + txt: "Eenrichtingsverkeer, óók voor fietsers. Dit gebruikt " + r(this.carWidth + this.cyclistWidth) + "m" }, { k: new And([new Tag("oneway", "yes"), new Tag("oneway:bicycle", "no")]), - txt: "Tweerichtingverkeer voor fietsers, eenrichting voor auto's Dit gebruikt " + (this.carWidth + 2 * this.cyclistWidth) + "m" + txt: "Tweerichtingverkeer voor fietsers, eenrichting voor auto's Dit gebruikt " + r(this.carWidth + 2 * this.cyclistWidth) + "m" }, { k: new Tag("oneway", "yes"), @@ -151,7 +211,7 @@ export class Widths extends LayerDefinition { }, { k: null, - txt: "Tweerichtingsverkeer voor iedereen. Dit gebruikt " + (2 * this.carWidth + 2 * this.cyclistWidth) + "m" + txt: "Tweerichtingsverkeer voor iedereen. Dit gebruikt " + r(2 * this.carWidth + 2 * this.cyclistWidth) + "m" } ] }).OnlyShowIf(this._notCarFree), @@ -160,12 +220,16 @@ export class Widths extends LayerDefinition { { tagsPreprocessor: (tags) => { const props = self.calcProps(tags); - tags.targetWidth = props.targetWidth; - console.log("PREP", tags) + tags.targetWidth = r(props.targetWidth); + tags.short = ""; + if (props.width < props.targetWidth) { + tags.short = "Er is dus " + r(props.targetWidth - props.width) + "m te weinig" + } }, freeform: { key: "width:carriageway", - renderTemplate: "De totale nodige ruimte voor vlot en veilig verkeer is dus {targetWidth}m.", + renderTemplate: "De totale nodige ruimte voor vlot en veilig verkeer is dus {targetWidth}m
" + + "{short}", template: "$$$", } } diff --git a/Customizations/Layouts/StreetWidth.ts b/Customizations/Layouts/StreetWidth.ts index 1850d3e..85b403e 100644 --- a/Customizations/Layouts/StreetWidth.ts +++ b/Customizations/Layouts/StreetWidth.ts @@ -9,8 +9,9 @@ export class StreetWidth extends Layout{ super( "width", "Straatbreedtes in Brugge", [new Widths( - 2.2, - 1.5 + 2.0, + 1.5, + 0.75 )], 15, diff --git a/index.ts b/index.ts index 4e1ed19..f9902c9 100644 --- a/index.ts +++ b/index.ts @@ -41,7 +41,7 @@ if (location.hostname === "localhost" || location.hostname === "127.0.0.1") { 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 = "http://127.0.0.1:8080/streetwidths.geojson"; + //Overpass.testUrl = "http://127.0.0.1:8080/streetwidths.geojson"; } @@ -80,7 +80,7 @@ if (paramDict.layout) { } if (paramDict.test) { - dryRun = true; + dryRun = paramDict.test === "true"; } const layoutToUse = AllKnownLayouts.allSets[defaultLayout];