Merge branches
This commit is contained in:
commit
19f69b31a4
24 changed files with 676 additions and 110 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ dist/*
|
||||||
node_modules
|
node_modules
|
||||||
.cache/*
|
.cache/*
|
||||||
.idea/*
|
.idea/*
|
||||||
|
scratch
|
||||||
|
|
0
Customizations/Layers/BikeCafes.ts
Normal file
0
Customizations/Layers/BikeCafes.ts
Normal file
114
Customizations/Layers/BikeOtherShops.ts
Normal file
114
Customizations/Layers/BikeOtherShops.ts
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
import { LayerDefinition } from "../LayerDefinition";
|
||||||
|
import Translations from "../../UI/i18n/Translations";
|
||||||
|
import {And, Tag, Or} from "../../Logic/TagsFilter";
|
||||||
|
import { ImageCarouselWithUploadConstructor } from "../../UI/Image/ImageCarouselWithUpload";
|
||||||
|
import ShopRetail from "../Questions/bike/ShopRetail";
|
||||||
|
import ShopPump from "../Questions/bike/ShopPump";
|
||||||
|
import ShopRental from "../Questions/bike/ShopRental";
|
||||||
|
import ShopRepair from "../Questions/bike/ShopRepair";
|
||||||
|
import ShopDiy from "../Questions/bike/ShopDiy";
|
||||||
|
import ShopName from "../Questions/bike/ShopName";
|
||||||
|
import ShopSecondHand from "../Questions/bike/ShopSecondHand";
|
||||||
|
import { TagRenderingOptions } from "../TagRendering";
|
||||||
|
import { PhoneNumberQuestion } from "../Questions/PhoneNumberQuestion";
|
||||||
|
import Website from "../Questions/Website";
|
||||||
|
|
||||||
|
|
||||||
|
function anyValueExcept(key: string, exceptValue: string) {
|
||||||
|
return new And([
|
||||||
|
new Tag(key, "*"),
|
||||||
|
new Tag(key, exceptValue, true)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class BikeOtherShops extends LayerDefinition {
|
||||||
|
private readonly sellsBikes = new Tag("service:bicycle:retail", "yes")
|
||||||
|
private readonly repairsBikes = anyValueExcept("service:bicycle:repair", "no")
|
||||||
|
private readonly rentsBikes = new Tag("service:bicycle:rental", "yes")
|
||||||
|
private readonly hasPump = new Tag("service:bicycle:pump", "yes")
|
||||||
|
private readonly hasDiy = new Tag("service:bicycle:diy", "yes")
|
||||||
|
private readonly sellsSecondHand = anyValueExcept("service:bicycle:repair", "no")
|
||||||
|
private readonly hasBikeServices = new Or([
|
||||||
|
this.sellsBikes,
|
||||||
|
this.repairsBikes,
|
||||||
|
// this.rentsBikes,
|
||||||
|
// this.hasPump,
|
||||||
|
// this.hasDiy,
|
||||||
|
// this.sellsSecondHand
|
||||||
|
])
|
||||||
|
|
||||||
|
private readonly to = Translations.t.cyclofix.nonBikeShop
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.name = this.to.name
|
||||||
|
this.icon = "./assets/bike/non_bike_repair_shop.svg"
|
||||||
|
this.overpassFilter = new And([
|
||||||
|
anyValueExcept("shop", "bicycle"),
|
||||||
|
this.hasBikeServices
|
||||||
|
])
|
||||||
|
this.newElementTags = undefined
|
||||||
|
this.maxAllowedOverlapPercentage = 10
|
||||||
|
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY
|
||||||
|
|
||||||
|
this.minzoom = 13;
|
||||||
|
this.style = this.generateStyleFunction();
|
||||||
|
this.title = new TagRenderingOptions({
|
||||||
|
mappings: [
|
||||||
|
{
|
||||||
|
k: new And([new Tag("name", "*"), this.sellsBikes]),
|
||||||
|
txt: this.to.titleShopNamed
|
||||||
|
},
|
||||||
|
{
|
||||||
|
k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "")]),
|
||||||
|
txt: this.to.titleShop
|
||||||
|
},
|
||||||
|
{
|
||||||
|
k: new And([new Tag("name", "*"), new Tag("service:bicycle:retail", "no")]),
|
||||||
|
txt: this.to.titleRepairNamed
|
||||||
|
},
|
||||||
|
{k: this.sellsBikes, txt: this.to.titleShop},
|
||||||
|
{k: new Tag("service:bicycle:retail", " "), txt: this.to.title},
|
||||||
|
{k: new Tag("service:bicycle:retail", "no"), txt: this.to.titleRepair},
|
||||||
|
{
|
||||||
|
k: new And([new Tag("name", "*")]),
|
||||||
|
txt: this.to.titleNamed
|
||||||
|
},
|
||||||
|
{k: null, txt: this.to.title},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
this.elementsToShow = [
|
||||||
|
new ImageCarouselWithUploadConstructor(),
|
||||||
|
new ShopName(),
|
||||||
|
new PhoneNumberQuestion("{name}"),
|
||||||
|
new Website("{name}"),
|
||||||
|
new ShopRetail(),
|
||||||
|
new ShopRental(),
|
||||||
|
new ShopRepair(),
|
||||||
|
new ShopPump(),
|
||||||
|
new ShopDiy(),
|
||||||
|
new ShopSecondHand()
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
private generateStyleFunction() {
|
||||||
|
const self = this;
|
||||||
|
return function (tags: any) {
|
||||||
|
let icon = "assets/bike/non_bike_repair_shop.svg";
|
||||||
|
|
||||||
|
if (self.sellsBikes.matchesProperties(tags)) {
|
||||||
|
icon = "assets/bike/non_bike_shop.svg";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
color: "#00bb00",
|
||||||
|
icon: {
|
||||||
|
iconUrl: icon,
|
||||||
|
iconSize: [50, 50],
|
||||||
|
iconAnchor: [25, 50]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,19 @@
|
||||||
import {LayerDefinition} from "../LayerDefinition";
|
import {LayerDefinition} from "../LayerDefinition";
|
||||||
import {And, Or, Tag} from "../../Logic/TagsFilter";
|
import {And, Or, Tag, TagsFilter} from "../../Logic/TagsFilter";
|
||||||
import {OperatorTag} from "../Questions/OperatorTag";
|
import {OperatorTag} from "../Questions/OperatorTag";
|
||||||
import FixedText from "../Questions/FixedText";
|
import FixedText from "../Questions/FixedText";
|
||||||
import ParkingType from "../Questions/bike/ParkingType";
|
import ParkingType from "../Questions/bike/ParkingType";
|
||||||
|
import ParkingCapacity from "../Questions/bike/ParkingCapacity";
|
||||||
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
|
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
|
||||||
import BikeStationOperator from "../Questions/bike/StationOperator";
|
|
||||||
import Translations from "../../UI/i18n/Translations";
|
import Translations from "../../UI/i18n/Translations";
|
||||||
import ParkingOperator from "../Questions/bike/ParkingOperator";
|
import ParkingOperator from "../Questions/bike/ParkingOperator";
|
||||||
import {TagRenderingOptions} from "../TagRendering";
|
import ParkingAccessCargo from "../Questions/bike/ParkingAccessCargo";
|
||||||
|
import ParkingCapacityCargo from "../Questions/bike/ParkingCapacityCargo";
|
||||||
|
|
||||||
|
|
||||||
export default class BikeParkings extends LayerDefinition {
|
export default class BikeParkings extends LayerDefinition {
|
||||||
|
private readonly accessCargoDesignated = new Tag("cargo_bike", "designated");
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.name = Translations.t.cyclofix.parking.name;
|
this.name = Translations.t.cyclofix.parking.name;
|
||||||
|
@ -28,14 +31,9 @@ export default class BikeParkings extends LayerDefinition {
|
||||||
new ImageCarouselWithUploadConstructor(),
|
new ImageCarouselWithUploadConstructor(),
|
||||||
//new ParkingOperator(),
|
//new ParkingOperator(),
|
||||||
new ParkingType(),
|
new ParkingType(),
|
||||||
new TagRenderingOptions({
|
new ParkingCapacity(),
|
||||||
question: "How many bicycles fit in this bicycle parking?",
|
new ParkingAccessCargo(),
|
||||||
freeform: {
|
new ParkingCapacityCargo().OnlyShowIf(this.accessCargoDesignated)
|
||||||
key: "capacity",
|
|
||||||
renderTemplate: "Place for {capacity} bikes",
|
|
||||||
template: "$nat$ bikes fit in here"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY;
|
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { LayerDefinition } from "../LayerDefinition";
|
import { LayerDefinition } from "../LayerDefinition";
|
||||||
import Translations from "../../UI/i18n/Translations";
|
import Translations from "../../UI/i18n/Translations";
|
||||||
import {And, Tag} from "../../Logic/TagsFilter";
|
import {And, Tag, Or} from "../../Logic/TagsFilter";
|
||||||
import FixedText from "../Questions/FixedText";
|
import FixedText from "../Questions/FixedText";
|
||||||
import { ImageCarouselWithUploadConstructor } from "../../UI/Image/ImageCarouselWithUpload";
|
import { ImageCarouselWithUploadConstructor } from "../../UI/Image/ImageCarouselWithUpload";
|
||||||
import ShopRetail from "../Questions/bike/ShopRetail";
|
import ShopRetail from "../Questions/bike/ShopRetail";
|
||||||
|
@ -12,6 +12,7 @@ import ShopName from "../Questions/bike/ShopName";
|
||||||
import ShopSecondHand from "../Questions/bike/ShopSecondHand";
|
import ShopSecondHand from "../Questions/bike/ShopSecondHand";
|
||||||
import { TagRenderingOptions } from "../TagRendering";
|
import { TagRenderingOptions } from "../TagRendering";
|
||||||
import {PhoneNumberQuestion} from "../Questions/PhoneNumberQuestion";
|
import {PhoneNumberQuestion} from "../Questions/PhoneNumberQuestion";
|
||||||
|
import Website from "../Questions/Website";
|
||||||
|
|
||||||
|
|
||||||
export default class BikeShops extends LayerDefinition {
|
export default class BikeShops extends LayerDefinition {
|
||||||
|
@ -52,6 +53,7 @@ export default class BikeShops extends LayerDefinition {
|
||||||
new ImageCarouselWithUploadConstructor(),
|
new ImageCarouselWithUploadConstructor(),
|
||||||
new ShopName(),
|
new ShopName(),
|
||||||
new PhoneNumberQuestion("{name}"),
|
new PhoneNumberQuestion("{name}"),
|
||||||
|
new Website("{name}"),
|
||||||
new ShopRetail(),
|
new ShopRetail(),
|
||||||
new ShopRental(),
|
new ShopRental(),
|
||||||
new ShopRepair(),
|
new ShopRepair(),
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWi
|
||||||
import PumpOperational from "../Questions/bike/PumpOperational";
|
import PumpOperational from "../Questions/bike/PumpOperational";
|
||||||
import PumpValves from "../Questions/bike/PumpValves";
|
import PumpValves from "../Questions/bike/PumpValves";
|
||||||
import Translations from "../../UI/i18n/Translations";
|
import Translations from "../../UI/i18n/Translations";
|
||||||
|
import { TagRenderingOptions } from "../TagRendering";
|
||||||
|
|
||||||
|
|
||||||
export default class BikeStations extends LayerDefinition {
|
export default class BikeStations extends LayerDefinition {
|
||||||
|
@ -19,6 +20,7 @@ export default class BikeStations extends LayerDefinition {
|
||||||
private readonly pumpOperationalAny = new Tag("service:bicycle:pump:operational_status", "yes");
|
private readonly pumpOperationalAny = new Tag("service:bicycle:pump:operational_status", "yes");
|
||||||
private readonly pumpOperationalOk = new Or([new Tag("service:bicycle:pump:operational_status", "yes"), new Tag("service:bicycle:pump:operational_status", "operational"), new Tag("service:bicycle:pump:operational_status", "ok"), new Tag("service:bicycle:pump:operational_status", "")]);
|
private readonly pumpOperationalOk = new Or([new Tag("service:bicycle:pump:operational_status", "yes"), new Tag("service:bicycle:pump:operational_status", "operational"), new Tag("service:bicycle:pump:operational_status", "ok"), new Tag("service:bicycle:pump:operational_status", "")]);
|
||||||
private readonly tools = new Tag("service:bicycle:tools", "yes");
|
private readonly tools = new Tag("service:bicycle:tools", "yes");
|
||||||
|
private readonly to = Translations.t.cyclofix.station
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -36,7 +38,19 @@ export default class BikeStations extends LayerDefinition {
|
||||||
|
|
||||||
this.minzoom = 13;
|
this.minzoom = 13;
|
||||||
this.style = this.generateStyleFunction();
|
this.style = this.generateStyleFunction();
|
||||||
this.title = new FixedText(Translations.t.cyclofix.station.title)
|
this.title = new TagRenderingOptions({
|
||||||
|
mappings: [
|
||||||
|
{
|
||||||
|
k: new And([this.pump, this.tools]),
|
||||||
|
txt: this.to.titlePumpAndRepair
|
||||||
|
},
|
||||||
|
{
|
||||||
|
k: new And([this.pump]),
|
||||||
|
txt: this.to.titlePump
|
||||||
|
},
|
||||||
|
{k: null, txt: this.to.titleRepair},
|
||||||
|
]
|
||||||
|
})
|
||||||
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY
|
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY
|
||||||
|
|
||||||
this.elementsToShow = [
|
this.elementsToShow = [
|
||||||
|
@ -65,9 +79,9 @@ export default class BikeStations extends LayerDefinition {
|
||||||
let iconName = "repair_station.svg";
|
let iconName = "repair_station.svg";
|
||||||
if (hasTools && hasPump && isOperational) {
|
if (hasTools && hasPump && isOperational) {
|
||||||
iconName = "repair_station_pump.svg"
|
iconName = "repair_station_pump.svg"
|
||||||
}else if(hasTools){
|
} else if(hasTools) {
|
||||||
iconName = "repair_station.svg"
|
iconName = "repair_station.svg"
|
||||||
}else if(hasPump){
|
} else if(hasPump) {
|
||||||
if (isOperational) {
|
if (isOperational) {
|
||||||
iconName = "pump.svg"
|
iconName = "pump.svg"
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import BikeShops from "../Layers/BikeShops";
|
||||||
import Translations from "../../UI/i18n/Translations";
|
import Translations from "../../UI/i18n/Translations";
|
||||||
import {DrinkingWater} from "../Layers/DrinkingWater";
|
import {DrinkingWater} from "../Layers/DrinkingWater";
|
||||||
import Combine from "../../UI/Base/Combine";
|
import Combine from "../../UI/Base/Combine";
|
||||||
|
import BikeOtherShops from "../Layers/BikeOtherShops";
|
||||||
|
|
||||||
|
|
||||||
export default class Cyclofix extends Layout {
|
export default class Cyclofix extends Layout {
|
||||||
|
@ -13,7 +14,7 @@ export default class Cyclofix extends Layout {
|
||||||
"cyclofix",
|
"cyclofix",
|
||||||
["en", "nl", "fr"],
|
["en", "nl", "fr"],
|
||||||
Translations.t.cyclofix.title,
|
Translations.t.cyclofix.title,
|
||||||
[new BikeServices(), new BikeShops(), new DrinkingWater(), new BikeParkings()],
|
[new BikeServices(), new BikeShops(), new DrinkingWater(), new BikeParkings(), new BikeOtherShops()],
|
||||||
16,
|
16,
|
||||||
50.8465573,
|
50.8465573,
|
||||||
4.3516970,
|
4.3516970,
|
||||||
|
|
17
Customizations/Questions/Website.ts
Normal file
17
Customizations/Questions/Website.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import {TagRenderingOptions} from "../TagRendering";
|
||||||
|
import {UIElement} from "../../UI/UIElement";
|
||||||
|
import Translations from "../../UI/i18n/Translations";
|
||||||
|
|
||||||
|
|
||||||
|
export default class Website extends TagRenderingOptions {
|
||||||
|
constructor(category: string | UIElement) {
|
||||||
|
super({
|
||||||
|
question: Translations.t.general.questions.websiteOf.Subs({category: category}),
|
||||||
|
freeform: {
|
||||||
|
renderTemplate: Translations.t.general.questions.websiteIs.Subs({category: category}),
|
||||||
|
template: "$phone$",
|
||||||
|
key: "phone"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
20
Customizations/Questions/bike/ParkingAccessCargo.ts
Normal file
20
Customizations/Questions/bike/ParkingAccessCargo.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { TagRenderingOptions } from "../../TagRendering";
|
||||||
|
import { Tag } from "../../../Logic/TagsFilter";
|
||||||
|
import Translations from "../../../UI/i18n/Translations";
|
||||||
|
|
||||||
|
|
||||||
|
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}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
18
Customizations/Questions/bike/ParkingCapacity.ts
Normal file
18
Customizations/Questions/bike/ParkingCapacity.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import Translations from "../../../UI/i18n/Translations";
|
||||||
|
import { TagRenderingOptions } from "../../TagRendering";
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
19
Customizations/Questions/bike/ParkingCapacityCargo.ts
Normal file
19
Customizations/Questions/bike/ParkingCapacityCargo.ts
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import Translations from "../../../UI/i18n/Translations";
|
||||||
|
import { TagRenderingOptions } from "../../TagRendering";
|
||||||
|
import Combine from "../../../UI/Base/Combine";
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
import { TagRenderingOptions } from "../../TagRendering";
|
||||||
|
import { Tag } from "../../../Logic/TagsFilter";
|
||||||
|
import Translations from "../../../UI/i18n/Translations";
|
||||||
|
|
||||||
|
|
||||||
|
export default class ParkingCovered extends TagRenderingOptions {
|
||||||
|
constructor() {
|
||||||
|
const key = 'covered'
|
||||||
|
const to = Translations.t.cyclofix.parking.covered
|
||||||
|
super({
|
||||||
|
priority: 15,
|
||||||
|
question: to.question.Render(),
|
||||||
|
mappings: [
|
||||||
|
{k: new Tag(key, "yes"), txt: to.yes},
|
||||||
|
{k: new Tag(key, "no"), txt: to.no}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,37 +1,34 @@
|
||||||
import {TagsFilter} from "./TagsFilter";
|
import {TagsFilter} from "./TagsFilter";
|
||||||
import * as OsmToGeoJson from "osmtogeojson";
|
import * as OsmToGeoJson from "osmtogeojson";
|
||||||
import * as $ from "jquery";
|
import * as $ from "jquery";
|
||||||
import {Basemap} from "./Basemap";
|
|
||||||
import {UIEventSource} from "../UI/UIEventSource";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interfaces overpass to get all the latest data
|
* Interfaces overpass to get all the latest data
|
||||||
*/
|
*/
|
||||||
export class Overpass {
|
export class Overpass {
|
||||||
|
private _filter: TagsFilter
|
||||||
|
public static testUrl: string = null
|
||||||
private _filter: TagsFilter;
|
|
||||||
public static testUrl: string = null;
|
|
||||||
|
|
||||||
constructor(filter: TagsFilter) {
|
constructor(filter: TagsFilter) {
|
||||||
this._filter = filter;
|
this._filter = filter
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildQuery(bbox: string): string {
|
public buildQuery(bbox: string): string {
|
||||||
const filters = this._filter.asOverpass();
|
const filters = this._filter.asOverpass()
|
||||||
let filter = "";
|
console.log(filters)
|
||||||
|
let filter = ""
|
||||||
for (const filterOr of filters) {
|
for (const filterOr of filters) {
|
||||||
filter += 'nwr' + filterOr + ';';
|
filter += 'nwr' + filterOr + ';'
|
||||||
}
|
}
|
||||||
const query =
|
const query =
|
||||||
'[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;';
|
'[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;'
|
||||||
console.log(query);
|
console.log(query)
|
||||||
return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query);
|
return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
queryGeoJson(bbox: string, continuation: ((any) => void), onFail: ((reason) => void)): void {
|
queryGeoJson(bbox: string, continuation: ((any) => void), onFail: ((reason) => void)): void {
|
||||||
let query = this.buildQuery(bbox);
|
let query = this.buildQuery(bbox)
|
||||||
|
|
||||||
if(Overpass.testUrl !== null){
|
if(Overpass.testUrl !== null){
|
||||||
console.log("Using testing URL")
|
console.log("Using testing URL")
|
||||||
|
@ -53,9 +50,5 @@ export class Overpass {
|
||||||
const geojson = OsmToGeoJson.default(json);
|
const geojson = OsmToGeoJson.default(json);
|
||||||
continuation(geojson);
|
continuation(geojson);
|
||||||
}).fail(onFail)
|
}).fail(onFail)
|
||||||
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -51,17 +51,23 @@ export class Regex extends TagsFilter {
|
||||||
substituteValues(tags: any) : TagsFilter{
|
substituteValues(tags: any) : TagsFilter{
|
||||||
throw "Substituting values is not supported on regex tags"
|
throw "Substituting values is not supported on regex tags"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Tag extends TagsFilter {
|
|
||||||
public key: string;
|
|
||||||
public value: string;
|
|
||||||
|
|
||||||
constructor(key: string, value: string) {
|
export class Tag extends TagsFilter {
|
||||||
|
public key: string
|
||||||
|
public value: string
|
||||||
|
public invertValue: boolean
|
||||||
|
|
||||||
|
constructor(key: string, value: string, invertValue = false) {
|
||||||
super()
|
super()
|
||||||
this.key = key;
|
this.key = key
|
||||||
this.value = value;
|
this.value = value
|
||||||
|
this.invertValue = invertValue
|
||||||
|
|
||||||
|
if (value === "*" && invertValue) {
|
||||||
|
throw new Error("Invalid combination: invertValue && value == *")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
matches(tags: { k: string; v: string }[]): boolean {
|
matches(tags: { k: string; v: string }[]): boolean {
|
||||||
|
@ -69,21 +75,22 @@ export class Tag extends TagsFilter {
|
||||||
if (tag.k === this.key) {
|
if (tag.k === this.key) {
|
||||||
if (tag.v === "") {
|
if (tag.v === "") {
|
||||||
// This tag has been removed
|
// This tag has been removed
|
||||||
return this.value === "";
|
return this.value === ""
|
||||||
}
|
}
|
||||||
if (this.value === "*") {
|
if (this.value === "*") {
|
||||||
// Any is allowed
|
// Any is allowed
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.value === tag.v;
|
return this.value === tag.v !== this.invertValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.value === ""){
|
|
||||||
return true;
|
if (this.value === "") {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return this.invertValue
|
||||||
}
|
}
|
||||||
|
|
||||||
asOverpass(): string[] {
|
asOverpass(): string[] {
|
||||||
|
@ -94,17 +101,17 @@ export class Tag extends TagsFilter {
|
||||||
// NOT having this key
|
// NOT having this key
|
||||||
return ['[!"' + this.key + '"]'];
|
return ['[!"' + this.key + '"]'];
|
||||||
}
|
}
|
||||||
return ['["' + this.key + '"="' + this.value + '"]'];
|
const compareOperator = this.invertValue ? '!=' : '='
|
||||||
|
return ['["' + this.key + '"' + compareOperator + '"' + this.value + '"]'];
|
||||||
}
|
}
|
||||||
|
|
||||||
substituteValues(tags: any) {
|
substituteValues(tags: any) {
|
||||||
return new Tag(this.key, TagUtils.ApplyTemplate(this.value, tags));
|
return new Tag(this.key, TagUtils.ApplyTemplate(this.value, tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Or extends TagsFilter {
|
|
||||||
|
|
||||||
|
export class Or extends TagsFilter {
|
||||||
public or: TagsFilter[]
|
public or: TagsFilter[]
|
||||||
|
|
||||||
constructor(or: TagsFilter[]) {
|
constructor(or: TagsFilter[]) {
|
||||||
|
@ -112,9 +119,7 @@ export class Or extends TagsFilter {
|
||||||
this.or = or;
|
this.or = or;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
matches(tags: { k: string; v: string }[]): boolean {
|
matches(tags: { k: string; v: string }[]): boolean {
|
||||||
|
|
||||||
for (const tagsFilter of this.or) {
|
for (const tagsFilter of this.or) {
|
||||||
if (tagsFilter.matches(tags)) {
|
if (tagsFilter.matches(tags)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,7 +130,6 @@ export class Or extends TagsFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
asOverpass(): string[] {
|
asOverpass(): string[] {
|
||||||
|
|
||||||
const choices = [];
|
const choices = [];
|
||||||
for (const tagsFilter of this.or) {
|
for (const tagsFilter of this.or) {
|
||||||
const subChoices = tagsFilter.asOverpass();
|
const subChoices = tagsFilter.asOverpass();
|
||||||
|
@ -143,11 +147,10 @@ export class Or extends TagsFilter {
|
||||||
}
|
}
|
||||||
return new Or(newChoices);
|
return new Or(newChoices);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class And extends TagsFilter {
|
|
||||||
|
|
||||||
|
export class And extends TagsFilter {
|
||||||
public and: TagsFilter[]
|
public and: TagsFilter[]
|
||||||
|
|
||||||
constructor(and: TagsFilter[]) {
|
constructor(and: TagsFilter[]) {
|
||||||
|
@ -156,7 +159,6 @@ export class And extends TagsFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
matches(tags: { k: string; v: string }[]): boolean {
|
matches(tags: { k: string; v: string }[]): boolean {
|
||||||
|
|
||||||
for (const tagsFilter of this.and) {
|
for (const tagsFilter of this.and) {
|
||||||
if (!tagsFilter.matches(tags)) {
|
if (!tagsFilter.matches(tags)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -175,8 +177,7 @@ export class And extends TagsFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
asOverpass(): string[] {
|
asOverpass(): string[] {
|
||||||
|
var allChoices: string[] = null;
|
||||||
var allChoices = null;
|
|
||||||
|
|
||||||
for (const andElement of this.and) {
|
for (const andElement of this.and) {
|
||||||
var andElementFilter = andElement.asOverpass();
|
var andElementFilter = andElement.asOverpass();
|
||||||
|
@ -185,10 +186,10 @@ export class And extends TagsFilter {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newChoices = []
|
var newChoices: string[] = []
|
||||||
for (var choice of allChoices) {
|
for (var choice of allChoices) {
|
||||||
newChoices.push(
|
newChoices.push(
|
||||||
this.combine(choice, andElementFilter)
|
...this.combine(choice, andElementFilter)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
allChoices = newChoices;
|
allChoices = newChoices;
|
||||||
|
@ -205,6 +206,7 @@ export class And extends TagsFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class Not extends TagsFilter{
|
export class Not extends TagsFilter{
|
||||||
private not: TagsFilter;
|
private not: TagsFilter;
|
||||||
|
|
||||||
|
@ -224,12 +226,10 @@ export class Not extends TagsFilter{
|
||||||
substituteValues(tags: any): TagsFilter {
|
substituteValues(tags: any): TagsFilter {
|
||||||
return new Not(this.not.substituteValues(tags));
|
return new Not(this.not.substituteValues(tags));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export class TagUtils {
|
export class TagUtils {
|
||||||
|
|
||||||
static proprtiesToKV(properties: any): { k: string, v: string }[] {
|
static proprtiesToKV(properties: any): { k: string, v: string }[] {
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const k in properties) {
|
for (const k in properties) {
|
||||||
|
@ -246,5 +246,4 @@ export class TagUtils {
|
||||||
}
|
}
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@ import {InputElement} from "./InputElement";
|
||||||
import {UIEventSource} from "../UIEventSource";
|
import {UIEventSource} from "../UIEventSource";
|
||||||
import {UIElement} from "../UIElement";
|
import {UIElement} from "../UIElement";
|
||||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||||
|
import Translations from "../i18n/Translations";
|
||||||
|
|
||||||
|
|
||||||
export class InputElementWrapper<T> extends InputElement<T>{
|
export class InputElementWrapper<T> extends InputElement<T>{
|
||||||
|
@ -16,9 +17,11 @@ export class InputElementWrapper<T> extends InputElement<T>{
|
||||||
|
|
||||||
) {
|
) {
|
||||||
super(undefined);
|
super(undefined);
|
||||||
this.pre = typeof(pre) === 'string' ? new FixedUiElement(pre) : pre
|
// this.pre = typeof(pre) === 'string' ? new FixedUiElement(pre) : pre
|
||||||
|
this.pre = Translations.W(pre)
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.post =typeof(post) === 'string' ? new FixedUiElement(post) : post
|
// this.post =typeof(post) === 'string' ? new FixedUiElement(post) : post
|
||||||
|
this.post = Translations.W(post)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
0
UI/MoreScreen.ts
Normal file
0
UI/MoreScreen.ts
Normal file
|
@ -19,12 +19,21 @@ export default class Translations {
|
||||||
fr: 'Cyclofix - Une carte ouverte pour les cyclistes'
|
fr: 'Cyclofix - Une carte ouverte pour les cyclistes'
|
||||||
}),
|
}),
|
||||||
description: new T({
|
description: new T({
|
||||||
en: "On this map we want to collect data about the whereabouts of bicycle pumps and public racks in Brussels and everywhere else." +
|
en: "The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.<br><br>" + //this works in spoken language: ; think about the nearest bike repair station for example
|
||||||
"As a result, cyclists will be able to quickly find the nearest infrastructure for their needs.",
|
"You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. " +
|
||||||
nl: "Op deze kaart willen we gegevens verzamelen over de locatie van fietspompen en openbare stelplaatsen in Brussel en overal ter wereld." +
|
"You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.<br><br>" +
|
||||||
"Hierdoor kunnen fietsers snel de dichtstbijzijnde infrastructuur vinden die voldoet aan hun behoeften.",
|
"All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.<br><br>" +
|
||||||
fr: "Sur cette carte, nous voulons collecter des données sur la localisation des pompes à vélo et des supports publics à Bruxelles." +
|
"For more information about the cyclofix project, go to <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a>.",
|
||||||
"Les cyclistes pourront ainsi trouver rapidement l'infrastructure la plus proche pour leurs besoins."
|
nl: "Het doel van deze kaart is om fietsers een gebruiksvriendelijke oplossing te bieden voor het vinden van de juiste infrastructuur voor hun behoeften.<br><br>" + //; denk bijvoorbeeld aan de dichtstbijzijnde fietsherstelplaats.
|
||||||
|
"U kunt uw exacte locatie volgen (enkel mobiel) en in de linkerbenedenhoek categorieën selecteren die voor u relevant zijn. " +
|
||||||
|
"U kunt deze tool ook gebruiken om 'spelden' aan de kaart toe te voegen of te bewerken en meer gegevens te verstrekken door de vragen te beantwoorden.<br><br>" +
|
||||||
|
"Alle wijzigingen die u maakt worden automatisch opgeslagen in de wereldwijde database van OpenStreetMap en kunnen door anderen vrij worden hergebruikt.<br><br>" +
|
||||||
|
"Bekijk voor meer info over cyclofix ook <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a>.",
|
||||||
|
fr: "Le but de cette carte est de présenter aux cyclistes une solution facile à utiliser pour trouver l'infrastructure appropriée à leurs besoins.<br><br>" + //; pensez par exemple à la station de réparation de vélos la plus proche.
|
||||||
|
"Vous pouvez suivre votre localisation précise (mobile uniquement) et sélectionner les couches qui vous concernent dans le coin inférieur gauche. " +
|
||||||
|
"Vous pouvez également utiliser cet outil pour ajouter ou modifier des épingles (points d'intérêt) sur la carte et fournir plus de données en répondant aux questions.<br><br>" +
|
||||||
|
"Toutes les modifications que vous apportez seront automatiquement enregistrées dans la base de données mondiale d'OpenStreetMap et peuvent être librement réutilisées par d'autres.<br><br>" +
|
||||||
|
"Pour plus d'informations sur le projet cyclofix, rendez-vous sur <a href='https://cyclofix.osm.be/'>cyclofix.osm.be</a>."
|
||||||
}),
|
}),
|
||||||
freeFormPlaceholder: new T({en: 'specify', nl: 'specifieer', fr: 'TODO: fr'}),
|
freeFormPlaceholder: new T({en: 'specify', nl: 'specifieer', fr: 'TODO: fr'}),
|
||||||
parking: {
|
parking: {
|
||||||
|
@ -33,13 +42,13 @@ export default class Translations {
|
||||||
type: {
|
type: {
|
||||||
render: new T({
|
render: new T({
|
||||||
en: 'This is a bicycle parking of the type: {bicycle_parking}',
|
en: 'This is a bicycle parking of the type: {bicycle_parking}',
|
||||||
nl: 'Dit is een fietsenparking van het type: {bicycle_parking}',
|
nl: 'Dit is een fietsparking van het type: {bicycle_parking}',
|
||||||
fr: 'Ceci est un parking à vélo de type {bicycle_parking}'
|
fr: 'Ceci est un parking à vélo de type {bicycle_parking}'
|
||||||
}),
|
}),
|
||||||
template: new T({en: 'Some other type: $$$', nl: 'Een ander type: $$$', fr: "D'autres types: $$$"}),
|
template: new T({en: 'Some other type: $$$', nl: 'Een ander type: $$$', fr: "D'autres types: $$$"}),
|
||||||
question: new T({
|
question: new T({
|
||||||
en: 'What is the type of this bicycle parking?',
|
en: 'What is the type of this bicycle parking?',
|
||||||
nl: 'Van welk type is deze fietsenparking?',
|
nl: 'Van welk type is deze fietsparking?',
|
||||||
fr: 'Quelle type de parking s\'agit il? '
|
fr: 'Quelle type de parking s\'agit il? '
|
||||||
}),
|
}),
|
||||||
eg: new T({en: ", for example", nl: ", bijvoorbeeld", fr: ",par example"}),
|
eg: new T({en: ", for example", nl: ", bijvoorbeeld", fr: ",par example"}),
|
||||||
|
@ -50,11 +59,10 @@ export default class Translations {
|
||||||
rack: new T({en: 'Rack', nl: 'Rek', fr: 'Râtelier'}),
|
rack: new T({en: 'Rack', nl: 'Rek', fr: 'Râtelier'}),
|
||||||
"two-tier": new T({en: 'Two-tiered', nl: 'Dubbel (twee verdiepingen)', fr: 'Superposé'}),
|
"two-tier": new T({en: 'Two-tiered', nl: 'Dubbel (twee verdiepingen)', fr: 'Superposé'}),
|
||||||
},
|
},
|
||||||
|
|
||||||
operator: {
|
operator: {
|
||||||
render: new T({
|
render: new T({
|
||||||
en: 'This bike parking is operated by {operator}',
|
en: 'This bike parking is operated by {operator}',
|
||||||
nl: 'Deze fietsenparking wordt beheerd door {operator}',
|
nl: 'Deze fietsparking wordt beheerd door {operator}',
|
||||||
fr: 'Ce parking est opéré par {operator}'
|
fr: 'Ce parking est opéré par {operator}'
|
||||||
}),
|
}),
|
||||||
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
||||||
|
@ -68,15 +76,95 @@ export default class Translations {
|
||||||
nl: 'Wordt beheerd door een privépersoon',
|
nl: 'Wordt beheerd door een privépersoon',
|
||||||
fr: 'Opéré par un tier privé'
|
fr: 'Opéré par un tier privé'
|
||||||
}),
|
}),
|
||||||
|
},
|
||||||
|
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.',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
yes: new T({
|
||||||
|
en: 'This parking is covered (it has a roof)',
|
||||||
|
nl: 'Deze parking is overdekt (er is een afdak)',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
no: new T({
|
||||||
|
en: 'This parking is not covered',
|
||||||
|
nl: 'Deze parking is niet overdekt',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
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)?",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
template: new T({
|
||||||
|
en: "This parking fits $nat$ bikes",
|
||||||
|
nl: "Deze parking heeft plaats voor $nat$ fietsen",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
render: new T({
|
||||||
|
en: "Place for {capacity} bikes (in total)",
|
||||||
|
nl: "Plaats voor {capacity} fietsen (in totaal)",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
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"
|
||||||
|
}),
|
||||||
|
template: new T({
|
||||||
|
en: "This parking fits $nat$ cargo bikes",
|
||||||
|
nl: "Deze parking heeft plaats voor $nat$ fietsen",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
render: new T({
|
||||||
|
en: "Place for {capacity:cargo_bike} cargo bikes",
|
||||||
|
nl: "Plaats voor {capacity:cargo_bike} bakfietsen",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
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"
|
||||||
|
}),
|
||||||
|
yes: new T({
|
||||||
|
en: "This parking has room for cargo bikes",
|
||||||
|
nl: "Deze parking is overdekt (er is een afdak)",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
designated: new T({
|
||||||
|
en: "This parking has designated (official) spots for cargo bikes.",
|
||||||
|
nl: "Deze parking is overdekt (er is een afdak)",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
}),
|
||||||
|
no: new T({
|
||||||
|
en: "You're not allowed to park cargo bikes",
|
||||||
|
nl: "Je mag hier geen bakfietsen parkeren",
|
||||||
|
fr: "TODO: fr"
|
||||||
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
station: {
|
station: {
|
||||||
name: new T({
|
name: new T({
|
||||||
en: 'bike station (repair, pump or both)',
|
en: 'bike station (repair, pump or both)',
|
||||||
nl: 'fietsstation (herstel, pomp of allebei)',
|
nl: 'fietspunt (herstel, pomp of allebei)',
|
||||||
fr: 'station velo (réparation, pompe à vélo)'
|
fr: 'station velo (réparation, pompe à vélo)'
|
||||||
}),
|
}),
|
||||||
title: new T({en: 'Bike station', nl: 'Fietsstation', fr: 'Station vélo'}),
|
// title: new T({en: 'Bike station', nl: 'Fietsstation', fr: 'Station vélo'}), Old, non-dynamic title
|
||||||
|
titlePump: new T({en: 'Bike pump', nl: 'Fietspomp', fr: 'TODO: fr'}),
|
||||||
|
titleRepair: new T({en: 'Bike repair station', nl: 'Herstelpunt', fr: 'TODO: fr'}),
|
||||||
|
titlePumpAndRepair: new T({
|
||||||
|
en: 'Bike station (pump & repair)',
|
||||||
|
nl: 'Herstelpunt met pomp',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
manometer: {
|
manometer: {
|
||||||
question: new T({
|
question: new T({
|
||||||
en: 'Does the pump have a pressure indicator or manometer?',
|
en: 'Does the pump have a pressure indicator or manometer?',
|
||||||
|
@ -84,7 +172,11 @@ export default class Translations {
|
||||||
fr: 'Est-ce que la pompe à un manomètre integré?'
|
fr: 'Est-ce que la pompe à un manomètre integré?'
|
||||||
}),
|
}),
|
||||||
yes: new T({en: 'There is a manometer', nl: 'Er is een luchtdrukmeter', fr: 'Il y a un manomètre'}),
|
yes: new T({en: 'There is a manometer', nl: 'Er is een luchtdrukmeter', fr: 'Il y a un manomètre'}),
|
||||||
no: new T({en: 'There is no manometer', nl: 'Er is geen luchtdrukmeter', fr: 'Il n\'y a pas de manomètre'}),
|
no: new T({
|
||||||
|
en: 'There is no manometer',
|
||||||
|
nl: 'Er is geen luchtdrukmeter',
|
||||||
|
fr: 'Il n\'y a pas de manomètre'
|
||||||
|
}),
|
||||||
broken: new T({
|
broken: new T({
|
||||||
en: 'There is manometer but it is broken',
|
en: 'There is manometer but it is broken',
|
||||||
nl: 'Er is een luchtdrukmeter maar die is momenteel defect',
|
nl: 'Er is een luchtdrukmeter maar die is momenteel defect',
|
||||||
|
@ -144,8 +236,8 @@ export default class Translations {
|
||||||
},
|
},
|
||||||
chain: {
|
chain: {
|
||||||
question: new T({
|
question: new T({
|
||||||
en: 'Does this bike station have a special tool to repair your bike chain?',
|
en: 'Does this bike repair station have a special tool to repair your bike chain?',
|
||||||
nl: 'Heeft dit fietsstation een speciale reparatieset voor je ketting?',
|
nl: 'Heeft dit herstelpunt een speciale reparatieset voor je ketting?',
|
||||||
fr: 'Est-ce que cette station vélo a un outils specifique pour réparer la chaîne du velo?'
|
fr: 'Est-ce que cette station vélo a un outils specifique pour réparer la chaîne du velo?'
|
||||||
}),
|
}),
|
||||||
yes: new T({
|
yes: new T({
|
||||||
|
@ -162,7 +254,7 @@ export default class Translations {
|
||||||
operator: {
|
operator: {
|
||||||
render: new T({
|
render: new T({
|
||||||
en: 'This bike station is operated by {operator}',
|
en: 'This bike station is operated by {operator}',
|
||||||
nl: 'Dit fietsstation wordt beheerd door {operator}',
|
nl: 'Dit fietspunt wordt beheerd door {operator}',
|
||||||
fr: 'Cette station vélo est opéré par {operator}'
|
fr: 'Cette station vélo est opéré par {operator}'
|
||||||
}),
|
}),
|
||||||
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
||||||
|
@ -180,7 +272,7 @@ export default class Translations {
|
||||||
services: {
|
services: {
|
||||||
question: new T({
|
question: new T({
|
||||||
en: 'Which services are available at this bike station?',
|
en: 'Which services are available at this bike station?',
|
||||||
nl: 'Welke functies biedt dit fietsstation?',
|
nl: 'Welke functies biedt dit fietspunt?',
|
||||||
fr: 'Quels services sont valables à cette station vélo?'
|
fr: 'Quels services sont valables à cette station vélo?'
|
||||||
}),
|
}),
|
||||||
pump: new T({
|
pump: new T({
|
||||||
|
@ -203,7 +295,7 @@ export default class Translations {
|
||||||
stand: {
|
stand: {
|
||||||
question: new T({
|
question: new T({
|
||||||
en: 'Does this bike station have a hook to suspend your bike with or a stand to elevate it?',
|
en: 'Does this bike station have a hook to suspend your bike with or a stand to elevate it?',
|
||||||
nl: 'Heeft dit fietsstation een haak of standaard om je fiets op te hangen/zetten?',
|
nl: 'Heeft dit herstelpunt een haak of standaard om je fiets op te hangen/zetten?',
|
||||||
fr: 'Est-ce que cette station vélo à un crochet pour suspendre son velo ou une accroche pour l\'élevé?'
|
fr: 'Est-ce que cette station vélo à un crochet pour suspendre son velo ou une accroche pour l\'élevé?'
|
||||||
}),
|
}),
|
||||||
yes: new T({en: 'There is a hook or stand', nl: 'Er is een haak of standaard', fr: 'Oui il y a un crochet ou une accroche'}),
|
yes: new T({en: 'There is a hook or stand', nl: 'Er is een haak of standaard', fr: 'Oui il y a un crochet ou une accroche'}),
|
||||||
|
@ -211,16 +303,23 @@ export default class Translations {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
shop: {
|
shop: {
|
||||||
name: new T({en: 'bike shop', nl: 'fietswinkel', fr: 'magasin de vélo'}),
|
name: new T({en: 'bike repair/shop', nl: 'fietszaak', fr: 'magasin ou réparateur de vélo'}),
|
||||||
|
|
||||||
title: new T({en: 'Bike shop', nl: 'Fietszaak', fr: 'Magasin de vélo'}),
|
title: new T({en: 'Bike repair/shop', nl: 'Fietszaak', fr: 'Magasin et réparateur de vélo'}),
|
||||||
titleRepair: new T({en: 'Bike repair', nl: 'Fietsenmaker', fr: 'Réparateur de vélo'}),
|
titleRepair: new T({en: 'Bike repair', nl: 'Fietsenmaker', fr: 'Réparateur de vélo'}),
|
||||||
titleShop: new T({en: 'Bike repair/shop', nl: 'Fietswinkel', fr: 'Magasin et réparateur de vélo'}),
|
titleShop: new T({en: 'Bike shop', nl: 'Fietswinkel', fr: 'Magasin de vélo'}),
|
||||||
|
|
||||||
titleNamed: new T({en: 'Bike repair/shop', nl: 'Fietszaak {name}', fr: 'Magasin de vélo'}),
|
|
||||||
titleRepairNamed: new T({en: 'Bike shop', nl: 'Fietsenmaker {name}', fr: 'Réparateur de vélo'}),
|
|
||||||
titleShopNamed: new T({en: 'Bike repair/shop', nl: 'Fietswinkel {name}', fr: 'Magasin et réparateur de vélo'}),
|
|
||||||
|
|
||||||
|
titleNamed: new T({
|
||||||
|
en: 'Bike repair/shop {name}',
|
||||||
|
nl: 'Fietszaak {name}',
|
||||||
|
fr: 'Magasin et réparateur de vélo {name}'
|
||||||
|
}),
|
||||||
|
titleRepairNamed: new T({
|
||||||
|
en: 'Bike repair {name}',
|
||||||
|
nl: 'Fietsenmaker {name}',
|
||||||
|
fr: 'Réparateur de vélo {name}'
|
||||||
|
}),
|
||||||
|
titleShopNamed: new T({en: 'Bike shop {name}', nl: 'Fietswinkel {name}', fr: 'Magasin de vélo {name}'}),
|
||||||
|
|
||||||
|
|
||||||
retail: {
|
retail: {
|
||||||
|
@ -229,7 +328,11 @@ export default class Translations {
|
||||||
nl: 'Verkoopt deze winkel fietsen?',
|
nl: 'Verkoopt deze winkel fietsen?',
|
||||||
fr: 'Est-ce que ce magasin vend des vélos?'
|
fr: 'Est-ce que ce magasin vend des vélos?'
|
||||||
}),
|
}),
|
||||||
yes: new T({en: 'This shop sells bikes', nl: 'Deze winkel verkoopt fietsen', fr: 'Ce magasin vend des vélos'}),
|
yes: new T({
|
||||||
|
en: 'This shop sells bikes',
|
||||||
|
nl: 'Deze winkel verkoopt fietsen',
|
||||||
|
fr: 'Ce magasin vend des vélos'
|
||||||
|
}),
|
||||||
no: new T({
|
no: new T({
|
||||||
en: 'This shop doesn\'t sell bikes',
|
en: 'This shop doesn\'t sell bikes',
|
||||||
nl: 'Deze winkel verkoopt geen fietsen',
|
nl: 'Deze winkel verkoopt geen fietsen',
|
||||||
|
@ -310,6 +413,33 @@ export default class Translations {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
nonBikeShop: {
|
||||||
|
name: new T({
|
||||||
|
en: 'shop that sells/repairs bikes',
|
||||||
|
nl: 'winkel die fietsen verkoopt/herstelt',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
|
||||||
|
title: new T({
|
||||||
|
en: 'Shop that sells/repairs bikes',
|
||||||
|
nl: 'Winkel die fietsen verkoopt/herstelt',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
titleRepair: new T({en: 'Shop that repairs bikes', nl: 'Winkel die fietsen herstelt', fr: 'TODO: fr'}),
|
||||||
|
titleShop: new T({en: 'Shop that sells bikes', nl: 'Winkel die fietsen verkoopt', fr: 'TODO: fr'}),
|
||||||
|
|
||||||
|
titleNamed: new T({
|
||||||
|
en: '{name} (sells/repairs bikes)',
|
||||||
|
nl: '{name} (verkoopt/herstelt fietsen)',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
titleRepairNamed: new T({
|
||||||
|
en: '{name} (repairs bikes)',
|
||||||
|
nl: '{name} (herstelt fietsen)',
|
||||||
|
fr: 'TODO: fr'
|
||||||
|
}),
|
||||||
|
titleShopNamed: new T({en: '{name} (sells bikes)', nl: '{name} (verkoopt fietsen)', fr: 'TODO: fr'}),
|
||||||
|
},
|
||||||
drinking_water: {
|
drinking_water: {
|
||||||
title: new T({
|
title: new T({
|
||||||
en: 'Drinking water',
|
en: 'Drinking water',
|
||||||
|
@ -526,6 +656,14 @@ export default class Translations {
|
||||||
phoneNumberIs: new T({
|
phoneNumberIs: new T({
|
||||||
en: "The phone number of this {category} is <a href='tel:{phone}' target='_blank'>{phone}</a>",
|
en: "The phone number of this {category} is <a href='tel:{phone}' target='_blank'>{phone}</a>",
|
||||||
nl: "Het telefoonnummer van {category} is <a href='tel:{phone}' target='_blank'>{phone}</a>"
|
nl: "Het telefoonnummer van {category} is <a href='tel:{phone}' target='_blank'>{phone}</a>"
|
||||||
|
}),
|
||||||
|
websiteOf: new T({
|
||||||
|
en: "What is the website of {category}?",
|
||||||
|
nl: "Wat is de website van {category}?"
|
||||||
|
}),
|
||||||
|
websiteIs: new T({
|
||||||
|
en: "Website: <a href='{website}' target='_blank'>{website}</a>",
|
||||||
|
nl: "Website: <a href='{website}' target='_blank'>{website}</a>"
|
||||||
})
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
|
@ -553,8 +691,6 @@ export default class Translations {
|
||||||
embedIntro: new T({
|
embedIntro: new T({
|
||||||
en: "<h3>Embed on your website</h3>Please, embed this map into your website. We encourage you to do it - you don't even have to ask permission. It is free, and always will be. The more people using this, the more valuable it becomes."
|
en: "<h3>Embed on your website</h3>Please, embed this map into your website. We encourage you to do it - you don't even have to ask permission. It is free, and always will be. The more people using this, the more valuable it becomes."
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
21
assets/bike/non_bike_repair_shop.svg
Normal file
21
assets/bike/non_bike_repair_shop.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 10 KiB |
164
assets/bike/non_bike_shop.svg
Normal file
164
assets/bike/non_bike_shop.svg
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<svg width="98" height="121" viewBox="0 0 98 121" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M53.0445 111.094C51.2614 114.981 45.7386 114.981 43.9555 111.094L13.2124 44.085C11.6928 40.7729 14.1129 37 17.7569 37L79.2431 37C82.8871 37 85.3072 40.7729 83.7876 44.085L53.0445 111.094Z" fill="#805793"/>
|
||||||
|
<circle cx="49" cy="49" r="49" fill="#805793"/>
|
||||||
|
<g filter="url(#filter0_d)">
|
||||||
|
<ellipse cx="20" cy="32.5" rx="7" ry="5.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter1_d)">
|
||||||
|
<ellipse cx="63.5" cy="32.5" rx="7.5" ry="5.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter2_d)">
|
||||||
|
<ellipse cx="78" cy="32.5" rx="7" ry="5.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter3_d)">
|
||||||
|
<ellipse cx="49" cy="32.5" rx="7" ry="5.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter4_d)">
|
||||||
|
<ellipse cx="34.5" cy="32.5" rx="7.5" ry="5.5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<path d="M19.5 24.5L30.3253 31.5H8.67468L19.5 24.5Z" fill="white"/>
|
||||||
|
<path d="M79 24.5L89.3253 31.5H67.6747L79 24.5Z" fill="white"/>
|
||||||
|
<rect x="19" y="20" width="60" height="14" fill="white"/>
|
||||||
|
<rect x="6" y="31" width="85" height="1" fill="#805793"/>
|
||||||
|
<g filter="url(#filter5_d)">
|
||||||
|
<rect x="21" y="38" width="4" height="34" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter6_d)">
|
||||||
|
<rect x="74" y="39" width="4" height="34" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter7_d)">
|
||||||
|
<rect x="16" y="72" width="67" height="5" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter8_d)">
|
||||||
|
<path d="M43.1579 63.8659H33.5872L38.8076 52.2202H44.028H47.7983H51.8586M51.8586 52.2202L50.4085 48.9355H52.4386H54.4688M51.8586 52.2202L52.4386 53.7132L53.5987 56.1021L56.789 63.8659M51.8586 52.2202L49.1034 56.6993L47.4502 59.3867M46.3481 61.1784L47.4502 59.3867M40.8377 55.5049L43.7379 62.0742L37.9375 48.9355L39.6776 52.5188M45.4781 62.6714L47.4502 59.3867" stroke="white" stroke-width="2"/>
|
||||||
|
<path d="M46.0937 63.3578C46.0937 64.25 45.395 64.9481 44.5635 64.9481C43.7321 64.9481 43.0334 64.25 43.0334 63.3578C43.0334 62.4657 43.7321 61.7676 44.5635 61.7676C45.395 61.7676 46.0937 62.4657 46.0937 63.3578Z" stroke="white"/>
|
||||||
|
<path d="M39.7932 62.7607C39.7932 66.359 36.9675 69.2258 33.5427 69.2258C30.1179 69.2258 27.2921 66.359 27.2921 62.7607C27.2921 59.1623 30.1179 56.2955 33.5427 56.2955C36.9675 56.2955 39.7932 59.1623 39.7932 62.7607Z" stroke="white" stroke-width="2"/>
|
||||||
|
<ellipse cx="60.279" cy="57.3748" rx="0.210172" ry="0.216394" fill="black" fill-opacity="0.49"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter9_d)">
|
||||||
|
<path d="M43.1579 63.8659H33.5872L38.8076 52.2202H44.028H47.7983H51.8586M51.8586 52.2202L50.4085 48.9355H52.4386H54.4688M51.8586 52.2202L52.4386 53.7132L53.5987 56.1021L56.789 63.8659M51.8586 52.2202L49.1034 56.6993L47.4502 59.3867M46.3481 61.1784L47.4502 59.3867M40.8377 55.5049L43.7379 62.0742L37.9375 48.9355L39.6776 52.5188M45.4781 62.6714L47.4502 59.3867" stroke="white" stroke-width="2"/>
|
||||||
|
<path d="M46.0937 63.3578C46.0937 64.25 45.395 64.9481 44.5635 64.9481C43.7321 64.9481 43.0334 64.25 43.0334 63.3578C43.0334 62.4657 43.7321 61.7676 44.5635 61.7676C45.395 61.7676 46.0937 62.4657 46.0937 63.3578Z" stroke="white"/>
|
||||||
|
<path d="M39.7932 62.7607C39.7932 66.359 36.9675 69.2258 33.5427 69.2258C30.1179 69.2258 27.2921 66.359 27.2921 62.7607C27.2921 59.1623 30.1179 56.2955 33.5427 56.2955C36.9675 56.2955 39.7932 59.1623 39.7932 62.7607Z" stroke="white" stroke-width="2"/>
|
||||||
|
<ellipse cx="60.279" cy="57.3748" rx="0.210172" ry="0.216394" fill="black" fill-opacity="0.49"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter10_d)">
|
||||||
|
<circle cx="56.5" cy="63.5" r="6.5" stroke="white" stroke-width="2"/>
|
||||||
|
</g>
|
||||||
|
<path d="M63.2749 56.3586C62.6089 56.7271 61.7919 56.2445 61.7916 55.4825L61.7903 51.7748C61.79 51.0004 62.6308 50.5198 63.2971 50.9134L66.5391 52.8283C67.2055 53.2219 67.1923 54.1913 66.5155 54.5658L63.2749 56.3586Z" fill="white"/>
|
||||||
|
<g filter="url(#filter11_d)">
|
||||||
|
<rect width="7.82366" height="6.20457" rx="1" transform="matrix(0.490888 -0.871223 0.870592 0.492006 61.4893 51.5931)" fill="white"/>
|
||||||
|
</g>
|
||||||
|
<path d="M66.0398 53.2049C62.045 51.8388 64.4607 45.5484 68.7455 48.7409" stroke="#805793" stroke-width="0.75"/>
|
||||||
|
<path d="M63.0112 49.4193L66.8764 51.3548M63.4944 48.4516L67.5528 50.4839" stroke="#805793" stroke-width="0.75"/>
|
||||||
|
<circle cx="63.5" cy="54.5" r="0.5" fill="#805793"/>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_d" x="9" y="27" width="22" height="19" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_d" x="52" y="27" width="23" height="19" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter2_d" x="67" y="27" width="22" height="19" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter3_d" x="38" y="27" width="22" height="19" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter4_d" x="23" y="27" width="23" height="19" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter5_d" x="17" y="38" width="12" height="42" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter6_d" x="70" y="39" width="12" height="42" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter7_d" x="12" y="72" width="75" height="13" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter8_d" x="22.2921" y="47.9355" width="42.197" height="30.2904" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter9_d" x="22.2921" y="47.9355" width="42.197" height="30.2904" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter10_d" x="45" y="56" width="23" height="23" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter11_d" x="57.8512" y="45.1395" width="16.5185" height="17.1438" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||||
|
<feOffset dy="4"/>
|
||||||
|
<feGaussianBlur stdDeviation="2"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||||
|
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||||
|
</filter>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
BIN
assets/bike/staples-annotated.png
Normal file
BIN
assets/bike/staples-annotated.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 MiB |
|
@ -956,6 +956,10 @@ form {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.question-text img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.question-subtext{
|
.question-subtext{
|
||||||
font-size: medium;
|
font-size: medium;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "parcel *.html UI/** Logic/** assets/**/* vendor/* vendor/*/*",
|
"start": "parcel *.html UI/** Logic/** assets/**/* assets/* vendor/* vendor/*/*",
|
||||||
"generate": "ts-node createLayouts.ts",
|
"generate": "ts-node createLayouts.ts",
|
||||||
"build": "rm -rf dist/ && parcel build --public-url ./ *.html assets/* assets/**/* vendor/* vendor/*/*",
|
"build": "rm -rf dist/ && parcel build --public-url ./ *.html assets/* assets/**/* vendor/* vendor/*/*",
|
||||||
"clean": "./clean.sh",
|
"clean": "./clean.sh",
|
||||||
|
|
BIN
static/staples-annotated.xcf
Normal file
BIN
static/staples-annotated.xcf
Normal file
Binary file not shown.
45
test.ts
45
test.ts
|
@ -1,14 +1,37 @@
|
||||||
import {TabbedComponent} from "./UI/Base/TabbedComponent";
|
|
||||||
import {FixedUiElement} from "./UI/Base/FixedUiElement";
|
import { And, Tag, Or } from "./Logic/TagsFilter";
|
||||||
import {Bookcases} from "./Customizations/Layouts/Bookcases";
|
import { Overpass } from "./Logic/Overpass";
|
||||||
import {ShareScreen} from "./UI/ShareScreen";
|
|
||||||
import {UIEventSource} from "./UI/UIEventSource";
|
|
||||||
|
|
||||||
|
|
||||||
const layout = new Bookcases();
|
function anyValueExcept(key: string, exceptValue: string) {
|
||||||
|
return new And([
|
||||||
|
new Tag(key, "*"),
|
||||||
|
new Tag(key, exceptValue, true)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
new ShareScreen(layout, new UIEventSource<{zoom: number, lat: number, lon: number}>({
|
const sellsBikes = new Tag("service:bicycle:retail", "yes")
|
||||||
zoom: 16,
|
const repairsBikes = anyValueExcept("service:bicycle:repair", "no")
|
||||||
lat: 51.5,
|
const rentsBikes = new Tag("service:bicycle:rental", "yes")
|
||||||
lon:3.2
|
const hasPump = new Tag("service:bicycle:pump", "yes")
|
||||||
})).AttachTo("maindiv")
|
const hasDiy = new Tag("service:bicycle:diy", "yes")
|
||||||
|
const sellsSecondHand = anyValueExcept("service:bicycle:repair", "no")
|
||||||
|
const hasBikeServices = new Or([
|
||||||
|
sellsBikes,
|
||||||
|
repairsBikes,
|
||||||
|
rentsBikes,
|
||||||
|
hasPump,
|
||||||
|
hasDiy,
|
||||||
|
sellsSecondHand
|
||||||
|
])
|
||||||
|
|
||||||
|
const overpassFilter = new And([
|
||||||
|
new Tag("shop", "bicycle", true),
|
||||||
|
hasBikeServices
|
||||||
|
])
|
||||||
|
|
||||||
|
const overpass = new Overpass(overpassFilter)
|
||||||
|
|
||||||
|
// console.log(overpass.buildQuery('bbox:51.12246976163816,3.1045767593383795,51.289518504257174,3.2848313522338866'))
|
||||||
|
|
||||||
|
console.log(overpassFilter.asOverpass())
|
||||||
|
|
Loading…
Reference in a new issue