incyclist-services 1.5.13 → 1.5.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/index.d.ts +1 -0
  2. package/lib/index.js +1 -0
  3. package/lib/maps/MapArea/MapArea.d.ts +2 -0
  4. package/lib/maps/MapArea/MapArea.js +14 -0
  5. package/lib/maps/MapArea/options.d.ts +1 -1
  6. package/lib/maps/MapArea/options.js +96 -68
  7. package/lib/maps/MapArea/service.d.ts +3 -3
  8. package/lib/maps/MapArea/service.js +13 -20
  9. package/lib/maps/MapArea/types.d.ts +2 -0
  10. package/lib/maps/MapArea/utils.d.ts +2 -1
  11. package/lib/maps/MapArea/utils.js +1 -1
  12. package/lib/ride/base/types.d.ts +25 -4
  13. package/lib/ride/display/service.js +17 -11
  14. package/lib/ride/route/FreeRideDisplayService.d.ts +39 -16
  15. package/lib/ride/route/FreeRideDisplayService.js +345 -92
  16. package/lib/ride/route/RLVDisplayService.d.ts +36 -0
  17. package/lib/ride/route/RLVDisplayService.js +137 -0
  18. package/lib/ride/route/RouteDisplayService.js +2 -1
  19. package/lib/routes/base/parsers/geojson.d.ts +16 -0
  20. package/lib/routes/base/parsers/geojson.js +2 -0
  21. package/lib/routes/base/parsers/geometry.d.ts +28 -0
  22. package/lib/routes/base/parsers/geometry.js +137 -0
  23. package/lib/routes/base/parsers/incyclist.d.ts +7 -4
  24. package/lib/routes/base/parsers/incyclist.js +34 -18
  25. package/lib/routes/base/parsers/xml.d.ts +2 -2
  26. package/lib/routes/base/types/index.d.ts +1 -1
  27. package/lib/routes/base/utils/route.d.ts +1 -1
  28. package/lib/routes/base/utils/route.js +24 -2
  29. package/lib/routes/free-ride/service.d.ts +4 -2
  30. package/lib/routes/free-ride/service.js +161 -46
  31. package/lib/video/ConvertSession.d.ts +5 -0
  32. package/lib/video/ConvertSession.js +62 -0
  33. package/lib/video/VideoConversion.d.ts +13 -0
  34. package/lib/video/VideoConversion.js +105 -0
  35. package/lib/video/VideoSyncHelper.d.ts +25 -0
  36. package/lib/video/VideoSyncHelper.js +145 -0
  37. package/lib/video/index.d.ts +3 -0
  38. package/lib/video/index.js +19 -0
  39. package/lib/video/types.d.ts +12 -0
  40. package/lib/video/types.js +2 -0
  41. package/package.json +5 -5
package/lib/index.d.ts CHANGED
@@ -13,4 +13,5 @@ export * from './routes';
13
13
  export * from './services';
14
14
  export { useUserSettings, initUserSettings, UserSettingsService, UserSettingsBinding, IUserSettingsBinding } from './settings';
15
15
  export * from './utils';
16
+ export * from './video';
16
17
  export * from './workouts';
package/lib/index.js CHANGED
@@ -34,4 +34,5 @@ Object.defineProperty(exports, "initUserSettings", { enumerable: true, get: func
34
34
  Object.defineProperty(exports, "UserSettingsService", { enumerable: true, get: function () { return settings_1.UserSettingsService; } });
35
35
  Object.defineProperty(exports, "UserSettingsBinding", { enumerable: true, get: function () { return settings_1.UserSettingsBinding; } });
36
36
  __exportStar(require("./utils"), exports);
37
+ __exportStar(require("./video"), exports);
37
38
  __exportStar(require("./workouts"), exports);
@@ -6,6 +6,7 @@ export declare class MapArea implements IMapArea {
6
6
  protected queryLocation: IncyclistNode;
7
7
  protected bounds: Boundary;
8
8
  protected logger: EventLogger;
9
+ protected lastUsed: number;
9
10
  constructor(data: FreeRideDataSet, queryLocation: IncyclistNode, bounds: Boundary);
10
11
  getQueryLocation(): IncyclistNode;
11
12
  getBoundary(): Boundary;
@@ -13,6 +14,7 @@ export declare class MapArea implements IMapArea {
13
14
  getWay(id: string): IncyclistWay;
14
15
  getNode(id: string): IncyclistNode;
15
16
  getStats(): Record<string, number>;
17
+ getLastUsed(): number;
16
18
  isWithinBoundary(location: LatLng): boolean;
17
19
  getNearestPath(point: IncyclistNode): NearestPathInfo;
18
20
  getFirstBranch(way: WayInfo, ignore?: string): SplitPointInfo;
@@ -14,6 +14,7 @@ class MapArea {
14
14
  this.queryLocation = queryLocation;
15
15
  this.bounds = bounds;
16
16
  this.logger = new gd_eventlog_1.EventLogger('MapArea');
17
+ this.lastUsed = Date.now();
17
18
  this.correctRoundabouts();
18
19
  }
19
20
  getQueryLocation() {
@@ -23,22 +24,30 @@ class MapArea {
23
24
  return this.bounds;
24
25
  }
25
26
  getWays() {
27
+ this.lastUsed = Date.now();
26
28
  return this.data.ways;
27
29
  }
28
30
  getWay(id) {
31
+ this.lastUsed = Date.now();
29
32
  return this.data.waysLookup[id];
30
33
  }
31
34
  getNode(id) {
35
+ this.lastUsed = Date.now();
32
36
  return this.data.nodesLookup[id];
33
37
  }
34
38
  getStats() {
35
39
  return this.data.typeStats;
36
40
  }
41
+ getLastUsed() {
42
+ return this.lastUsed;
43
+ }
37
44
  isWithinBoundary(location) {
45
+ this.lastUsed = Date.now();
38
46
  return (0, utils_1.isWithinBoundary)(location, this.bounds);
39
47
  }
40
48
  getNearestPath(point) {
41
49
  var _a, _b;
50
+ this.lastUsed = Date.now();
42
51
  const ways = (_b = (_a = this.data) === null || _a === void 0 ? void 0 : _a.ways) !== null && _b !== void 0 ? _b : [];
43
52
  if (!(ways === null || ways === void 0 ? void 0 : ways.length))
44
53
  return;
@@ -55,6 +64,7 @@ class MapArea {
55
64
  return min;
56
65
  }
57
66
  getFirstBranch(way, ignore) {
67
+ this.lastUsed = Date.now();
58
68
  if ((way === null || way === void 0 ? void 0 : way.path) === undefined)
59
69
  return;
60
70
  let pFound = undefined;
@@ -78,6 +88,7 @@ class MapArea {
78
88
  return pFound;
79
89
  }
80
90
  splitAtFirstBranch(way) {
91
+ this.lastUsed = Date.now();
81
92
  if ((way === null || way === void 0 ? void 0 : way.path) === undefined)
82
93
  return;
83
94
  const path = [...way.path];
@@ -107,6 +118,7 @@ class MapArea {
107
118
  return result;
108
119
  }
109
120
  splitAtCrossingPoint(way, crossing) {
121
+ this.lastUsed = Date.now();
110
122
  if ((way === null || way === void 0 ? void 0 : way.path) === undefined || (crossing === null || crossing === void 0 ? void 0 : crossing.idx) === undefined || (crossing === null || crossing === void 0 ? void 0 : crossing.point) === undefined)
111
123
  return;
112
124
  const { point, idx: crossingIdx, distance } = crossing;
@@ -172,6 +184,7 @@ class MapArea {
172
184
  return res;
173
185
  }
174
186
  buildSegmentInfo(from, parts) {
187
+ this.lastUsed = Date.now();
175
188
  const segments = [];
176
189
  const points = [];
177
190
  parts.forEach((option, i) => {
@@ -188,6 +201,7 @@ class MapArea {
188
201
  }
189
202
  getHeading(way, position = 'start') {
190
203
  var _a;
204
+ this.lastUsed = Date.now();
191
205
  if (((_a = way === null || way === void 0 ? void 0 : way.path) === null || _a === void 0 ? void 0 : _a.length) < 2)
192
206
  return;
193
207
  let fullWay = this.getWay(way.id);
@@ -17,7 +17,7 @@ export declare class OptionManager {
17
17
  protected getOptionsRoundabout(location: IncyclistNode, w: IncyclistWay, options: FreeRideContinuation[]): any;
18
18
  protected getWay(props: string | IncyclistWay): IncyclistWay;
19
19
  protected getNode(props?: string | IncyclistNode): IncyclistNode;
20
- getRemaining(partial: IncyclistWay): IncyclistWay;
20
+ protected getRemaining(partial: IncyclistWay): IncyclistWay;
21
21
  protected findClosestPoint(path: IncyclistNode[], point: IncyclistNode, exclude: IncyclistNode): number;
22
22
  getOptionsOnCurrentWay(location: IncyclistNode, way: IncyclistWay, options: Array<FreeRideContinuation>): Array<FreeRideContinuation>;
23
23
  protected logError(err: Error, fn: string, args?: any): void;
@@ -32,7 +32,7 @@ class OptionManager {
32
32
  const options = [];
33
33
  const parts = this.map.splitAtCrossingPoint(way, crossing);
34
34
  const { segments, points } = this.map.buildSegmentInfo(way, parts);
35
- for (const segment of segments) {
35
+ for (const segment of segments !== null && segments !== void 0 ? segments : []) {
36
36
  try {
37
37
  const path = segment.path;
38
38
  const opts = yield this.getNextOptions(segment);
@@ -65,51 +65,71 @@ class OptionManager {
65
65
  }
66
66
  getNextOptions(from, props) {
67
67
  return __awaiter(this, void 0, void 0, function* () {
68
- if ((from === null || from === void 0 ? void 0 : from.id) === undefined || (from === null || from === void 0 ? void 0 : from.path) === undefined || (from === null || from === void 0 ? void 0 : from.path.length) < 1) {
69
- return [];
70
- }
71
- const way = Object.assign(Object.assign({}, this.getWay(from.id)), { path: from.path });
72
- let location = way.path[way.path.length - 1];
73
- if (location.id === undefined) {
74
- if (way.path.length > 1)
75
- location = way.path[way.path.length - 2];
76
- else {
68
+ var _a;
69
+ try {
70
+ if ((from === null || from === void 0 ? void 0 : from.id) === undefined || (from === null || from === void 0 ? void 0 : from.path) === undefined || (from === null || from === void 0 ? void 0 : from.path.length) < 1) {
77
71
  return [];
78
72
  }
79
- }
80
- const map = yield this.service.load(location);
81
- if (!map) {
82
- if (!this.map)
83
- return [];
84
- }
85
- else {
86
- this.setMap(map);
87
- }
88
- const node = this.getNode(location);
89
- const remaining = this.getRemaining(way);
90
- let options = [];
91
- if (node !== undefined) {
92
- node.ways.forEach((wid) => {
93
- if (wid === remaining.id) {
94
- options = this.getOptionsOnCurrentWay(node, remaining, options);
73
+ let originalWay = this.getWay(from.id);
74
+ if (!originalWay) {
75
+ const map = this.service.getMap(from.path[0]);
76
+ const query = { id: from.id, path: from.path, map: map };
77
+ originalWay = this.getWay(query);
78
+ if (!originalWay) {
79
+ return [];
95
80
  }
81
+ }
82
+ const way = Object.assign(Object.assign({}, originalWay), { path: from.path });
83
+ let location = way.path[way.path.length - 1];
84
+ if (location.id === undefined) {
85
+ if (way.path.length > 1)
86
+ location = way.path[way.path.length - 2];
96
87
  else {
97
- const w = this.getWay(wid);
98
- options = this.checkOptionsOnDifferentWay(node, w, options);
88
+ return [];
99
89
  }
90
+ }
91
+ const map = yield this.service.load(location);
92
+ if (!map) {
93
+ if (!this.map)
94
+ return [];
95
+ }
96
+ else {
97
+ this.setMap(map);
98
+ }
99
+ const node = this.getNode(location);
100
+ const remaining = this.getRemaining(way);
101
+ let options = [];
102
+ if (node !== undefined) {
103
+ node.ways.forEach((wid) => {
104
+ if (wid === remaining.id) {
105
+ options = this.getOptionsOnCurrentWay(node, remaining, options);
106
+ }
107
+ else {
108
+ const w = this.getWay(wid);
109
+ options = this.checkOptionsOnDifferentWay(node, w, options);
110
+ }
111
+ });
112
+ }
113
+ const currentDirection = this.map.getHeading(way, 'end');
114
+ options.forEach((option) => {
115
+ const direction = this.map.getHeading(option, 'start');
116
+ option.direction = direction - currentDirection;
117
+ if (option.direction > 180)
118
+ option.direction = option.direction - 360;
100
119
  });
120
+ if (props === null || props === void 0 ? void 0 : props.minDistance) {
121
+ yield this.checkMinDistance(options, props.minDistance);
122
+ }
123
+ if (options === null || options === void 0 ? void 0 : options.length) {
124
+ const fromNode = (_a = from.path) === null || _a === void 0 ? void 0 : _a[from.path.length - 2];
125
+ options = options.filter(o => o.path.length > 0 && o.path[1].id !== fromNode.id);
126
+ }
127
+ return options;
101
128
  }
102
- const currentDirection = this.map.getHeading(way, 'end');
103
- options.forEach((option) => {
104
- const direction = this.map.getHeading(option, 'start');
105
- option.direction = direction - currentDirection;
106
- if (option.direction > 180)
107
- option.direction = option.direction - 360;
108
- });
109
- if (props === null || props === void 0 ? void 0 : props.minDistance) {
110
- yield this.checkMinDistance(options, props.minDistance);
129
+ catch (err) {
130
+ this.logError(err, 'getNextOptions');
131
+ return [];
111
132
  }
112
- return options;
113
133
  });
114
134
  }
115
135
  checkMinDistance(options, minDistance) {
@@ -293,8 +313,10 @@ class OptionManager {
293
313
  if (typeof props === 'string') {
294
314
  return (0, clone_1.default)((_a = this.map) === null || _a === void 0 ? void 0 : _a.getWay(props));
295
315
  }
296
- if (props.id !== undefined)
297
- return (0, clone_1.default)((_b = this.map) === null || _b === void 0 ? void 0 : _b.getWay(props.id));
316
+ if (props.id !== undefined) {
317
+ const map = (_b = props.map) !== null && _b !== void 0 ? _b : this.map;
318
+ return (0, clone_1.default)(map.getWay(props.id));
319
+ }
298
320
  }
299
321
  getNode(props) {
300
322
  var _a, _b;
@@ -311,37 +333,43 @@ class OptionManager {
311
333
  }
312
334
  }
313
335
  getRemaining(partial) {
314
- const originalWay = this.getWay(partial);
315
- const path = originalWay.path;
316
- const roundabout = (0, utils_1.isRoundabout)(originalWay);
317
- if (roundabout)
318
- return Object.assign(Object.assign({}, originalWay), { roundabout });
319
- let newPath = path;
320
- const last = partial.path[partial.path.length - 1];
321
- const prev = partial.path[partial.path.length - 2];
322
- const idxLast = path.findIndex((p) => (0, utils_1.pointEquals)(p, last));
323
- let idxPrev = path.findIndex((p) => (0, utils_1.pointEquals)(p, prev));
324
- if (idxPrev === -1)
325
- idxPrev = this.findClosestPoint(path, prev, last);
326
- let lastOriginal;
327
- if (idxPrev > idxLast) {
328
- lastOriginal = originalWay.path[0];
329
- }
330
- else {
331
- lastOriginal = originalWay.path[originalWay.path.length - 1];
332
- }
333
- if (last.id === lastOriginal.id) {
334
- return Object.assign(Object.assign({}, originalWay), { path: [], roundabout: false });
335
- }
336
- if (idxLast !== -1 && idxPrev !== -1) {
337
- if (idxPrev < idxLast)
338
- newPath = path.slice(idxLast);
336
+ try {
337
+ const originalWay = this.getWay(partial);
338
+ const path = originalWay.path;
339
+ const roundabout = (0, utils_1.isRoundabout)(originalWay);
340
+ if (roundabout)
341
+ return Object.assign(Object.assign({}, originalWay), { roundabout });
342
+ let newPath = path;
343
+ const last = partial.path[partial.path.length - 1];
344
+ const prev = partial.path[partial.path.length - 2];
345
+ const idxLast = path.findIndex((p) => (0, utils_1.pointEquals)(p, last));
346
+ let idxPrev = path.findIndex((p) => (0, utils_1.pointEquals)(p, prev));
347
+ if (idxPrev === -1)
348
+ idxPrev = this.findClosestPoint(path, prev, last);
349
+ let lastOriginal;
350
+ if (idxPrev > idxLast) {
351
+ lastOriginal = originalWay.path[0];
352
+ }
339
353
  else {
340
- newPath = path.slice(0, idxLast + 1);
341
- newPath.reverse();
354
+ lastOriginal = originalWay.path[originalWay.path.length - 1];
355
+ }
356
+ if (last.id === lastOriginal.id) {
357
+ return Object.assign(Object.assign({}, originalWay), { path: [], roundabout: false });
342
358
  }
359
+ if (idxLast !== -1 && idxPrev !== -1) {
360
+ if (idxPrev < idxLast)
361
+ newPath = path.slice(idxLast);
362
+ else {
363
+ newPath = path.slice(0, idxLast + 1);
364
+ newPath.reverse();
365
+ }
366
+ }
367
+ return Object.assign(Object.assign({}, originalWay), { path: newPath, roundabout });
368
+ }
369
+ catch (err) {
370
+ this.logError(err, 'getRemaining');
371
+ return Object.assign(Object.assign({}, partial), { path: [], roundabout: false });
343
372
  }
344
- return Object.assign(Object.assign({}, originalWay), { path: newPath, roundabout });
345
373
  }
346
374
  findClosestPoint(path, point, exclude) {
347
375
  let found = -1;
@@ -9,8 +9,8 @@ type MapAreaRecord = {
9
9
  lastUsed: number;
10
10
  radius: number;
11
11
  };
12
- export declare const getMapInfo: (m: any) => string;
13
- export declare const getMapsInfo: (maps: any, key: string) => string;
12
+ export declare const getMapInfo: (m: MapAreaRecord) => string;
13
+ export declare const getMapsInfo: (maps: Record<string, MapAreaRecord>, key: string) => string;
14
14
  export declare class MapAreaService extends IncyclistService implements IMapAreaService {
15
15
  protected static consts: {
16
16
  DEFAULT_RADIUS: number;
@@ -32,7 +32,7 @@ export declare class MapAreaService extends IncyclistService implements IMapArea
32
32
  protected iv: NodeJS.Timeout;
33
33
  constructor();
34
34
  load(location: IncyclistNode): Promise<IMapArea>;
35
- getMap(location: IncyclistNode): MapArea;
35
+ getMap(location: IncyclistNode): IMapArea;
36
36
  getOptionManager(): OptionManager;
37
37
  setFilter(filter: Array<string> | null): void;
38
38
  protected findBestMap(location: IncyclistNode): Promise<IMapArea | undefined>;
@@ -66,19 +66,22 @@ const getMapInfo = (m) => {
66
66
  try {
67
67
  const boundary = m.map.getBoundary();
68
68
  const bInfo = `${boundary.northeast.lat},${boundary.northeast.lng},${boundary.southwest.lat},${boundary.southwest.lng}`;
69
- return `${m.radius},[${bInfo}]`;
69
+ return `${m.radius},{${bInfo}}`;
70
70
  }
71
- catch (_a) {
71
+ catch (err) {
72
+ console.log('# ERROR', err);
72
73
  return '';
73
74
  }
74
75
  };
75
76
  exports.getMapInfo = getMapInfo;
76
77
  const getMapsInfo = (maps, key) => {
78
+ var _a;
77
79
  try {
78
80
  const m = maps[key];
79
- return `${key}:${(0, exports.getMapInfo)(m)}`;
81
+ const time = Number((Date.now() - ((_a = m.map.getLastUsed()) !== null && _a !== void 0 ? _a : m.lastUsed)) / 1000).toFixed(1);
82
+ return `${key}:${(0, exports.getMapInfo)(m)}:age=${time}s`;
80
83
  }
81
- catch (_a) {
84
+ catch (_b) {
82
85
  return '';
83
86
  }
84
87
  };
@@ -131,7 +134,6 @@ let MapAreaService = (() => {
131
134
  const records = this.getMapsForLocation(location);
132
135
  let updateRequired = true;
133
136
  let minDist = Number.MAX_VALUE;
134
- let minPct;
135
137
  let best;
136
138
  do {
137
139
  if (records.length === 0)
@@ -144,17 +146,13 @@ let MapAreaService = (() => {
144
146
  updateRequired = dist > (radius / 5);
145
147
  if (!updateRequired) {
146
148
  minDist = dist;
147
- minPct = minDist / radius * 100;
148
149
  best = record;
149
150
  }
150
151
  else if (dist < minDist) {
151
152
  minDist = dist;
152
- minPct = minDist / radius * 100;
153
153
  }
154
154
  yield (0, utils_2.waitNextTick)();
155
155
  } while (records.length > 0 && updateRequired);
156
- const { lat, lng, id } = location;
157
- this.logEvent({ message: 'distance between previous overpass request', location: { lat, lng, id }, dist: minDist, pct: minPct, updateRequired, map: (0, exports.getMapInfo)(best === null || best === void 0 ? void 0 : best.map) });
158
156
  return best === null || best === void 0 ? void 0 : best.map;
159
157
  });
160
158
  }
@@ -195,22 +193,16 @@ let MapAreaService = (() => {
195
193
  }
196
194
  addMap(map, location) {
197
195
  this.current = map;
198
- this.maps[this.mapsKey(location)] = { map, lastUsed: Date.now(), radius: this.radius };
199
- this.logEvent({ message: 'Map added', cnt: Object.keys(this.maps).length, maps: Object.keys(this.maps).map(k => (0, exports.getMapsInfo)(this.maps, k)) });
196
+ const record = { map, lastUsed: Date.now(), radius: this.radius };
197
+ this.maps[this.mapsKey(location)] = record;
198
+ const mapInfo = `${location.lat},${location.lng},${(0, exports.getMapInfo)(record)}`;
199
+ this.logEvent({ message: 'Map added', map: mapInfo, cnt: Object.keys(this.maps).length, maps: Object.keys(this.maps).map(k => (0, exports.getMapsInfo)(this.maps, k)) });
200
200
  }
201
201
  getMapsForLocation(location) {
202
202
  return Object.values(this.maps).filter(m => m.map.isWithinBoundary(location));
203
203
  }
204
204
  createMapData(openmapData) {
205
- var _a, _b;
206
- let ts = Date.now();
207
205
  const data = (0, utils_1.parseMapData)(openmapData, this.filter);
208
- let ts1 = Date.now();
209
- this.logger.logEvent({ message: 'Parse', duration: (ts1 - ts),
210
- ways: (_a = data === null || data === void 0 ? void 0 : data.ways.length) !== null && _a !== void 0 ? _a : 0,
211
- nodes: Object.keys((_b = data === null || data === void 0 ? void 0 : data.nodesLookup) !== null && _b !== void 0 ? _b : {}).length,
212
- typeStats: data === null || data === void 0 ? void 0 : data.typeStats
213
- });
214
206
  if (data !== undefined) {
215
207
  this.loaded = 'success';
216
208
  }
@@ -250,8 +242,9 @@ let MapAreaService = (() => {
250
242
  this.iv = undefined;
251
243
  }
252
244
  garbageCollection() {
245
+ const tsLastUsed = (m) => { var _a; return (_a = m.map.getLastUsed()) !== null && _a !== void 0 ? _a : m.lastUsed; };
253
246
  const now = Date.now();
254
- const maps = Object.values(this.maps).filter(m => now - m.lastUsed < 1000 * 60 * 5);
247
+ const maps = Object.values(this.maps).filter(m => now - tsLastUsed(m) < 1000 * 60 * 5);
255
248
  const keyLastUsed = this.mapsKey(this.current.getQueryLocation());
256
249
  const deleteTarget = maps.filter(m => this.mapsKey(m.map.getQueryLocation()) !== keyLastUsed);
257
250
  if (deleteTarget.length > MAX_MAPS) {
@@ -39,6 +39,7 @@ export type FreeRideContinuation = {
39
39
  };
40
40
  export interface IMapAreaService {
41
41
  load(location: IncyclistNode): Promise<IMapArea>;
42
+ getMap(location: IncyclistNode): IMapArea;
42
43
  }
43
44
  export type Boundary = {
44
45
  southwest: LatLng;
@@ -104,6 +105,7 @@ export interface IncyclistWay extends WayInfo {
104
105
  name: string;
105
106
  tags: Record<string, any>;
106
107
  bounds: OverpassBounds;
108
+ map?: IMapArea;
107
109
  roundabout?: boolean;
108
110
  originalId?: string;
109
111
  }
@@ -1,12 +1,13 @@
1
1
  import { Vector } from "../../utils";
2
2
  import { LatLng } from "../../utils/geo";
3
3
  import { Boundary, CrossingInfo, IncyclistNode, IncyclistWay, FreeRideDataSet, SplitPointInfo, PathCrossingInfo, WayInfo } from "./types";
4
+ import { RoutePoint } from "../../routes/base/types";
4
5
  export declare function addNode(node: number, nodesLookup: Record<string, IncyclistNode>, id: number, path: Array<IncyclistNode>): void;
5
6
  export declare function addWay(w: IncyclistWay, ways: Array<IncyclistWay>, waysLookup: Record<string, IncyclistWay>): void;
6
7
  export declare function updateTypeStats(types: Record<string, number>, type: string): void;
7
8
  export declare function parseMapData(str: JSON | string, filter: any): FreeRideDataSet;
8
9
  export declare function splitAtIndex(way: any, idxSplit: any): any[][];
9
- export declare function concatPaths(path: IncyclistNode[], path2: IncyclistNode[], position: 'before' | 'after'): void;
10
+ export declare function concatPaths(path: IncyclistNode[] | RoutePoint[], path2: IncyclistNode[] | RoutePoint[], position: 'before' | 'after'): void;
10
11
  export declare function splitAtPointInfo(way: WayInfo, split: SplitPointInfo): Array<Array<IncyclistNode>>;
11
12
  export declare function isRoundabout(w: IncyclistWay, strictCheck?: boolean): boolean;
12
13
  export declare function removeDuplicates(options: any): any;
@@ -126,7 +126,7 @@ function splitAtIndex(way, idxSplit) {
126
126
  return result;
127
127
  }
128
128
  function concatPaths(path, path2, position) {
129
- const append = [...path2];
129
+ const append = path2.map(p => (Object.assign({}, p)));
130
130
  if (position === 'after') {
131
131
  append.shift();
132
132
  path.push(...append);
@@ -9,6 +9,7 @@ import { ActiveRideListAvatar, ActivityDetails, PrevRidesListDisplayProps, Scree
9
9
  import { Workout } from "../../workouts";
10
10
  import { FreeRideOption } from "../../routes/list/types";
11
11
  import { MapViewPort } from "../route/types";
12
+ import { LatLng } from "../../utils/geo";
12
13
  export type RideType = 'Free-Ride' | 'GPX' | 'Video' | 'Workout';
13
14
  export type CurrentRideState = 'Idle' | 'Starting' | 'Started' | 'Active' | 'Paused' | 'Error' | 'Finished';
14
15
  export type CurrentRideDeviceState = 'Starting' | 'Started' | 'Error';
@@ -53,21 +54,41 @@ export interface RouteDisplayProps extends IRideModeServiceDisplayProps {
53
54
  upcomingElevation?: OverlayDisplayProps;
54
55
  totalElevation?: OverlayDisplayProps;
55
56
  }
57
+ export interface VideoDisplayProps {
58
+ src: any;
59
+ playback: 'native' | 'converted';
60
+ startTime?: number;
61
+ observer: Observer;
62
+ muted?: boolean;
63
+ onPlaybackUpdate?: (time: number, rate: number) => void;
64
+ onLoaded?: () => void;
65
+ onPlaybackError?: (error: string) => void;
66
+ onLoadError?: (error: string) => void;
67
+ }
68
+ export interface RLVDisplayProps extends RouteDisplayProps {
69
+ video?: VideoDisplayProps;
70
+ }
56
71
  export interface MapOverlayDisplayProps extends OverlayDisplayProps {
57
72
  viewport?: MapViewPort;
58
73
  viewportOverwrite?: boolean;
74
+ center?: LatLng;
75
+ bounds?: Number[][];
59
76
  onViewportChange?: (viewport: MapViewPort) => void;
60
77
  }
61
78
  export interface GpxDisplayProps extends RouteDisplayProps {
62
79
  rideView: 'sv' | 'map' | 'sat';
63
80
  }
64
- export interface FreeRideDisplayProps extends GpxDisplayProps {
65
- options?: FreeRideOption[];
81
+ export interface RouteOptionDisplayProps {
66
82
  optionsDelay?: number;
67
83
  optionsId?: string;
68
84
  onOptionsVisibleChanged: (visible: boolean) => void;
85
+ isNearby?: boolean;
86
+ distance?: number;
87
+ turn?: boolean;
69
88
  }
70
- export interface VideoDisplayProps extends RouteDisplayProps {
89
+ export interface FreeRideDisplayProps extends GpxDisplayProps {
90
+ options?: FreeRideOption[];
91
+ optionProps?: RouteOptionDisplayProps;
71
92
  }
72
93
  export interface StartOverlayProps {
73
94
  mode: RideType;
@@ -76,7 +97,7 @@ export interface StartOverlayProps {
76
97
  readyToStart: boolean;
77
98
  }
78
99
  export interface OverlayDisplayProps {
79
- show: boolean;
100
+ show?: boolean;
80
101
  minimized?: boolean;
81
102
  }
82
103
  export interface PrevRidesDisplayProps extends OverlayDisplayProps {
@@ -61,9 +61,9 @@ const utils_1 = require("../../utils");
61
61
  const base_1 = require("../base/base");
62
62
  const FreeRideDisplayService_1 = require("../route/FreeRideDisplayService");
63
63
  const FollowRouteDisplayService_1 = require("../route/FollowRouteDisplayService");
64
- const VideoDisplayService_1 = require("../route/VideoDisplayService");
65
64
  const WorkoutDisplayService_1 = require("../workout/WorkoutDisplayService");
66
65
  const api_1 = require("../../api");
66
+ const RLVDisplayService_1 = require("../route/RLVDisplayService");
67
67
  let RideDisplayService = (() => {
68
68
  let _classDecorators = [types_1.Singleton];
69
69
  let _classDescriptor;
@@ -359,8 +359,11 @@ let RideDisplayService = (() => {
359
359
  if (!this.type) {
360
360
  try {
361
361
  this.type = this.detectRideType();
362
+ console.log('#ride type', this.type);
363
+ }
364
+ catch (err) {
365
+ console.log('# error detecting ride type', err);
362
366
  }
363
- catch (_a) { }
364
367
  }
365
368
  return this.type;
366
369
  }
@@ -375,14 +378,14 @@ let RideDisplayService = (() => {
375
378
  return (_a = this.getWorkoutRide().getWorkout()) !== null && _a !== void 0 ? _a : this.getWorkoutList().getSelected();
376
379
  }
377
380
  get route() {
378
- var _a;
381
+ var _a, _b;
379
382
  const route = this.getRouteList().getSelected();
380
383
  const settings = this.getRouteList().getStartSettings();
381
384
  if (!route && (settings === null || settings === void 0 ? void 0 : settings.type) === 'Free-Ride') {
382
385
  return this.getRideModeService().getCurrentRoute();
383
386
  }
384
387
  if (((_a = route === null || route === void 0 ? void 0 : route.description) === null || _a === void 0 ? void 0 : _a.hasVideo) && (settings === null || settings === void 0 ? void 0 : settings.type) === 'Route') {
385
- return this.getRideModeService().getCurrentRoute();
388
+ return (_b = this.getRideModeService().getCurrentRoute()) !== null && _b !== void 0 ? _b : route;
386
389
  }
387
390
  return route;
388
391
  }
@@ -445,18 +448,21 @@ let RideDisplayService = (() => {
445
448
  (_a = this.observer) === null || _a === void 0 ? void 0 : _a.emit('state-update', this.state);
446
449
  }
447
450
  detectRideType() {
448
- var _a, _b, _c, _d;
451
+ var _a;
452
+ const route = this.getRouteList().getSelected();
449
453
  const startSettings = this.getRouteList().getStartSettings();
450
454
  const workout = this.getWorkoutList().getSelected();
451
455
  if ((startSettings === null || startSettings === void 0 ? void 0 : startSettings.type) === 'Free-Ride') {
452
456
  return 'Free-Ride';
453
457
  }
454
- if (!((_a = this.route) === null || _a === void 0 ? void 0 : _a.details) && !!workout) {
458
+ if (!(route === null || route === void 0 ? void 0 : route.details) && !!workout) {
455
459
  return 'Workout';
456
460
  }
457
- if (!((_b = this.route) === null || _b === void 0 ? void 0 : _b.details))
458
- throw new Error('unknown ride typpe');
459
- return ((_d = (_c = this.route) === null || _c === void 0 ? void 0 : _c.description) === null || _d === void 0 ? void 0 : _d.hasVideo) ? 'Video' : 'GPX';
461
+ if (!(route === null || route === void 0 ? void 0 : route.details)) {
462
+ console.log('# this.route?.details', route === null || route === void 0 ? void 0 : route.details, route);
463
+ throw new Error('unknown ride type');
464
+ }
465
+ return ((_a = route === null || route === void 0 ? void 0 : route.description) === null || _a === void 0 ? void 0 : _a.hasVideo) ? 'Video' : 'GPX';
460
466
  }
461
467
  getRideModeService(overwrite) {
462
468
  if (this.displayService && !overwrite)
@@ -466,7 +472,7 @@ let RideDisplayService = (() => {
466
472
  switch (type) {
467
473
  case 'Free-Ride': return new FreeRideDisplayService_1.FreeRideDisplayService();
468
474
  case 'GPX': return new FollowRouteDisplayService_1.FollowRouteDisplayService();
469
- case 'Video': return new VideoDisplayService_1.VideoDisplayService();
475
+ case 'Video': return new RLVDisplayService_1.RLVDisplayService();
470
476
  case 'Workout': return new WorkoutDisplayService_1.WorkoutDisplayService();
471
477
  default:
472
478
  return new base_1.RideModeService();
@@ -567,13 +573,13 @@ let RideDisplayService = (() => {
567
573
  console.log('# lap completed', oldLap, newLap);
568
574
  }
569
575
  onRouteUpdated(route) {
570
- console.log('# route updated', this.route.points);
571
576
  this.getActivityRide().onRouteUpdate(route.points);
572
577
  }
573
578
  onRouteCompleted() {
574
579
  var _a;
575
580
  if (this.state !== 'Active' && this.state !== 'Paused')
576
581
  return;
582
+ console.log('# route completed', this.getWorkoutRide().inUse());
577
583
  if (this.getWorkoutRide().inUse()) {
578
584
  this.getRouteList().unselect();
579
585
  this.type = 'Workout';