diff --git a/app/components/sidebar/container.vue b/app/components/sidebar/lines.vue similarity index 100% rename from app/components/sidebar/container.vue rename to app/components/sidebar/lines.vue diff --git a/app/components/sidebar/trip.vue b/app/components/sidebar/trip.vue new file mode 100644 index 0000000..b831021 --- /dev/null +++ b/app/components/sidebar/trip.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/app/pages/index.vue b/app/pages/index.vue index bd6e6f1..ebf83a0 100644 --- a/app/pages/index.vue +++ b/app/pages/index.vue @@ -1,6 +1,6 @@ diff --git a/app/pages/trip.vue b/app/pages/trip.vue new file mode 100644 index 0000000..52e883f --- /dev/null +++ b/app/pages/trip.vue @@ -0,0 +1,29 @@ + + + diff --git a/app/types.d.ts b/app/types.d.ts index 67d8943..c5a337a 100644 --- a/app/types.d.ts +++ b/app/types.d.ts @@ -52,3 +52,29 @@ interface StopTimes { occupancy: string; occupancyId: number; } + +interface PlannerResource extends Record { + routerId: string; + fromPlace: string; + toPlace: string; + arriveBy: string; + time: string; + date: string; + routerId: string; + optimize: OptimizeType; + walkSpeed: string; + walkReluctance: string; + locale: string; + mode: string; + showIntermediateStops?: string; + minTransferTime?: string; + transferPenalty?: string; + numItineraries?: string; + walkBoardCost?: string; + bannedAgencies?: string; +} + +type OptimizeType = + "FLAT" | "GREENWAYS" | "QUICK" | "SAFE" | "TRANSFERS" | "TRIANGLE"; + +type PlannerModes = "WALK" | "TRANSIT"; diff --git a/app/utils/trip.ts b/app/utils/trip.ts new file mode 100644 index 0000000..6dc2275 --- /dev/null +++ b/app/utils/trip.ts @@ -0,0 +1,81 @@ +import type { LngLat } from "maplibre-gl"; + +class RoutePlanner { + fromPlace: LngLat; + toPlace: LngLat; + date: Date; + + arriveBy = false; + routerId = "default"; + optimize: OptimizeType = "QUICK"; + walkSpeed = 1.1112; + walkReluctance = 10; + locale: string = "fr"; + mode: Set = new Set(["WALK"]); + otpUrl = new URL("https://data.mobilites-m.fr/api/routers/default/plan"); + + showIntermediateStops?: boolean; + minTransferTime?: number; + transferPenalty?: number; + numItineraries?: number; + walkBoardCost?: number; + bannedAgencies?: string; + + constructor(from: LngLat, to: LngLat) { + this.fromPlace = from; + this.toPlace = to; + this.date = new Date(); + } + + toURLSearchParams() { + const params: PlannerResource = { + fromPlace: `${this.fromPlace.lng},${this.fromPlace.lat}`, + toPlace: `${this.toPlace.lng},${this.toPlace.lat}`, + arriveBy: this.arriveBy.toString(), + date: this.date.toISOString().substring(0, 10), + time: this.date.toISOString().substring(11, 16), + routerId: this.routerId, + optimize: this.optimize, + walkSpeed: this.walkSpeed.toString(), + walkReluctance: this.walkReluctance.toString(), + locale: this.locale, + mode: Array.from(this.mode.values()).join(","), + }; + if (this.showIntermediateStops) { + params["showIntermediateStops"] = this.showIntermediateStops.toString(); + } + if (this.minTransferTime) { + params["minTransferTime"] = this.minTransferTime.toString(); + } + if (this.transferPenalty) { + params["transferPenalty"] = this.transferPenalty.toString(); + } + if (this.numItineraries) { + params["numItineraries"] = this.numItineraries.toString(); + } + if (this.walkBoardCost) { + params["walkBoardCost"] = this.walkBoardCost.toString(); + } + if (this.bannedAgencies) { + params["bannedAgencies"] = this.bannedAgencies.toString(); + } + return new URLSearchParams(params); + } + + async request() { + this.otpUrl.search = this.toURLSearchParams().toString(); + return await $fetch(this.otpUrl.toString()); + } +} + +class TransitRoutePlanner extends RoutePlanner { + override mode = new Set(["WALK", "TRANSIT"]); + override showIntermediateStops = true; + override minTransferTime = 60; + override transferPenalty = 60; + override numItineraries = 2; + override walkBoardCost = 300; + override bannedAgencies = "MCO:MCO"; +} + +export { RoutePlanner, TransitRoutePlanner };