@igo2/geo 18.0.0-next.10 → 18.0.0-next.11

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 (38) hide show
  1. package/esm2022/lib/directions/directions-buttons/directions-buttons.component.mjs +151 -102
  2. package/esm2022/lib/directions/directions-inputs/directions-inputs.component.mjs +177 -83
  3. package/esm2022/lib/directions/directions-results/directions-results.component.mjs +93 -44
  4. package/esm2022/lib/directions/directions-sources/directions-source.mjs +1 -1
  5. package/esm2022/lib/directions/directions-sources/osrm-directions-source.mjs +1 -1
  6. package/esm2022/lib/directions/directions.component.mjs +49 -31
  7. package/esm2022/lib/directions/shared/directions.enum.mjs +51 -7
  8. package/esm2022/lib/directions/shared/directions.interface.mjs +1 -1
  9. package/esm2022/lib/directions/shared/directions.service.mjs +122 -96
  10. package/esm2022/lib/directions/shared/directions.utils.mjs +281 -318
  11. package/esm2022/lib/directions/shared/store.mjs +2 -2
  12. package/esm2022/lib/draw/draw/draw-popup.component.mjs +1 -1
  13. package/esm2022/lib/draw/shared/draw.utils.mjs +1 -1
  14. package/esm2022/lib/map/shared/controllers/geolocation.interface.mjs +1 -1
  15. package/esm2022/lib/map/shared/controllers/view.mjs +1 -1
  16. package/esm2022/lib/map/shared/map.utils.mjs +3 -3
  17. package/esm2022/lib/print/shared/print.service.mjs +1 -1
  18. package/fesm2022/igo2-geo.mjs +910 -668
  19. package/fesm2022/igo2-geo.mjs.map +1 -1
  20. package/lib/directions/directions-buttons/directions-buttons.component.d.ts +57 -20
  21. package/lib/directions/directions-inputs/directions-inputs.component.d.ts +115 -13
  22. package/lib/directions/directions-results/directions-results.component.d.ts +50 -16
  23. package/lib/directions/directions-sources/directions-source.d.ts +2 -2
  24. package/lib/directions/directions-sources/osrm-directions-source.d.ts +2 -2
  25. package/lib/directions/directions.component.d.ts +5 -5
  26. package/lib/directions/shared/directions.enum.d.ts +42 -1
  27. package/lib/directions/shared/directions.interface.d.ts +50 -25
  28. package/lib/directions/shared/directions.service.d.ts +46 -8
  29. package/lib/directions/shared/directions.utils.d.ts +102 -23
  30. package/lib/directions/shared/store.d.ts +3 -3
  31. package/lib/draw/shared/draw.utils.d.ts +2 -1
  32. package/lib/map/shared/controllers/geolocation.interface.d.ts +2 -1
  33. package/lib/map/shared/map.utils.d.ts +5 -3
  34. package/locale/en.geo.json +87 -89
  35. package/locale/fr.geo.json +87 -89
  36. package/package.json +5 -5
  37. package/src/lib/directions/directions-inputs/directions-inputs.theming.scss +21 -0
  38. package/src/lib/directions/directions.theming.scss +2 -0
@@ -239,7 +239,7 @@ function stringToLonLat(str, mapProjection, opts = {}) {
239
239
  const toProjection = '4326';
240
240
  let projectionStr;
241
241
  const projectionRegex = new RegExp(projectionPattern, 'g');
242
- const lonlatCoord = '([-+])?([\\d]{1,3})([,.](\\d+))?';
242
+ const lonlatCoord = '([-+])?([\\d]{1,3})([,.](\\d+))?°?';
243
243
  const lonLatPattern = `${lonlatCoord}[\\s,]+${lonlatCoord}`;
244
244
  const lonLatRegex = new RegExp(`^${lonLatPattern}$`, 'g');
245
245
  const dmsCoord = '([0-9]{1,2})[:|°]?\\s*([0-9]{1,2})?[:|\'|′|’]?\\s*([0-9]{1,2}(?:.[0-9]+){0,1})?\\s*["|″|”]?\\s*';
@@ -550,7 +550,7 @@ function roundCoordTo(coord, decimal = 3) {
550
550
  ];
551
551
  }
552
552
  function roundCoordToString(coord, decimal = 3) {
553
- return roundCoordTo(coord, decimal).map((r) => r.toString());
553
+ return roundCoordTo(coord, decimal).map((r) => r.toString() + '°');
554
554
  }
555
555
  /**
556
556
  * Returns an array of converted coordinates.
@@ -7103,24 +7103,69 @@ var ProposalType;
7103
7103
  ProposalType["Coord"] = "coord";
7104
7104
  ProposalType["Text"] = "text";
7105
7105
  })(ProposalType || (ProposalType = {}));
7106
- var DirectionType;
7107
- (function (DirectionType) {
7108
- DirectionType["Stop"] = "stop";
7109
- DirectionType["Route"] = "route";
7110
- DirectionType["Vertex"] = "vertex";
7111
- })(DirectionType || (DirectionType = {}));
7106
+ var DirectionsType;
7107
+ (function (DirectionsType) {
7108
+ DirectionsType["Stop"] = "stop";
7109
+ DirectionsType["Route"] = "route";
7110
+ DirectionsType["Vertex"] = "vertex";
7111
+ })(DirectionsType || (DirectionsType = {}));
7112
7112
  var DirectionRelativePositionType;
7113
7113
  (function (DirectionRelativePositionType) {
7114
7114
  DirectionRelativePositionType["Start"] = "start";
7115
7115
  DirectionRelativePositionType["Intermediate"] = "intermediate";
7116
7116
  DirectionRelativePositionType["End"] = "end";
7117
7117
  })(DirectionRelativePositionType || (DirectionRelativePositionType = {}));
7118
+ var ManeuverType;
7119
+ (function (ManeuverType) {
7120
+ ManeuverType["Turn"] = "turn";
7121
+ ManeuverType["NewName"] = "new name";
7122
+ ManeuverType["Depart"] = "depart";
7123
+ ManeuverType["Arrive"] = "arrive";
7124
+ ManeuverType["Merge"] = "merge";
7125
+ ManeuverType["Ramp"] = "ramp";
7126
+ ManeuverType["OnRamp"] = "on ramp";
7127
+ ManeuverType["OffRamp"] = "off ramp";
7128
+ ManeuverType["Fork"] = "fork";
7129
+ ManeuverType["EndOfRoad"] = "end of road";
7130
+ ManeuverType["UseLane"] = "use lane";
7131
+ ManeuverType["Continue"] = "continue";
7132
+ ManeuverType["Roundabout"] = "roundabout";
7133
+ ManeuverType["Rotary"] = "rotary";
7134
+ ManeuverType["RoundaboutTurn"] = "roundabout turn";
7135
+ ManeuverType["Notification"] = "notification";
7136
+ ManeuverType["ExitRoundabout"] = "exit roundabout";
7137
+ ManeuverType["ExitRotary"] = "exit rotary";
7138
+ })(ManeuverType || (ManeuverType = {}));
7139
+ var ManeuverModifier;
7140
+ (function (ManeuverModifier) {
7141
+ ManeuverModifier["Uturn"] = "uturn";
7142
+ ManeuverModifier["SharpRight"] = "sharp right";
7143
+ ManeuverModifier["Right"] = "right";
7144
+ ManeuverModifier["SlightRight"] = "slight right";
7145
+ ManeuverModifier["SharpLeft"] = "sharp left";
7146
+ ManeuverModifier["Left"] = "left";
7147
+ ManeuverModifier["SlightLeft"] = "slight left";
7148
+ ManeuverModifier["Straight"] = "straight";
7149
+ })(ManeuverModifier || (ManeuverModifier = {}));
7150
+ var LaneType;
7151
+ (function (LaneType) {
7152
+ LaneType["None"] = "none";
7153
+ LaneType["Uturn"] = "uturn";
7154
+ LaneType["SharpRight"] = "sharp right";
7155
+ LaneType["Right"] = "right";
7156
+ LaneType["SlightRight"] = "slight right";
7157
+ LaneType["SharpLeft"] = "sharp left";
7158
+ LaneType["Left"] = "left";
7159
+ LaneType["SlightLeft"] = "slight left";
7160
+ LaneType["Straight"] = "straight";
7161
+ })(LaneType || (LaneType = {}));
7118
7162
 
7119
7163
  /**
7120
- * Function that updat the sort of the list base on the provided field.
7121
- * @param source stop store
7122
- * @param direction asc / desc sort order
7123
- * @param field the field to use to sort the view
7164
+ * Updates the sorting of the stops in the provided StopsStore based on the specified field and direction.
7165
+ *
7166
+ * @param {StopsStore} stopsStore - The StopsStore to update the sorting for.
7167
+ * @param {'asc' | 'desc'} [direction='asc'] - The direction of sorting ('asc' for ascending, 'desc' for descending).
7168
+ * @param {string} [field='position'] - The field to sort the stops by.
7124
7169
  */
7125
7170
  function updateStoreSorting(stopsStore, direction = 'asc', field = 'position') {
7126
7171
  stopsStore.view.sort({
@@ -7128,70 +7173,73 @@ function updateStoreSorting(stopsStore, direction = 'asc', field = 'position') {
7128
7173
  valueAccessor: (entity) => entity[field]
7129
7174
  });
7130
7175
  }
7131
- function computeRelativePosition(index, totalLength) {
7176
+ /**
7177
+ * Computes the relative position of a stop in a list of stops.
7178
+ *
7179
+ * @param {number} stopIndex - The index of the stop.
7180
+ * @param {number} stopListLength - The total number of stops.
7181
+ * @return {DirectionRelativePositionType} The relative position of the stop.
7182
+ */
7183
+ function computeRelativePosition(stopIndex, stopListLength) {
7132
7184
  let relativePosition = DirectionRelativePositionType.Intermediate;
7133
- if (index === 0) {
7185
+ if (stopIndex === 0) {
7134
7186
  relativePosition = DirectionRelativePositionType.Start;
7135
7187
  }
7136
- else if (index === totalLength - 1) {
7188
+ else if (stopIndex === stopListLength) {
7137
7189
  relativePosition = DirectionRelativePositionType.End;
7138
7190
  }
7139
7191
  return relativePosition;
7140
7192
  }
7141
- function computeStopsPosition(stopsStore) {
7142
- const stopsToComputePosition = [...stopsStore.all()];
7143
- stopsToComputePosition.sort((a, b) => a.position - b.position);
7144
- stopsToComputePosition.map((stop, i) => {
7145
- stop.position = i;
7146
- stop.relativePosition = computeRelativePosition(stop.position, stopsToComputePosition.length);
7147
- });
7148
- if (stopsToComputePosition) {
7149
- stopsStore.updateMany(stopsToComputePosition);
7193
+ /**
7194
+ * Computes the position and relative position of stops in the given stopsStore.
7195
+ *
7196
+ * @param {StopsStore} stopsStore - The store containing the stops.
7197
+ */
7198
+ function computeStopsPosition(deletedStopIndex, stopsStore) {
7199
+ for (const stop of stopsStore.all()) {
7200
+ stop.position =
7201
+ stop.position > deletedStopIndex ? (stop.position -= 1) : stop.position;
7202
+ stop.relativePosition = computeRelativePosition(stop.position, stopsStore.all().length - 1);
7150
7203
  }
7151
7204
  }
7152
7205
  /**
7153
- * Function that add a stop to the stop store. Stop are always added before the last stop.
7154
- * @param stopsStore stop store as an EntityStore
7206
+ * Adds a stop to the given stopsStore. The stop is always added as the last stop.
7207
+ *
7208
+ * @param {StopsStore} stopsStore - The store containing the stops.
7209
+ * @return {Stop} The newly added stop.
7155
7210
  */
7156
7211
  function addStopToStore(stopsStore) {
7157
7212
  const id = uuid();
7158
7213
  const stops = stopsStore.all();
7159
- let positions;
7160
- if (stopsStore.count === 0) {
7161
- positions = [0];
7162
- }
7163
- else {
7164
- positions = stops.map((stop) => stop.position);
7165
- }
7166
- const maxPosition = Math.max(...positions);
7167
- const insertPosition = maxPosition;
7168
- const lastPosition = maxPosition + 1;
7169
- const stopToUpdate = stopsStore
7170
- .all()
7171
- .find((stop) => stop.position === maxPosition);
7172
- if (stopToUpdate) {
7173
- stopToUpdate.position = lastPosition;
7174
- stopToUpdate.relativePosition = computeRelativePosition(lastPosition, stopsStore.count + 1);
7214
+ const insertIndex = stops.length;
7215
+ for (const stop of stopsStore.all()) {
7216
+ stop.relativePosition = computeRelativePosition(stop.position, stops.length);
7175
7217
  }
7176
7218
  stopsStore.insert({
7177
7219
  id,
7178
- position: insertPosition,
7179
- relativePosition: computeRelativePosition(insertPosition, stopsStore.count + 1)
7220
+ position: insertIndex,
7221
+ relativePosition: computeRelativePosition(insertIndex, stops.length)
7180
7222
  });
7181
7223
  updateStoreSorting(stopsStore);
7182
7224
  return stopsStore.get(id);
7183
7225
  }
7226
+ /**
7227
+ * Removes a stop from the given stopsStore and updates the positions of the remaining stops.
7228
+ *
7229
+ * @param {StopsStore} stopsStore - The store containing the stops.
7230
+ * @param {Stop} stop - The stop to be removed.
7231
+ */
7184
7232
  function removeStopFromStore(stopsStore, stop) {
7185
7233
  stopsStore.delete(stop);
7186
- computeStopsPosition(stopsStore);
7234
+ computeStopsPosition(stop.position, stopsStore);
7187
7235
  }
7188
7236
  /**
7189
- * Create a style for the directions stops and routes
7237
+ * Create a style for the directions steps, stops and route
7190
7238
  * @param feature OlFeature
7191
7239
  * @returns OL style function
7192
7240
  */
7193
7241
  function directionsStyle(feature) {
7194
- const vertexStyle = [
7242
+ const stepStyle = [
7195
7243
  new olStyle.Style({
7196
7244
  geometry: feature.getGeometry(),
7197
7245
  image: new olStyle.Circle({
@@ -7220,16 +7268,22 @@ function directionsStyle(feature) {
7220
7268
  })
7221
7269
  })
7222
7270
  ];
7223
- if (feature.get('type') === DirectionType.Stop) {
7271
+ if (feature.get('type') === DirectionsType.Stop) {
7224
7272
  return stopStyle;
7225
7273
  }
7226
- if (feature.get('type') === 'vertex') {
7227
- return vertexStyle;
7274
+ if (feature.get('type') === DirectionsType.Vertex) {
7275
+ return stepStyle;
7228
7276
  }
7229
- if (feature.get('type') === DirectionType.Route) {
7277
+ if (feature.get('type') === DirectionsType.Route) {
7230
7278
  return routeStyle;
7231
7279
  }
7232
7280
  }
7281
+ /**
7282
+ * Initializes the stops feature store with the provided language service.
7283
+ *
7284
+ * @param {StopsFeatureStore} stopsFeatureStore - The stops feature store to initialize.
7285
+ * @param {LanguageService} languageService - The language service used for translations.
7286
+ */
7233
7287
  function initStopsFeatureStore(stopsFeatureStore, languageService) {
7234
7288
  const loadingStrategy = new FeatureStoreLoadingStrategy({
7235
7289
  motion: FeatureMotion.None
@@ -7237,10 +7291,11 @@ function initStopsFeatureStore(stopsFeatureStore, languageService) {
7237
7291
  const stopsLayer = new VectorLayer({
7238
7292
  isIgoInternalLayer: true,
7239
7293
  id: 'igo-direction-stops-layer',
7240
- title: languageService.translate.instant('igo.geo.directionsForm.stopLayer'),
7294
+ title: languageService.translate.instant('igo.geo.directions.layer.stops'),
7241
7295
  zIndex: 911,
7242
7296
  source: new FeatureDataSource(),
7243
7297
  showInLayerList: true,
7298
+ visible: true,
7244
7299
  workspace: {
7245
7300
  enabled: false
7246
7301
  },
@@ -7259,9 +7314,14 @@ function initStopsFeatureStore(stopsFeatureStore, languageService) {
7259
7314
  style: directionsStyle
7260
7315
  });
7261
7316
  tryBindStoreLayer(stopsFeatureStore, stopsLayer);
7262
- stopsFeatureStore.layer.visible = true;
7263
7317
  tryAddLoadingStrategy(stopsFeatureStore, loadingStrategy);
7264
7318
  }
7319
+ /**
7320
+ * Initializes the routes feature store with the provided language service.
7321
+ *
7322
+ * @param {StopsFeatureStore} routesFeatureStore - The routes feature store to initialize.
7323
+ * @param {LanguageService} languageService - The language service used for translations.
7324
+ */
7265
7325
  function initRoutesFeatureStore(routesFeatureStore, languageService) {
7266
7326
  const loadingStrategy = new FeatureStoreLoadingStrategy({
7267
7327
  motion: FeatureMotion.None
@@ -7269,10 +7329,11 @@ function initRoutesFeatureStore(routesFeatureStore, languageService) {
7269
7329
  const routeLayer = new VectorLayer({
7270
7330
  isIgoInternalLayer: true,
7271
7331
  id: 'igo-direction-route-layer',
7272
- title: languageService.translate.instant('igo.geo.directionsForm.routeLayer'),
7332
+ title: languageService.translate.instant('igo.geo.directions.layer.route'),
7273
7333
  zIndex: 910,
7274
7334
  source: new FeatureDataSource(),
7275
7335
  showInLayerList: true,
7336
+ visible: true,
7276
7337
  workspace: {
7277
7338
  enabled: false
7278
7339
  },
@@ -7284,10 +7345,14 @@ function initRoutesFeatureStore(routesFeatureStore, languageService) {
7284
7345
  style: directionsStyle
7285
7346
  });
7286
7347
  tryBindStoreLayer(routesFeatureStore, routeLayer);
7287
- routesFeatureStore.layer.visible = true;
7288
7348
  tryAddLoadingStrategy(routesFeatureStore, loadingStrategy);
7289
7349
  }
7290
- function initStepFeatureStore(stepFeatureStore) {
7350
+ /**
7351
+ * Initializes the routes feature store.
7352
+ *
7353
+ * @param {StopsFeatureStore} stepsFeatureStore - The steps feature store to initialize.
7354
+ */
7355
+ function initStepsFeatureStore(stepsFeatureStore) {
7291
7356
  const loadingStrategy = new FeatureStoreLoadingStrategy({
7292
7357
  motion: FeatureMotion.None
7293
7358
  });
@@ -7298,6 +7363,7 @@ function initStepFeatureStore(stepFeatureStore) {
7298
7363
  zIndex: 910,
7299
7364
  source: new FeatureDataSource(),
7300
7365
  showInLayerList: false,
7366
+ visible: true,
7301
7367
  workspace: {
7302
7368
  enabled: false
7303
7369
  },
@@ -7308,44 +7374,53 @@ function initStepFeatureStore(stepFeatureStore) {
7308
7374
  browsable: false,
7309
7375
  style: directionsStyle
7310
7376
  });
7311
- tryBindStoreLayer(stepFeatureStore, stepLayer);
7312
- stepFeatureStore.layer.visible = true;
7313
- tryAddLoadingStrategy(stepFeatureStore, loadingStrategy);
7377
+ tryBindStoreLayer(stepsFeatureStore, stepLayer);
7378
+ tryAddLoadingStrategy(stepsFeatureStore, loadingStrategy);
7314
7379
  }
7315
- function addStopToStopsFeatureStore(stop, stopsStore, stopsFeatureStore, projection, languageService) {
7380
+ /**
7381
+ * Adds a stop to the stopsFeatureStore.
7382
+ *
7383
+ * @param {Stop} stop - The stop to be added.
7384
+ * @param {StopsFeatureStore} stopsFeatureStore - The stopsFeatureStore to add the stop to.
7385
+ * @param {string} projection - The projection of the stop coordinates.
7386
+ * @param {LanguageService} languageService - The language service for translating stop text.
7387
+ */
7388
+ function addStopToStopsFeatureStore(stop, stopsFeatureStore, projection, languageService) {
7316
7389
  let stopColor;
7317
7390
  let stopText;
7318
7391
  switch (stop.relativePosition) {
7319
7392
  case DirectionRelativePositionType.Start:
7320
7393
  stopColor = '#008000';
7321
- stopText = languageService.translate.instant('igo.geo.directionsForm.start');
7394
+ stopText = languageService.translate.instant('igo.geo.directions.input.start');
7322
7395
  break;
7323
7396
  case DirectionRelativePositionType.End:
7324
7397
  stopColor = '#f64139';
7325
- stopText = languageService.translate.instant('igo.geo.directionsForm.end');
7398
+ stopText = languageService.translate.instant('igo.geo.directions.input.end');
7326
7399
  break;
7327
7400
  default:
7328
7401
  stopColor = '#ffd700';
7329
7402
  stopText =
7330
- languageService.translate.instant('igo.geo.directionsForm.intermediate') +
7403
+ languageService.translate.instant('igo.geo.directions.input.intermediate') +
7331
7404
  ' #' +
7332
7405
  stop.position;
7333
7406
  break;
7334
7407
  }
7335
- const geometry = new olgeom.Point(olproj.transform(stop.coordinates, projection, stopsFeatureStore.map.projection));
7336
- const geojsonGeom = new OlGeoJSON().writeGeometryObject(geometry, {
7337
- featureProjection: stopsFeatureStore.map.projection,
7338
- dataProjection: stopsFeatureStore.map.projection
7408
+ const point = new olgeom.Point(olproj.transform(stop.coordinates, projection, stopsFeatureStore.map.projectionCode));
7409
+ const geojsonGeom = new OlGeoJSON().writeGeometryObject(point, {
7410
+ featureProjection: stopsFeatureStore.map.projectionCode,
7411
+ dataProjection: stopsFeatureStore.map.projectionCode
7339
7412
  });
7340
7413
  const previousStop = stopsFeatureStore.get(stop.id);
7341
- const previousStopRevision = previousStop ? previousStop.meta.revision : 0;
7414
+ const previousStopRevision = previousStop
7415
+ ? previousStop.meta.revision
7416
+ : 0;
7342
7417
  const stopFeatureStore = {
7343
7418
  type: FEATURE,
7344
7419
  geometry: geojsonGeom,
7345
- projection: stopsFeatureStore.map.projection,
7420
+ projection: stopsFeatureStore.map.projectionCode,
7346
7421
  properties: {
7347
7422
  id: stop.id,
7348
- type: DirectionType.Stop,
7423
+ type: DirectionsType.Stop,
7349
7424
  stopText,
7350
7425
  stopColor,
7351
7426
  stopOpacity: 1,
@@ -7355,310 +7430,242 @@ function addStopToStopsFeatureStore(stop, stopsStore, stopsFeatureStore, project
7355
7430
  id: stop.id,
7356
7431
  revision: previousStopRevision + 1
7357
7432
  },
7358
- ol: new OlFeature({ geometry })
7433
+ ol: new OlFeature({ point })
7359
7434
  };
7360
7435
  stopsFeatureStore.update(stopFeatureStore);
7361
7436
  }
7362
- function addDirectionToRoutesFeatureStore(routesFeatureStore, direction, projection, active = false) {
7363
- const geom = direction.geometry.coordinates;
7364
- const geometry4326 = new olgeom.LineString(geom);
7365
- const geometry = geometry4326.transform(projection, routesFeatureStore.map.projection);
7366
- const geojsonGeom = new OlGeoJSON().writeGeometryObject(geometry, {
7367
- featureProjection: routesFeatureStore.map.projection,
7368
- dataProjection: routesFeatureStore.map.projection
7437
+ /**
7438
+ * Adds a route to the routes feature store.
7439
+ *
7440
+ * @param {RoutesFeatureStore} routesFeatureStore - The routes feature store to add the route to.
7441
+ * @param {Directions} directions - The directions object containing the geometry and other information.
7442
+ * @param {string} projection - The projection of the geometry coordinates.
7443
+ * @param {boolean} [active=false] - Indicates whether the direction is active or not. Default is false.
7444
+ */
7445
+ function addRouteToRoutesFeatureStore(routesFeatureStore, directions, projection, active = false) {
7446
+ const coordinate = directions.geometry.coordinates;
7447
+ const linestring4326 = new olgeom.LineString(coordinate);
7448
+ const linestringStore = linestring4326.transform(projection, routesFeatureStore.map.projectionCode);
7449
+ const geojsonGeom = new OlGeoJSON().writeGeometryObject(linestringStore, {
7450
+ featureProjection: routesFeatureStore.map.projectionCode,
7451
+ dataProjection: routesFeatureStore.map.projectionCode
7369
7452
  });
7370
- const previousRoute = routesFeatureStore.get(direction.id);
7371
- const previousRouteRevision = previousRoute ? previousRoute.meta.revision : 0;
7453
+ const previousRoute = routesFeatureStore.get(directions.id);
7454
+ const previousRouteRevision = previousRoute
7455
+ ? previousRoute.meta.revision
7456
+ : 0;
7372
7457
  const routeFeatureStore = {
7373
7458
  type: FEATURE,
7374
7459
  geometry: geojsonGeom,
7375
- projection: routesFeatureStore.map.projection,
7460
+ projection: routesFeatureStore.map.projectionCode,
7376
7461
  properties: {
7377
- id: direction.id,
7378
- type: DirectionType.Route,
7462
+ id: directions.id,
7463
+ type: DirectionsType.Route,
7379
7464
  active,
7380
- direction
7465
+ directions
7381
7466
  },
7382
7467
  meta: {
7383
- id: direction.id,
7468
+ id: directions.id,
7384
7469
  revision: previousRouteRevision + 1
7385
7470
  },
7386
- ol: new OlFeature({ geometry })
7471
+ ol: new OlFeature({ linestringStore })
7387
7472
  };
7388
7473
  routesFeatureStore.update(routeFeatureStore);
7389
7474
  }
7390
- function formatDistance(distance) {
7391
- if (distance === 0) {
7392
- return;
7393
- }
7394
- if (distance >= 100000) {
7395
- return NumberUtils.roundToNDecimal(Math.round(distance) / 1000, 1) + ' km';
7396
- }
7397
- if (distance >= 10000) {
7398
- return (NumberUtils.roundToNDecimal(Math.round(distance) / 100 / 10, 1) + ' km');
7399
- }
7400
- if (distance >= 1000) {
7401
- return (NumberUtils.roundToNDecimal(Math.round(distance) / 100 / 10, 1) + ' km');
7402
- }
7403
- return NumberUtils.roundToNDecimal(distance, 0) + ' m';
7404
- }
7405
- function formatDuration(duration) {
7406
- if (duration >= 3600) {
7407
- const hour = Math.floor(duration / 3600);
7408
- const minute = Math.round((duration / 3600 - hour) * 60);
7409
- if (minute === 60) {
7410
- return hour + 1 + ' h';
7411
- }
7412
- return hour + ' h ' + minute + ' min';
7475
+ /**
7476
+ * Formats the given distance in meters to a human-readable string.
7477
+ *
7478
+ * @param {number} meters - The distance in meters to be formatted.
7479
+ * @return {string | undefined} The formatted distance string.
7480
+ */
7481
+ function formatDistance(meters) {
7482
+ if (meters === 0) {
7483
+ return undefined;
7413
7484
  }
7414
- if (duration >= 60) {
7415
- return Math.round(duration / 60) + ' min';
7485
+ if (meters < 1000) {
7486
+ return `${Math.round(meters)} m`;
7416
7487
  }
7417
- return duration + ' s';
7488
+ const kilometers = meters / 1000;
7489
+ const roundToDecimal = kilometers >= 10 ? 1 : 0;
7490
+ return `${NumberUtils.roundToNDecimal(kilometers, roundToDecimal)} km`.replace('.', ',');
7418
7491
  }
7419
- function formatInstruction(type, modifier, route = 'Voie', direction, stepPosition, exit, languageService, lastStep = false) {
7492
+ /**
7493
+ * Formats the given duration in seconds to a human-readable string.
7494
+ *
7495
+ * @param {number} seconds - The duration in seconds to be formatted.
7496
+ * @return {string} The formatted duration string.
7497
+ */
7498
+ function formatDuration(seconds) {
7499
+ const hours = Math.floor(seconds / 3600);
7500
+ const minutes = Math.floor((seconds % 3600) / 60);
7501
+ if (hours) {
7502
+ return `${hours} h ${minutes} min`;
7503
+ }
7504
+ if (minutes) {
7505
+ return `${minutes} min`;
7506
+ }
7507
+ return '< 1 min';
7508
+ }
7509
+ function formatStep(step, languageService, lastStep = false) {
7510
+ const maneuverType = step.maneuver.type;
7511
+ const maneuverModifier = step.maneuver.modifier;
7512
+ const name = step.name;
7513
+ const maneuverBearingAfter = step.maneuver.bearing_after;
7420
7514
  const translate = languageService.translate;
7421
- let directive;
7422
- let image = 'arrow_forward';
7423
- let cssClass = 'rotate-270';
7424
- const translatedDirection = translateBearing(direction, languageService);
7425
- const translatedModifier = translateModifier(modifier, languageService);
7426
- const prefix = modifier === 'straight'
7427
- ? ''
7428
- : translate.instant('igo.geo.directions.modifier.prefix');
7429
- let aggregatedDirection = prefix + translatedModifier;
7430
- if (modifier?.search('slight') >= 0) {
7431
- aggregatedDirection = translatedModifier;
7432
- }
7433
- if (modifier === 'uturn') {
7434
- image = 'arrow_forward';
7435
- cssClass = 'rotate-90';
7436
- }
7437
- else if (modifier === 'sharp right') {
7438
- image = 'subdirectory_arrow_right';
7439
- cssClass = 'icon-flipped';
7440
- }
7441
- else if (modifier === 'right') {
7442
- image = 'subdirectory_arrow_right';
7443
- cssClass = 'icon-flipped';
7444
- }
7445
- else if (modifier === 'slight right') {
7446
- image = 'arrow_forward';
7447
- cssClass = 'rotate-290';
7448
- }
7449
- else if (modifier === 'straight') {
7450
- image = 'arrow_forward';
7451
- }
7452
- else if (modifier === 'slight left') {
7453
- image = 'arrow_forward';
7454
- cssClass = 'rotate-250';
7455
- }
7456
- else if (modifier === 'left') {
7457
- image = 'subdirectory_arrow_left';
7458
- cssClass = 'icon-flipped';
7459
- }
7460
- else if (modifier === 'sharp left') {
7461
- image = 'subdirectory_arrow_left';
7462
- cssClass = 'icon-flipped';
7463
- }
7464
- if (type === 'turn') {
7465
- if (modifier === 'straight') {
7466
- directive = translate.instant('igo.geo.directions.turn.straight', {
7467
- route
7515
+ const translatedManeuverBearingAfter = translateManeuverBearing(maneuverBearingAfter, languageService);
7516
+ const translatedManeuverModifier = translateManeuverModifier(maneuverModifier, languageService);
7517
+ let iconName = 'straight'; // arrow point up by default
7518
+ let instruction = '';
7519
+ if (maneuverType === ManeuverType.Turn) {
7520
+ if (maneuverModifier === ManeuverModifier.Uturn ||
7521
+ maneuverModifier === ManeuverModifier.Straight) {
7522
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.turn.${maneuverModifier}`, {
7523
+ maneuverModifier: translatedManeuverModifier,
7524
+ name
7468
7525
  });
7469
- }
7470
- else if (modifier === 'uturn') {
7471
- directive = translate.instant('igo.geo.directions.turn.uturn', { route });
7526
+ if (maneuverModifier === ManeuverModifier.Uturn) {
7527
+ iconName = 'u_turn_left';
7528
+ }
7472
7529
  }
7473
7530
  else {
7474
- directive = translate.instant('igo.geo.directions.turn.else', {
7475
- route,
7476
- aggregatedDirection,
7477
- translatedModifier
7531
+ instruction = translate.instant('igo.geo.directions.results.maneuverType.turn.else', {
7532
+ maneuverModifier: translatedManeuverModifier,
7533
+ name
7478
7534
  });
7535
+ if (maneuverModifier === ManeuverModifier.SlightRight) {
7536
+ iconName = 'turn_slight_right';
7537
+ }
7538
+ else if (maneuverModifier === ManeuverModifier.Right ||
7539
+ maneuverModifier === ManeuverModifier.SharpRight) {
7540
+ iconName = 'turn_right';
7541
+ }
7542
+ else if (maneuverModifier === ManeuverModifier.Left ||
7543
+ maneuverModifier === ManeuverModifier.SharpLeft) {
7544
+ iconName = 'turn_left';
7545
+ }
7546
+ else if (maneuverModifier === ManeuverModifier.SlightLeft) {
7547
+ iconName = 'turn_slight_left';
7548
+ }
7479
7549
  }
7480
7550
  }
7481
- else if (type === 'new name') {
7482
- directive = translate.instant('igo.geo.directions.new name', {
7483
- route,
7484
- translatedDirection
7551
+ else if (maneuverType === ManeuverType.NewName) {
7552
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.new name`, {
7553
+ name,
7554
+ maneuverBearing: translatedManeuverBearingAfter
7485
7555
  });
7486
- image = 'explore';
7487
- cssClass = '';
7488
7556
  }
7489
- else if (type === 'depart') {
7490
- directive = translate.instant('igo.geo.directions.depart', {
7491
- route,
7492
- translatedDirection
7557
+ else if (maneuverType === ManeuverType.Depart) {
7558
+ iconName = 'directions';
7559
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.depart`, {
7560
+ name,
7561
+ maneuverBearing: translatedManeuverBearingAfter
7493
7562
  });
7494
- image = 'explore';
7495
- cssClass = '';
7496
7563
  }
7497
- else if (type === 'arrive') {
7498
- if (lastStep) {
7499
- const coma = !translatedModifier ? '' : ', ';
7500
- aggregatedDirection = !translatedModifier ? '' : aggregatedDirection;
7501
- directive = translate.instant('igo.geo.directions.arrive.lastStep', {
7502
- coma,
7503
- aggregatedDirection
7504
- });
7505
- }
7506
- else {
7507
- directive = translate.instant('igo.geo.directions.arrive.intermediate', {
7508
- route
7509
- });
7510
- image = 'location_on';
7511
- cssClass = '';
7512
- }
7564
+ else if (maneuverType === ManeuverType.Arrive) {
7565
+ iconName = 'sports_score';
7566
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.arrive.${lastStep ? 'lastStep' : 'intermediate'}`, {
7567
+ name
7568
+ });
7513
7569
  }
7514
- else if (type === 'merge') {
7515
- directive = translate.instant('igo.geo.directions.merge', { route });
7516
- image = 'arrow_forward';
7517
- cssClass = 'rotate-270';
7570
+ else if (maneuverType === ManeuverType.Merge) {
7571
+ instruction = translate.instant('igo.geo.directions.results.maneuverType.merge', {
7572
+ name
7573
+ });
7574
+ iconName = 'merge';
7518
7575
  }
7519
- else if (type === 'on ramp') {
7520
- directive = translate.instant('igo.geo.directions.on ramp', {
7521
- aggregatedDirection
7576
+ else if (maneuverType === ManeuverType.OnRamp ||
7577
+ maneuverType === ManeuverType.OffRamp) {
7578
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.${maneuverType}`, {
7579
+ maneuverModifier: translatedManeuverModifier
7522
7580
  });
7523
7581
  }
7524
- else if (type === 'off ramp') {
7525
- directive = translate.instant('igo.geo.directions.off ramp', {
7526
- aggregatedDirection
7582
+ else if (maneuverType === ManeuverType.Fork) {
7583
+ const directionKey = maneuverModifier.search('left') >= 0 ? 'left' : 'right';
7584
+ iconName =
7585
+ directionKey === 'left' ? 'turn_slight_left' : 'turn_slight_right';
7586
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.fork.${directionKey}`, {
7587
+ name
7527
7588
  });
7528
7589
  }
7529
- else if (type === 'fork') {
7530
- if (modifier.search('left') >= 0) {
7531
- directive = translate.instant('igo.geo.directions.fork.left', { route });
7532
- }
7533
- else if (modifier.search('right') >= 0) {
7534
- directive = translate.instant('igo.geo.directions.fork.right', { route });
7590
+ else if (maneuverType === ManeuverType.EndOfRoad ||
7591
+ maneuverType === ManeuverType.UseLane ||
7592
+ maneuverType === ManeuverType.Continue) {
7593
+ if (maneuverType === ManeuverType.Continue) {
7594
+ if (maneuverModifier === ManeuverModifier.Uturn) {
7595
+ iconName = 'u_turn_left';
7596
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.turn.${maneuverModifier}`, {
7597
+ maneuverModifier: translatedManeuverModifier,
7598
+ name
7599
+ });
7600
+ }
7601
+ else {
7602
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.${maneuverType}`, {
7603
+ maneuverModifier: translatedManeuverModifier,
7604
+ name
7605
+ });
7606
+ }
7535
7607
  }
7536
7608
  else {
7537
- directive = translate.instant('igo.geo.directions.fork.else', { route });
7609
+ if (maneuverModifier === ManeuverModifier.SharpRight ||
7610
+ maneuverModifier === ManeuverModifier.Right) {
7611
+ iconName = 'turn_right';
7612
+ }
7613
+ else if (maneuverModifier === ManeuverModifier.SharpLeft ||
7614
+ maneuverModifier === ManeuverModifier.Left) {
7615
+ iconName = 'turn_left';
7616
+ }
7617
+ else if (maneuverModifier === ManeuverModifier.SlightRight) {
7618
+ iconName = 'turn_slight_right';
7619
+ }
7620
+ else if (maneuverModifier === ManeuverModifier.SlightLeft) {
7621
+ iconName = 'turn_slight_left';
7622
+ }
7623
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.${maneuverType}`, {
7624
+ maneuverModifier: translatedManeuverModifier,
7625
+ name
7626
+ });
7538
7627
  }
7539
7628
  }
7540
- else if (type === 'end of road') {
7541
- directive = translate.instant('igo.geo.directions.end of road', {
7542
- translatedModifier,
7543
- route
7544
- });
7545
- }
7546
- else if (type === 'use lane') {
7547
- directive = translate.instant('igo.geo.directions.use lane');
7548
- }
7549
- else if (type === 'continue' && modifier !== 'uturn') {
7550
- directive = translate.instant('igo.geo.directions.continue.notUturn', {
7551
- route
7629
+ else if (maneuverType === ManeuverType.Roundabout ||
7630
+ maneuverType === ManeuverType.Rotary ||
7631
+ maneuverType === ManeuverType.RoundaboutTurn ||
7632
+ maneuverType === ManeuverType.ExitRoundabout) {
7633
+ const roundaboutKey = maneuverType.replace('roundabout ', '');
7634
+ instruction = translate.instant(`igo.geo.directions.results.maneuverType.${roundaboutKey}`, {
7635
+ name
7552
7636
  });
7553
- image = 'arrow_forward';
7554
- cssClass = 'rotate-270';
7637
+ iconName = 'donut_large';
7555
7638
  }
7556
- else if (type === 'roundabout') {
7557
- const cntSuffix = exit === 1
7558
- ? translate.instant('igo.geo.directions.cntSuffix.first')
7559
- : translate.instant('igo.geo.directions.cntSuffix.secondAndMore');
7560
- directive = translate.instant('igo.geo.directions.roundabout', {
7561
- exit,
7562
- cntSuffix,
7563
- route
7564
- });
7565
- image = 'donut_large';
7566
- cssClass = '';
7639
+ else if (maneuverType === ManeuverType.Notification) {
7640
+ instruction = translate.instant('igo.geo.directions.results.maneuverType.notification');
7567
7641
  }
7568
- else if (type === 'rotary') {
7569
- directive = translate.instant('igo.geo.directions.rotary');
7570
- image = 'donut_large';
7571
- cssClass = '';
7572
- }
7573
- else if (type === 'roundabout turn') {
7574
- directive = translate.instant('igo.geo.directions.roundabout turn');
7575
- image = 'donut_large';
7576
- cssClass = '';
7577
- }
7578
- else if (type === 'exit roundabout') {
7579
- directive = translate.instant('igo.geo.directions.exit roundabout', {
7580
- route
7581
- });
7582
- image = 'arrow_forward';
7583
- cssClass = 'rotate-270';
7584
- }
7585
- else if (type === 'notification') {
7586
- directive = translate.instant('igo.geo.directions.notification');
7587
- }
7588
- else if (modifier === 'uturn') {
7589
- directive = translate.instant('igo.geo.directions.uturnText', {
7590
- translatedDirection,
7591
- route
7592
- });
7593
- }
7594
- else {
7595
- directive = translate.instant('igo.geo.directions.unknown');
7596
- }
7597
- image = lastStep ? 'flag' : image;
7598
- cssClass = lastStep ? '' : cssClass;
7599
- image = stepPosition === 0 ? 'explore' : image;
7600
- cssClass = stepPosition === 0 ? '' : cssClass;
7601
- return { instruction: directive, image, cssClass };
7642
+ return { instruction, iconName };
7602
7643
  }
7603
- function translateModifier(modifier, languageService) {
7644
+ /**
7645
+ * Translates a maneuver modifier into a human-readable string using the provided language service.
7646
+ *
7647
+ * @param {ManeuverModifier} maneuverModifier - The maneuver modifier to be translated.
7648
+ * @param {LanguageService} languageService - The language service used for translation.
7649
+ * @return {string | undefined} The translated maneuver modifier string, or undefined if the modifier is falsy.
7650
+ */
7651
+ function translateManeuverModifier(maneuverModifier, languageService) {
7604
7652
  const translate = languageService.translate;
7605
- if (modifier === 'uturn') {
7606
- return translate.instant('igo.geo.directions.uturn');
7607
- }
7608
- else if (modifier === 'sharp right') {
7609
- return translate.instant('igo.geo.directions.sharp right');
7610
- }
7611
- else if (modifier === 'right') {
7612
- return translate.instant('igo.geo.directions.right');
7613
- }
7614
- else if (modifier === 'slight right') {
7615
- return translate.instant('igo.geo.directions.slight right');
7616
- }
7617
- else if (modifier === 'sharp left') {
7618
- return languageService.translate.instant('igo.geo.directions.sharp left');
7619
- }
7620
- else if (modifier === 'left') {
7621
- return languageService.translate.instant('igo.geo.directions.left');
7622
- }
7623
- else if (modifier === 'slight left') {
7624
- return languageService.translate.instant('igo.geo.directions.slight left');
7625
- }
7626
- else if (modifier === 'straight') {
7627
- return languageService.translate.instant('igo.geo.directions.straight');
7628
- }
7629
- else {
7630
- return modifier;
7631
- }
7653
+ return maneuverModifier
7654
+ ? translate.instant(`igo.geo.directions.results.maneuverModifier.${maneuverModifier}`)
7655
+ : undefined;
7632
7656
  }
7633
- function translateBearing(bearing, languageService) {
7657
+ /**
7658
+ * Translates the given bearing value into a human-readable direction using the provided language service.
7659
+ *
7660
+ * @param {number} bearing - The bearing value to be translated.
7661
+ * @param {LanguageService} languageService - The language service used for translation.
7662
+ * @return {string} The translated direction corresponding to the given bearing value.
7663
+ */
7664
+ function translateManeuverBearing(bearing, languageService) {
7634
7665
  const translate = languageService.translate;
7635
- if (bearing >= 337 || bearing < 23) {
7636
- return translate.instant('igo.geo.cardinalPoints.n');
7637
- }
7638
- else if (bearing < 67) {
7639
- return translate.instant('igo.geo.cardinalPoints.ne');
7640
- }
7641
- else if (bearing < 113) {
7642
- return translate.instant('igo.geo.cardinalPoints.e');
7643
- }
7644
- else if (bearing < 157) {
7645
- return translate.instant('igo.geo.cardinalPoints.se');
7646
- }
7647
- else if (bearing < 203) {
7648
- return translate.instant('igo.geo.cardinalPoints.s');
7649
- }
7650
- else if (bearing < 247) {
7651
- return translate.instant('igo.geo.cardinalPoints.sw');
7652
- }
7653
- else if (bearing < 293) {
7654
- return translate.instant('igo.geo.cardinalPoints.w');
7655
- }
7656
- else if (bearing < 337) {
7657
- return translate.instant('igo.geo.cardinalPoints.nw');
7658
- }
7659
- else {
7660
- return;
7661
- }
7666
+ const directions = ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'];
7667
+ const directionIndex = Math.round(bearing / 45) % 8;
7668
+ return translate.instant(`igo.geo.directions.results.direction.${directions[directionIndex]}`);
7662
7669
  }
7663
7670
 
7664
7671
  class DirectionsService {
@@ -7676,34 +7683,48 @@ class DirectionsService {
7676
7683
  this.document = document;
7677
7684
  this.activityService = activityService;
7678
7685
  }
7686
+ /**
7687
+ * Routes the given coordinates using the specified directions source and options.
7688
+ *
7689
+ * @param {DirectionsSource} source - The directions source to use for routing.
7690
+ * @param {Position[]} coordinates - The array of coordinates to route.
7691
+ * @param {DirectionOptions} [directionsOptions={}] - The optional direction options.
7692
+ * @return {Observable<Directions[]>} An observable that emits an array of directions.
7693
+ */
7679
7694
  route(coordinates, directionsOptions = {}) {
7680
7695
  if (coordinates.length === 0) {
7681
7696
  return;
7682
7697
  }
7683
- return this.routeSource(this.directionsSourceService.sources[0], coordinates, directionsOptions);
7684
- }
7685
- routeSource(source, coordinates, directionsOptions = {}) {
7698
+ const source = this.directionsSourceService.sources[0];
7686
7699
  const request = source.route(coordinates, directionsOptions);
7687
7700
  return request;
7688
7701
  }
7689
- downloadDirection(map, direction) {
7702
+ /**
7703
+ * Downloads directions for a given map and directions object.
7704
+ *
7705
+ * @param {IgoMap} map - The map object to download directions for.
7706
+ * @param {Directions} directions - The directions object containing the route information.
7707
+ * @return {Observable<SubjectStatus>} An observable that emits the status of the download process.
7708
+ */
7709
+ downloadDirections(map, directions) {
7690
7710
  const activityId = this.activityService.register();
7691
7711
  const status$ = new Subject();
7692
7712
  const doc = new jsPDF({
7693
7713
  orientation: 'p',
7694
- format: 'Letter',
7714
+ format: 'letter',
7695
7715
  unit: 'mm' // default
7696
7716
  });
7697
- const { width: pageWidth, height: pageHeight } = doc.internal.pageSize;
7698
- /** top | right | bottom | left */
7699
- const margins = [20, 10, 20, 10];
7700
- this.addAttribution(map, doc, margins);
7701
- const width = pageWidth - margins[3] - margins[1];
7702
- const height = pageHeight - margins[0] - margins[2];
7703
- const imageDimensions = [width, height];
7704
- const title = `${direction.title} (${formatDistance(direction.distance)}, ${formatDuration(direction.duration)})`;
7705
- const titlePosition = 25;
7706
- doc.text(title, doc.internal.pageSize.width / 2, titlePosition, {
7717
+ const pageSize = doc.internal.pageSize;
7718
+ const margins = [30, 10, 20, 10];
7719
+ const zoneWidth = pageSize.getWidth() - margins[3] - margins[1];
7720
+ const zoneHeight = pageSize.getHeight() - margins[0] - margins[2];
7721
+ const imageDimensions = [zoneWidth, zoneHeight];
7722
+ const distance = formatDistance(directions.distance);
7723
+ const duration = formatDuration(directions.duration);
7724
+ const title = distance && duration
7725
+ ? `${directions.title} (${distance} - ${duration})`
7726
+ : directions.title;
7727
+ doc.text(title, pageSize.getWidth() / 2, 25, {
7707
7728
  align: 'center'
7708
7729
  });
7709
7730
  const resolution = 96; // Default is 96
@@ -7711,7 +7732,7 @@ class DirectionsService {
7711
7732
  .addMap(doc, map, resolution, imageDimensions, margins)
7712
7733
  .subscribe(async (status) => {
7713
7734
  if (status === SubjectStatus.Done) {
7714
- await this.addInstructions(doc, direction, title);
7735
+ await this.addInstructions(doc, directions, title);
7715
7736
  this.setPageHeaderFooter(doc);
7716
7737
  await doc.save(`${title}.pdf`, { returnPromise: true });
7717
7738
  }
@@ -7720,100 +7741,110 @@ class DirectionsService {
7720
7741
  });
7721
7742
  return status$;
7722
7743
  }
7723
- addAttribution(map, doc, margins) {
7724
- const verticalSpacing = 5;
7725
- const attributionText = this.printService.getAttributionText(map);
7726
- if (attributionText) {
7727
- margins[2] += verticalSpacing;
7728
- const xPosition = margins[3];
7729
- const marginBottom = margins[2];
7730
- // calculate text position Y
7731
- const yPosition = doc.internal.pageSize.height - marginBottom + verticalSpacing;
7732
- doc.setFontSize(10);
7733
- doc.text(attributionText, xPosition, yPosition);
7734
- }
7735
- }
7736
- async setHTMLTableContent(direction) {
7737
- const data = await this.directionsInstruction(direction);
7744
+ /**
7745
+ * Generates an HTML table element with directions steps.
7746
+ *
7747
+ * @param {Directions} directions - The directions object containing the steps.
7748
+ * @return {Promise<HTMLTableElement>} - A promise that resolves to the generated HTML table element.
7749
+ */
7750
+ async setHTMLTableDirections(directions) {
7751
+ const steps = await this.directionsSteps(directions);
7738
7752
  const table = document.createElement('table');
7739
7753
  const tblBody = document.createElement('tbody');
7740
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
7741
- for (let index = 0; index < data.length; index++) {
7742
- const element = data[index];
7754
+ for (const step of steps) {
7743
7755
  const row = document.createElement('tr');
7744
- const cellImage = document.createElement('td');
7745
- const cellText = document.createElement('td');
7746
7756
  // icon
7747
- const img = document.createElement('img');
7748
- img.src = element.icon;
7749
- // instruction text
7750
- const span = document.createElement('span');
7751
- span.innerHTML = element.instruction;
7752
- cellImage.appendChild(img);
7753
- cellText.appendChild(span);
7754
- if (element.distance) {
7755
- const spanDistance = document.createElement('span');
7756
- spanDistance.style.verticalAlign = 'middle';
7757
- spanDistance.innerHTML =
7758
- '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' + element.distance;
7759
- cellText.appendChild(spanDistance);
7760
- }
7761
- row.append(cellImage);
7757
+ const cellIcon = document.createElement('td');
7758
+ const iconElement = document.createElement('img');
7759
+ iconElement.style.verticalAlign = 'middle';
7760
+ iconElement.src = step.icon;
7761
+ cellIcon.appendChild(iconElement);
7762
+ row.append(cellIcon);
7763
+ // instruction
7764
+ const cellText = document.createElement('td');
7765
+ const spanInstructionElement = document.createElement('span');
7766
+ spanInstructionElement.style.verticalAlign = 'middle';
7767
+ spanInstructionElement.innerHTML = step.instruction;
7768
+ cellText.appendChild(spanInstructionElement);
7769
+ // distance/duration
7770
+ if (step.distanceDuration) {
7771
+ const spanDistanceElement = document.createElement('span');
7772
+ spanDistanceElement.style.verticalAlign = 'middle';
7773
+ spanDistanceElement.innerHTML = ' ' + step.distanceDuration;
7774
+ cellText.appendChild(spanDistanceElement);
7775
+ }
7762
7776
  row.append(cellText);
7763
7777
  tblBody.appendChild(row);
7764
7778
  }
7765
7779
  table.appendChild(tblBody);
7766
7780
  return table;
7767
7781
  }
7768
- async directionsInstruction(direction) {
7769
- const matListItems = this.document
7782
+ /**
7783
+ * Generates formatted steps for the given directions.
7784
+ *
7785
+ * @param {Directions} directions - The directions object containing the steps.
7786
+ * @return {Promise<{ instruction: string; icon: string; distanceDuration: string }[]>}
7787
+ * A promise that resolves to an array of formatted steps.
7788
+ */
7789
+ async directionsSteps(directions) {
7790
+ const matListElement = this.document
7770
7791
  .getElementsByTagName('igo-directions-results')[0]
7771
7792
  .getElementsByTagName('mat-list')[0];
7772
- const matListItem = matListItems.getElementsByTagName('mat-list-item');
7773
- // convert icon list to base64
7774
- const iconsArray = [];
7775
- // eslint-disable-next-line @typescript-eslint/prefer-for-of
7776
- for (let index = 0; index < matListItem.length; index++) {
7777
- const element = matListItem[index];
7778
- const icon = element.getElementsByTagName('mat-icon')[0];
7779
- const iconName = icon.innerText;
7780
- const found = iconsArray.some((el) => el.name === iconName);
7793
+ const matListItemElements = matListElement.getElementsByTagName('mat-list-item');
7794
+ // convert icons list to base64
7795
+ const icons = [];
7796
+ for (const element of Array.from(matListItemElements)) {
7797
+ const iconElement = element.getElementsByTagName('mat-icon')[0];
7798
+ const iconName = iconElement.innerText;
7799
+ const found = icons.some((icon) => icon.name === iconName);
7781
7800
  if (!found) {
7782
- const iconCanvas = await html2canvas(icon, { scale: 3 });
7783
- iconsArray.push({ name: iconName, icon: iconCanvas.toDataURL() });
7801
+ const iconCanvas = await html2canvas(iconElement);
7802
+ icons.push({ name: iconName, icon: iconCanvas.toDataURL() });
7803
+ }
7804
+ }
7805
+ const formattedSteps = [];
7806
+ for (let stepIndex = 0; stepIndex < directions.steps.length; stepIndex++) {
7807
+ const step = directions.steps[stepIndex];
7808
+ const formattedStep = formatStep(step, this.languageService, stepIndex === directions.steps.length - 1);
7809
+ const formattedDistance = formatDistance(step.distance);
7810
+ const formattedDuration = formatDuration(step.duration);
7811
+ if ((formattedDistance && formattedDuration) ||
7812
+ stepIndex === directions.steps.length - 1) {
7813
+ formattedSteps.push({
7814
+ instruction: `${formattedStep.instruction}`,
7815
+ icon: icons.find((icon) => icon.name === formattedStep.iconName).icon,
7816
+ distanceDuration: formattedDistance && formattedDuration
7817
+ ? `(${formattedDistance} - ${formattedDuration})`
7818
+ : ''
7819
+ });
7784
7820
  }
7785
7821
  }
7786
- const formattedDirection = [];
7787
- for (let i = 0; i < direction.steps.length; i++) {
7788
- const step = direction.steps[i];
7789
- const instruction = formatInstruction(step.maneuver.type, step.maneuver.modifier, step.name, step.maneuver.bearing_after, i, step.maneuver.exit, this.languageService, i === direction.steps.length - 1);
7790
- const distance = formatDistance(step.distance);
7791
- formattedDirection.push({
7792
- instruction: i + 1 + '. ' + instruction.instruction,
7793
- icon: iconsArray.find((icon) => icon.name === instruction.image).icon,
7794
- distance: distance ? '(' + distance + ')' : undefined
7795
- });
7796
- }
7797
- return formattedDirection;
7822
+ return formattedSteps;
7798
7823
  }
7799
- async addInstructions(doc, direction, title) {
7824
+ /**
7825
+ * Adds instructions to the given jsPDF document.
7826
+ *
7827
+ * @param {jsPDF} doc - The jsPDF document to add instructions to.
7828
+ * @param {Directions} directions - The directions object containing the instructions.
7829
+ * @param {string} title - The title of the instructions.
7830
+ * @return {Promise<void>} A promise that resolves when the instructions are added to the document.
7831
+ */
7832
+ async addInstructions(doc, directions, title) {
7800
7833
  doc.addPage();
7801
- const titlePosition = 25;
7802
- doc.text(title, doc.internal.pageSize.width / 2, titlePosition, {
7834
+ doc.text(title, doc.internal.pageSize.getWidth() / 2, 25, {
7803
7835
  align: 'center'
7804
7836
  });
7805
- const HTMLtable = await this.setHTMLTableContent(direction);
7806
- const tablePos = titlePosition + 5;
7837
+ const HTMLtable = await this.setHTMLTableDirections(directions);
7807
7838
  doc.autoTable({
7808
7839
  html: HTMLtable,
7809
- startY: tablePos,
7840
+ startY: 30,
7810
7841
  margin: { top: 20, bottom: 20 },
7811
7842
  columnStyles: {
7812
7843
  0: { cellWidth: 10 }
7813
7844
  },
7814
7845
  theme: 'plain',
7815
7846
  styles: {
7816
- fontSize: 12
7847
+ fontSize: 10
7817
7848
  },
7818
7849
  didDrawCell: function (data) {
7819
7850
  if (data.column.index === 0 && data.cell.section === 'body') {
@@ -7825,23 +7856,25 @@ class DirectionsService {
7825
7856
  }
7826
7857
  });
7827
7858
  }
7859
+ /**
7860
+ * Sets the header and footer of each page in the given jsPDF document.
7861
+ *
7862
+ * @param {jsPDF} doc - The jsPDF document to modify.
7863
+ */
7828
7864
  setPageHeaderFooter(doc) {
7829
7865
  const pageCount = doc.getNumberOfPages();
7830
- const date = moment(Date.now()).format('DD/MM/YYYY hh:mm').toString();
7831
- const logoConfig = this.configService.getConfig('directionsSources.logo');
7832
- const logo = logoConfig ? logoConfig : 'assets/logo.png';
7833
- for (let index = 0; index < pageCount; index++) {
7834
- doc.setPage(index);
7866
+ const dateTime = moment(Date.now()).format('YYYY-MM-DD HH:mm');
7867
+ const logo = this.configService.getConfig('directionsSources.logo')
7868
+ ? this.configService.getConfig('directionsSources.logo')
7869
+ : 'assets/logo.png';
7870
+ for (let pageIndex = 0; pageIndex < pageCount; pageIndex++) {
7871
+ doc.setPage(pageIndex);
7835
7872
  doc.setFontSize(8);
7836
7873
  const pageSize = doc.internal.pageSize;
7837
- const pageHeight = pageSize.height
7838
- ? pageSize.height
7839
- : pageSize.getHeight();
7840
- const width = pageSize.width ? pageSize.width : pageSize.getWidth();
7841
- doc.text(date, 10, 10, { baseline: 'top' });
7842
- doc.addImage(logo, 'PNG', width - 20, 5, 10, 10);
7843
- doc.text(date, 10, pageHeight - 10);
7844
- doc.text('Page ' + doc.getCurrentPageInfo().pageNumber + ' / ' + pageCount, width - 20, pageHeight - 10);
7874
+ doc.text(dateTime, 10, 10, { baseline: 'top' });
7875
+ doc.addImage(logo, 'PNG', pageSize.getWidth() - 20, 5, 10, 10);
7876
+ doc.text(dateTime, 10, pageSize.getHeight() - 10);
7877
+ doc.text('Page ' + doc.getCurrentPageInfo().pageNumber + ' / ' + pageCount, pageSize.getWidth() - 20, pageSize.getHeight() - 10);
7845
7878
  }
7846
7879
  }
7847
7880
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsService, deps: [{ token: DirectionsSourceService }, { token: i1$2.ConfigService }, { token: i1$1.LanguageService }, { token: PrintService }, { token: DOCUMENT }, { token: i3.ActivityService }], target: i0.ɵɵFactoryTarget.Injectable });
@@ -7869,136 +7902,189 @@ class StopsFeatureStore extends FeatureStore {
7869
7902
  }
7870
7903
  class RoutesFeatureStore extends FeatureStore {
7871
7904
  }
7872
- class StepFeatureStore extends FeatureStore {
7905
+ class StepsFeatureStore extends FeatureStore {
7873
7906
  }
7874
7907
 
7875
7908
  class DirectionsButtonsComponent {
7876
7909
  languageService;
7877
7910
  messageService;
7878
- route;
7911
+ routeService;
7879
7912
  directionsService;
7880
- get activeRoute() {
7881
- return this.routesFeatureStore
7882
- .all()
7883
- .find((route) => route.properties.active);
7884
- }
7885
7913
  contextUri;
7886
- zoomToActiveRoute$ = new Subject();
7914
+ zoomOnActiveRoute$ = new Subject();
7887
7915
  stopsStore;
7888
7916
  routesFeatureStore;
7889
- stepFeatureStore;
7890
- disabled$ = new BehaviorSubject(false);
7891
- constructor(languageService, messageService, route, directionsService) {
7917
+ stepsFeatureStore;
7918
+ downloadDirectionsBtnDisabled = false;
7919
+ constructor(languageService, messageService, routeService, directionsService) {
7892
7920
  this.languageService = languageService;
7893
7921
  this.messageService = messageService;
7894
- this.route = route;
7922
+ this.routeService = routeService;
7895
7923
  this.directionsService = directionsService;
7896
7924
  }
7925
+ /**
7926
+ * Returns the active route from the routesFeatureStore.
7927
+ *
7928
+ * @return {FeatureWithDirections | undefined} The active route, or undefined if no active route is found.
7929
+ */
7930
+ get activeRoute() {
7931
+ return this.routesFeatureStore
7932
+ .all()
7933
+ .find((route) => route.properties.active);
7934
+ }
7935
+ /**
7936
+ * Resets the stops in the stopsStore by clearing all the stops.
7937
+ *
7938
+ */
7897
7939
  resetStops() {
7898
7940
  this.stopsStore.clearStops();
7899
7941
  }
7900
- // stop are always added before the last stop.
7901
- addStop() {
7902
- addStopToStore(this.stopsStore);
7942
+ /**
7943
+ * Triggers the zoom on the active route.
7944
+ *
7945
+ */
7946
+ zoomOnActiveRoute() {
7947
+ this.zoomOnActiveRoute$.next();
7903
7948
  }
7904
- copyLinkToClipboard() {
7905
- const successful = Clipboard.copy(this.getUrl());
7949
+ /**
7950
+ * Copies the directions to the clipboard and displays a success message if the copy is successful.
7951
+ *
7952
+ */
7953
+ copyDirectionsToClipboard() {
7954
+ const directions = this.directionsToText();
7955
+ const successful = Clipboard.copy(directions);
7906
7956
  if (successful) {
7907
- this.messageService.success('igo.geo.directionsForm.dialog.copyMsgLink', 'igo.geo.directionsForm.dialog.copyTitle');
7957
+ this.messageService.success('igo.geo.directions.buttons.message.copyDirections');
7908
7958
  }
7909
7959
  }
7910
- zoomRoute() {
7911
- this.zoomToActiveRoute$.next();
7912
- }
7913
- copyDirectionsToClipboard() {
7914
- const directionsBody = this.directionsToText();
7915
- const successful = Clipboard.copy(directionsBody);
7916
- if (successful) {
7917
- this.messageService.success('igo.geo.directionsForm.dialog.copyMsg', 'igo.geo.directionsForm.dialog.copyTitle');
7960
+ /**
7961
+ * Copies the link to the clipboard and displays a success message if the copy is successful.
7962
+ *
7963
+ */
7964
+ copyLinkToClipboard() {
7965
+ const copySuccessful = Clipboard.copy(this.getLink());
7966
+ if (copySuccessful) {
7967
+ this.messageService.success('igo.geo.directions.buttons.message.copyLink');
7918
7968
  }
7919
7969
  }
7970
+ /**
7971
+ * Downloads the directions.
7972
+ *
7973
+ */
7974
+ downloadDirections() {
7975
+ this.stepsFeatureStore.clear();
7976
+ this.downloadDirectionsBtnDisabled = true;
7977
+ this.directionsService
7978
+ .downloadDirections(this.routesFeatureStore.map, this.activeRoute.properties.directions)
7979
+ .subscribe(() => {
7980
+ this.downloadDirectionsBtnDisabled = false;
7981
+ });
7982
+ }
7983
+ /**
7984
+ * Generates a text representation of the directions, including summary, stops, URL, and directions.
7985
+ *
7986
+ * @return {string} The directions in text format.
7987
+ */
7920
7988
  directionsToText() {
7921
7989
  const indent = '\t';
7922
- let activeRouteDirective = this.languageService.translate.instant('igo.geo.directionsForm.instructions') + ':\n';
7923
- let wayPointList = '';
7924
- const summary = this.languageService.translate.instant('igo.geo.directionsForm.summary') +
7925
- ': \n' +
7926
- indent +
7927
- this.activeRoute.properties.direction.title +
7928
- '\n' +
7929
- indent +
7930
- formatDistance(this.activeRoute.properties.direction.distance) +
7931
- '\n' +
7990
+ const newLine = '\n';
7991
+ let summary = this.languageService.translate.instant('igo.geo.directions.directionsText.summary') +
7992
+ ':' +
7993
+ newLine +
7932
7994
  indent +
7933
- formatDuration(this.activeRoute.properties.direction.duration) +
7934
- '\n\n' +
7935
- this.languageService.translate.instant('igo.geo.directionsForm.stopsList') +
7936
- ':\n';
7937
- const url = this.languageService.translate.instant('igo.geo.directionsForm.link') +
7938
- ':\n' +
7939
- indent +
7940
- this.getUrl();
7941
- let wayPointsCnt = 1;
7995
+ this.activeRoute.properties.directions.title;
7996
+ const distance = formatDistance(this.activeRoute.properties.directions.distance);
7997
+ const duration = formatDuration(this.activeRoute.properties.directions.duration);
7998
+ if (distance && duration) {
7999
+ summary += ' (' + distance + ' - ' + duration + ')';
8000
+ }
8001
+ summary += newLine + newLine;
8002
+ let stops = this.languageService.translate.instant('igo.geo.directions.directionsText.stopList') +
8003
+ ':' +
8004
+ newLine;
8005
+ let stopNumber = 1;
7942
8006
  this.stopsStore.view.all().forEach((stop) => {
7943
- let coord = '';
8007
+ let coords = '';
7944
8008
  let stopText = '';
7945
- if (stop.text !== roundCoordTo(stop.coordinates).join(',')) {
8009
+ if (stop.text !== roundCoordToString(stop.coordinates, 6).join(', ')) {
7946
8010
  stopText = stop.text;
7947
- coord = ` ( ${roundCoordTo(stop.coordinates).join(',')} )`;
8011
+ coords = ` (${roundCoordToString(stop.coordinates, 6).join(', ')})`;
7948
8012
  }
7949
8013
  else {
7950
- stopText = roundCoordTo(stop.coordinates).join(',');
8014
+ stopText = roundCoordToString(stop.coordinates, 6).join(', ');
7951
8015
  }
7952
- wayPointList =
7953
- wayPointList +
8016
+ stops =
8017
+ stops +
7954
8018
  indent +
7955
- wayPointsCnt.toLocaleString() +
8019
+ stopNumber.toLocaleString() +
7956
8020
  '. ' +
7957
8021
  stopText +
7958
- coord +
7959
- '\n';
7960
- wayPointsCnt++;
7961
- });
7962
- let localCnt = 0;
7963
- this.activeRoute.properties.direction.steps.forEach((step) => {
7964
- const instruction = this.formatStep(step, localCnt).instruction;
7965
- const distance = formatDistance(step.distance) === undefined
7966
- ? ''
7967
- : ' (' + formatDistance(step.distance) + ')';
7968
- activeRouteDirective =
7969
- activeRouteDirective +
7970
- indent +
7971
- (localCnt + 1).toLocaleString() +
7972
- '. ' +
7973
- instruction +
7974
- distance +
7975
- '\n';
7976
- localCnt++;
7977
- });
7978
- const directionsBody = summary + wayPointList + '\n' + url + '\n\n' + activeRouteDirective;
8022
+ coords +
8023
+ newLine;
8024
+ stopNumber++;
8025
+ });
8026
+ stops += newLine;
8027
+ const url = this.languageService.translate.instant('igo.geo.directions.directionsText.link') +
8028
+ ':' +
8029
+ newLine +
8030
+ indent +
8031
+ this.getLink() +
8032
+ newLine +
8033
+ newLine;
8034
+ let directions = this.languageService.translate.instant('igo.geo.directions.directions') +
8035
+ ':' +
8036
+ newLine;
8037
+ this.activeRoute.properties.directions.steps.forEach((step, stepIndex, steps) => {
8038
+ const distance = formatDistance(step.distance);
8039
+ const duration = formatDuration(step.duration);
8040
+ if ((distance && duration) || stepIndex === steps.length - 1) {
8041
+ const instruction = this.getFormattedStepInstruction(step, stepIndex);
8042
+ const formattedDistanceDuration = distance && duration ? ` (${distance} - ${duration}) ` : '';
8043
+ directions =
8044
+ directions +
8045
+ indent +
8046
+ '- ' +
8047
+ instruction +
8048
+ formattedDistanceDuration +
8049
+ newLine;
8050
+ }
8051
+ });
8052
+ const directionsBody = summary + stops + url + directions;
7979
8053
  return directionsBody;
7980
8054
  }
7981
- formatStep(step, cnt) {
7982
- return formatInstruction(step.maneuver.type, step.maneuver.modifier, step.name, step.maneuver.bearing_after, cnt, step.maneuver.exit, this.languageService, cnt === this.activeRoute.properties.direction.steps.length - 1);
8055
+ /**
8056
+ * Formats a step.
8057
+ *
8058
+ * @param {IgoStep} step - The step to format.
8059
+ * @param {number} stepIndex - The index of the step in the directions.
8060
+ * @return {string} The formatted instruction for the step.
8061
+ */
8062
+ getFormattedStepInstruction(step, stepIndex) {
8063
+ return formatStep(step, this.languageService, stepIndex === this.activeRoute.properties.directions.steps.length - 1).instruction;
7983
8064
  }
7984
- getUrl() {
7985
- if (!this.route) {
8065
+ /**
8066
+ * Generates a link based on the current route and stops.
8067
+ *
8068
+ * @return {string | undefined} The generated link, or undefined if the route service is not available.
8069
+ */
8070
+ getLink() {
8071
+ if (!this.routeService) {
7986
8072
  return;
7987
8073
  }
7988
8074
  let context = '';
7989
8075
  if (this.contextUri) {
7990
8076
  context = `context=${this.contextUri}&`;
7991
8077
  }
7992
- const pos = this.routesFeatureStore
8078
+ const routeIndex = this.routesFeatureStore
7993
8079
  .all()
7994
8080
  .map((direction) => direction.properties.id)
7995
8081
  .indexOf(this.activeRoute.properties.id);
7996
8082
  let routingOptions = '';
7997
- if (pos !== 0) {
7998
- const routingOptionsKey = this.route.options.directionsOptionsKey;
7999
- routingOptions = `&${routingOptionsKey}=result:${pos}`;
8083
+ if (routeIndex !== 0) {
8084
+ const routingOptionsKey = this.routeService.options.directionsOptionsKey;
8085
+ routingOptions = `&${routingOptionsKey}=result:${routeIndex}`;
8000
8086
  }
8001
- const directionsKey = this.route.options.directionsCoordKey;
8087
+ const directionsKey = this.routeService.options.directionsCoordKey;
8002
8088
  const stopsCoordinates = this.stopsStore.view
8003
8089
  .all()
8004
8090
  .map((stop) => roundCoordTo(stop.coordinates, 6));
@@ -8009,17 +8095,8 @@ class DirectionsButtonsComponent {
8009
8095
  }
8010
8096
  return;
8011
8097
  }
8012
- printDirections() {
8013
- this.stepFeatureStore.clear();
8014
- this.disabled$.next(true);
8015
- this.directionsService
8016
- .downloadDirection(this.routesFeatureStore.map, this.activeRoute.properties.direction)
8017
- .subscribe(() => {
8018
- this.disabled$.next(false);
8019
- });
8020
- }
8021
8098
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsButtonsComponent, deps: [{ token: i1$1.LanguageService }, { token: i2.MessageService }, { token: i3$1.RouteService, optional: true }, { token: DirectionsService }], target: i0.ɵɵFactoryTarget.Component });
8022
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsButtonsComponent, isStandalone: true, selector: "igo-directions-buttons", inputs: { contextUri: "contextUri", zoomToActiveRoute$: "zoomToActiveRoute$", stopsStore: "stopsStore", routesFeatureStore: "routesFeatureStore", stepFeatureStore: "stepFeatureStore" }, ngImport: i0, template: "<div class=\"igo-form-button-group\">\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.addStop' | translate\"\n color=\"primary\"\n (click)=\"addStop()\"\n >\n <mat-icon>add_location_alt</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"\n (routesFeatureStore.count$ | async) >= 1 ||\n (stopsStore.count$ | async) >= 1\n \"\n [matTooltip]=\"'igo.geo.directionsForm.resetDirectionsBtn' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n >\n <mat-icon>restore_page</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"zoomRoute()\"\n [matTooltip]=\"'igo.geo.directionsForm.zoomRoute' | translate\"\n color=\"primary\"\n >\n <mat-icon>zoom_in</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"copyDirectionsToClipboard()\"\n [matTooltip]=\"'igo.geo.directionsForm.copy' | translate\"\n color=\"primary\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"copyLinkToClipboard()\"\n [matTooltip]=\"'igo.geo.directionsForm.link' | translate\"\n color=\"primary\"\n >\n <mat-icon>link</mat-icon>\n </button>\n\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"printDirections()\"\n [disabled]=\"disabled$ | async\"\n [matTooltip]=\"'igo.geo.directionsForm.print' | translate\"\n color=\"primary\"\n >\n <mat-icon>print</mat-icon>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8099
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsButtonsComponent, isStandalone: true, selector: "igo-directions-buttons", inputs: { contextUri: "contextUri", zoomOnActiveRoute$: "zoomOnActiveRoute$", stopsStore: "stopsStore", routesFeatureStore: "routesFeatureStore", stepsFeatureStore: "stepsFeatureStore" }, ngImport: i0, template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"zoomOnActiveRoute()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8023
8100
  }
8024
8101
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsButtonsComponent, decorators: [{
8025
8102
  type: Component,
@@ -8030,27 +8107,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
8030
8107
  NgIf,
8031
8108
  AsyncPipe,
8032
8109
  IgoLanguageModule
8033
- ], template: "<div class=\"igo-form-button-group\">\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.addStop' | translate\"\n color=\"primary\"\n (click)=\"addStop()\"\n >\n <mat-icon>add_location_alt</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"\n (routesFeatureStore.count$ | async) >= 1 ||\n (stopsStore.count$ | async) >= 1\n \"\n [matTooltip]=\"'igo.geo.directionsForm.resetDirectionsBtn' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n >\n <mat-icon>restore_page</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"zoomRoute()\"\n [matTooltip]=\"'igo.geo.directionsForm.zoomRoute' | translate\"\n color=\"primary\"\n >\n <mat-icon>zoom_in</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"copyDirectionsToClipboard()\"\n [matTooltip]=\"'igo.geo.directionsForm.copy' | translate\"\n color=\"primary\"\n >\n <mat-icon>content_copy</mat-icon>\n </button>\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"copyLinkToClipboard()\"\n [matTooltip]=\"'igo.geo.directionsForm.link' | translate\"\n color=\"primary\"\n >\n <mat-icon>link</mat-icon>\n </button>\n\n <button\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n *ngIf=\"(routesFeatureStore.count$ | async) >= 1\"\n (click)=\"printDirections()\"\n [disabled]=\"disabled$ | async\"\n [matTooltip]=\"'igo.geo.directionsForm.print' | translate\"\n color=\"primary\"\n >\n <mat-icon>print</mat-icon>\n </button>\n</div>\n" }]
8110
+ ], template: "<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.resetStops' | translate\"\n color=\"warn\"\n (click)=\"resetStops()\"\n>\n <mat-icon>restart_alt</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.zoomOnRoute' | translate\"\n color=\"primary\"\n (click)=\"zoomOnActiveRoute()\"\n>\n <mat-icon>frame_inspect</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyDirections' | translate\"\n color=\"primary\"\n (click)=\"copyDirectionsToClipboard()\"\n>\n <mat-icon>content_copy</mat-icon>\n</button>\n<button\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.buttons.copyLink' | translate\"\n color=\"primary\"\n (click)=\"copyLinkToClipboard()\"\n>\n <mat-icon>link</mat-icon>\n</button>\n\n<button\n mat-icon-button\n [disabled]=\"downloadDirectionsBtnDisabled\"\n [matTooltip]=\"'igo.geo.directions.buttons.downloadDirections' | translate\"\n color=\"primary\"\n (click)=\"downloadDirections()\"\n>\n <mat-icon>download</mat-icon>\n</button>\n" }]
8034
8111
  }], ctorParameters: () => [{ type: i1$1.LanguageService }, { type: i2.MessageService }, { type: i3$1.RouteService, decorators: [{
8035
8112
  type: Optional
8036
8113
  }] }, { type: DirectionsService }], propDecorators: { contextUri: [{
8037
- type: Input
8038
- }], zoomToActiveRoute$: [{
8039
- type: Input
8114
+ type: Input,
8115
+ args: [{ required: true }]
8116
+ }], zoomOnActiveRoute$: [{
8117
+ type: Input,
8118
+ args: [{ required: true }]
8040
8119
  }], stopsStore: [{
8041
- type: Input
8120
+ type: Input,
8121
+ args: [{ required: true }]
8042
8122
  }], routesFeatureStore: [{
8043
- type: Input
8044
- }], stepFeatureStore: [{
8045
- type: Input
8123
+ type: Input,
8124
+ args: [{ required: true }]
8125
+ }], stepsFeatureStore: [{
8126
+ type: Input,
8127
+ args: [{ required: true }]
8046
8128
  }] } });
8047
8129
 
8048
8130
  class DirectionsInputsComponent {
8049
8131
  languageService;
8050
- invalidKeys = ['Control', 'Shift', 'Alt'];
8051
- onMapClickEventKeys = [];
8052
- stopWithHover;
8053
- stopIsDragged = false;
8054
8132
  stopsStore;
8055
8133
  stopsFeatureStore;
8056
8134
  projection;
@@ -8058,143 +8136,238 @@ class DirectionsInputsComponent {
8058
8136
  debounce = 200;
8059
8137
  length = 2;
8060
8138
  stopInputHasFocus = new EventEmitter(false);
8139
+ invalidKeys = ['Control', 'Shift', 'Alt'];
8140
+ onMapClickEventKeys = [];
8141
+ stopWithHover;
8142
+ stopIsDragged = false;
8061
8143
  constructor(languageService) {
8062
8144
  this.languageService = languageService;
8063
8145
  }
8146
+ /**
8147
+ * Returns the position property of the geolocationController.
8148
+ *
8149
+ * @return {BehaviorSubject<boolean> | undefined} The position property of
8150
+ * the geolocationController.
8151
+ */
8152
+ get currentPosition() {
8153
+ return (this.stopsFeatureStore?.map?.geolocationController?.position$?.value
8154
+ ?.position &&
8155
+ this.stopsFeatureStore?.map?.geolocationController?.tracking);
8156
+ }
8064
8157
  ngOnDestroy() {
8065
8158
  this.unlistenMapSingleClick();
8066
8159
  }
8160
+ /**
8161
+ * Sets the stop with hover to the given stop.
8162
+ *
8163
+ * @param {Stop} stop - The stop to set as the stop with hover.
8164
+ */
8067
8165
  onStopEnter(stop) {
8068
8166
  this.stopWithHover = stop;
8069
8167
  }
8168
+ /**
8169
+ * Sets the stop with hover to undefined.
8170
+ *
8171
+ */
8070
8172
  onStopLeave() {
8071
8173
  this.stopWithHover = undefined;
8072
8174
  }
8175
+ /**
8176
+ * Adds a stop to the stops store.
8177
+ *
8178
+ */
8179
+ addStop() {
8180
+ addStopToStore(this.stopsStore);
8181
+ }
8182
+ /**
8183
+ * Returns the title of the option if it is an object and has a meta property with a title,
8184
+ * otherwise returns the option itself.
8185
+ *
8186
+ * @param {any} option - The option to get the text from.
8187
+ * @return {string} The title of the option if it is an object and has a meta property with a title,
8188
+ * otherwise returns the option itself.
8189
+ */
8073
8190
  getOptionText(option) {
8074
8191
  if (option instanceof Object) {
8075
- return option?.meta ? option.meta.title : '';
8192
+ const { meta } = option;
8193
+ return meta?.title || '';
8076
8194
  }
8077
8195
  return option;
8078
8196
  }
8079
- chooseProposal(event, stop) {
8080
- const result = event.option.value;
8081
- if (result) {
8082
- let geomCoord;
8083
- const geom = result.geometry;
8084
- if (geom.type === 'Point') {
8085
- geomCoord = geom.coordinates;
8197
+ /**
8198
+ * Chooses an option from a MatAutocomplete and updates the stop coordinates and text
8199
+ * based on the selected feature.
8200
+ *
8201
+ * @param {Object} event - The event object containing the MatAutocomplete and MatOption.
8202
+ * @param {MatAutocomplete} event.source - The MatAutocomplete component.
8203
+ * @param {MatOption} event.option - The selected MatOption.
8204
+ * @param {Stop} stop - The stop object to update.
8205
+ */
8206
+ chooseOption(event, stop) {
8207
+ const feature = event.option.value;
8208
+ if (feature) {
8209
+ let coords;
8210
+ const geometry = feature.geometry;
8211
+ if (geometry.type === 'Point') {
8212
+ coords = geometry.coordinates;
8086
8213
  }
8087
8214
  else {
8088
- const point = pointOnFeature(result.geometry);
8089
- geomCoord = [
8090
- point.geometry.coordinates[0],
8091
- point.geometry.coordinates[1]
8092
- ];
8215
+ const point = pointOnFeature(feature.geometry);
8216
+ coords = [point.geometry.coordinates[0], point.geometry.coordinates[1]];
8093
8217
  }
8094
- if (geomCoord) {
8095
- stop.coordinates = geomCoord;
8096
- stop.text = result.meta.title;
8218
+ if (coords) {
8219
+ stop.coordinates = coords;
8220
+ stop.text = feature.meta.title;
8097
8221
  this.stopsStore.update(stop);
8098
8222
  }
8099
8223
  }
8100
8224
  }
8225
+ /**
8226
+ * Sets the text of a stop based on the value of an input field.
8227
+ *
8228
+ * @param {KeyboardEvent} event - The keyboard event triggered by the input field.
8229
+ * @param {Stop} stop - The stop object to update.
8230
+ */
8101
8231
  setStopText(event, stop) {
8102
8232
  this.unlistenMapSingleClick();
8103
- const term = event.target.value;
8104
- if (term.length === 0) {
8105
- this.clearStop(stop);
8233
+ const searchTerm = event.target.value;
8234
+ if (searchTerm.length === 0) {
8235
+ this.clearStopInput(stop);
8106
8236
  }
8107
- else if (this.validateTerm(term)) {
8108
- stop.text = term;
8237
+ else if (this.validateSearchTerm(searchTerm)) {
8238
+ stop.text = searchTerm;
8109
8239
  this.stopsStore.update(stop);
8110
8240
  }
8111
8241
  }
8112
- validateTerm(term) {
8113
- if (this.keyIsValid(term) &&
8114
- (term.length >= this.length || term.length === 0)) {
8115
- return true;
8116
- }
8117
- return false;
8118
- }
8119
- keyIsValid(key) {
8120
- return this.invalidKeys.find((value) => value === key) === undefined;
8121
- }
8122
- getNgClass(stop) {
8123
- if (!this.stopWithHover) {
8124
- return 'igo-input-container';
8125
- }
8126
- else if (stop.id === this.stopWithHover.id) {
8127
- return 'igo-input-container reduce';
8128
- }
8129
- else {
8130
- return 'igo-input-container';
8131
- }
8242
+ /**
8243
+ * Validates a search term by checking if it contains any invalid characters and if its length is valid.
8244
+ *
8245
+ * @param {string} searchTerm - The search term to be validated.
8246
+ * @return {boolean} Returns true if the search term is valid, false otherwise.
8247
+ */
8248
+ validateSearchTerm(searchTerm) {
8249
+ const charactersAreValid = this.invalidKeys.indexOf(searchTerm) === -1;
8250
+ const lengthIsValid = searchTerm.length >= this.length || searchTerm.length === 0;
8251
+ return charactersAreValid && lengthIsValid;
8132
8252
  }
8133
- getPlaceholder(stop) {
8134
- let extra = '';
8135
- if (stop.relativePosition) {
8136
- if (stop.relativePosition === DirectionRelativePositionType.Intermediate) {
8137
- extra = ' #' + stop.position;
8138
- }
8139
- return (this.languageService.translate.instant('igo.geo.directionsForm.' + stop.relativePosition) + extra);
8140
- }
8141
- else {
8142
- return '';
8143
- }
8253
+ /**
8254
+ * Returns the label for the given stop input.
8255
+ *
8256
+ * @param {Stop} stop - The stop containing relativePosition and position.
8257
+ * @return {string} The label for the stop input.
8258
+ */
8259
+ getInputLabel(stop) {
8260
+ const { relativePosition, position } = stop;
8261
+ const label = relativePosition
8262
+ ? this.languageService.translate.instant(`igo.geo.directions.input.${relativePosition}`)
8263
+ : '';
8264
+ return relativePosition === DirectionRelativePositionType.Intermediate
8265
+ ? `${label} #${position}`
8266
+ : label;
8144
8267
  }
8268
+ /**
8269
+ * Removes a stop from the stops store.
8270
+ *
8271
+ * @param {Stop} stop - The stop object to be removed.
8272
+ */
8145
8273
  removeStop(stop) {
8146
8274
  removeStopFromStore(this.stopsStore, stop);
8147
8275
  }
8148
- clearStop(stop) {
8276
+ /**
8277
+ * Clears the specified stop in the stops store.
8278
+ *
8279
+ * @param {Stop} stop - The stop to be cleared.
8280
+ */
8281
+ clearStopInput(stop) {
8149
8282
  this.stopsStore.update({
8150
8283
  id: stop.id,
8151
8284
  relativePosition: stop.relativePosition,
8152
8285
  position: stop.position
8153
8286
  });
8154
8287
  }
8155
- drop(event) {
8288
+ /**
8289
+ * Use the current position as a stop.
8290
+ *
8291
+ * @param {Stop} stop - The stop to update with the current position.
8292
+ */
8293
+ useCurrentPosition(stop) {
8294
+ this.useCoordinatesAsStop(this.stopsFeatureStore.map.geolocationController.position$.value.position, stop);
8295
+ }
8296
+ /**
8297
+ * Moves a stop in the list of stops..
8298
+ *
8299
+ * @param {CdkDragDrop<string[]>} event - The event containing the previous and current index of the dropped stop.
8300
+ */
8301
+ dropStop(event) {
8156
8302
  this.moveStops(event.previousIndex, event.currentIndex);
8157
8303
  }
8304
+ /**
8305
+ * Moves a stop in the list of stops from one index to another.
8306
+ *
8307
+ * @param {number} fromIndex - The index to move the stop from.
8308
+ * @param {number} toIndex - The index to move the stop to.
8309
+ */
8158
8310
  moveStops(fromIndex, toIndex) {
8159
8311
  if (fromIndex !== toIndex) {
8160
8312
  const stops = [...this.stopsStore.view.all()];
8161
8313
  moveItemInArray(stops, fromIndex, toIndex);
8162
- stops.map((stop, i) => {
8163
- stop.relativePosition = computeRelativePosition(i, stops.length);
8164
- stop.position = i;
8314
+ stops.map((stop, stopIndex) => {
8315
+ stop.relativePosition = computeRelativePosition(stopIndex, stops.length - 1);
8316
+ stop.position = stopIndex;
8165
8317
  });
8166
8318
  this.stopsStore.updateMany(stops);
8167
8319
  updateStoreSorting(this.stopsStore);
8168
8320
  }
8169
8321
  }
8322
+ /**
8323
+ * Handles the focus event on an input field for a stop.
8324
+ *
8325
+ * @param {Stop} stop - The stop that the input field is associated with.
8326
+ */
8170
8327
  onInputFocus(stop) {
8171
- if (!stop.text || stop.text?.length === 0) {
8172
- this.unlistenMapSingleClick();
8173
- this.stopInputHasFocus.emit(true);
8174
- this.listenMapSingleClick(stop);
8175
- }
8328
+ this.unlistenMapSingleClick();
8329
+ this.stopInputHasFocus.emit(true);
8330
+ this.listenMapSingleClick(stop);
8176
8331
  }
8332
+ /**
8333
+ * Listens for a single click event on the map and uses the coordinates of the click
8334
+ * to set the given stop's coordinates.
8335
+ *
8336
+ * @param {Stop} stop - The stop to update with the clicked coordinates.
8337
+ */
8177
8338
  listenMapSingleClick(stop) {
8178
8339
  const key = this.stopsFeatureStore.layer.map.ol.once('singleclick', (event) => {
8179
- const clickCoordinates = olproj.transform(event.coordinate, this.stopsFeatureStore.layer.map.projection, this.projection);
8180
- const roundedCoord = roundCoordTo(clickCoordinates, this.coordRoundedDecimals);
8181
- stop.text = roundedCoord.join(',');
8182
- stop.coordinates = roundedCoord;
8183
- this.stopsStore.update(stop);
8184
- setTimeout(() => {
8185
- this.stopInputHasFocus.emit(false);
8186
- }, 500);
8340
+ this.useCoordinatesAsStop(event.coordinate, stop);
8187
8341
  });
8188
8342
  this.onMapClickEventKeys.push(key);
8189
8343
  }
8344
+ /**
8345
+ * Unlistens for map single click events and clears the list of event keys.
8346
+ */
8190
8347
  unlistenMapSingleClick() {
8191
8348
  this.onMapClickEventKeys.map((key) => {
8192
8349
  olObservable.unByKey(key);
8193
8350
  });
8194
8351
  this.onMapClickEventKeys = [];
8195
8352
  }
8353
+ /**
8354
+ * Uses the given coordinates to update the given stop.
8355
+ *
8356
+ * @param {Coordinate} coordinates - The coordinates to transform and round.
8357
+ * @param {Stop} stop - The stop to update with the new coordinates and text.
8358
+ */
8359
+ useCoordinatesAsStop(coordinates, stop) {
8360
+ const projectedCoordinates = olproj.transform(coordinates, this.stopsFeatureStore.layer.map.projection, this.projection);
8361
+ const roundedCoordinates = roundCoordTo(projectedCoordinates, this.coordRoundedDecimals);
8362
+ stop.text = roundCoordToString(projectedCoordinates, this.coordRoundedDecimals).join(', ');
8363
+ stop.coordinates = roundedCoordinates;
8364
+ this.stopsStore.update(stop);
8365
+ setTimeout(() => {
8366
+ this.stopInputHasFocus.emit(false);
8367
+ }, 500);
8368
+ }
8196
8369
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsInputsComponent, deps: [{ token: i1$1.LanguageService }], target: i0.ɵɵFactoryTarget.Component });
8197
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsInputsComponent, isStandalone: true, selector: "igo-directions-inputs", inputs: { stopsStore: "stopsStore", stopsFeatureStore: "stopsFeatureStore", projection: "projection", coordRoundedDecimals: "coordRoundedDecimals", debounce: "debounce", length: "length" }, outputs: { stopInputHasFocus: "stopInputHasFocus" }, ngImport: i0, template: "<div cdkDropList class=\"stops-list\" (cdkDropListDropped)=\"drop($event)\">\n <div\n touchleave\n (touchenter)=\"onStopEnter(stop)\"\n (touchleave)=\"onStopLeave()\"\n (mouseover)=\"onStopEnter(stop)\"\n (mouseleave)=\"onStopLeave()\"\n (cdkDragStarted)=\"stopIsDragged = true\"\n (cdkDragEnded)=\"stopIsDragged = false\"\n cdkDragLockAxis=\"y\"\n class=\"stop-box\"\n *ngFor=\"let stop of stopsStore.view.all$() | async; let i = index\"\n cdkDrag\n >\n <div [ngClass]=\"getNgClass(stop)\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ getPlaceholder(stop) }}</mat-label>\n <input\n id=\"{{ stop.id }}\"\n type=\"text\"\n [placeholder]=\"getPlaceholder(stop)\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"stop.text\"\n aria-label=\"Number\"\n matInput\n (focus)=\"onInputFocus(stop)\"\n [(ngModel)]=\"stop.text\"\n (keyup)=\"setStopText($event, stop)\"\n (keydown.enter)=\"$event.preventDefault()\"\n [matAutocomplete]=\"auto\"\n />\n <button\n *ngIf=\"\n (stop.text || stop.coordinates) &&\n stopWithHover &&\n stop.id === stopWithHover.id\n \"\n mat-icon-button\n matSuffix\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.clearStop' | translate\"\n color=\"warn\"\n aria-label=\"Clear\"\n (click)=\"clearStop(stop)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-autocomplete\n [displayWith]=\"getOptionText\"\n #auto=\"matAutocomplete\"\n (optionSelected)=\"chooseProposal($event, stop)\"\n >\n <mat-optgroup\n *ngFor=\"let source of stop.searchProposals\"\n [label]=\"source.source.title\"\n [disabled]=\"source.source.enabled === false\"\n >\n <mat-option\n *ngFor=\"let result of source.results\"\n [value]=\"result\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"result.meta ? result.meta.title : ''\"\n >\n {{ result.meta ? result.meta.title : '' }}\n </mat-option>\n </mat-optgroup>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"!stopIsDragged && stopWithHover && stop.id === stopWithHover.id\"\n class=\"igo-form-button-group\"\n >\n <button\n class=\"swipe-vertical\"\n cdkDragHandle\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.moveStop' | translate\"\n color=\"primary\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n\n <button\n *ngIf=\"(stopsStore.count$ | async) > 2\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.removeStop' | translate\"\n color=\"warn\"\n (click)=\"removeStop(stop)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host .igo-input-container{display:flex;width:100%}:host .igo-input-container mat-form-field{flex:1}:host .igo-form-button-group{display:flex;align-items:center;padding-left:12px}:host .stops-list{max-width:100%;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden;padding:20px 10px}:host .swipe-vertical{cursor:move}:host .stop-box{color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;background:#fff}:host .stop-box:not(:last-child){margin-bottom:16px}:host .cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}:host .cdk-drag-placeholder{opacity:0}:host .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}:host .stops-list.cdk-drop-list-dragging .stop-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i6.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "directive", type: i6.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8370
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsInputsComponent, isStandalone: true, selector: "igo-directions-inputs", inputs: { stopsStore: "stopsStore", stopsFeatureStore: "stopsFeatureStore", projection: "projection", coordRoundedDecimals: "coordRoundedDecimals", debounce: "debounce", length: "length" }, outputs: { stopInputHasFocus: "stopInputHasFocus" }, ngImport: i0, template: "<div cdkDropList class=\"stops-list\" (cdkDropListDropped)=\"dropStop($event)\">\n <div\n *ngFor=\"let stop of stopsStore.view.all$() | async; let stopIndex = index\"\n class=\"stop\"\n >\n <div\n (touchenter)=\"onStopEnter(stop)\"\n (touchleave)=\"onStopLeave()\"\n (mouseover)=\"onStopEnter(stop)\"\n (mouseleave)=\"onStopLeave()\"\n (cdkDragStarted)=\"stopIsDragged = true\"\n (cdkDragEnded)=\"stopIsDragged = false\"\n cdkDragLockAxis=\"y\"\n class=\"stop-box\"\n cdkDrag\n >\n <div class=\"prefix-actions\">\n <button\n class=\"swipe-vertical\"\n cdkDragHandle\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.input.moveStop' | translate\"\n color=\"primary\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n </div>\n\n <div class=\"igo-input-container\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ getInputLabel(stop) }}</mat-label>\n <input\n [id]=\"stop.id\"\n type=\"text\"\n [placeholder]=\"'igo.geo.directions.input.placeholder' | translate\"\n matInput\n (focus)=\"onInputFocus(stop)\"\n [(ngModel)]=\"stop.text\"\n (keyup)=\"setStopText($event, stop)\"\n (keydown.enter)=\"$event.preventDefault()\"\n [matAutocomplete]=\"auto\"\n />\n <button\n *ngIf=\"currentPosition\"\n mat-icon-button\n matPrefix\n [matTooltip]=\"\n 'igo.geo.directions.input.currentPosition' | translate\n \"\n color=\"accent\"\n (click)=\"useCurrentPosition(stop); $event.stopPropagation()\"\n >\n <mat-icon>my_location</mat-icon>\n </button>\n <button\n *ngIf=\"stop.text || stop.coordinates\"\n mat-icon-button\n matSuffix\n [matTooltip]=\"'igo.geo.directions.input.clearStop' | translate\"\n color=\"warn\"\n (click)=\"clearStopInput(stop)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-autocomplete\n [displayWith]=\"getOptionText\"\n #auto=\"matAutocomplete\"\n (optionSelected)=\"chooseOption($event, stop)\"\n >\n <mat-optgroup\n *ngFor=\"let source of stop.searchProposals\"\n [label]=\"source.source.title\"\n [disabled]=\"!source.source.enabled\"\n >\n <mat-option\n *ngFor=\"let result of source.results\"\n [value]=\"result\"\n >\n {{ result.meta ? result.meta.title : '' }}\n </mat-option>\n </mat-optgroup>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n <button\n class=\"delete-button\"\n *ngIf=\"(stopsStore.count$ | async) > 2\"\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.input.removeStop' | translate\"\n color=\"warn\"\n (click)=\"removeStop(stop)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"prefix-actions\">\n <button\n mat-icon-button\n [disabled]=\"\n (stopsStore.count$ | async) !== (stopsFeatureStore.count$ | async) ||\n stopIsDragged\n \"\n [matTooltip]=\"'igo.geo.directions.input.addStop' | translate\"\n color=\"primary\"\n (click)=\"addStop()\"\n >\n <mat-icon>add_location_alt</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host .igo-input-container{display:flex;width:100%}:host .igo-input-container mat-form-field{flex:1}:host .stops-list{padding:12px 10px}:host .stops-list,:host .stop{display:flex;flex-flow:column;row-gap:12px}:host .stop:hover .swipe-vertical,:host .stop:hover .delete-button{visibility:visible;display:block}:host .swipe-vertical{visibility:hidden;cursor:move}:host .delete-button{display:none}:host .stop-box{display:flex;align-items:center;justify-content:space-between}:host .cdk-drag-placeholder{opacity:0}:host .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}:host .stops-list.cdk-drop-list-dragging .stop-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatLabel, selector: "mat-label" }, { kind: "directive", type: i2$2.MatPrefix, selector: "[matPrefix], [matIconPrefix], [matTextPrefix]", inputs: ["matTextPrefix"] }, { kind: "directive", type: i2$2.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4$1.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: MatAutocompleteModule }, { kind: "component", type: i6.MatAutocomplete, selector: "mat-autocomplete", inputs: ["aria-label", "aria-labelledby", "displayWith", "autoActiveFirstOption", "autoSelectActiveOption", "requireSelection", "panelWidth", "disableRipple", "class", "hideSingleSelectionIndicator"], outputs: ["optionSelected", "opened", "closed", "optionActivated"], exportAs: ["matAutocomplete"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: i6$1.MatOptgroup, selector: "mat-optgroup", inputs: ["label", "disabled"], exportAs: ["matOptgroup"] }, { kind: "directive", type: i6.MatAutocompleteTrigger, selector: "input[matAutocomplete], textarea[matAutocomplete]", inputs: ["matAutocomplete", "matAutocompletePosition", "matAutocompleteConnectedTo", "autocomplete", "matAutocompleteDisabled"], exportAs: ["matAutocompleteTrigger"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i2$1.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8198
8371
  }
8199
8372
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsInputsComponent, decorators: [{
8200
8373
  type: Component,
@@ -8215,13 +8388,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
8215
8388
  CdkDragHandle,
8216
8389
  AsyncPipe,
8217
8390
  IgoLanguageModule
8218
- ], template: "<div cdkDropList class=\"stops-list\" (cdkDropListDropped)=\"drop($event)\">\n <div\n touchleave\n (touchenter)=\"onStopEnter(stop)\"\n (touchleave)=\"onStopLeave()\"\n (mouseover)=\"onStopEnter(stop)\"\n (mouseleave)=\"onStopLeave()\"\n (cdkDragStarted)=\"stopIsDragged = true\"\n (cdkDragEnded)=\"stopIsDragged = false\"\n cdkDragLockAxis=\"y\"\n class=\"stop-box\"\n *ngFor=\"let stop of stopsStore.view.all$() | async; let i = index\"\n cdkDrag\n >\n <div [ngClass]=\"getNgClass(stop)\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ getPlaceholder(stop) }}</mat-label>\n <input\n id=\"{{ stop.id }}\"\n type=\"text\"\n [placeholder]=\"getPlaceholder(stop)\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"stop.text\"\n aria-label=\"Number\"\n matInput\n (focus)=\"onInputFocus(stop)\"\n [(ngModel)]=\"stop.text\"\n (keyup)=\"setStopText($event, stop)\"\n (keydown.enter)=\"$event.preventDefault()\"\n [matAutocomplete]=\"auto\"\n />\n <button\n *ngIf=\"\n (stop.text || stop.coordinates) &&\n stopWithHover &&\n stop.id === stopWithHover.id\n \"\n mat-icon-button\n matSuffix\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.clearStop' | translate\"\n color=\"warn\"\n aria-label=\"Clear\"\n (click)=\"clearStop(stop)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-autocomplete\n [displayWith]=\"getOptionText\"\n #auto=\"matAutocomplete\"\n (optionSelected)=\"chooseProposal($event, stop)\"\n >\n <mat-optgroup\n *ngFor=\"let source of stop.searchProposals\"\n [label]=\"source.source.title\"\n [disabled]=\"source.source.enabled === false\"\n >\n <mat-option\n *ngFor=\"let result of source.results\"\n [value]=\"result\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"result.meta ? result.meta.title : ''\"\n >\n {{ result.meta ? result.meta.title : '' }}\n </mat-option>\n </mat-optgroup>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n\n <div\n *ngIf=\"!stopIsDragged && stopWithHover && stop.id === stopWithHover.id\"\n class=\"igo-form-button-group\"\n >\n <button\n class=\"swipe-vertical\"\n cdkDragHandle\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.moveStop' | translate\"\n color=\"primary\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n\n <button\n *ngIf=\"(stopsStore.count$ | async) > 2\"\n mat-icon-button\n tooltip-position=\"below\"\n matTooltipShowDelay=\"500\"\n [matTooltip]=\"'igo.geo.directionsForm.removeStop' | translate\"\n color=\"warn\"\n (click)=\"removeStop(stop)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host .igo-input-container{display:flex;width:100%}:host .igo-input-container mat-form-field{flex:1}:host .igo-form-button-group{display:flex;align-items:center;padding-left:12px}:host .stops-list{max-width:100%;min-height:60px;display:block;background:#fff;border-radius:4px;overflow:hidden;padding:20px 10px}:host .swipe-vertical{cursor:move}:host .stop-box{color:#000000de;display:flex;flex-direction:row;align-items:center;justify-content:space-between;box-sizing:border-box;background:#fff}:host .stop-box:not(:last-child){margin-bottom:16px}:host .cdk-drag-preview{box-sizing:border-box;border-radius:4px;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}:host .cdk-drag-placeholder{opacity:0}:host .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}:host .stops-list.cdk-drop-list-dragging .stop-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
8391
+ ], template: "<div cdkDropList class=\"stops-list\" (cdkDropListDropped)=\"dropStop($event)\">\n <div\n *ngFor=\"let stop of stopsStore.view.all$() | async; let stopIndex = index\"\n class=\"stop\"\n >\n <div\n (touchenter)=\"onStopEnter(stop)\"\n (touchleave)=\"onStopLeave()\"\n (mouseover)=\"onStopEnter(stop)\"\n (mouseleave)=\"onStopLeave()\"\n (cdkDragStarted)=\"stopIsDragged = true\"\n (cdkDragEnded)=\"stopIsDragged = false\"\n cdkDragLockAxis=\"y\"\n class=\"stop-box\"\n cdkDrag\n >\n <div class=\"prefix-actions\">\n <button\n class=\"swipe-vertical\"\n cdkDragHandle\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.input.moveStop' | translate\"\n color=\"primary\"\n >\n <mat-icon>drag_indicator</mat-icon>\n </button>\n </div>\n\n <div class=\"igo-input-container\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <mat-label>{{ getInputLabel(stop) }}</mat-label>\n <input\n [id]=\"stop.id\"\n type=\"text\"\n [placeholder]=\"'igo.geo.directions.input.placeholder' | translate\"\n matInput\n (focus)=\"onInputFocus(stop)\"\n [(ngModel)]=\"stop.text\"\n (keyup)=\"setStopText($event, stop)\"\n (keydown.enter)=\"$event.preventDefault()\"\n [matAutocomplete]=\"auto\"\n />\n <button\n *ngIf=\"currentPosition\"\n mat-icon-button\n matPrefix\n [matTooltip]=\"\n 'igo.geo.directions.input.currentPosition' | translate\n \"\n color=\"accent\"\n (click)=\"useCurrentPosition(stop); $event.stopPropagation()\"\n >\n <mat-icon>my_location</mat-icon>\n </button>\n <button\n *ngIf=\"stop.text || stop.coordinates\"\n mat-icon-button\n matSuffix\n [matTooltip]=\"'igo.geo.directions.input.clearStop' | translate\"\n color=\"warn\"\n (click)=\"clearStopInput(stop)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n\n <mat-autocomplete\n [displayWith]=\"getOptionText\"\n #auto=\"matAutocomplete\"\n (optionSelected)=\"chooseOption($event, stop)\"\n >\n <mat-optgroup\n *ngFor=\"let source of stop.searchProposals\"\n [label]=\"source.source.title\"\n [disabled]=\"!source.source.enabled\"\n >\n <mat-option\n *ngFor=\"let result of source.results\"\n [value]=\"result\"\n >\n {{ result.meta ? result.meta.title : '' }}\n </mat-option>\n </mat-optgroup>\n </mat-autocomplete>\n </mat-form-field>\n </div>\n <button\n class=\"delete-button\"\n *ngIf=\"(stopsStore.count$ | async) > 2\"\n mat-icon-button\n [matTooltip]=\"'igo.geo.directions.input.removeStop' | translate\"\n color=\"warn\"\n (click)=\"removeStop(stop)\"\n >\n <mat-icon>delete</mat-icon>\n </button>\n </div>\n </div>\n <div class=\"prefix-actions\">\n <button\n mat-icon-button\n [disabled]=\"\n (stopsStore.count$ | async) !== (stopsFeatureStore.count$ | async) ||\n stopIsDragged\n \"\n [matTooltip]=\"'igo.geo.directions.input.addStop' | translate\"\n color=\"primary\"\n (click)=\"addStop()\"\n >\n <mat-icon>add_location_alt</mat-icon>\n </button>\n </div>\n</div>\n", styles: [":host .igo-input-container{display:flex;width:100%}:host .igo-input-container mat-form-field{flex:1}:host .stops-list{padding:12px 10px}:host .stops-list,:host .stop{display:flex;flex-flow:column;row-gap:12px}:host .stop:hover .swipe-vertical,:host .stop:hover .delete-button{visibility:visible;display:block}:host .swipe-vertical{visibility:hidden;cursor:move}:host .delete-button{display:none}:host .stop-box{display:flex;align-items:center;justify-content:space-between}:host .cdk-drag-placeholder{opacity:0}:host .cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}:host .stops-list.cdk-drop-list-dragging .stop-box:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
8219
8392
  }], ctorParameters: () => [{ type: i1$1.LanguageService }], propDecorators: { stopsStore: [{
8220
- type: Input
8393
+ type: Input,
8394
+ args: [{ required: true }]
8221
8395
  }], stopsFeatureStore: [{
8222
- type: Input
8396
+ type: Input,
8397
+ args: [{ required: true }]
8223
8398
  }], projection: [{
8224
- type: Input
8399
+ type: Input,
8400
+ args: [{ required: true }]
8225
8401
  }], coordRoundedDecimals: [{
8226
8402
  type: Input
8227
8403
  }], debounce: [{
@@ -8235,11 +8411,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
8235
8411
  class DirectionsResultsComponent {
8236
8412
  languageService;
8237
8413
  cdRef;
8238
- activeDirection;
8239
- directions;
8240
- entities$$;
8241
8414
  routesFeatureStore;
8242
- stepFeatureStore;
8415
+ stepsFeatureStore;
8416
+ activeRoute;
8417
+ routes;
8418
+ entities$$;
8243
8419
  constructor(languageService, cdRef) {
8244
8420
  this.languageService = languageService;
8245
8421
  this.cdRef = cdRef;
@@ -8247,83 +8423,128 @@ class DirectionsResultsComponent {
8247
8423
  ngOnInit() {
8248
8424
  this.entities$$ = this.routesFeatureStore.entities$
8249
8425
  .pipe(debounceTime(200))
8250
- .subscribe((entities) => {
8251
- const activeFeatureWithDirection = entities.find((entity) => entity.properties.active);
8252
- this.directions = entities.map((entity) => entity.properties.direction);
8253
- if (activeFeatureWithDirection) {
8254
- this.activeDirection =
8255
- activeFeatureWithDirection.properties.direction;
8256
- }
8257
- else {
8258
- this.activeDirection = undefined;
8259
- }
8426
+ .subscribe((features) => {
8427
+ const activeFeature = features.find((entity) => entity.properties.active);
8428
+ this.routes = features.map((entity) => entity.properties.directions);
8429
+ this.activeRoute = activeFeature
8430
+ ? activeFeature.properties.directions
8431
+ : undefined;
8260
8432
  this.cdRef.detectChanges();
8261
8433
  });
8262
8434
  }
8263
8435
  ngOnDestroy() {
8264
8436
  this.entities$$.unsubscribe();
8265
8437
  }
8266
- changeRoute() {
8267
- this.routesFeatureStore.entities$.value.map((entity) => (entity.properties.active = !entity.properties.active));
8438
+ /**
8439
+ * Toggles the active state of all features in the routesFeatureStore and updates
8440
+ * the active state of their corresponding features in the layer.
8441
+ */
8442
+ chooseRouteOption() {
8443
+ this.routesFeatureStore.entities$.value.map((feature) => (feature.properties.active = !feature.properties.active));
8268
8444
  this.routesFeatureStore.layer.ol
8269
8445
  .getSource()
8270
8446
  .getFeatures()
8271
8447
  .map((feature) => feature.set('active', !feature.get('active')));
8272
8448
  }
8449
+ /**
8450
+ * Formats the given distance in meters.
8451
+ *
8452
+ * @param {number} distance - The distance in meters to be formatted.
8453
+ * @return {string} The formatted distance string.
8454
+ */
8273
8455
  formatDistance(distance) {
8274
8456
  return formatDistance(distance);
8275
8457
  }
8458
+ /**
8459
+ * Formats the given duration in seconds.
8460
+ *
8461
+ * @param {number} duration - The duration in seconds to be formatted.
8462
+ * @return {string} The formatted duration string.
8463
+ */
8276
8464
  formatDuration(duration) {
8277
8465
  return formatDuration(duration);
8278
8466
  }
8279
- formatStep(step, cnt) {
8280
- return formatInstruction(step.maneuver.type, step.maneuver.modifier, step.name, step.maneuver.bearing_after, cnt, step.maneuver.exit, this.languageService, cnt === this.activeDirection.steps.length - 1);
8467
+ /**
8468
+ * Returns a formatted string containing the distance and duration of the active route.
8469
+ *
8470
+ * @return {string} The formatted string, or an empty string if either distance or duration is undefined.
8471
+ */
8472
+ getTitleDurationAndDistance() {
8473
+ return this.formatDistance(this.activeRoute.distance) &&
8474
+ this.formatDuration(this.activeRoute.duration)
8475
+ ? ' (' +
8476
+ this.formatDistance(this.activeRoute.distance) +
8477
+ ' - ' +
8478
+ this.formatDuration(this.activeRoute.duration) +
8479
+ ')'
8480
+ : '';
8281
8481
  }
8282
- onStepsListBlur() {
8283
- this.stepFeatureStore.clear();
8482
+ /**
8483
+ * Formats a step and returns the formatted step.
8484
+ *
8485
+ * @param {IgoStep} step - The step to be formatted.
8486
+ * @param {number} stepIndex - The index of the step in the active route.
8487
+ * @return {FormattedStep} The formatted step.
8488
+ */
8489
+ getFormattedStep(step, stepIndex) {
8490
+ return formatStep(step, this.languageService, stepIndex === this.activeRoute.steps.length - 1);
8284
8491
  }
8285
- showSegment(step, zoomToExtent = false) {
8492
+ /**
8493
+ * Clears the step feature store when the user's mouse leaves the list.
8494
+ */
8495
+ onLeaveList() {
8496
+ this.stepsFeatureStore.clear();
8497
+ }
8498
+ /**
8499
+ * Shows a step on the map and optionally zooming to the step.
8500
+ *
8501
+ * @param {IgoStep} step - The step to be shown.
8502
+ * @param {boolean} [zoomToExtent=false] - Whether to zoom to the extent of the route segment geometry.
8503
+ */
8504
+ showStep(step, zoomToExtent = false) {
8286
8505
  this.showRouteSegmentGeometry(step, zoomToExtent);
8287
8506
  }
8288
8507
  showRouteSegmentGeometry(step, zoomToExtent = false) {
8289
8508
  const coordinates = step.geometry.coordinates;
8290
8509
  const vertexId = 'vertex';
8291
8510
  const geometry4326 = new olgeom.LineString(coordinates);
8292
- const geometryMapProjection = geometry4326.transform('EPSG:4326', this.stepFeatureStore.layer.map.projection);
8511
+ const geometryMapProjection = geometry4326.transform('EPSG:4326', this.stepsFeatureStore.layer.map.projection);
8293
8512
  const routeSegmentCoordinates = geometryMapProjection.getCoordinates();
8294
- const lastPoint = routeSegmentCoordinates[0];
8295
- const geometry = new olgeom.Point(lastPoint);
8296
- const feature = new OlFeature({ geometry });
8297
- const geojsonGeom = new OlGeoJSON().writeGeometryObject(geometry, {
8298
- featureProjection: this.stepFeatureStore.layer.map.projection,
8299
- dataProjection: this.stepFeatureStore.layer.map.projection
8513
+ const lastPointCoordinates = routeSegmentCoordinates[0];
8514
+ const lastPointGeometry = new olgeom.Point(lastPointCoordinates);
8515
+ const lastPointFeature = new OlFeature({
8516
+ geometry: lastPointGeometry
8300
8517
  });
8301
- const previousVertex = this.stepFeatureStore.get(vertexId);
8518
+ const geojsonGeom = new OlGeoJSON().writeGeometryObject(lastPointGeometry, {
8519
+ featureProjection: this.stepsFeatureStore.layer.map.projection,
8520
+ dataProjection: this.stepsFeatureStore.layer.map.projection
8521
+ });
8522
+ const previousVertex = this.stepsFeatureStore.get(vertexId);
8302
8523
  const previousVertexRevision = previousVertex
8303
8524
  ? previousVertex.meta.revision
8304
8525
  : 0;
8305
8526
  const stepFeature = {
8306
8527
  type: FEATURE,
8307
8528
  geometry: geojsonGeom,
8308
- projection: this.stepFeatureStore.layer.map.projection,
8529
+ projection: this.stepsFeatureStore.layer.map.projection,
8309
8530
  properties: {
8310
8531
  id: vertexId,
8311
8532
  step,
8312
- type: DirectionType.Vertex
8533
+ type: DirectionsType.Vertex
8313
8534
  },
8314
8535
  meta: {
8315
8536
  id: vertexId,
8316
8537
  revision: previousVertexRevision + 1
8317
8538
  },
8318
- ol: feature
8539
+ ol: lastPointFeature
8319
8540
  };
8320
- this.stepFeatureStore.update(stepFeature);
8541
+ this.stepsFeatureStore.update(stepFeature);
8321
8542
  if (zoomToExtent) {
8322
- this.stepFeatureStore.layer.map.viewController.zoomToExtent(feature.getGeometry().getExtent());
8543
+ this.stepsFeatureStore.layer.map.viewController.zoomToExtent(lastPointFeature.getGeometry().getExtent());
8323
8544
  }
8324
8545
  }
8325
8546
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsResultsComponent, deps: [{ token: i1$1.LanguageService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
8326
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsResultsComponent, isStandalone: true, selector: "igo-directions-results", inputs: { routesFeatureStore: "routesFeatureStore", stepFeatureStore: "stepFeatureStore" }, ngImport: i0, template: "<div class=\"igo-input-container\" *ngIf=\"directions && activeDirection\">\n <mat-form-field *ngIf=\"directions && directions.length > 1\">\n <mat-label>{{\n 'igo.geo.directionsForm.drivingOptions' | translate\n }}</mat-label>\n <mat-select\n placeholder=\"{{ 'igo.geo.directionsForm.drivingOptions' | translate }}\"\n (selectionChange)=\"changeRoute()\"\n [(ngModel)]=\"activeDirection\"\n >\n <mat-option\n *ngFor=\"let direction of directions; let cnt = index\"\n [value]=\"direction\"\n >\n Option {{ cnt + 1 }} : {{ formatDistance(direction.distance) }} ({{\n formatDuration(direction.duration)\n }})\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <mat-divider *ngIf=\"directions && directions.length === 0\"></mat-divider>\n\n <mat-list (mouseleave)=\"onStepsListBlur()\">\n <h2 mat-header class=\"igo-route-title\">{{ activeDirection.title }}</h2>\n <span class=\"mat-caption\">\n {{ formatDistance(activeDirection.distance) }},\n {{ formatDuration(activeDirection.duration) }}\n </span>\n <mat-list-item\n class=\"igo-steps\"\n (mouseenter)=\"showSegment(step)\"\n (click)=\"showSegment(step, true)\"\n *ngFor=\"let step of activeDirection.steps; let cnt = index\"\n igoListItem\n >\n <mat-icon [ngClass]=\"formatStep(step, cnt).cssClass\" matListItemIcon\n >{{ formatStep(step, cnt).image }}\n </mat-icon>\n\n <span class=\"igo-step-text\">\n {{ cnt + 1 }}. {{ formatStep(step, cnt).instruction }}\n </span>\n <span matListItemMeta>\n {{ formatDistance(step.distance) }}\n </span>\n </mat-list-item>\n\n <mat-divider></mat-divider>\n </mat-list>\n</div>\n", styles: [".igo-input-container{width:100%;padding:20px 10px;box-sizing:border-box}.igo-input-container mat-form-field{width:70%}.igo-route-title{font-weight:700}.igo-steps{cursor:pointer;padding:35px 0}.igo-steps .igo-step-text{overflow-wrap:break-word;word-wrap:break-word;white-space:pre-wrap}.mat-mdc-list-item{word-wrap:break-word!important;white-space:pre-wrap!important}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-45{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.rotate-250{-webkit-transform:rotate(250deg);-moz-transform:rotate(250deg);-ms-transform:rotate(250deg);-o-transform:rotate(250deg);transform:rotate(250deg)}.rotate-290{-webkit-transform:rotate(290deg);-moz-transform:rotate(290deg);-ms-transform:rotate(290deg);-o-transform:rotate(290deg);transform:rotate(290deg)}.icon-flipped{-o-transform:scaleY(-1);-moz-transform:scaleY(-1);-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "component", type: i3$3.MatDivider, selector: "mat-divider", inputs: ["vertical", "inset"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$4.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i1$4.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$4.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i1$4.MatListItemMeta, selector: "[matListItemMeta]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8547
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsResultsComponent, isStandalone: true, selector: "igo-directions-results", inputs: { routesFeatureStore: "routesFeatureStore", stepsFeatureStore: "stepsFeatureStore" }, ngImport: i0, template: "<div class=\"igo-input-container\" *ngIf=\"routes && activeRoute\">\n <mat-form-field *ngIf=\"routes.length > 1\" [matTooltip]=\"activeRoute.title\">\n <mat-label>{{\n 'igo.geo.directions.results.routeOptions' | translate\n }}</mat-label>\n <mat-select\n (selectionChange)=\"chooseRouteOption()\"\n [(ngModel)]=\"activeRoute\"\n >\n <mat-option\n *ngFor=\"let route of routes; let routeIndex = index\"\n [value]=\"route\"\n >\n Option {{ routeIndex + 1 }}: {{ route.title }} ({{\n formatDistance(route.distance)\n }}\n - {{ formatDuration(route.duration) }})\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <h3 mat-header class=\"igo-route-title\">\n {{ activeRoute.title }}\n {{ getTitleDurationAndDistance() }}\n </h3>\n <mat-list (mouseleave)=\"onLeaveList()\">\n <ng-container *ngFor=\"let step of activeRoute.steps; let stepIndex = index\">\n <mat-list-item\n *ngIf=\"\n (formatDistance(step.distance) && formatDuration(step.duration)) ||\n stepIndex === activeRoute.steps.length - 1\n \"\n matListItem\n class=\"igo-steps step\"\n (mouseenter)=\"showStep(step)\"\n (click)=\"showStep(step, true)\"\n >\n <mat-icon\n matListItemIcon\n [matTooltip]=\"\n 'igo.geo.directions.results.stepTitleTooltip' | translate\n \"\n >{{ getFormattedStep(step, stepIndex).iconName }}\n </mat-icon>\n\n <span\n matListItemTitle\n class=\"step-title\"\n [matTooltip]=\"getFormattedStep(step, stepIndex).instruction\"\n >\n {{ getFormattedStep(step, stepIndex).instruction }}\n </span>\n <span\n *ngIf=\"stepIndex !== activeRoute.steps.length - 1\"\n matListItemLine\n >\n {{ formatDistance(step.distance) }} -\n {{ formatDuration(step.duration) }}\n </span>\n </mat-list-item>\n </ng-container>\n </mat-list>\n</div>\n", styles: [".igo-input-container{width:100%;padding:20px 10px;box-sizing:border-box}.igo-input-container mat-form-field{width:100%}.igo-route-title{font-weight:700;margin:0}.step{cursor:pointer}\n"], dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "component", type: i2$2.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i2$2.MatLabel, selector: "mat-label" }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i8.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i6$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: MatOptionModule }, { kind: "ngmodule", type: MatDividerModule }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i3$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i1$4.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i1$4.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i1$4.MatListItemIcon, selector: "[matListItemIcon]" }, { kind: "directive", type: i1$4.MatListItemLine, selector: "[matListItemLine]" }, { kind: "directive", type: i1$4.MatListItemTitle, selector: "[matListItemTitle]" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
8327
8548
  }
8328
8549
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsResultsComponent, decorators: [{
8329
8550
  type: Component,
@@ -8335,15 +8556,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
8335
8556
  NgFor,
8336
8557
  MatOptionModule,
8337
8558
  MatDividerModule,
8559
+ MatTooltipModule,
8338
8560
  MatListModule,
8339
8561
  MatIconModule,
8340
8562
  NgClass,
8341
8563
  IgoLanguageModule
8342
- ], template: "<div class=\"igo-input-container\" *ngIf=\"directions && activeDirection\">\n <mat-form-field *ngIf=\"directions && directions.length > 1\">\n <mat-label>{{\n 'igo.geo.directionsForm.drivingOptions' | translate\n }}</mat-label>\n <mat-select\n placeholder=\"{{ 'igo.geo.directionsForm.drivingOptions' | translate }}\"\n (selectionChange)=\"changeRoute()\"\n [(ngModel)]=\"activeDirection\"\n >\n <mat-option\n *ngFor=\"let direction of directions; let cnt = index\"\n [value]=\"direction\"\n >\n Option {{ cnt + 1 }} : {{ formatDistance(direction.distance) }} ({{\n formatDuration(direction.duration)\n }})\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <mat-divider *ngIf=\"directions && directions.length === 0\"></mat-divider>\n\n <mat-list (mouseleave)=\"onStepsListBlur()\">\n <h2 mat-header class=\"igo-route-title\">{{ activeDirection.title }}</h2>\n <span class=\"mat-caption\">\n {{ formatDistance(activeDirection.distance) }},\n {{ formatDuration(activeDirection.duration) }}\n </span>\n <mat-list-item\n class=\"igo-steps\"\n (mouseenter)=\"showSegment(step)\"\n (click)=\"showSegment(step, true)\"\n *ngFor=\"let step of activeDirection.steps; let cnt = index\"\n igoListItem\n >\n <mat-icon [ngClass]=\"formatStep(step, cnt).cssClass\" matListItemIcon\n >{{ formatStep(step, cnt).image }}\n </mat-icon>\n\n <span class=\"igo-step-text\">\n {{ cnt + 1 }}. {{ formatStep(step, cnt).instruction }}\n </span>\n <span matListItemMeta>\n {{ formatDistance(step.distance) }}\n </span>\n </mat-list-item>\n\n <mat-divider></mat-divider>\n </mat-list>\n</div>\n", styles: [".igo-input-container{width:100%;padding:20px 10px;box-sizing:border-box}.igo-input-container mat-form-field{width:70%}.igo-route-title{font-weight:700}.igo-steps{cursor:pointer;padding:35px 0}.igo-steps .igo-step-text{overflow-wrap:break-word;word-wrap:break-word;white-space:pre-wrap}.mat-mdc-list-item{word-wrap:break-word!important;white-space:pre-wrap!important}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-45{-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.rotate-250{-webkit-transform:rotate(250deg);-moz-transform:rotate(250deg);-ms-transform:rotate(250deg);-o-transform:rotate(250deg);transform:rotate(250deg)}.rotate-290{-webkit-transform:rotate(290deg);-moz-transform:rotate(290deg);-ms-transform:rotate(290deg);-o-transform:rotate(290deg);transform:rotate(290deg)}.icon-flipped{-o-transform:scaleY(-1);-moz-transform:scaleY(-1);-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}\n"] }]
8564
+ ], template: "<div class=\"igo-input-container\" *ngIf=\"routes && activeRoute\">\n <mat-form-field *ngIf=\"routes.length > 1\" [matTooltip]=\"activeRoute.title\">\n <mat-label>{{\n 'igo.geo.directions.results.routeOptions' | translate\n }}</mat-label>\n <mat-select\n (selectionChange)=\"chooseRouteOption()\"\n [(ngModel)]=\"activeRoute\"\n >\n <mat-option\n *ngFor=\"let route of routes; let routeIndex = index\"\n [value]=\"route\"\n >\n Option {{ routeIndex + 1 }}: {{ route.title }} ({{\n formatDistance(route.distance)\n }}\n - {{ formatDuration(route.duration) }})\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <h3 mat-header class=\"igo-route-title\">\n {{ activeRoute.title }}\n {{ getTitleDurationAndDistance() }}\n </h3>\n <mat-list (mouseleave)=\"onLeaveList()\">\n <ng-container *ngFor=\"let step of activeRoute.steps; let stepIndex = index\">\n <mat-list-item\n *ngIf=\"\n (formatDistance(step.distance) && formatDuration(step.duration)) ||\n stepIndex === activeRoute.steps.length - 1\n \"\n matListItem\n class=\"igo-steps step\"\n (mouseenter)=\"showStep(step)\"\n (click)=\"showStep(step, true)\"\n >\n <mat-icon\n matListItemIcon\n [matTooltip]=\"\n 'igo.geo.directions.results.stepTitleTooltip' | translate\n \"\n >{{ getFormattedStep(step, stepIndex).iconName }}\n </mat-icon>\n\n <span\n matListItemTitle\n class=\"step-title\"\n [matTooltip]=\"getFormattedStep(step, stepIndex).instruction\"\n >\n {{ getFormattedStep(step, stepIndex).instruction }}\n </span>\n <span\n *ngIf=\"stepIndex !== activeRoute.steps.length - 1\"\n matListItemLine\n >\n {{ formatDistance(step.distance) }} -\n {{ formatDuration(step.duration) }}\n </span>\n </mat-list-item>\n </ng-container>\n </mat-list>\n</div>\n", styles: [".igo-input-container{width:100%;padding:20px 10px;box-sizing:border-box}.igo-input-container mat-form-field{width:100%}.igo-route-title{font-weight:700;margin:0}.step{cursor:pointer}\n"] }]
8343
8565
  }], ctorParameters: () => [{ type: i1$1.LanguageService }, { type: i0.ChangeDetectorRef }], propDecorators: { routesFeatureStore: [{
8344
- type: Input
8345
- }], stepFeatureStore: [{
8346
- type: Input
8566
+ type: Input,
8567
+ args: [{ required: true }]
8568
+ }], stepsFeatureStore: [{
8569
+ type: Input,
8570
+ args: [{ required: true }]
8347
8571
  }] } });
8348
8572
 
8349
8573
  const EYE_CLOSE_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>eye-closed</title><path d="M12 17.5C8.2 17.5 4.8 15.4 3.2 12H1C2.7 16.4 7 19.5 12 19.5S21.3 16.4 23 12H20.8C19.2 15.4 15.8 17.5 12 17.5Z" /></svg>`;
@@ -17138,7 +17362,7 @@ class DirectionsComponent {
17138
17362
  projection = 'EPSG:4326';
17139
17363
  hasOsrmPrivateAccess = false;
17140
17364
  twoSourcesAvailable = false;
17141
- zoomRoute$$;
17365
+ zoomOnActiveRoute$$;
17142
17366
  storeEmpty$$;
17143
17367
  storeChange$$;
17144
17368
  routesQueries$$ = [];
@@ -17154,11 +17378,11 @@ class DirectionsComponent {
17154
17378
  stopsStore;
17155
17379
  stopsFeatureStore;
17156
17380
  routesFeatureStore;
17157
- stepFeatureStore;
17381
+ stepsFeatureStore;
17158
17382
  debounce = 200;
17159
17383
  length = 2;
17160
17384
  coordRoundedDecimals = 6;
17161
- zoomToActiveRoute$ = new Subject();
17385
+ zoomOnActiveRoute$ = new Subject();
17162
17386
  authenticated$;
17163
17387
  /**
17164
17388
  * Wheter one of the direction control is active
@@ -17207,7 +17431,7 @@ class DirectionsComponent {
17207
17431
  setTimeout(() => {
17208
17432
  initStopsFeatureStore(this.stopsFeatureStore, this.languageService);
17209
17433
  initRoutesFeatureStore(this.routesFeatureStore, this.languageService);
17210
- initStepFeatureStore(this.stepFeatureStore);
17434
+ initStepsFeatureStore(this.stepsFeatureStore);
17211
17435
  this.initOlInteraction();
17212
17436
  }, 1);
17213
17437
  }
@@ -17216,7 +17440,7 @@ class DirectionsComponent {
17216
17440
  this.storeEmpty$$.unsubscribe();
17217
17441
  this.storeChange$$.unsubscribe();
17218
17442
  this.routesQueries$$.map((u) => u.unsubscribe());
17219
- this.zoomRoute$$.unsubscribe();
17443
+ this.zoomOnActiveRoute$$.unsubscribe();
17220
17444
  this.authenticated$$.unsubscribe();
17221
17445
  this.freezeStores();
17222
17446
  if (this.stopsFeatureStore.empty) {
@@ -17230,7 +17454,7 @@ class DirectionsComponent {
17230
17454
  this.interactions.map((interaction) => this.routesFeatureStore.layer.map.ol.removeInteraction(interaction));
17231
17455
  this.stopsFeatureStore.deactivateStrategyOfType(FeatureStoreLoadingStrategy);
17232
17456
  this.routesFeatureStore.deactivateStrategyOfType(FeatureStoreLoadingStrategy);
17233
- this.stepFeatureStore.deactivateStrategyOfType(FeatureStoreLoadingStrategy);
17457
+ this.stepsFeatureStore.deactivateStrategyOfType(FeatureStoreLoadingStrategy);
17234
17458
  }
17235
17459
  initEntityStores() {
17236
17460
  this.watcher = new EntityStoreWatcher(this.stopsStore, this.cdRef);
@@ -17239,14 +17463,26 @@ class DirectionsComponent {
17239
17463
  this.monitorActiveRouteZoom();
17240
17464
  }
17241
17465
  monitorActiveRouteZoom() {
17242
- this.zoomRoute$$ = this.zoomToActiveRoute$.subscribe(() => {
17466
+ this.zoomOnActiveRoute$$ = this.zoomOnActiveRoute$.subscribe(() => {
17243
17467
  if (this.routesFeatureStore.count >= 1) {
17244
17468
  const activeRoute = this.routesFeatureStore
17245
17469
  .all()
17246
17470
  .find((route) => route.properties.active);
17247
17471
  if (activeRoute) {
17248
- activeRoute.ol.getGeometry();
17249
- const routeExtent = activeRoute.ol.getGeometry().getExtent();
17472
+ const stopsCoordinates = this.stopsStore
17473
+ .all()
17474
+ .map((stop) => olproj.transform(stop.coordinates, 'EPSG:4326', 'EPSG:3857'));
17475
+ const routeCoordinates = activeRoute.geometry.coordinates;
17476
+ const coordinates = [
17477
+ ...stopsCoordinates,
17478
+ ...routeCoordinates
17479
+ ];
17480
+ const routeExtent = coordinates.reduce(([x_min, y_min, x_max, y_max], [x, y]) => [
17481
+ Math.min(x_min, x),
17482
+ Math.min(y_min, y),
17483
+ Math.max(x_max, x),
17484
+ Math.max(y_max, y)
17485
+ ], [Infinity, Infinity, -Infinity, -Infinity]);
17250
17486
  this.routesFeatureStore.layer.map.viewController.zoomToExtent(routeExtent);
17251
17487
  }
17252
17488
  }
@@ -17276,16 +17512,16 @@ class DirectionsComponent {
17276
17512
  condition: olCondition.click,
17277
17513
  hitTolerance: 7,
17278
17514
  filter: (feature) => {
17279
- return (feature.get('type') === DirectionType.Route &&
17515
+ return (feature.get('type') === DirectionsType.Route &&
17280
17516
  feature.get('active') &&
17281
17517
  !this.isTranslating);
17282
17518
  }
17283
17519
  });
17284
17520
  this.selectedRoute.on('select', (evt) => {
17285
17521
  if (this.focusOnStop === false) {
17286
- const selectCoordinates = roundCoordTo(olproj.transform(evt.mapBrowserEvent.coordinate, this.routesFeatureStore.layer.map.projection, this.projection), this.coordRoundedDecimals);
17522
+ const selectCoordinates = olproj.transform(evt.mapBrowserEvent.coordinate, this.routesFeatureStore.layer.map.projection, this.projection);
17287
17523
  const addedStop = addStopToStore(this.stopsStore);
17288
- addedStop.text = selectCoordinates.join(',');
17524
+ addedStop.text = roundCoordToString(selectCoordinates, this.coordRoundedDecimals).join(', ');
17289
17525
  addedStop.coordinates = [selectCoordinates[0], selectCoordinates[1]];
17290
17526
  }
17291
17527
  });
@@ -17306,7 +17542,7 @@ class DirectionsComponent {
17306
17542
  const translatedStop = this.stopsStore.get(translatedStopId);
17307
17543
  const roundedCoord = roundCoordTo(translationCoordinates, this.coordRoundedDecimals);
17308
17544
  translatedStop.coordinates = roundedCoord;
17309
- translatedStop.text = roundedCoord.join(',');
17545
+ translatedStop.text = roundCoordToString(translationCoordinates, this.coordRoundedDecimals).join(', ');
17310
17546
  this.stopsStore.update(translatedStop);
17311
17547
  }
17312
17548
  monitorEmptyEntityStore() {
@@ -17447,12 +17683,12 @@ class DirectionsComponent {
17447
17683
  if (routeResponse) {
17448
17684
  this.routesQueries$$.push(routeResponse.subscribe((directions) => {
17449
17685
  this.routesFeatureStore.deleteMany(this.routesFeatureStore.all());
17450
- directions.map((direction) => addDirectionToRoutesFeatureStore(this.routesFeatureStore, direction, this.projection, direction === directions[0] ? true : false));
17686
+ directions.map((direction) => addRouteToRoutesFeatureStore(this.routesFeatureStore, direction, this.projection, direction === directions[0] ? true : false));
17451
17687
  }));
17452
17688
  }
17453
17689
  }
17454
17690
  addStopOverlay(stop) {
17455
- addStopToStopsFeatureStore(stop, this.stopsStore, this.stopsFeatureStore, this.projection, this.languageService);
17691
+ addStopToStopsFeatureStore(stop, this.stopsFeatureStore, this.projection, this.languageService);
17456
17692
  }
17457
17693
  onToggleDirectionsControl(isActive) {
17458
17694
  this.queryService.queryEnabled = !isActive;
@@ -17465,7 +17701,7 @@ class DirectionsComponent {
17465
17701
  this.directionsSourceService.sources[0].profiles.forEach((profile) => (profile.enabled = false));
17466
17702
  if (isActive) {
17467
17703
  this.directionsSourceService.sources[0].profiles.find((profile) => profile.authorization).enabled = true;
17468
- this.messageService.alert(this.languageService.translate.instant('igo.geo.directionsForm.forestRoadsWarning.text'), this.languageService.translate.instant('igo.geo.directionsForm.forestRoadsWarning.title'));
17704
+ this.messageService.alert(this.languageService.translate.instant('igo.geo.directions.forestRoadsWarning.text'), this.languageService.translate.instant('igo.geo.directions.forestRoadsWarning.title'));
17469
17705
  }
17470
17706
  else {
17471
17707
  this.directionsSourceService.sources[0].profiles.find((profile) => !profile.authorization).enabled = true;
@@ -17473,7 +17709,7 @@ class DirectionsComponent {
17473
17709
  this.getRoutes();
17474
17710
  }
17475
17711
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.HttpClient }, { token: i1$1.LanguageService }, { token: DirectionsService }, { token: DirectionsSourceService }, { token: SearchService }, { token: QueryService }, { token: i2.MessageService }], target: i0.ɵɵFactoryTarget.Component });
17476
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsComponent, isStandalone: true, selector: "igo-directions", inputs: { contextUri: "contextUri", stopsStore: "stopsStore", stopsFeatureStore: "stopsFeatureStore", routesFeatureStore: "routesFeatureStore", stepFeatureStore: "stepFeatureStore", debounce: "debounce", length: "length", coordRoundedDecimals: "coordRoundedDecimals", zoomToActiveRoute$: "zoomToActiveRoute$", authenticated$: "authenticated$" }, ngImport: i0, template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directionsForm.toggleActive' | translate }}\n </mat-slide-toggle>\n <mat-slide-toggle\n *ngIf=\"hasOsrmPrivateAccess && twoSourcesAvailable\"\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directionsForm.toggleType' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-buttons\n [stepFeatureStore]=\"stepFeatureStore\"\n [contextUri]=\"contextUri\"\n [zoomToActiveRoute$]=\"zoomToActiveRoute$\"\n [routesFeatureStore]=\"routesFeatureStore\"\n [stopsStore]=\"stopsStore\"\n></igo-directions-buttons>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore\"\n [stopsStore]=\"stopsStore\"\n [debounce]=\"debounce\"\n [length]=\"length\"\n></igo-directions-inputs>\n\n<igo-directions-results\n [stepFeatureStore]=\"stepFeatureStore\"\n [routesFeatureStore]=\"routesFeatureStore\"\n></igo-directions-results>\n", styles: [".directions-options mat-slide-toggle{width:100%;padding:10px}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;width:calc(100% - 60px)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i5$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: DirectionsButtonsComponent, selector: "igo-directions-buttons", inputs: ["contextUri", "zoomToActiveRoute$", "stopsStore", "routesFeatureStore", "stepFeatureStore"] }, { kind: "component", type: DirectionsInputsComponent, selector: "igo-directions-inputs", inputs: ["stopsStore", "stopsFeatureStore", "projection", "coordRoundedDecimals", "debounce", "length"], outputs: ["stopInputHasFocus"] }, { kind: "component", type: DirectionsResultsComponent, selector: "igo-directions-results", inputs: ["routesFeatureStore", "stepFeatureStore"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
17712
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DirectionsComponent, isStandalone: true, selector: "igo-directions", inputs: { contextUri: "contextUri", stopsStore: "stopsStore", stopsFeatureStore: "stopsFeatureStore", routesFeatureStore: "routesFeatureStore", stepsFeatureStore: "stepsFeatureStore", debounce: "debounce", length: "length", coordRoundedDecimals: "coordRoundedDecimals", zoomOnActiveRoute$: "zoomOnActiveRoute$", authenticated$: "authenticated$" }, ngImport: i0, template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n <mat-slide-toggle\n *ngIf=\"hasOsrmPrivateAccess && twoSourcesAvailable\"\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.type' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore\"\n [stopsStore]=\"stopsStore\"\n [debounce]=\"debounce\"\n [length]=\"length\"\n></igo-directions-inputs>\n\n<igo-directions-buttons\n *ngIf=\"routesFeatureStore.all().length > 0\"\n [stepsFeatureStore]=\"stepsFeatureStore\"\n [contextUri]=\"contextUri\"\n [zoomOnActiveRoute$]=\"zoomOnActiveRoute$\"\n [routesFeatureStore]=\"routesFeatureStore\"\n [stopsStore]=\"stopsStore\"\n></igo-directions-buttons>\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore\"\n [routesFeatureStore]=\"routesFeatureStore\"\n></igo-directions-results>\n", styles: [".directions-options{display:flex;flex-flow:column;align-items:center;margin:0 12px}.directions-options mat-slide-toggle{width:100%;padding:10px}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i8$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: MatSlideToggleModule }, { kind: "component", type: i5$1.MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "component", type: DirectionsButtonsComponent, selector: "igo-directions-buttons", inputs: ["contextUri", "zoomOnActiveRoute$", "stopsStore", "routesFeatureStore", "stepsFeatureStore"] }, { kind: "component", type: DirectionsInputsComponent, selector: "igo-directions-inputs", inputs: ["stopsStore", "stopsFeatureStore", "projection", "coordRoundedDecimals", "debounce", "length"], outputs: ["stopInputHasFocus"] }, { kind: "component", type: DirectionsResultsComponent, selector: "igo-directions-results", inputs: ["routesFeatureStore", "stepsFeatureStore"] }, { kind: "ngmodule", type: IgoLanguageModule }, { kind: "pipe", type: i5.TranslatePipe, name: "translate" }] });
17477
17713
  }
17478
17714
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DirectionsComponent, decorators: [{
17479
17715
  type: Component,
@@ -17484,27 +17720,33 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
17484
17720
  DirectionsInputsComponent,
17485
17721
  DirectionsResultsComponent,
17486
17722
  IgoLanguageModule
17487
- ], template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directionsForm.toggleActive' | translate }}\n </mat-slide-toggle>\n <mat-slide-toggle\n *ngIf=\"hasOsrmPrivateAccess && twoSourcesAvailable\"\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directionsForm.toggleType' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-buttons\n [stepFeatureStore]=\"stepFeatureStore\"\n [contextUri]=\"contextUri\"\n [zoomToActiveRoute$]=\"zoomToActiveRoute$\"\n [routesFeatureStore]=\"routesFeatureStore\"\n [stopsStore]=\"stopsStore\"\n></igo-directions-buttons>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore\"\n [stopsStore]=\"stopsStore\"\n [debounce]=\"debounce\"\n [length]=\"length\"\n></igo-directions-inputs>\n\n<igo-directions-results\n [stepFeatureStore]=\"stepFeatureStore\"\n [routesFeatureStore]=\"routesFeatureStore\"\n></igo-directions-results>\n", styles: [".directions-options mat-slide-toggle{width:100%;padding:10px}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;width:calc(100% - 60px)}\n"] }]
17723
+ ], template: "<div class=\"directions-options\">\n <mat-slide-toggle\n [checked]=\"directionControlIsActive\"\n [labelPosition]=\"'before'\"\n (change)=\"onToggleDirectionsControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.activateControl' | translate }}\n </mat-slide-toggle>\n <mat-slide-toggle\n *ngIf=\"hasOsrmPrivateAccess && twoSourcesAvailable\"\n [checked]=\"enabledProfileHasAuthorization\"\n [labelPosition]=\"'before'\"\n (change)=\"onTogglePrivateModeControl($event.checked)\"\n >\n {{ 'igo.geo.directions.toggle.type' | translate }}\n </mat-slide-toggle>\n</div>\n\n<igo-directions-inputs\n (stopInputHasFocus)=\"onStopInputHasFocusChange($event)\"\n [coordRoundedDecimals]=\"coordRoundedDecimals\"\n [projection]=\"projection\"\n [stopsFeatureStore]=\"stopsFeatureStore\"\n [stopsStore]=\"stopsStore\"\n [debounce]=\"debounce\"\n [length]=\"length\"\n></igo-directions-inputs>\n\n<igo-directions-buttons\n *ngIf=\"routesFeatureStore.all().length > 0\"\n [stepsFeatureStore]=\"stepsFeatureStore\"\n [contextUri]=\"contextUri\"\n [zoomOnActiveRoute$]=\"zoomOnActiveRoute$\"\n [routesFeatureStore]=\"routesFeatureStore\"\n [stopsStore]=\"stopsStore\"\n></igo-directions-buttons>\n\n<igo-directions-results\n [stepsFeatureStore]=\"stepsFeatureStore\"\n [routesFeatureStore]=\"routesFeatureStore\"\n></igo-directions-results>\n", styles: [".directions-options{display:flex;flex-flow:column;align-items:center;margin:0 12px}.directions-options mat-slide-toggle{width:100%;padding:10px}.directions-options mat-slide-toggle ::ng-deep .mdc-form-field{width:100%}.directions-options mat-slide-toggle ::ng-deep .mdc-label{margin-left:0;margin-right:auto;width:auto;padding-right:0}.directions-options mat-slide-toggle ::ng-deep .mdc-slide-toggle{margin-left:auto;margin-right:0}\n"] }]
17488
17724
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.HttpClient }, { type: i1$1.LanguageService }, { type: DirectionsService }, { type: DirectionsSourceService }, { type: SearchService }, { type: QueryService }, { type: i2.MessageService }], propDecorators: { contextUri: [{
17489
17725
  type: Input
17490
17726
  }], stopsStore: [{
17491
- type: Input
17727
+ type: Input,
17728
+ args: [{ required: true }]
17492
17729
  }], stopsFeatureStore: [{
17493
- type: Input
17730
+ type: Input,
17731
+ args: [{ required: true }]
17494
17732
  }], routesFeatureStore: [{
17495
- type: Input
17496
- }], stepFeatureStore: [{
17497
- type: Input
17733
+ type: Input,
17734
+ args: [{ required: true }]
17735
+ }], stepsFeatureStore: [{
17736
+ type: Input,
17737
+ args: [{ required: true }]
17498
17738
  }], debounce: [{
17499
17739
  type: Input
17500
17740
  }], length: [{
17501
17741
  type: Input
17502
17742
  }], coordRoundedDecimals: [{
17503
17743
  type: Input
17504
- }], zoomToActiveRoute$: [{
17505
- type: Input
17744
+ }], zoomOnActiveRoute$: [{
17745
+ type: Input,
17746
+ args: [{ required: true }]
17506
17747
  }], authenticated$: [{
17507
- type: Input
17748
+ type: Input,
17749
+ args: [{ required: true }]
17508
17750
  }] } });
17509
17751
 
17510
17752
  class IgoDirectionsModule {
@@ -42422,5 +42664,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
42422
42664
  * Generated bundle index. Do not edit.
42423
42665
  */
42424
42666
 
42425
- export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibaryComponent, CatalogService, ClusterDataSource, ConfigFileToGeoDBService, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionType, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EsriStyleGenerator, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoDBService, GeoNetworkService, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleListModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InsertSourceInsertDBEnum, LAYER, LAYER_DIRECTIVES, LabelType, Layer, LayerBase, LayerController, LayerDBService, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NominatimSearchSource, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, ResponseType, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STYLELIST_OPTIONS, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleListService, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, ToastComponent, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addDirectionToRoutesFeatureStore, addLayerAndFeaturesStyledToMap, addLayerAndFeaturesToMap, addLinearRingToOlPolygon, addOrRemoveLayer, addStopToStopsFeatureStore, addStopToStore, buildUrl, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeMVTOptionsOnHover, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createOverlayDefaultStyle, createOverlayLayer, createOverlayLayerStyle, createOverlayMarkerStyle, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, entitiesToRowData, exportToCSV, featureFromOl, featureRandomStyle, featureRandomStyleFunction, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, formatDistance, formatDuration, formatInstruction, formatMeasure, formatScale, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getCommonVectorSelectedStyle, getCommonVectorStyle, getFileExtension, getFormatFromOptions, getGeoServiceAction, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, hoverFeatureMarkerStyle, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepFeatureStore, initStopsFeatureStore, isBaseLayer, isBaseLayerLinked, isCsvExport, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, olStyleToBasicIgoStyle, optionsApiFactory, osrmDirectionsSourcesFactory, pointerPositionSummaryMarkerStyle, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideNominatimSearchSource, provideOffline, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyleListLoader, provideStyleListOptions, provideWorkspaceSearchSource, querySearchSourceFactory, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, styleListFactory, translateBearing, translateModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withIChercheReverseSource, withIChercheSource, withILayerSource, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
42667
+ export { AddCatalogDialogComponent, ArcGISRestCapabilitiesLayerTypes, ArcGISRestDataSource, BaseLayersSwitcherComponent, CATALOG_DIRECTIVES, CATALOG_LIBRARY_DIRECTIVES, CadastreSearchSource, CapabilitiesService, CartoDataSource, Catalog, CatalogBrowserComponent, CatalogItemType, CatalogLibaryComponent, CatalogService, ClusterDataSource, ConfigFileToGeoDBService, ConfirmationPopupComponent, CoordinatesReverseSearchSource, CoordinatesReverseSearchSourceFactory, CoordinatesSearchResultFormatter, CoordinatesUnit, CsvSeparator, DDtoDMS, DataService, DataSource, DataSourceService, DirectionRelativePositionType, DirectionSourceKind, DirectionsButtonsComponent, DirectionsComponent, DirectionsFormat, DirectionsInputsComponent, DirectionsResultsComponent, DirectionsService, DirectionsSource, DirectionsType, DownloadButtonComponent, DownloadService, DrawComponent, DrawControl, DrawIconService, DrawStyleService, DropGeoFileDirective, EditionWorkspace, EditionWorkspaceService, EsriStyleGenerator, ExportButtonComponent, ExportError, ExportFormat, ExportFormatLegacy, ExportInvalidFileError, ExportNothingToExportError, ExportService, FEATURE, FEATURE_DETAILS_DIRECTIVES, FEATURE_DIRECTIVES, FILTER_DIRECTIVES, FeatureDataSource, FeatureDetailsComponent, FeatureDetailsDirective, FeatureFormComponent, FeatureMotion, FeatureStore, FeatureStoreInMapExtentStrategy, FeatureStoreInMapResolutionStrategy, FeatureStoreLoadingLayerStrategy, FeatureStoreLoadingStrategy, FeatureStoreSearchIndexStrategy, FeatureStoreSelectionStrategy, FeatureWorkspace, FeatureWorkspaceService, FilterableDataSourcePipe, GEOMETRY_FORM_FIELD_DIRECTIVES, GeoDBService, GeoNetworkService, GeoPropertiesStrategy, GeolocateButtonComponent, GeolocationOverlayType, GeometryFormFieldComponent, GeometryFormFieldInputComponent, GeometrySliceError, GeometrySliceLineStringError, GeometrySliceMultiPolygonError, GeometrySliceTooManyIntersectionError, GeometryType, GoogleLinks, HomeExtentButtonComponent, HoverFeatureDirective, IChercheReverseSearchSource, IChercheSearchResultFormatter, IChercheSearchSource, ILayerSearchResultFormatter, ILayerSearchSource, IMPORT_EXPORT_DIRECTIVES, IgoCatalogBrowserModule, IgoCatalogLibraryModule, IgoCatalogModule, IgoConfirmationPopupModule, IgoDirectionsModule, IgoDownloadModule, IgoDrawModule, IgoDrawingToolModule, IgoFeatureDetailsModule, IgoFeatureFormModule, IgoFeatureModule, IgoFilterModule, IgoGeoModule, IgoGeoWorkspaceModule, IgoGeometryFormFieldModule, IgoGeometryModule, IgoHttpParameterCodec, IgoImportExportModule, IgoLayerModule, IgoMap, IgoMapModule, IgoMeasureModule, IgoMeasurerModule, IgoMetadataModule, IgoOgcFilterModule, IgoPrintModule, IgoQueryModule, IgoSearchBarModule, IgoSearchModule, IgoSearchResultsModule, IgoSearchSelectorModule, IgoSearchSettingsModule, IgoStyleListModule, IgoStyleModule, IgoToastModule, IgoWktModule, IgoWorkspaceSelectorModule, IgoWorkspaceUpdatorModule, ImageArcGISRestDataSource, ImageLayer, ImageWatcher, ImportError, ImportExportComponent, ImportInvalidFileError, ImportNothingToImportError, ImportOgreServerError, ImportSRSError, ImportService, ImportSizeError, ImportUnreadableFileError, InfoSectionComponent, InsertSourceInsertDBEnum, LAYER, LAYER_DIRECTIVES, LabelType, LaneType, Layer, LayerBase, LayerController, LayerDBService, LayerGroup, LayerGroupBase, LayerGroupComponent, LayerItemComponent, LayerLegendComponent, LayerLegendItemComponent, LayerLegendListBindingDirective, LayerLegendListComponent, LayerListComponent, LayerListControlsEnum, LayerListToolComponent, LayerListToolService, LayerSearchComponent, LayerService, LayerUnavailableComponent, LayerUnavailableListComponent, LayerViewerBottomActionsComponent, LayerViewerComponent, LayerVisibilityButtonComponent, Linked, LinkedProperties, MAP_DIRECTIVES, MEASURER_DIRECTIVES, MEASURE_UNIT_AUTO, METADATA_DIRECTIVES, MVTDataSource, ManeuverModifier, ManeuverType, MapBase, MapBrowserComponent, MapCenterComponent, MapController, MapGeolocationController, MapOfflineDirective, MapService, MapViewAction, MapViewController, MeasureAreaUnit, MeasureAreaUnitAbbreviation, MeasureFormatPipe, MeasureLengthUnit, MeasureLengthUnitAbbreviation, MeasureType, MeasurerComponent, MenuButtonComponent, MetadataAbstractComponent, MetadataButtonComponent, MetadataService, MiniBaseMapComponent, ModifyControl, NominatimSearchSource, OGCFilterService, OSMDataSource, OfflineButtonComponent, OgcFilterButtonComponent, OgcFilterComponent, OgcFilterFormComponent, OgcFilterOperator, OgcFilterOperatorType, OgcFilterSelectionComponent, OgcFilterTimeComponent, OgcFilterTimeSliderComponent, OgcFilterWidget, OgcFilterWriter, OgcFilterableFormComponent, OgcFilterableItemComponent, OgcFilterableListBindingDirective, OgcFilterableListComponent, OlDragSelectInteraction, OptionsApiService, OptionsService, OsmLinks, OsrmDirectionsSource, Overlay, OverlayAction, PointerPositionDirective, PrintComponent, PrintFormComponent, PrintLegendPosition, PrintOrientation, PrintOutputFormat, PrintPaperFormat, PrintResolution, PrintSaveImageFormat, PrintService, ProjectionService, PropertyTypeDetectorService, ProposalType, QueryDirective, QueryFormat, QueryFormatMimeType, QueryHtmlTarget, QuerySearchSource, QueryService, ResponseType, RotationButtonComponent, RoutesFeatureStore, SEARCH_DIRECTIVES, SEARCH_RESULTS_DIRECTIVES, SEARCH_TYPES, STYLELIST_OPTIONS, SearchBarComponent, SearchPointerSummaryDirective, SearchResultAddButtonComponent, SearchResultMode, SearchResultsComponent, SearchSelectorComponent, SearchService, SearchSettingsComponent, SearchSource, SearchSourceKind, SearchSourceService, SliceControl, SourceDirectionsType, SpatialFilterItemComponent, SpatialFilterItemType, SpatialFilterListComponent, SpatialFilterQueryType, SpatialFilterService, SpatialFilterType, SpatialFilterTypeComponent, StepsFeatureStore, StopsFeatureStore, StopsStore, StoredQueriesReverseSearchSource, StoredQueriesSearchSource, StyleListService, StyleModalDrawingComponent, StyleModalLayerButtonComponent, StyleModalLayerComponent, StyleService, SwipeControlComponent, TileArcGISRestDataSource, TileDebugDataSource, TileLayer, TileWatcher, TimeFilterButtonComponent, TimeFilterFormComponent, TimeFilterItemComponent, TimeFilterListBindingDirective, TimeFilterListComponent, TimeFilterService, TimeFilterStyle, TimeFilterType, ToastComponent, TooltipType, TrackFeatureButtonComponent, TypeCapabilities, TypeCatalog, VectorLayer, VectorTileLayer, VectorWatcher, WFSDataSource, WFSService, WMSDataSource, WMTSDataSource, WakeLockButtonComponent, WebSocketDataSource, WfsWorkspace, WfsWorkspaceService, WktService, WorkspaceSearchSource, WorkspaceSelectorDirective, WorkspaceUpdatorDirective, XYZDataSource, ZoomButtonComponent, addLayerAndFeaturesStyledToMap, addLayerAndFeaturesToMap, addLinearRingToOlPolygon, addOrRemoveLayer, addRouteToRoutesFeatureStore, addStopToStopsFeatureStore, addStopToStore, buildUrl, cadastreSearchSourceFactory, checkWfsParams, clearOlGeometryMidpoints, computeBestAreaUnit, computeBestLengthUnit, computeLayerTitleFromFile, computeMVTOptionsOnHover, computeOlFeatureExtent, computeOlFeaturesDiff, computeOlFeaturesExtent, computeProjectionsConstraints, computeRelativePosition, computeStopsPosition, computeTermSimilarity, convertDDToDMS, createDefaultTileGrid, createDrawHoleInteractionStyle, createDrawInteractionStyle, createFilterInMapExtentOrResolutionStrategy, createInteractionStyle, createMeasureInteractionStyle, createMeasureLayerStyle, createOlTooltipAtPoint, createOlTooltipDrawAtPoint, createOverlayDefaultStyle, createOverlayLayer, createOverlayLayerStyle, createOverlayMarkerStyle, createTableTemplate, ctrlKeyDown, defaultCoordinatesSearchResultFormatterFactory, defaultEpsg, defaultFieldNameGeometry, defaultIChercheSearchResultFormatterFactory, defaultMaxFeatures, defaultWfsVersion, detectFileEPSG, directionsStyle, entitiesToRowData, exportToCSV, featureFromOl, featureRandomStyle, featureRandomStyleFunction, featureToOl, featureToSearchResult, featuresAreOutOfView, featuresAreTooDeepInView, findDiff, findLayerByLinkId, formatDistance, formatDuration, formatMeasure, formatScale, formatStep, formatWFSQueryString, generateArcgisRestIdFromSourceOptions, generateFeatureIdFromSourceOptions, generateId, generateIdFromSourceOptions, generateWMSIdFromSourceOptions, generateWMTSIdFromSourceOptions, generateWfsIdFromSourceOptions, generateXYZIdFromSourceOptions, getAllChildLayersByDeletion, getAllChildLayersByProperty, getCommonVectorSelectedStyle, getCommonVectorStyle, getFileExtension, getFormatFromOptions, getGeoServiceAction, getLayersByDeletion, getLayersLegends, getLinkedLayersOptions, getMousePositionFromOlGeometryEvent, getOlTooltipAtCenter, getOlTooltipsAtMidpoints, getResolutionFromScale, getRootParentByDeletion, getRootParentByProperty, getRowsInMapExtent, getScaleFromResolution, getSelectedOnly, getTooltipsOfOlGeometry, gmlRegex, handleFileExportError, handleFileExportSuccess, handleFileImportError, handleFileImportSuccess, handleInvalidFileImportError, handleLayerPropertyChange, handleNothingToExportError, handleNothingToImportError, handleOgreServerImportError, handleSRSImportError, handleSizeFileImportError, handleUnreadbleFileImportError, hideOlFeature, hoverFeatureMarkerStyle, ichercheReverseSearchSourceFactory, ichercheSearchSourceFactory, ilayerSearchResultFormatterFactory, ilayerSearchSourceFactory, initRoutesFeatureStore, initStepsFeatureStore, initStopsFeatureStore, isBaseLayer, isBaseLayerLinked, isCsvExport, isLayerGroup, isLayerGroupOptions, isLayerItem, isLayerItemOptions, isLayerLinked, isLayerLinkedOptions, isLayerLinkedTogether, isLinkMaster, isSaveableLayer, jsonRegex, layerFeatureIsQueryable, layerIsQueryable, lonLatConversion, mapExtentStrategyActiveToolTip, measureOlGeometry, measureOlGeometryArea, measureOlGeometryLength, metersToFeet, metersToKilometers, metersToMiles, metersToUnit, moveToOlFeatures, mtmZoneFromLonLat, noElementSelected, nominatimSearchSourceFactory, ogcFilterWidgetFactory, olLayerFeatureIsQueryable, olLayerIsQueryable, olStyleToBasicIgoStyle, optionsApiFactory, osrmDirectionsSourcesFactory, pointerPositionSummaryMarkerStyle, provideCadastreSearchSource, provideCoordinatesReverseSearchSource, provideDefaultCoordinatesSearchResultFormatter, provideDefaultIChercheSearchResultFormatter, provideDirection, provideIChercheReverseSearchSource, provideIChercheSearchSource, provideILayerSearchResultFormatter, provideILayerSearchSource, provideNominatimSearchSource, provideOffline, provideOgcFilterWidget, provideOptionsApi, provideOsrmDirectionsSource, provideQuerySearchSource, provideSearch, provideSearchSourceService, provideStoredQueriesReverseSearchSource, provideStoredQueriesSearchSource, provideStyleListLoader, provideStyleListOptions, provideWorkspaceSearchSource, querySearchSourceFactory, removeStopFromStore, renderFeatureFromOl, roundCoordTo, roundCoordToString, scaleExtent, searchSourceServiceFactory, setRowsInMapExtent, setSelectedOnly, sliceOlGeometry, sliceOlPolygon, sortLayersByZindex, sourceCanReverseSearch, sourceCanReverseSearchAsSummary, sourceCanSearch, squareMetersToAcres, squareMetersToHectares, squareMetersToSquareFeet, squareMetersToSquareKilometers, squareMetersToSquareMiles, squareMetersToUnit, standardizeUrl, storedqueriesReverseSearchSourceFactory, storedqueriesSearchSourceFactory, stringToLonLat, styleListFactory, translateManeuverBearing, translateManeuverModifier, tryAddLoadingStrategy, tryAddSelectionStrategy, tryBindStoreLayer, updateOlGeometryCenter, updateOlGeometryMidpoints, updateOlTooltipAtCenter, updateOlTooltipDrawAtCenter, updateOlTooltipsAtMidpoints, updateOlTooltipsDrawAtMidpoints, updateStoreSorting, utmZoneFromLonLat, viewStatesAreEqual, withCadastreSource, withCoordinatesReverseSource, withIChercheReverseSource, withIChercheSource, withILayerSource, withNominatimSource, withOsrmSource, withStoredQueriesReverseSource, withStoredQueriesSource, withWorkspaceSource, workspaceSearchSourceFactory, zoneMtm, zoneUtm };
42426
42668
  //# sourceMappingURL=igo2-geo.mjs.map