openskidata-format 8.0.0 → 9.0.0

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.
@@ -29,6 +29,7 @@ type PitchData = {
29
29
  maxPitchInPercent: number | null;
30
30
  inclinedLengthInMeters: number;
31
31
  overallPitchInPercent: number | null;
32
+ pitchCalculationResolutionInMeters: number;
32
33
  };
33
34
  export declare function getElevationData(profileGeometry: GeoJSON.LineString): ElevationData;
34
35
  export declare function getPitchData(profileGeometry: GeoJSON.LineString, resolutionInMeters?: number): PitchData;
@@ -44,8 +44,23 @@ function getPitchData(profileGeometry, resolutionInMeters = 25) {
44
44
  totalInclinedLength += Math.sqrt(Math.pow(lengthInMeters, 2) + Math.pow(elevation, 2));
45
45
  totalElevationChange += Math.abs(elevation);
46
46
  }
47
- // Chunk the line into fixed-length segments for max pitch calculation
48
- const chunkedGeometries = (0, line_chunk_1.lineChunk)(profileGeometry, resolutionInMeters, {
47
+ // If the line is too short relative to the resolution, pitch calculations are unreliable
48
+ // due to elevation data resolution. A 1m elevation change over 1m distance would be a 45 degree slope,
49
+ // which can easily happen due to elevation data precision issues.
50
+ if (totalLength < resolutionInMeters / 2) {
51
+ return {
52
+ averagePitchInPercent: null,
53
+ maxPitchInPercent: null,
54
+ inclinedLengthInMeters: totalInclinedLength,
55
+ overallPitchInPercent: null,
56
+ pitchCalculationResolutionInMeters: totalLength,
57
+ };
58
+ }
59
+ // Calculate a resolution that divides the distance evenly, with the constraint that it must be <= resolutionInMeters
60
+ const numSegments = Math.ceil(totalLength / resolutionInMeters);
61
+ const actualResolution = totalLength / numSegments;
62
+ // Chunk the line into segments using the calculated resolution for max pitch calculation
63
+ const chunkedGeometries = (0, line_chunk_1.lineChunk)(profileGeometry, actualResolution, {
49
64
  units: 'meters',
50
65
  }).features.map((feature) => feature.geometry);
51
66
  // turf 7.3+ adds Z coordinates to newly created points using segment-end elevation,
@@ -55,41 +70,27 @@ function getPitchData(profileGeometry, resolutionInMeters = 25) {
55
70
  stripNonOriginalElevations(chunkedGeometries, coordinates);
56
71
  // Mutates the geometries in place to add elevation data
57
72
  interpolateElevation(chunkedGeometries);
58
- // Initialize max pitch values
59
- let maxPitchValue = null;
60
- // Calculate max pitch over the fixed-length chunks
73
+ // Calculate max pitch over the evenly-divided chunks
74
+ let maxPitchValue = 0;
61
75
  for (const chunk of chunkedGeometries) {
62
76
  const chunkCoords = chunk.coordinates;
63
77
  const startPoint = chunkCoords[0];
64
78
  const endPoint = chunkCoords[chunkCoords.length - 1];
65
79
  const elevationChange = endPoint[2] - startPoint[2];
66
80
  const chunkLengthInMeters = (0, length_1.default)({ type: 'Feature', geometry: chunk, properties: {} }, { units: 'meters' });
67
- // Skip chunks that are too close together to calculate pitch reliably (can happen for the last chunk)
68
- if (chunkLengthInMeters < resolutionInMeters / 2)
69
- continue;
70
81
  const chunkPitch = Math.abs(elevationChange / chunkLengthInMeters);
71
- if (maxPitchValue === null || chunkPitch > maxPitchValue) {
82
+ if (chunkPitch > maxPitchValue) {
72
83
  maxPitchValue = chunkPitch;
73
84
  }
74
85
  }
75
86
  const averagePitch = totalElevationChange / totalLength;
76
87
  const overallElevationChange = Math.abs(coordinates[coordinates.length - 1][2] - coordinates[0][2]);
77
- // null maxPitchValue indicates the line is shorter than half the resolution, in which case the accuracy of pitch calculations
78
- // is questionable as a 1m change in elevation over
79
- // 1m of distance would be a 45 degree slope, this can happen due to resolution of the elevation data.
80
- if (maxPitchValue === null) {
81
- return {
82
- averagePitchInPercent: null,
83
- maxPitchInPercent: null,
84
- inclinedLengthInMeters: totalInclinedLength,
85
- overallPitchInPercent: null,
86
- };
87
- }
88
88
  return {
89
89
  averagePitchInPercent: averagePitch,
90
90
  maxPitchInPercent: maxPitchValue,
91
91
  inclinedLengthInMeters: totalInclinedLength,
92
92
  overallPitchInPercent: overallElevationChange / totalLength,
93
+ pitchCalculationResolutionInMeters: actualResolution,
93
94
  };
94
95
  }
95
96
  function getProfileGeometry(geometry, elevationProfile) {
@@ -1 +1 @@
1
- {"version":3,"file":"ElevationProfile.js","sourceRoot":"","sources":["../src/ElevationProfile.ts"],"names":[],"mappings":";;AAyCA,4CAQC;AAED,oCAmGC;AAED,gDAmBC;AAKD,4EA2BC;AAED,kDAiDC;;AA9PD,sEAAqC;AACrC,kEAAiC;AACjC,iDAA4C;AAuC5C,SAAgB,gBAAgB,CAC9B,eAAmC;IAEnC,OAAO;QACL,GAAG,mBAAmB,CAAC,eAAe,CAAC;QACvC,GAAG,YAAY,CAAC,eAAe,CAAC;QAChC,eAAe;KAChB,CAAA;AACH,CAAC;AAED,SAAgB,YAAY,CAC1B,eAAmC,EACnC,qBAA6B,EAAE;IAE/B,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,CAAA;IAC/C,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,+CAA+C,CAAA;IACvD,CAAC;IAED,+DAA+D;IAC/D,IAAI,WAAW,GAAG,CAAC,CAAA;IACnB,IAAI,mBAAmB,GAAG,CAAC,CAAA;IAC3B,IAAI,oBAAoB,GAAG,CAAC,CAAA;IAE5B,2DAA2D;IAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAChC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACtC,MAAM,QAAQ,GAAuB;YACnC,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC;SAC7B,CAAA;QACD,MAAM,OAAO,GAAoB;YAC/B,IAAI,EAAE,SAAS;YACf,QAAQ;YACR,UAAU,EAAE,EAAE;SACf,CAAA;QACD,MAAM,cAAc,GAAG,IAAA,gBAAM,EAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;QAE3D,WAAW,IAAI,cAAc,CAAA;QAC7B,mBAAmB,IAAI,IAAI,CAAC,IAAI,CAC9B,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CACrD,CAAA;QACD,oBAAoB,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IAC7C,CAAC;IAED,sEAAsE;IACtE,MAAM,iBAAiB,GAAG,IAAA,sBAAS,EAAC,eAAe,EAAE,kBAAkB,EAAE;QACvE,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9C,oFAAoF;IACpF,kFAAkF;IAClF,+CAA+C;IAC/C,6CAA6C;IAC7C,0BAA0B,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;IAE1D,wDAAwD;IACxD,oBAAoB,CAAC,iBAAiB,CAAC,CAAA;IAEvC,8BAA8B;IAC9B,IAAI,aAAa,GAAkB,IAAI,CAAA;IAEvC,mDAAmD;IACnD,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAA;QAErC,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;QACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAEpD,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAA;QACnD,MAAM,mBAAmB,GAAG,IAAA,gBAAM,EAChC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,EAAE,EACpD,EAAE,KAAK,EAAE,QAAQ,EAAE,CACpB,CAAA;QAED,sGAAsG;QACtG,IAAI,mBAAmB,GAAG,kBAAkB,GAAG,CAAC;YAAE,SAAQ;QAE1D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,GAAG,mBAAmB,CAAC,CAAA;QAClE,IAAI,aAAa,KAAK,IAAI,IAAI,UAAU,GAAG,aAAa,EAAE,CAAC;YACzD,aAAa,GAAG,UAAU,CAAA;QAC5B,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,oBAAoB,GAAG,WAAW,CAAA;IACvD,MAAM,sBAAsB,GAAG,IAAI,CAAC,GAAG,CACrC,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAA;IAED,8HAA8H;IAC9H,mDAAmD;IACnD,sGAAsG;IACtG,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,OAAO;YACL,qBAAqB,EAAE,IAAI;YAC3B,iBAAiB,EAAE,IAAI;YACvB,sBAAsB,EAAE,mBAAmB;YAC3C,qBAAqB,EAAE,IAAI;SAC5B,CAAA;IACH,CAAC;IAED,OAAO;QACL,qBAAqB,EAAE,YAAY;QACnC,iBAAiB,EAAE,aAAa;QAChC,sBAAsB,EAAE,mBAAmB;QAC3C,qBAAqB,EAAE,sBAAsB,GAAG,WAAW;KAC5D,CAAA;AACH,CAAC;AAED,SAAgB,kBAAkB,CAChC,QAA4B,EAC5B,gBAAkC;IAElC,MAAM,WAAW,GAAG,gCAAgC,CAClD,QAAQ,EACR,gBAAgB,CAAC,UAAU,CAC5B,CAAA;IACD,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,KAAK,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACvE,MAAM,wCAAwC,CAAA;IAChD,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACxC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;QAC1C,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACpB,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;;GAEG;AACH,SAAgB,gCAAgC,CAC9C,QAAoB,EACpB,UAAkB;IAElB,iIAAiI;IACjI,MAAM,UAAU,GAAG,IAAA,sBAAS,EAAC,QAAQ,EAAE,UAAU,EAAE;QACjD,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAE9C,MAAM,MAAM,GAAuB,EAAE,CAAA;IACrC,KAAK,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnC,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CAAA;QACnC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;YACvC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,MAAM;KACpB,CAAA;AACH,CAAC;AAED,SAAgB,mBAAmB,CACjC,eAAmC;IAEnC,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,CAAA;IAC/C,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,iEAAiE,CAAA;IACzE,CAAC;IACD,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,wDAAwD,CAAA;IAChE,CAAC;IACD,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1C,MAAM,MAAM,GAAG,WAAW;SACvB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SACxB,MAAM,CACL,CAAC,WAAW,EAAE,gBAAgB,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,gBAAgB,GAAG,WAAW,CAAC,aAAa,CAAA;QAC3D,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACf,WAAW,CAAC,MAAM,IAAI,MAAM,CAAA;QAC9B,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,OAAO,IAAI,MAAM,CAAA;QAC/B,CAAC;QACD,WAAW,CAAC,aAAa,GAAG,gBAAgB,CAAA;QAC5C,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CACjC,gBAAgB,EAChB,WAAW,CAAC,YAAY,CACzB,CAAA;QACD,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CACjC,gBAAgB,EAChB,WAAW,CAAC,YAAY,CACzB,CAAA;QAED,OAAO,WAAW,CAAA;IACpB,CAAC,EACD;QACE,MAAM,EAAE,CAAC;QACT,OAAO,EAAE,CAAC;QACV,YAAY,EAAE,gBAAgB;QAC9B,YAAY,EAAE,gBAAgB;QAC9B,aAAa,EAAE,gBAAgB;KAChC,CACF,CAAA;IAEH,OAAO;QACL,cAAc,EAAE,MAAM,CAAC,MAAM;QAC7B,eAAe,EAAE,MAAM,CAAC,OAAO;QAC/B,oBAAoB,EAAE,MAAM,CAAC,YAAY;QACzC,oBAAoB,EAAE,MAAM,CAAC,YAAY;QACzC,gBAAgB,EAAE,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY;KAC5D,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,0BAA0B,CACjC,UAAgC,EAChC,mBAAuC;IAEvC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAE9E,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;YACrC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC/C,KAAK,CAAC,MAAM,GAAG,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,oBAAoB,CAAC,UAAgC;IAC5D,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAM;IACR,CAAC;IAED,oEAAoE;IACpE,MAAM,SAAS,GAKT,EAAE,CAAA;IAER,8DAA8D;IAC9D,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,IAAI,aAAa,GAA4B,IAAI,CAAA;IAEjD,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;QAClC,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;YACzC,yCAAyC;YACzC,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,aAAa,GAAG,IAAA,kBAAQ,EAAC,aAAa,EAAE,KAAK,EAAE;oBACnD,KAAK,EAAE,QAAQ;iBAChB,CAAC,CAAA;gBACF,aAAa,IAAI,aAAa,CAAA;YAChC,CAAC;YAED,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAA;YACtC,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK;gBACL,YAAY;gBACZ,KAAK,EAAE,UAAU,EAAE;gBACnB,iBAAiB,EAAE,aAAa;aACjC,CAAC,CAAA;YAEF,aAAa,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,MAAM,eAAe,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAA;IAE/D,IAAI,eAAe,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,sDAAsD,CAAA;IAC9D,CAAC;IAED,yDAAyD;IACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACpD,MAAM,UAAU,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QACrC,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAEvC,6BAA6B;QAC7B,IAAI,QAAQ,CAAC,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;YACvC,MAAM,sCAAsC,CAAA;QAC9C,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QAC1C,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACtC,MAAM,cAAc,GAAG,YAAY,GAAG,cAAc,CAAA;QAEpD,6DAA6D;QAC7D,MAAM,mBAAmB,GACvB,QAAQ,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAA;QAE3D,uDAAuD;QACvD,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAA;YAE9B,2DAA2D;YAC3D,IAAI,SAAS,CAAC,YAAY,EAAE,CAAC;gBAC3B,MAAM,6DAA6D,CAAA;YACrE,CAAC;YACD,qEAAqE;YACrE,MAAM,iBAAiB,GACrB,SAAS,CAAC,iBAAiB,GAAG,UAAU,CAAC,iBAAiB,CAAA;YAE5D,0FAA0F;YAC1F,IAAI,qBAAqB,GAAG,cAAc,CAAA;YAC1C,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,mBAAmB,GAAG,iBAAiB,GAAG,mBAAmB,CAAA;gBACnE,qBAAqB;oBACnB,cAAc,GAAG,cAAc,GAAG,mBAAmB,CAAA;YACzD,CAAC;YAED,wEAAwE;YACxE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QAC7C,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"ElevationProfile.js","sourceRoot":"","sources":["../src/ElevationProfile.ts"],"names":[],"mappings":"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"}
package/dist/Lift.d.ts CHANGED
@@ -3,16 +3,22 @@ import { FeatureType } from './FeatureType';
3
3
  import { Place } from './Place';
4
4
  import { SkiAreaSummaryFeature } from './SkiArea';
5
5
  import { Source } from './Source';
6
+ import { LiftStationSpotFeature } from './Spot';
6
7
  import { Status } from './Status';
7
8
  export type LiftFeature = GeoJSON.Feature<LiftGeometry, LiftProperties>;
8
9
  export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString;
10
+ /**
11
+ * Access restriction for a lift feature.
12
+ * - 'private': The lift has restricted access (derived from OSM access=private tag)
13
+ * - null: No access restriction or access information not available
14
+ */
15
+ export type Access = 'private' | null;
9
16
  /**
10
17
  * A feature representing a ski lift.
11
18
  *
12
19
  * Lifts are derived from OpenStreetMap aerialway/railway features that are commonly used for winter sports.
13
20
  *
14
21
  * Note:
15
- * - Private lifts are not included in this dataset.
16
22
  * - Railways (except funiculars) are included only if they are part of a site=piste relation.
17
23
  * - Railway parts are not merged together so a single railway line may be represented as multiple features.
18
24
  * - Some lifts included in the dataset may be for other purposes (amusement parks, etc).
@@ -22,6 +28,7 @@ export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString;
22
28
  * @property {string} id - Unique identifier for the lift. The ID is just a hash of the feature, so will change if the feature changes in any way.
23
29
  * @property {LiftType} liftType - Type of lift (e.g. chair_lift, gondola). Derived from OpenStreetMap aerialway/railway tags.
24
30
  * @property {Status} status - Operational status of the lift. Derived from OpenStreetMap lifecycle tags.
31
+ * @property {Access} access - Access restriction for the lift. Set to "private" when derived from OpenStreetMap access=private tag, otherwise null.
25
32
  * @property {string | null} name - Name of the lift. Derived from the OpenStreetMap name tag.
26
33
  * @property {string | null} ref - Reference code/number for the lift. Derived from the OpenStreetMap ref tag.
27
34
  * @property {string | null} refFRCAIRN - French CAIRN reference identifier. Derived from the OpenStreetMap ref:FR:CAIRN tag.
@@ -33,6 +40,7 @@ export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString;
33
40
  * @property {boolean | null} detachable - Whether the lift has detachable grips. Derived from the OpenStreetMap aerialway:detachable tag.
34
41
  * @property {boolean | null} bubble - Whether the lift has bubbles/covers to protect from weather. Derived from the OpenStreetMap aerialway:bubble tag.
35
42
  * @property {boolean | null} heating - Whether the lift has heated carriers/seats. Derived from the OpenStreetMap aerialway:heating tag.
43
+ * @property {LiftStationSpotFeature[]} stations - Lift station spot features associated with this lift.
36
44
  * @property {SkiAreaSummaryFeature[]} skiAreas - Ski areas this lift is a part of.
37
45
  * @property {Source[]} sources - Data sources for the feature.
38
46
  * @property {string[]} websites - Websites associated with this lift. Derived from the OpenStreetMap website tag.
@@ -44,6 +52,7 @@ export type LiftProperties = {
44
52
  id: string;
45
53
  liftType: LiftType;
46
54
  status: Status;
55
+ access: Access;
47
56
  name: string | null;
48
57
  ref: string | null;
49
58
  refFRCAIRN: string | null;
@@ -55,6 +64,7 @@ export type LiftProperties = {
55
64
  detachable: boolean | null;
56
65
  bubble: boolean | null;
57
66
  heating: boolean | null;
67
+ stations: LiftStationSpotFeature[];
58
68
  skiAreas: SkiAreaSummaryFeature[];
59
69
  sources: Source[];
60
70
  websites: string[];
package/dist/Lift.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Lift.js","sourceRoot":"","sources":["../src/Lift.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Lift.js","sourceRoot":"","sources":["../src/Lift.ts"],"names":[],"mappings":"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"}
package/dist/SkiArea.d.ts CHANGED
@@ -90,6 +90,8 @@ export type RunStatisticsByDifficulty = {
90
90
  [key in RunDifficulty | 'other']?: {
91
91
  count: number;
92
92
  lengthInKm: number;
93
+ snowmakingLengthInKm?: number;
94
+ snowfarmingLengthInKm?: number;
93
95
  };
94
96
  };
95
97
  export type LiftStatistics = {
package/dist/Spot.d.ts CHANGED
@@ -9,6 +9,10 @@ import { Source } from './Source';
9
9
  * Spots are used to represent lift stations, road crossings, or certain terrain features.
10
10
  */
11
11
  export type SpotFeature = GeoJSON.Feature<SpotGeometry, SpotProperties>;
12
+ /**
13
+ * A GeoJSON feature representing a lift station spot.
14
+ */
15
+ export type LiftStationSpotFeature = GeoJSON.Feature<SpotGeometry, LiftStationSpotProperties>;
12
16
  /**
13
17
  * Geometry type for spots - always a point.
14
18
  */
@@ -65,6 +69,7 @@ export declare enum DismountRequirement {
65
69
  * @property {LiftStationPosition | null} position - From OpenStreetMap tag `aerialway:station=bottom|mid|top`.
66
70
  * @property {boolean | null} entry - Whether passengers can board here. From OpenStreetMap tag `aerialway:access=entry|both|no`.
67
71
  * @property {boolean | null} exit - Whether passengers can alight here. From OpenStreetMap tag `aerialway:access=exit|both|no`.
72
+ * @property {string} liftId - ID of the lift feature associated with this station.
68
73
  */
69
74
  export type LiftStationSpotProperties = SpotBaseProperties & {
70
75
  spotType: SpotType.LiftStation;
@@ -72,6 +77,7 @@ export type LiftStationSpotProperties = SpotBaseProperties & {
72
77
  position: LiftStationPosition | null;
73
78
  entry: boolean | null;
74
79
  exit: boolean | null;
80
+ liftId: string;
75
81
  };
76
82
  /**
77
83
  * Position of a lift station along the lift line.
package/dist/Spot.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Spot.js","sourceRoot":"","sources":["../src/Spot.ts"],"names":[],"mappings":";;;AAuCA;;GAEG;AACH,IAAY,QAMX;AAND,WAAY,QAAQ;IAClB,iCAAqB,CAAA;IACrB,wCAA4B,CAAA;IAC5B,2EAA+D,CAAA;IAC/D,+EAAmE,CAAA;IACnE,iCAAqB,CAAA;AACvB,CAAC,EANW,QAAQ,wBAAR,QAAQ,QAMnB;AAaD;;GAEG;AACH,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,kCAAW,CAAA;IACX,gCAAS,CAAA;IACT,8CAAuB,CAAA;AACzB,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B;AAqBD;;GAEG;AACH,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,kCAAW,CAAA;IACX,kCAAW,CAAA;IACX,wCAAiB,CAAA;AACnB,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B"}
1
+ {"version":3,"file":"Spot.js","sourceRoot":"","sources":["../src/Spot.ts"],"names":[],"mappings":";;;AA+CA;;GAEG;AACH,IAAY,QAMX;AAND,WAAY,QAAQ;IAClB,iCAAqB,CAAA;IACrB,wCAA4B,CAAA;IAC5B,2EAA+D,CAAA;IAC/D,+EAAmE,CAAA;IACnE,iCAAqB,CAAA;AACvB,CAAC,EANW,QAAQ,wBAAR,QAAQ,QAMnB;AAaD;;GAEG;AACH,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,kCAAW,CAAA;IACX,gCAAS,CAAA;IACT,8CAAuB,CAAA;AACzB,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B;AAuBD;;GAEG;AACH,IAAY,mBAIX;AAJD,WAAY,mBAAmB;IAC7B,kCAAW,CAAA;IACX,kCAAW,CAAA;IACX,wCAAiB,CAAA;AACnB,CAAC,EAJW,mBAAmB,mCAAnB,mBAAmB,QAI9B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openskidata-format",
3
- "version": "8.0.0",
3
+ "version": "9.0.0",
4
4
  "description": "Data format for OpenSkiMap.org",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -74,7 +74,11 @@ describe('ElevationProfile', () => {
74
74
 
75
75
  const result = getPitchData(profileGeometry)
76
76
 
77
- expect(result.maxPitchInPercent).toBeCloseTo(0.377)
77
+ // With the new resolution calculation, the actual resolution divides the distance evenly
78
+ // Total length is ~60.44m, with default resolution of 25m: numSegments = ceil(60.44/25) = 3, actualResolution = 60.44/3 ≈ 20.15m
79
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(20.15, 1)
80
+ expect(result.pitchCalculationResolutionInMeters).toBeLessThanOrEqual(25)
81
+ expect(result.maxPitchInPercent).toBeCloseTo(0.489, 2)
78
82
  expect(result.averagePitchInPercent).toBeCloseTo(0.2482)
79
83
  expect(result.inclinedLengthInMeters).toBeCloseTo(63.0597)
80
84
  })
@@ -97,6 +101,101 @@ describe('ElevationProfile', () => {
97
101
  // The overall change should be more reasonable when calculated over fixed distances
98
102
  expect(result.maxPitchInPercent).toBeLessThan(0.5) // Should be much less than the individual segment pitch
99
103
  })
104
+
105
+ it('calculates resolution that divides distance evenly', () => {
106
+ const profileGeometry: GeoJSON.LineString = {
107
+ type: 'LineString',
108
+ coordinates: [
109
+ [0, 0, 100],
110
+ [0, 0.001, 110], // ~111m distance
111
+ [0, 0.002, 105], // ~111m distance
112
+ ],
113
+ }
114
+
115
+ const result = getPitchData(profileGeometry, 50)
116
+
117
+ // Resolution should be <= 50
118
+ expect(result.pitchCalculationResolutionInMeters).toBeLessThanOrEqual(50)
119
+
120
+ // With ~222m total length and 50m input resolution:
121
+ // numSegments = ceil(222/50) = 5
122
+ // actualResolution = 222/5 = 44.4m
123
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(44.4, 0)
124
+ })
125
+
126
+ it('uses total length as resolution when line is shorter than input resolution', () => {
127
+ const profileGeometry: GeoJSON.LineString = {
128
+ type: 'LineString',
129
+ coordinates: [
130
+ [0, 0, 100],
131
+ [0, 0.0001, 110], // ~11m distance
132
+ ],
133
+ }
134
+
135
+ const result = getPitchData(profileGeometry, 50)
136
+
137
+ // Resolution should equal the total length since numSegments = ceil(11/50) = 1
138
+ // actualResolution = 11/1 = 11m
139
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(11.1, 0)
140
+ expect(result.pitchCalculationResolutionInMeters).toBeLessThanOrEqual(50)
141
+ })
142
+
143
+ it('ensures all chunks are processed without skipping short chunks', () => {
144
+ // Create a line that would previously have a short final chunk
145
+ const profileGeometry: GeoJSON.LineString = {
146
+ type: 'LineString',
147
+ coordinates: [
148
+ [11.177425600412874, 47.31265682344346, 100],
149
+ [11.177224899122194, 47.312533118812354, 120], // ~20m, steep
150
+ [11.176823496540862, 47.31229807921545, 105], // ~40m, gentle descent
151
+ ],
152
+ }
153
+
154
+ const result = getPitchData(profileGeometry, 25)
155
+
156
+ // With evenly divided chunks, no chunks should be skipped
157
+ // The max pitch should be calculated from all segments
158
+ expect(result.maxPitchInPercent).toBeGreaterThan(0)
159
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(20.15, 1)
160
+ })
161
+
162
+ it('returns null pitch data for very short lines', () => {
163
+ const profileGeometry: GeoJSON.LineString = {
164
+ type: 'LineString',
165
+ coordinates: [
166
+ [0, 0, 100],
167
+ [0, 0.00001, 101], // ~1.11m distance
168
+ ],
169
+ }
170
+
171
+ const result = getPitchData(profileGeometry, 25)
172
+
173
+ // Lines shorter than half the resolution should return null pitch data
174
+ // because elevation data resolution makes pitch calculations unreliable
175
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(1.11, 1)
176
+ expect(result.maxPitchInPercent).toBeNull()
177
+ expect(result.averagePitchInPercent).toBeNull()
178
+ expect(result.overallPitchInPercent).toBeNull()
179
+ expect(result.inclinedLengthInMeters).toBeGreaterThan(0) // This should still be calculated
180
+ })
181
+
182
+ it('calculates pitch data for lines just above the minimum threshold', () => {
183
+ const profileGeometry: GeoJSON.LineString = {
184
+ type: 'LineString',
185
+ coordinates: [
186
+ [0, 0, 100],
187
+ [0, 0.00015, 105], // ~16.7m distance, just above half of 25m
188
+ ],
189
+ }
190
+
191
+ const result = getPitchData(profileGeometry, 25)
192
+
193
+ // Lines at or above half the resolution should calculate pitch data
194
+ expect(result.pitchCalculationResolutionInMeters).toBeCloseTo(16.7, 0)
195
+ expect(result.maxPitchInPercent).not.toBeNull()
196
+ expect(result.averagePitchInPercent).not.toBeNull()
197
+ expect(result.overallPitchInPercent).not.toBeNull()
198
+ })
100
199
  })
101
200
 
102
201
  describe('extractPointsForElevationProfile', () => {
@@ -239,6 +338,7 @@ describe('ElevationProfile', () => {
239
338
  id: '123',
240
339
  liftType: LiftType.ChairLift,
241
340
  status: Status.Operating,
341
+ access: null,
242
342
  name: 'Test Lift',
243
343
  skiAreas: [],
244
344
  sources: [],
@@ -252,6 +352,7 @@ describe('ElevationProfile', () => {
252
352
  detachable: null,
253
353
  bubble: null,
254
354
  heating: null,
355
+ stations: [],
255
356
  websites: [],
256
357
  wikidataID: null,
257
358
  places: [],
@@ -37,6 +37,7 @@ type PitchData = {
37
37
  maxPitchInPercent: number | null
38
38
  inclinedLengthInMeters: number
39
39
  overallPitchInPercent: number | null
40
+ pitchCalculationResolutionInMeters: number
40
41
  }
41
42
 
42
43
  export function getElevationData(
@@ -86,8 +87,25 @@ export function getPitchData(
86
87
  totalElevationChange += Math.abs(elevation)
87
88
  }
88
89
 
89
- // Chunk the line into fixed-length segments for max pitch calculation
90
- const chunkedGeometries = lineChunk(profileGeometry, resolutionInMeters, {
90
+ // If the line is too short relative to the resolution, pitch calculations are unreliable
91
+ // due to elevation data resolution. A 1m elevation change over 1m distance would be a 45 degree slope,
92
+ // which can easily happen due to elevation data precision issues.
93
+ if (totalLength < resolutionInMeters / 2) {
94
+ return {
95
+ averagePitchInPercent: null,
96
+ maxPitchInPercent: null,
97
+ inclinedLengthInMeters: totalInclinedLength,
98
+ overallPitchInPercent: null,
99
+ pitchCalculationResolutionInMeters: totalLength,
100
+ }
101
+ }
102
+
103
+ // Calculate a resolution that divides the distance evenly, with the constraint that it must be <= resolutionInMeters
104
+ const numSegments = Math.ceil(totalLength / resolutionInMeters)
105
+ const actualResolution = totalLength / numSegments
106
+
107
+ // Chunk the line into segments using the calculated resolution for max pitch calculation
108
+ const chunkedGeometries = lineChunk(profileGeometry, actualResolution, {
91
109
  units: 'meters',
92
110
  }).features.map((feature) => feature.geometry)
93
111
 
@@ -100,10 +118,8 @@ export function getPitchData(
100
118
  // Mutates the geometries in place to add elevation data
101
119
  interpolateElevation(chunkedGeometries)
102
120
 
103
- // Initialize max pitch values
104
- let maxPitchValue: number | null = null
105
-
106
- // Calculate max pitch over the fixed-length chunks
121
+ // Calculate max pitch over the evenly-divided chunks
122
+ let maxPitchValue = 0
107
123
  for (const chunk of chunkedGeometries) {
108
124
  const chunkCoords = chunk.coordinates
109
125
 
@@ -116,11 +132,8 @@ export function getPitchData(
116
132
  { units: 'meters' },
117
133
  )
118
134
 
119
- // Skip chunks that are too close together to calculate pitch reliably (can happen for the last chunk)
120
- if (chunkLengthInMeters < resolutionInMeters / 2) continue
121
-
122
135
  const chunkPitch = Math.abs(elevationChange / chunkLengthInMeters)
123
- if (maxPitchValue === null || chunkPitch > maxPitchValue) {
136
+ if (chunkPitch > maxPitchValue) {
124
137
  maxPitchValue = chunkPitch
125
138
  }
126
139
  }
@@ -130,23 +143,12 @@ export function getPitchData(
130
143
  coordinates[coordinates.length - 1][2] - coordinates[0][2],
131
144
  )
132
145
 
133
- // null maxPitchValue indicates the line is shorter than half the resolution, in which case the accuracy of pitch calculations
134
- // is questionable as a 1m change in elevation over
135
- // 1m of distance would be a 45 degree slope, this can happen due to resolution of the elevation data.
136
- if (maxPitchValue === null) {
137
- return {
138
- averagePitchInPercent: null,
139
- maxPitchInPercent: null,
140
- inclinedLengthInMeters: totalInclinedLength,
141
- overallPitchInPercent: null,
142
- }
143
- }
144
-
145
146
  return {
146
147
  averagePitchInPercent: averagePitch,
147
148
  maxPitchInPercent: maxPitchValue,
148
149
  inclinedLengthInMeters: totalInclinedLength,
149
150
  overallPitchInPercent: overallElevationChange / totalLength,
151
+ pitchCalculationResolutionInMeters: actualResolution,
150
152
  }
151
153
  }
152
154
 
package/src/Lift.ts CHANGED
@@ -3,6 +3,7 @@ import { FeatureType } from './FeatureType'
3
3
  import { Place } from './Place'
4
4
  import { SkiAreaSummaryFeature } from './SkiArea'
5
5
  import { Source } from './Source'
6
+ import { LiftStationSpotFeature } from './Spot'
6
7
  import { Status } from './Status'
7
8
  import { exhaustiveMatchingGuard } from './util/exhaustiveMatchingGuard'
8
9
 
@@ -10,13 +11,19 @@ export type LiftFeature = GeoJSON.Feature<LiftGeometry, LiftProperties>
10
11
 
11
12
  export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString
12
13
 
14
+ /**
15
+ * Access restriction for a lift feature.
16
+ * - 'private': The lift has restricted access (derived from OSM access=private tag)
17
+ * - null: No access restriction or access information not available
18
+ */
19
+ export type Access = 'private' | null
20
+
13
21
  /**
14
22
  * A feature representing a ski lift.
15
23
  *
16
24
  * Lifts are derived from OpenStreetMap aerialway/railway features that are commonly used for winter sports.
17
25
  *
18
26
  * Note:
19
- * - Private lifts are not included in this dataset.
20
27
  * - Railways (except funiculars) are included only if they are part of a site=piste relation.
21
28
  * - Railway parts are not merged together so a single railway line may be represented as multiple features.
22
29
  * - Some lifts included in the dataset may be for other purposes (amusement parks, etc).
@@ -26,6 +33,7 @@ export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString
26
33
  * @property {string} id - Unique identifier for the lift. The ID is just a hash of the feature, so will change if the feature changes in any way.
27
34
  * @property {LiftType} liftType - Type of lift (e.g. chair_lift, gondola). Derived from OpenStreetMap aerialway/railway tags.
28
35
  * @property {Status} status - Operational status of the lift. Derived from OpenStreetMap lifecycle tags.
36
+ * @property {Access} access - Access restriction for the lift. Set to "private" when derived from OpenStreetMap access=private tag, otherwise null.
29
37
  * @property {string | null} name - Name of the lift. Derived from the OpenStreetMap name tag.
30
38
  * @property {string | null} ref - Reference code/number for the lift. Derived from the OpenStreetMap ref tag.
31
39
  * @property {string | null} refFRCAIRN - French CAIRN reference identifier. Derived from the OpenStreetMap ref:FR:CAIRN tag.
@@ -37,6 +45,7 @@ export type LiftGeometry = GeoJSON.LineString | GeoJSON.MultiLineString
37
45
  * @property {boolean | null} detachable - Whether the lift has detachable grips. Derived from the OpenStreetMap aerialway:detachable tag.
38
46
  * @property {boolean | null} bubble - Whether the lift has bubbles/covers to protect from weather. Derived from the OpenStreetMap aerialway:bubble tag.
39
47
  * @property {boolean | null} heating - Whether the lift has heated carriers/seats. Derived from the OpenStreetMap aerialway:heating tag.
48
+ * @property {LiftStationSpotFeature[]} stations - Lift station spot features associated with this lift.
40
49
  * @property {SkiAreaSummaryFeature[]} skiAreas - Ski areas this lift is a part of.
41
50
  * @property {Source[]} sources - Data sources for the feature.
42
51
  * @property {string[]} websites - Websites associated with this lift. Derived from the OpenStreetMap website tag.
@@ -48,6 +57,7 @@ export type LiftProperties = {
48
57
  id: string
49
58
  liftType: LiftType
50
59
  status: Status
60
+ access: Access
51
61
  name: string | null
52
62
  ref: string | null
53
63
  refFRCAIRN: string | null
@@ -59,6 +69,7 @@ export type LiftProperties = {
59
69
  detachable: boolean | null
60
70
  bubble: boolean | null
61
71
  heating: boolean | null
72
+ stations: LiftStationSpotFeature[]
62
73
  skiAreas: SkiAreaSummaryFeature[]
63
74
  sources: Source[]
64
75
  websites: string[]
package/src/SkiArea.ts CHANGED
@@ -102,7 +102,12 @@ export type RunStatisticsByActivityAndDifficulty = {
102
102
  }
103
103
 
104
104
  export type RunStatisticsByDifficulty = {
105
- [key in RunDifficulty | 'other']?: { count: number; lengthInKm: number }
105
+ [key in RunDifficulty | 'other']?: {
106
+ count: number
107
+ lengthInKm: number
108
+ snowmakingLengthInKm?: number
109
+ snowfarmingLengthInKm?: number
110
+ }
106
111
  }
107
112
 
108
113
  export type LiftStatistics = {
package/src/Spot.ts CHANGED
@@ -11,6 +11,14 @@ import { Source } from './Source'
11
11
  */
12
12
  export type SpotFeature = GeoJSON.Feature<SpotGeometry, SpotProperties>
13
13
 
14
+ /**
15
+ * A GeoJSON feature representing a lift station spot.
16
+ */
17
+ export type LiftStationSpotFeature = GeoJSON.Feature<
18
+ SpotGeometry,
19
+ LiftStationSpotProperties
20
+ >
21
+
14
22
  /**
15
23
  * Geometry type for spots - always a point.
16
24
  */
@@ -78,6 +86,7 @@ export enum DismountRequirement {
78
86
  * @property {LiftStationPosition | null} position - From OpenStreetMap tag `aerialway:station=bottom|mid|top`.
79
87
  * @property {boolean | null} entry - Whether passengers can board here. From OpenStreetMap tag `aerialway:access=entry|both|no`.
80
88
  * @property {boolean | null} exit - Whether passengers can alight here. From OpenStreetMap tag `aerialway:access=exit|both|no`.
89
+ * @property {string} liftId - ID of the lift feature associated with this station.
81
90
  */
82
91
  export type LiftStationSpotProperties = SpotBaseProperties & {
83
92
  spotType: SpotType.LiftStation
@@ -85,6 +94,7 @@ export type LiftStationSpotProperties = SpotBaseProperties & {
85
94
  position: LiftStationPosition | null
86
95
  entry: boolean | null
87
96
  exit: boolean | null
97
+ liftId: string
88
98
  }
89
99
 
90
100
  /**