mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 16:03:02 +00:00
feat(tours): plan ski and winter tours, snowshoeing and winter hiking among them
Ski becomes "Ski & winter", a type the planner plans with six disciplines (alpine, snowboard, cross-country, ski touring, snowshoeing, winter hiking), nothing preselected; saving needs a discipline, and a technique for cross-country. Every leg is drawn straight between the points through planner/skiRouting.ts, the one place the piste router will plug in, with its heights from the elevation source and no ski time worked out. The hike's winter label goes entirely: its migration, column, field, marks, GPX rule, MCP field and strings. A hike is summer only; a ski tour with the snowshoe discipline exports as snowshoeing. The unreleased ski migration takes the six disciplines and the collection migration loses the winter column. The pistes are offered for a ski tour, shown until switched off, and with no tour open, never for a hike. Export, copy, collections, stages (untimed), actual tracks, the atlas, list and day marks (one glyph per discipline), 3D, planning over a ski import and list_tours/get_tour_plan know the planned ski tour.
This commit is contained in:
@@ -28,7 +28,6 @@ export class CollectionTours {
|
||||
match_confidence?: number | null;
|
||||
max_hiking_difficulty?: number | null;
|
||||
bike_profile?: string | null;
|
||||
winter_activity?: string | null;
|
||||
run_profile?: string | null;
|
||||
run_pace_seconds_per_km?: number | null;
|
||||
ski_discipline?: string | null;
|
||||
@@ -76,7 +75,6 @@ export const CollectionToursSchema = defineEntity({
|
||||
match_confidence: p.double().nullable(),
|
||||
max_hiking_difficulty: p.integer().nullable(),
|
||||
bike_profile: p.text().nullable(),
|
||||
winter_activity: p.text().nullable(),
|
||||
run_profile: p.text().nullable(),
|
||||
run_pace_seconds_per_km: p.integer().nullable(),
|
||||
ski_discipline: p.text().nullable(),
|
||||
|
||||
@@ -44,7 +44,6 @@ export class Tours {
|
||||
taken_over_from_trip_title?: string | null;
|
||||
taken_over_from_tour_name?: string | null;
|
||||
bike_profile?: TToursBikeProfile | null;
|
||||
winter_activity?: TToursWinterActivity | null;
|
||||
run_profile?: TToursRunProfile | null;
|
||||
run_pace_seconds_per_km?: number | null;
|
||||
ski_discipline?: TToursSkiDiscipline | null;
|
||||
@@ -102,13 +101,6 @@ export const ToursBikeProfile = {
|
||||
|
||||
export type TToursBikeProfile = (typeof ToursBikeProfile)[keyof typeof ToursBikeProfile];
|
||||
|
||||
export const ToursWinterActivity = {
|
||||
WINTER_HIKE: 'winter_hike',
|
||||
SNOWSHOE: 'snowshoe',
|
||||
} as const;
|
||||
|
||||
export type TToursWinterActivity = (typeof ToursWinterActivity)[keyof typeof ToursWinterActivity];
|
||||
|
||||
export const ToursRunProfile = {
|
||||
RUNNING: 'running',
|
||||
TRAIL: 'trail',
|
||||
@@ -121,6 +113,8 @@ export const ToursSkiDiscipline = {
|
||||
SNOWBOARD: 'snowboard',
|
||||
CROSS_COUNTRY: 'cross_country',
|
||||
TOURING: 'touring',
|
||||
SNOWSHOE: 'snowshoe',
|
||||
WINTER_HIKE: 'winter_hike',
|
||||
} as const;
|
||||
|
||||
export type TToursSkiDiscipline = (typeof ToursSkiDiscipline)[keyof typeof ToursSkiDiscipline];
|
||||
@@ -181,7 +175,6 @@ export const ToursSchema = defineEntity({
|
||||
taken_over_from_trip_title: p.text().nullable(),
|
||||
taken_over_from_tour_name: p.text().nullable(),
|
||||
bike_profile: p.enum(() => ToursBikeProfile).nullable(),
|
||||
winter_activity: p.enum(() => ToursWinterActivity).nullable(),
|
||||
run_profile: p.enum(() => ToursRunProfile).nullable(),
|
||||
run_pace_seconds_per_km: p.integer().nullable(),
|
||||
ski_discipline: p.enum(() => ToursSkiDiscipline).nullable(),
|
||||
|
||||
@@ -23,7 +23,6 @@ export interface CollectionToursTable {
|
||||
match_confidence: InsertOptional<number | null>;
|
||||
max_hiking_difficulty: InsertOptional<number | null>;
|
||||
bike_profile: InsertOptional<string | null>;
|
||||
winter_activity: InsertOptional<string | null>;
|
||||
run_profile: InsertOptional<string | null>;
|
||||
run_pace_seconds_per_km: InsertOptional<number | null>;
|
||||
ski_discipline: InsertOptional<string | null>;
|
||||
|
||||
@@ -31,7 +31,6 @@ export interface ToursTable {
|
||||
taken_over_from_trip_title: InsertOptional<string | null>;
|
||||
taken_over_from_tour_name: InsertOptional<string | null>;
|
||||
bike_profile: InsertOptional<string | null>;
|
||||
winter_activity: InsertOptional<string | null>;
|
||||
run_profile: InsertOptional<string | null>;
|
||||
run_pace_seconds_per_km: InsertOptional<number | null>;
|
||||
ski_discipline: InsertOptional<string | null>;
|
||||
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
/**
|
||||
* HIK-01: a hike can carry a winter label, winter hiking or snowshoeing. It
|
||||
* is a column of the tour, NULL on every tour saved before and on every other
|
||||
* type, so no existing tour changes, and nothing routes or times by it.
|
||||
*/
|
||||
export class Migration20200101045500_a_hike_can_be_marked_as_a_winter_activity extends Migration {
|
||||
override name = 'Migration20200101045500_a_hike_can_be_marked_as_a_winter_activity';
|
||||
|
||||
override up(): void {
|
||||
this.addSql(
|
||||
"ALTER TABLE tours ADD COLUMN winter_activity TEXT CHECK (winter_activity IS NULL OR winter_activity IN ('winter_hike', 'snowshoe'))",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
/**
|
||||
* SKI-02: a tour can be a ski track, imported from a GPX file and kept as it
|
||||
* was recorded. The `ski` key has been in `tour_types`, disabled and without
|
||||
* a routing profile, since every contract type was seeded; it is switched on
|
||||
* here and keeps no routing profile, since TREK routes no ski track. The
|
||||
* discipline and, for cross-country, the technique are columns of the tour,
|
||||
* NULL on every other type, so no existing tour changes its meaning.
|
||||
* SKI-02: a tour can be a ski and winter tour, planned in the planner or
|
||||
* imported from a GPX file. The `ski` key has been in `tour_types`, disabled
|
||||
* and without a routing profile, since every contract type was seeded; it is
|
||||
* switched on here and keeps no routing profile: the planner draws its legs
|
||||
* itself. The discipline (alpine, snowboard, cross-country, ski touring,
|
||||
* snowshoe or winter hike) and, for cross-country, the technique are columns
|
||||
* of the tour, NULL on every other type, so no existing tour changes its
|
||||
* meaning.
|
||||
*/
|
||||
export class Migration20200101045520_a_tour_can_be_a_ski_track extends Migration {
|
||||
override name = 'Migration20200101045520_a_tour_can_be_a_ski_track';
|
||||
|
||||
override up(): void {
|
||||
this.addSql(
|
||||
"ALTER TABLE tours ADD COLUMN ski_discipline TEXT CHECK (ski_discipline IS NULL OR ski_discipline IN ('alpine', 'snowboard', 'cross_country', 'touring'))",
|
||||
"ALTER TABLE tours ADD COLUMN ski_discipline TEXT CHECK (ski_discipline IS NULL OR ski_discipline IN ('alpine', 'snowboard', 'cross_country', 'touring', 'snowshoe', 'winter_hike'))",
|
||||
);
|
||||
this.addSql(
|
||||
"ALTER TABLE tours ADD COLUMN ski_technique TEXT CHECK (ski_technique IS NULL OR ski_technique IN ('classic', 'skating', 'unknown'))",
|
||||
|
||||
@@ -36,7 +36,6 @@ export class Migration20200101046100_a_collection_keeps_whole_tours extends Migr
|
||||
match_confidence REAL,
|
||||
max_hiking_difficulty INTEGER,
|
||||
bike_profile TEXT,
|
||||
winter_activity TEXT,
|
||||
run_profile TEXT,
|
||||
run_pace_seconds_per_km INTEGER,
|
||||
ski_discipline TEXT,
|
||||
|
||||
@@ -32,7 +32,6 @@ export interface CollectionTourRow {
|
||||
match_confidence: number | null;
|
||||
max_hiking_difficulty: number | null;
|
||||
bike_profile: string | null;
|
||||
winter_activity: string | null;
|
||||
run_profile: string | null;
|
||||
run_pace_seconds_per_km: number | null;
|
||||
ski_discipline: string | null;
|
||||
|
||||
@@ -11,7 +11,6 @@ import type {
|
||||
RunProfile,
|
||||
SkiDiscipline,
|
||||
SkiTechnique,
|
||||
WinterActivity,
|
||||
} from '@trek/shared';
|
||||
|
||||
/**
|
||||
@@ -40,12 +39,10 @@ export interface TourListRow {
|
||||
origin: string;
|
||||
/** BIK-01: a bike tour's profile; NULL on every other type. */
|
||||
bike_profile: string | null;
|
||||
/** HIK-01: a hike's winter label; NULL for none and on every other type. */
|
||||
winter_activity: string | null;
|
||||
/** RUN-01: a run's profile and the pace it is planned at, seconds per km; NULL on every other type. */
|
||||
run_profile: string | null;
|
||||
run_pace_seconds_per_km: number | null;
|
||||
/** SKI-02: a ski track's discipline and, for cross-country, its technique; NULL on every other type. */
|
||||
/** SKI-02: a ski tour's discipline and, for cross-country, its technique; NULL on every other type. */
|
||||
ski_discipline: string | null;
|
||||
ski_technique: string | null;
|
||||
boat_type: string | null;
|
||||
@@ -120,7 +117,6 @@ export interface TourRow {
|
||||
taken_over_from_trip_title: string | null;
|
||||
taken_over_from_tour_name: string | null;
|
||||
bike_profile: string | null;
|
||||
winter_activity: string | null;
|
||||
run_profile: string | null;
|
||||
run_pace_seconds_per_km: number | null;
|
||||
ski_discipline: string | null;
|
||||
@@ -144,12 +140,10 @@ export interface TourInsert {
|
||||
max_hiking_difficulty: number | null;
|
||||
/** BIK-01: a bike tour's profile; left out, NULL. */
|
||||
bike_profile?: BikeProfile | null;
|
||||
/** HIK-01: a hike's winter label; left out, NULL on a new tour and kept as it is by an edit. */
|
||||
winter_activity?: WinterActivity | null;
|
||||
/** RUN-01: a run's profile and its pace, seconds per km; left out, NULL. */
|
||||
run_profile?: RunProfile | null;
|
||||
run_pace_seconds_per_km?: number | null;
|
||||
/** SKI-02: a ski track's discipline and technique; left out, NULL. */
|
||||
/** SKI-02: a ski tour's discipline and technique; left out, NULL. */
|
||||
ski_discipline?: SkiDiscipline | null;
|
||||
ski_technique?: SkiTechnique | null;
|
||||
/** A paddle tour's boat, water and chosen speed; left out, a hike's NULLs. */
|
||||
@@ -307,7 +301,6 @@ export class ToursRepository extends TrekRepository<Tours> {
|
||||
't.derived_from_place_id as derived_from_place_id',
|
||||
't.origin as origin',
|
||||
't.bike_profile as bike_profile',
|
||||
't.winter_activity as winter_activity',
|
||||
't.run_profile as run_profile',
|
||||
't.run_pace_seconds_per_km as run_pace_seconds_per_km',
|
||||
't.ski_discipline as ski_discipline',
|
||||
@@ -774,7 +767,6 @@ export class ToursRepository extends TrekRepository<Tours> {
|
||||
match_confidence: input.match_confidence,
|
||||
max_hiking_difficulty: input.max_hiking_difficulty,
|
||||
bike_profile: input.bike_profile ?? null,
|
||||
winter_activity: input.winter_activity ?? null,
|
||||
run_profile: input.run_profile ?? null,
|
||||
run_pace_seconds_per_km: input.run_pace_seconds_per_km ?? null,
|
||||
ski_discipline: input.ski_discipline ?? null,
|
||||
@@ -876,7 +868,6 @@ export class ToursRepository extends TrekRepository<Tours> {
|
||||
portage_speed_kmh: input.portage_speed_kmh,
|
||||
paddle_lake_style: input.paddle_lake_style,
|
||||
...(input.hiking_preferences !== undefined ? { hiking_preferences: input.hiking_preferences } : {}),
|
||||
...(input.winter_activity !== undefined ? { winter_activity: input.winter_activity } : {}),
|
||||
})
|
||||
.where('place_id', '=', place_id)
|
||||
.where('place_id', 'in', (eb) => eb.selectFrom('places').select('id').where('trip_id', '=', trip_id))
|
||||
|
||||
Reference in New Issue
Block a user