Added cyclofix capacity cargo; covered; non-bike shop; pump dyn title
This commit is contained in:
parent
a7bb4a1fcc
commit
948ff74a8b
23 changed files with 624 additions and 91 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ dist/*
|
|||
node_modules
|
||||
.cache/*
|
||||
.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 {And, Or, Tag} from "../../Logic/TagsFilter";
|
||||
import {And, Or, Tag, TagsFilter} from "../../Logic/TagsFilter";
|
||||
import {OperatorTag} from "../Questions/OperatorTag";
|
||||
import FixedText from "../Questions/FixedText";
|
||||
import ParkingType from "../Questions/bike/ParkingType";
|
||||
import ParkingCapacity from "../Questions/bike/ParkingCapacity";
|
||||
import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWithUpload";
|
||||
import BikeStationOperator from "../Questions/bike/StationOperator";
|
||||
import Translations from "../../UI/i18n/Translations";
|
||||
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 {
|
||||
private readonly accessCargoDesignated = new Tag("cargo_bike", "designated");
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.name = Translations.t.cyclofix.parking.name;
|
||||
|
@ -28,14 +31,9 @@ export default class BikeParkings extends LayerDefinition {
|
|||
new ImageCarouselWithUploadConstructor(),
|
||||
//new ParkingOperator(),
|
||||
new ParkingType(),
|
||||
new TagRenderingOptions({
|
||||
question: "How many bicycles fit in this bicycle parking?",
|
||||
freeform: {
|
||||
key: "capacity",
|
||||
renderTemplate: "Place for {capacity} bikes",
|
||||
template: "$nat$ bikes fit in here"
|
||||
}
|
||||
})
|
||||
new ParkingCapacity(),
|
||||
new ParkingAccessCargo(),
|
||||
new ParkingCapacityCargo().OnlyShowIf(this.accessCargoDesignated)
|
||||
];
|
||||
this.wayHandling = LayerDefinition.WAYHANDLING_CENTER_AND_WAY;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { LayerDefinition } from "../LayerDefinition";
|
||||
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 { ImageCarouselWithUploadConstructor } from "../../UI/Image/ImageCarouselWithUpload";
|
||||
import ShopRetail from "../Questions/bike/ShopRetail";
|
||||
|
@ -12,6 +12,7 @@ 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";
|
||||
|
||||
|
||||
export default class BikeShops extends LayerDefinition {
|
||||
|
@ -52,6 +53,7 @@ export default class BikeShops extends LayerDefinition {
|
|||
new ImageCarouselWithUploadConstructor(),
|
||||
new ShopName(),
|
||||
new PhoneNumberQuestion("{name}"),
|
||||
new Website("{name}"),
|
||||
new ShopRetail(),
|
||||
new ShopRental(),
|
||||
new ShopRepair(),
|
||||
|
|
|
@ -12,6 +12,7 @@ import {ImageCarouselWithUploadConstructor} from "../../UI/Image/ImageCarouselWi
|
|||
import PumpOperational from "../Questions/bike/PumpOperational";
|
||||
import PumpValves from "../Questions/bike/PumpValves";
|
||||
import Translations from "../../UI/i18n/Translations";
|
||||
import { TagRenderingOptions } from "../TagRendering";
|
||||
|
||||
|
||||
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 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 to = Translations.t.cyclofix.station
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
@ -36,7 +38,19 @@ export default class BikeStations extends LayerDefinition {
|
|||
|
||||
this.minzoom = 13;
|
||||
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.elementsToShow = [
|
||||
|
|
|
@ -5,6 +5,7 @@ import BikeShops from "../Layers/BikeShops";
|
|||
import Translations from "../../UI/i18n/Translations";
|
||||
import {DrinkingWater} from "../Layers/DrinkingWater";
|
||||
import Combine from "../../UI/Base/Combine";
|
||||
import BikeOtherShops from "../Layers/BikeOtherShops";
|
||||
|
||||
|
||||
export default class Cyclofix extends Layout {
|
||||
|
@ -13,7 +14,7 @@ export default class Cyclofix extends Layout {
|
|||
"cyclofix",
|
||||
["en", "nl", "fr"],
|
||||
Translations.t.cyclofix.title,
|
||||
[new BikeServices(), new BikeShops(), new DrinkingWater(), new BikeParkings()],
|
||||
[new BikeServices(), new BikeShops(), new DrinkingWater(), new BikeParkings(), new BikeOtherShops()],
|
||||
16,
|
||||
50.8465573,
|
||||
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 * as OsmToGeoJson from "osmtogeojson";
|
||||
import * as $ from "jquery";
|
||||
import {Basemap} from "./Basemap";
|
||||
import {UIEventSource} from "../UI/UIEventSource";
|
||||
|
||||
|
||||
/**
|
||||
* Interfaces overpass to get all the latest data
|
||||
*/
|
||||
export class Overpass {
|
||||
|
||||
|
||||
private _filter: TagsFilter;
|
||||
public static testUrl: string = null;
|
||||
private _filter: TagsFilter
|
||||
public static testUrl: string = null
|
||||
|
||||
constructor(filter: TagsFilter) {
|
||||
this._filter = filter;
|
||||
this._filter = filter
|
||||
}
|
||||
|
||||
private buildQuery(bbox: string): string {
|
||||
const filters = this._filter.asOverpass();
|
||||
let filter = "";
|
||||
public buildQuery(bbox: string): string {
|
||||
const filters = this._filter.asOverpass()
|
||||
console.log(filters)
|
||||
let filter = ""
|
||||
for (const filterOr of filters) {
|
||||
filter += 'nwr' + filterOr + ';';
|
||||
filter += 'nwr' + filterOr + ';'
|
||||
}
|
||||
const query =
|
||||
'[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;';
|
||||
console.log(query);
|
||||
return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query);
|
||||
'[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;'
|
||||
console.log(query)
|
||||
return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query)
|
||||
}
|
||||
|
||||
|
||||
queryGeoJson(bbox: string, continuation: ((any) => void), onFail: ((reason) => void)): void {
|
||||
let query = this.buildQuery(bbox);
|
||||
let query = this.buildQuery(bbox)
|
||||
|
||||
if(Overpass.testUrl !== null){
|
||||
console.log("Using testing URL")
|
||||
|
@ -53,9 +50,5 @@ export class Overpass {
|
|||
const geojson = OsmToGeoJson.default(json);
|
||||
continuation(geojson);
|
||||
}).fail(onFail)
|
||||
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -51,17 +51,23 @@ export class Regex extends TagsFilter {
|
|||
substituteValues(tags: any) : TagsFilter{
|
||||
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()
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.key = key
|
||||
this.value = value
|
||||
this.invertValue = invertValue
|
||||
|
||||
if (value === "*" && invertValue) {
|
||||
throw new Error("Invalid combination: invertValue && value == *")
|
||||
}
|
||||
}
|
||||
|
||||
matches(tags: { k: string; v: string }[]): boolean {
|
||||
|
@ -69,21 +75,22 @@ export class Tag extends TagsFilter {
|
|||
if (tag.k === this.key) {
|
||||
if (tag.v === "") {
|
||||
// This tag has been removed
|
||||
return this.value === "";
|
||||
return this.value === ""
|
||||
}
|
||||
if (this.value === "*") {
|
||||
// Any is allowed
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.value === tag.v;
|
||||
return this.value === tag.v !== this.invertValue
|
||||
}
|
||||
}
|
||||
if(this.value === ""){
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (this.value === "") {
|
||||
return true
|
||||
}
|
||||
|
||||
return this.invertValue
|
||||
}
|
||||
|
||||
asOverpass(): string[] {
|
||||
|
@ -94,17 +101,17 @@ export class Tag extends TagsFilter {
|
|||
// NOT having this key
|
||||
return ['[!"' + this.key + '"]'];
|
||||
}
|
||||
return ['["' + this.key + '"="' + this.value + '"]'];
|
||||
const compareOperator = this.invertValue ? '!=' : '='
|
||||
return ['["' + this.key + '"' + compareOperator + '"' + this.value + '"]'];
|
||||
}
|
||||
|
||||
substituteValues(tags: any) {
|
||||
return new Tag(this.key, TagUtils.ApplyTemplate(this.value, tags));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class Or extends TagsFilter {
|
||||
|
||||
export class Or extends TagsFilter {
|
||||
public or: TagsFilter[]
|
||||
|
||||
constructor(or: TagsFilter[]) {
|
||||
|
@ -112,9 +119,7 @@ export class Or extends TagsFilter {
|
|||
this.or = or;
|
||||
}
|
||||
|
||||
|
||||
matches(tags: { k: string; v: string }[]): boolean {
|
||||
|
||||
for (const tagsFilter of this.or) {
|
||||
if (tagsFilter.matches(tags)) {
|
||||
return true;
|
||||
|
@ -125,7 +130,6 @@ export class Or extends TagsFilter {
|
|||
}
|
||||
|
||||
asOverpass(): string[] {
|
||||
|
||||
const choices = [];
|
||||
for (const tagsFilter of this.or) {
|
||||
const subChoices = tagsFilter.asOverpass();
|
||||
|
@ -143,11 +147,10 @@ export class Or extends TagsFilter {
|
|||
}
|
||||
return new Or(newChoices);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class And extends TagsFilter {
|
||||
|
||||
export class And extends TagsFilter {
|
||||
public and: TagsFilter[]
|
||||
|
||||
constructor(and: TagsFilter[]) {
|
||||
|
@ -156,7 +159,6 @@ export class And extends TagsFilter {
|
|||
}
|
||||
|
||||
matches(tags: { k: string; v: string }[]): boolean {
|
||||
|
||||
for (const tagsFilter of this.and) {
|
||||
if (!tagsFilter.matches(tags)) {
|
||||
return false;
|
||||
|
@ -175,8 +177,7 @@ export class And extends TagsFilter {
|
|||
}
|
||||
|
||||
asOverpass(): string[] {
|
||||
|
||||
var allChoices = null;
|
||||
var allChoices: string[] = null;
|
||||
|
||||
for (const andElement of this.and) {
|
||||
var andElementFilter = andElement.asOverpass();
|
||||
|
@ -185,10 +186,10 @@ export class And extends TagsFilter {
|
|||
continue;
|
||||
}
|
||||
|
||||
var newChoices = []
|
||||
var newChoices: string[] = []
|
||||
for (var choice of allChoices) {
|
||||
newChoices.push(
|
||||
this.combine(choice, andElementFilter)
|
||||
...this.combine(choice, andElementFilter)
|
||||
)
|
||||
}
|
||||
allChoices = newChoices;
|
||||
|
@ -205,6 +206,7 @@ export class And extends TagsFilter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
export class Not extends TagsFilter{
|
||||
private not: TagsFilter;
|
||||
|
||||
|
@ -224,12 +226,10 @@ export class Not extends TagsFilter{
|
|||
substituteValues(tags: any): TagsFilter {
|
||||
return new Not(this.not.substituteValues(tags));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export class TagUtils {
|
||||
|
||||
static proprtiesToKV(properties: any): { k: string, v: string }[] {
|
||||
const result = [];
|
||||
for (const k in properties) {
|
||||
|
@ -246,5 +246,4 @@ export class TagUtils {
|
|||
}
|
||||
return template;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ import {InputElement} from "./InputElement";
|
|||
import {UIEventSource} from "../UIEventSource";
|
||||
import {UIElement} from "../UIElement";
|
||||
import {FixedUiElement} from "../Base/FixedUiElement";
|
||||
import Translations from "../i18n/Translations";
|
||||
|
||||
|
||||
export class InputElementWrapper<T> extends InputElement<T>{
|
||||
|
@ -16,9 +17,11 @@ export class InputElementWrapper<T> extends InputElement<T>{
|
|||
|
||||
) {
|
||||
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.post =typeof(post) === 'string' ? new FixedUiElement(post) : post
|
||||
// this.post =typeof(post) === 'string' ? new FixedUiElement(post) : post
|
||||
this.post = Translations.W(post)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,13 +33,13 @@ export default class Translations {
|
|||
type: {
|
||||
render: new T({
|
||||
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: 'TODO: fr'
|
||||
}),
|
||||
template: new T({en: 'Some other type: $$$', nl: 'Een ander type: $$$', fr: 'TODO: fr'}),
|
||||
question: new T({
|
||||
en: 'What is the type of this bicycle parking?',
|
||||
nl: 'Van welk type is deze fietsenparking?',
|
||||
nl: 'Van welk type is deze fietsparking?',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
eg: new T({en: ", for example", nl: ", bijvoorbeeld"}),
|
||||
|
@ -50,17 +50,16 @@ export default class Translations {
|
|||
rack: new T({en: 'Rack', nl: 'Rek', fr: 'TODO: fr'}),
|
||||
"two-tier": new T({en: 'Two-tiered', nl: 'Dubbel (twee verdiepingen)', fr: 'TODO: fr'}),
|
||||
},
|
||||
|
||||
operator: {
|
||||
render: new T({
|
||||
en: 'This bike parking is operated by {operator}',
|
||||
nl: 'Deze fietsenparking wordt beheerd door {operator}',
|
||||
nl: 'Deze fietsparking wordt beheerd door {operator}',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
||||
question: new T({
|
||||
en: 'Who operates this bike station (name of university, shop, city...)?',
|
||||
nl: 'Wie beheert deze fietsenparking (naam universiteit, winkel, stad...)?',
|
||||
en: 'Who operates this bike parking (name of university, shop, city...)?',
|
||||
nl: 'Wie beheert deze fietsparking (naam universiteit, winkel, stad...)?',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
private: new T({
|
||||
|
@ -68,15 +67,90 @@ export default class Translations {
|
|||
nl: 'Wordt beheerd door een privépersoon',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
},
|
||||
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: {
|
||||
name: new T({
|
||||
en: 'bike station (repair, pump or both)',
|
||||
nl: 'fietsstation (herstel, pomp of allebei)',
|
||||
nl: 'fietspunt (herstel, pomp of allebei)',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
title: new T({en: 'Bike station', nl: 'Fietsstation', fr: 'TODO: fr'}),
|
||||
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: {
|
||||
question: new T({
|
||||
en: 'Does the pump have a pressure indicator or manometer?',
|
||||
|
@ -144,8 +218,8 @@ export default class Translations {
|
|||
},
|
||||
chain: {
|
||||
question: new T({
|
||||
en: 'Does this bike station have a special tool to repair your bike chain?',
|
||||
nl: 'Heeft dit fietsstation een speciale reparatieset voor je ketting?',
|
||||
en: 'Does this bike repair station have a special tool to repair your bike chain?',
|
||||
nl: 'Heeft dit herstelpunt een speciale reparatieset voor je ketting?',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
yes: new T({
|
||||
|
@ -162,7 +236,7 @@ export default class Translations {
|
|||
operator: {
|
||||
render: new T({
|
||||
en: 'This bike station is operated by {operator}',
|
||||
nl: 'Dit fietsstation wordt beheerd door {operator}',
|
||||
nl: 'Dit fietspunt wordt beheerd door {operator}',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
template: new T({en: 'A different operator: $$$', nl: 'Een andere beheerder: $$$', fr: 'TODO: fr'}),
|
||||
|
@ -180,7 +254,7 @@ export default class Translations {
|
|||
services: {
|
||||
question: new T({
|
||||
en: 'Which services are available at this bike station?',
|
||||
nl: 'Welke functies biedt dit fietsstation?',
|
||||
nl: 'Welke functies biedt dit fietspunt?',
|
||||
fr: 'TODO: fr'
|
||||
}),
|
||||
pump: new T({
|
||||
|
@ -203,7 +277,7 @@ export default class Translations {
|
|||
stand: {
|
||||
question: new T({
|
||||
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: 'TODO: fr'
|
||||
}),
|
||||
yes: new T({en: 'There is a hook or stand', nl: 'Er is een haak of standaard', fr: 'TODO: fr'}),
|
||||
|
@ -211,17 +285,15 @@ export default class Translations {
|
|||
}
|
||||
},
|
||||
shop: {
|
||||
name: new T({en: 'bike shop', nl: 'fietswinkel', fr: 'TODO: fr'}),
|
||||
name: new T({en: 'bike repair/shop', nl: 'fietszaak', fr: 'TODO: fr'}),
|
||||
|
||||
title: new T({en: 'Bike shop', nl: 'Fietszaak', fr: 'TODO: fr'}),
|
||||
title: new T({en: 'Bike repair/shop', nl: 'Fietszaak', fr: 'TODO: fr'}),
|
||||
titleRepair: new T({en: 'Bike repair', nl: 'Fietsenmaker', fr: 'TODO: fr'}),
|
||||
titleShop: new T({en: 'Bike repair/shop', nl: 'Fietswinkel', fr: 'TODO: fr'}),
|
||||
|
||||
titleNamed: new T({en: 'Bike repair/shop', nl: 'Fietszaak {name}', fr: 'TODO: fr'}),
|
||||
titleRepairNamed: new T({en: 'Bike shop', nl: 'Fietsenmaker {name}', fr: 'TODO: fr'}),
|
||||
titleShopNamed: new T({en: 'Bike repair/shop', nl: 'Fietswinkel {name}', fr: 'TODO: fr'}),
|
||||
|
||||
titleShop: new T({en: 'Bike shop', nl: 'Fietswinkel', fr: 'TODO: fr'}),
|
||||
|
||||
titleNamed: new T({en: 'Bike repair/shop {name}', nl: 'Fietszaak {name}', fr: 'TODO: fr'}),
|
||||
titleRepairNamed: new T({en: 'Bike repair {name}', nl: 'Fietsenmaker {name}', fr: 'TODO: fr'}),
|
||||
titleShopNamed: new T({en: 'Bike shop {name}', nl: 'Fietswinkel {name}', fr: 'TODO: fr'}),
|
||||
|
||||
retail: {
|
||||
question: new T({
|
||||
|
@ -310,6 +382,17 @@ 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: {
|
||||
title: new T({
|
||||
en: 'Drinking water',
|
||||
|
@ -502,8 +585,15 @@ export default class Translations {
|
|||
phoneNumberIs: new T({
|
||||
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>"
|
||||
}),
|
||||
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>"
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
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 |
|
@ -980,6 +980,10 @@ form {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.question-text img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.question-subtext{
|
||||
font-size: medium;
|
||||
font-weight: normal;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
]
|
||||
},
|
||||
"scripts": {
|
||||
"start": "parcel *.html UI/** Logic/** assets/**/* vendor/* vendor/*/*",
|
||||
"start": "parcel *.html UI/** Logic/** assets/**/* assets/* vendor/* vendor/*/*",
|
||||
"generate": "ts-node createLayouts.ts",
|
||||
"build": "rm -rf dist/ && parcel build --public-url ./ *.html assets/* assets/**/* vendor/* vendor/*/*",
|
||||
"clean": "./clean.sh",
|
||||
|
|
BIN
static/staples-annotated.xcf
Normal file
BIN
static/staples-annotated.xcf
Normal file
Binary file not shown.
36
test.ts
36
test.ts
|
@ -0,0 +1,36 @@
|
|||
import { And, Tag, Or } from "./Logic/TagsFilter";
|
||||
import { Overpass } from "./Logic/Overpass";
|
||||
|
||||
|
||||
function anyValueExcept(key: string, exceptValue: string) {
|
||||
return new And([
|
||||
new Tag(key, "*"),
|
||||
new Tag(key, exceptValue, true)
|
||||
])
|
||||
}
|
||||
|
||||
const sellsBikes = new Tag("service:bicycle:retail", "yes")
|
||||
const repairsBikes = anyValueExcept("service:bicycle:repair", "no")
|
||||
const rentsBikes = new Tag("service:bicycle:rental", "yes")
|
||||
const hasPump = new Tag("service:bicycle:pump", "yes")
|
||||
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