@wemap/geo 12.4.0 → 12.8.9

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.
package/dist/index.js CHANGED
@@ -342,7 +342,7 @@ class Coordinates {
342
342
  if (Math.abs(lat) <= 90) {
343
343
  this._lat = lat;
344
344
  } else {
345
- throw new Error("lat argument is not in [-90; 90]");
345
+ throw new Error(`lat argument is not in [-90; 90], value is ${lat}`);
346
346
  }
347
347
  this._ecef = null;
348
348
  }
@@ -1111,15 +1111,16 @@ class GeoRef {
1111
1111
  return coordinates;
1112
1112
  }
1113
1113
  const geojsonPt = [coordinates.lng, coordinates.lat];
1114
- let buildingLevel = buildingLevelsByAltitude.find((buildingLevel2) => buildingLevel2.geometry && booleanPointInPolygon(geojsonPt, buildingLevel2.geometry));
1114
+ let buildingLevel = buildingLevelsByAltitude.find((buildingLevel2) => buildingLevel2.geometries.some((geom) => booleanPointInPolygon(geojsonPt, geom)));
1115
1115
  if (buildingLevel) {
1116
1116
  updateLevelAndHeightFromFloor(buildingLevel);
1117
1117
  return coordinates;
1118
1118
  }
1119
- if (buildingLevelsByAltitude.every((bl) => Boolean(bl.geometry))) {
1119
+ const hasLevelGeometries = (bl) => bl.geometries.length !== 0;
1120
+ if (buildingLevelsByAltitude.every(hasLevelGeometries)) {
1120
1121
  return coordinates;
1121
1122
  }
1122
- if (buildingLevelsByAltitude.every((bl) => !Boolean(bl.geometry))) {
1123
+ if (buildingLevelsByAltitude.every((bl) => !hasLevelGeometries(bl))) {
1123
1124
  buildingLevel = buildingLevelsByAltitude[0];
1124
1125
  updateLevelAndHeightFromFloor(buildingLevel);
1125
1126
  return coordinates;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/Constants.ts","../src/coordinates/Level.ts","../src/coordinates/Coordinates.ts","../src/coordinates/UserPosition.ts","../src/Utils.ts","../src/coordinates/BoundingBox.ts","../src/coordinates/RelativePosition.ts","../src/coordinates/GeoRelativePosition.ts","../src/coordinates/GeoRef.ts","../src/rotations/Attitude.ts","../src/rotations/AbsoluteHeading.ts"],"sourcesContent":["export const R_MAJOR = 6378137.0;\nexport const R_MINOR = 6356752.3142;\nexport const EARTH_GRAVITY = 9.80665;\n\n/**\n * latitude and longitude epsilon in degrees\n * 1e-8° correspond to ~1mm at latitude = 0\n */\nexport const EPS_DEG_MM = 1e-8;\n\n/**\n * epsilon in meters which corresponds to 1 millimeter\n */\nexport const EPS_MM = 1e-3;\n\n\nexport const ELLIPSOID_FLATNESS = (R_MAJOR - R_MINOR) / R_MAJOR;\n\nexport const ECCENTRICITY = Math.sqrt(ELLIPSOID_FLATNESS * (2 - ELLIPSOID_FLATNESS));\nexport const ECCENTRICITY_2 = ECCENTRICITY * ECCENTRICITY;\n\nexport const R_MAJOR_2 = R_MAJOR * R_MAJOR;\nexport const R_MAJOR_4 = R_MAJOR_2 * R_MAJOR_2;\nexport const R_MINOR_2 = R_MINOR * R_MINOR;\nexport const R_MINOR_4 = R_MINOR_2 * R_MINOR_2;\nexport const CIRCUMFERENCE = R_MAJOR * 2 * Math.PI;\n","import { Level_t } from \"../types\";\n\n/**\n * A Level is the representation of a building floor number\n * A level can be a simple number or a range (low, up)\n * The range is an array of two numbers\n */\nclass Level {\n\n static VERIFY_TYPING = false;\n\n static checkType(level: Level_t) {\n if (level === null) {\n return;\n }\n if (typeof level === 'number' && !isNaN(level)) {\n return;\n }\n if (Array.isArray(level) && level.length === 2) {\n const [low, up] = level;\n if (typeof low === 'number' && !isNaN(low)\n && typeof up === 'number' && !isNaN(up)) {\n if (low > up || low === up) {\n throw Error(`Invalid level range: [${low}, ${up}]`);\n }\n return;\n }\n }\n throw Error(`Unknown level format: ${level}`);\n }\n\n /**\n * Return true if the level is a range, false otherwise\n */\n static isRange(level: Level_t): level is [number, number] {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n return Array.isArray(level);\n }\n\n static clone(level: Level_t): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n if (typeof level === 'number') {\n return level;\n }\n\n return [level[0], level[1]];\n }\n\n /**\n * Create a level from a string (eg. 1, -2, 1;2, -2;3, 2;-1, 0.5;1 ...)\n */\n static fromString(str: string | null): Level_t {\n\n if (str === null) {\n return null;\n }\n\n if (typeof str !== 'string' || !str.length) {\n throw Error(`argument must be a non empty string, got ${typeof str}`);\n }\n\n if (!isNaN(Number(str))) {\n return parseFloat(str);\n }\n\n const splited = str.split(';');\n if (splited.length > 1) {\n const levels = splited.map(str => Number(str));\n const low = Math.min(...levels);\n const up = Math.max(...levels);\n Level.checkType([low, up]);\n return [low, up];\n } else {\n const rangeSeparator = str.substring(1).indexOf('-') + 1;\n if (rangeSeparator > 0) {\n const low = Number(str.substring(0, rangeSeparator));\n const up = Number(str.substring(rangeSeparator + 1));\n Level.checkType([low, up]);\n return [low, up];\n }\n }\n\n throw Error(`Cannot parse following level: ${str}`);\n }\n\n\n /**\n * Returns if a level is contained in another\n * @param {null|number|[number, number]} container The container level\n * @param {null|number|[number, number]} targeted The targeted level\n */\n static contains(container: Level_t, targeted: Level_t): boolean {\n if (Level.VERIFY_TYPING) {\n Level.checkType(container);\n Level.checkType(targeted);\n }\n\n // Covers null and number\n if (container === targeted) {\n return true;\n }\n\n if (Array.isArray(container)) {\n if (Array.isArray(targeted)) {\n return container[0] <= targeted[0] && container[1] >= targeted[1];\n }\n if (targeted === null) {\n return false;\n }\n return container[0] <= targeted && container[1] >= targeted;\n }\n if (container === null || targeted === null) {\n return false;\n }\n return container <= (targeted as [number, number])[0]\n && container >= (targeted as [number, number])[1];\n }\n\n /**\n * Retrieve the intersection of two levels\n * null n null => null\n * null n 1 => null // Conception choice\n * null n [1,2] => null // Conception choice\n * 1 n 1 => 1\n * 1 n 2 => null\n * 1 n [1,2] => 1\n * 1 n [0,2] => 1\n * 1 n [2,3] => null\n * [1,2] n [1,2] => [1,2]\n * [1,2] n [2,3] => 2\n * [1,2] n [3,4] => null\n */\n static intersection(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (Level.equals(first, second)) {\n return Level.clone(first);\n }\n\n if (typeof first === 'number' && typeof second === 'number') {\n return first === second ? first : null;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (Level.contains(first, second)) {\n return second;\n }\n return null;\n }\n if (!Array.isArray(first) && Array.isArray(second)) {\n if (Level.contains(second, first)) {\n return first;\n }\n return null;\n }\n\n // There are two ranges\n const low = Math.max((first as [number, number])[0], (second as [number, number])[0]);\n const up = Math.min((first as [number, number])[1], (second as [number, number])[1]);\n if (up === low) {\n return up;\n }\n return up < low ? null : [low, up];\n }\n\n /**\n * Retrieve the intersection of two levels\n * @param {null|number|[number, number]} first The first level\n * @param {null|number|[number, number]} second The second level\n * @returns {boolean}\n */\n static intersect(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null && second === null) {\n return true;\n }\n\n return Level.intersection(first, second) !== null;\n }\n\n /**\n * Retrieve the union of two levels\n * null u null => null\n * null u 1 => null // Conception choice\n * null u [1,2] => null // Conception choice\n * 1 u 1 => 1\n * 1 u 2 => [1,2]\n * 1 u [1,2] => [1,2]\n * 1 u [0,2] => [0,2]\n * 1 u [2,3] => [1,3]\n * [1,2] u [1,2] => [1,2]\n * [1,2] u [2,3] => [1,3]\n * [1,2] u [3,4] => [1,4]\n */\n static union(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return Level.clone(first);\n }\n\n if (second === null) {\n return null;\n // return Level.clone(first);\n }\n\n if (first === null) {\n return null;\n // return Level.clone(second);\n }\n\n let low, up;\n if (!Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first, second);\n up = Math.max(first, second);\n } else if (Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first[0], second);\n up = Math.max(first[1], second);\n } else if (!Array.isArray(first) && Array.isArray(second)) {\n low = Math.min(second[0], first);\n up = Math.max(second[1], first);\n } else {\n /* if (Array.isArray(first) && Array.isArray(second)) */\n low = Math.min((first as [number, number])[0], (second as [number, number])[0]);\n up = Math.max((first as [number, number])[1], (second as [number, number])[1]);\n }\n\n if (low === up) {\n return low;\n }\n return [low, up];\n }\n\n /**\n * Multiply a level by a factor\n * @param {null|number|[number, number]} level the level to multiply\n * @param {number} factor\n * @returns {null|number|[number, number]}\n */\n static multiplyBy(level: Level_t, factor: number): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n\n if (level === null) {\n return null;\n }\n\n return Array.isArray(level) ? [level[0] * factor, level[1] * factor] : level * factor;\n }\n\n static toString(level: Level_t): string | null {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n return Array.isArray(level) ? level[0] + ';' + level[1] : String(level);\n }\n\n static equals(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return true;\n }\n\n if (Array.isArray(first) && Array.isArray(second)) {\n return first[0] === second[0] && first[1] === second[1];\n }\n\n return false;\n }\n\n\n static diff(first: Level_t, second: Level_t): null | number {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (!Array.isArray(first) && !Array.isArray(second)) {\n return second - first;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (first[0] === second) {\n return second - first[1];\n }\n if (first[1] === second) {\n return second - first[0];\n }\n return null;\n }\n\n if (Array.isArray(second) && !Array.isArray(first)) {\n if (first === second[0]) {\n return second[1] - first;\n }\n if (first === second[1]) {\n return second[0] - first;\n }\n return null;\n }\n\n if (Level.equals(first, second)) {\n return 0;\n }\n\n return null;\n }\n}\n\nexport default Level;\n","import {\n deg2rad, Vector3, Quaternion, rad2deg, wrap, Vector3_t, Quaternion_t\n} from '@wemap/maths';\nimport { EPS_DEG_MM, EPS_MM, R_MAJOR } from '../Constants.js';\n\nimport { CoordinatesCompressedJson, CoordinatesJson, Level_t } from '../types.js';\nimport Level from './Level.js';\n\n/**\n * A Coordinates position using at least latitude (lat) and longitude (lng).\n * Optionnal fields are: altitude (alt) and level.\n *\n * Basic geo methods are directly accessibles from here:\n * distanceTo, bearingTo, toEcef...\n *\n * /!\\ This class has been adapted to use earth as a sphere and not as an ellipsoid\n * /!\\ So, this class does not stricly represent WGS84 coordinates anymore\n * /!\\ This modifications have been made for computational improvements.\n */\nclass Coordinates {\n\n private _lat!: number;\n private _lng!: number;\n private _alt: number | null = null;\n private _level: Level_t | null = null;\n private _heightFromFloor: number | null = null;\n private _heightFromGround: number | null = null;\n\n private _ecef: Vector3_t | null;\n\n autoWrap = true;\n\n constructor(lat: number, lng: number, alt: number | null = null, level: Level_t | null = null) {\n this.lat = lat;\n this.lng = lng;\n this.alt = alt;\n this.level = level;\n this._ecef = null;\n }\n\n get lat() {\n return this._lat;\n }\n\n set lat(lat: number) {\n if (Math.abs(lat) <= 90) {\n this._lat = lat;\n } else {\n throw new Error('lat argument is not in [-90; 90]');\n }\n this._ecef = null;\n }\n\n get latitude() {\n return this._lat;\n }\n\n set latitude(_) {\n throw new Error('Please use Coordinates#lat setter instead of Coordinate#latitude');\n }\n\n get lng() {\n return this._lng;\n }\n\n set lng(lng) {\n this._lng = lng;\n if (this.autoWrap) {\n this.wrap();\n }\n this._ecef = null;\n }\n\n get longitude() {\n return this._lng;\n }\n\n set longitude(_) {\n throw new Error('Please use Coordinates#lng setter instead of Coordinate#longitude');\n }\n\n /**\n * alt does not denote the altitude of a point but its height from\n * the \"level\" field (if defined) or from the ground\n */\n get alt() {\n return this._alt;\n }\n\n set alt(alt) {\n this._alt = alt;\n this._ecef = null;\n }\n\n get level() {\n return this._level;\n }\n\n set level(level) {\n Level.checkType(level);\n this._level = level;\n }\n\n get heightFromFloor() {\n return this._heightFromFloor;\n }\n\n set heightFromFloor(heightFromFloor) {\n this._heightFromFloor = heightFromFloor;\n }\n\n get heightFromGround() {\n return this._heightFromGround;\n }\n\n set heightFromGround(heightFromGround) {\n this._heightFromGround = heightFromGround;\n }\n\n /**\n * Deep clone coordinates\n */\n clone() {\n const output = new Coordinates(this.lat, this.lng, this.alt);\n if (this.level !== null) {\n output.level = Level.clone(this.level);\n }\n return output;\n }\n\n wrap() {\n if (this._lng <= -180 || this._lng > 180) {\n this._lng = wrap(this._lng, -180, 180);\n }\n }\n\n\n static equals(pos1: Coordinates | null, pos2: Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof Coordinates) || !(pos2 instanceof Coordinates)) {\n return false;\n }\n\n return Math.abs(pos2.lat - pos1.lat) < eps\n && Math.abs(pos2.lng - pos1.lng) < eps\n && (pos1.alt === pos2.alt\n || pos1.alt !== null && pos2.alt !== null\n && Math.abs(pos2.alt - pos1.alt) < epsAlt)\n && Level.equals(pos1.level, pos2.level);\n }\n\n equals(other: Coordinates) {\n return Coordinates.equals(this, other);\n }\n\n /**\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n /**\n * Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n move(distance: number, bearing: number, elevation: number | null = null) {\n\n const dR = distance / R_MAJOR;\n const cosDr = Math.cos(dR);\n const sinDr = Math.sin(dR);\n\n const phi1 = deg2rad(this.lat);\n const lambda1 = deg2rad(this.lng);\n\n const phi2 = Math.asin(\n Math.sin(phi1) * cosDr\n + Math.cos(phi1) * sinDr * Math.cos(bearing)\n );\n const lambda2 = lambda1 + Math.atan2(\n Math.sin(bearing) * sinDr * Math.cos(phi1),\n cosDr - Math.sin(phi1) * Math.sin(phi2)\n );\n\n this.lat = rad2deg(phi2);\n this.lng = rad2deg(lambda2);\n\n if (elevation !== null) {\n if (this.alt === null) {\n throw new Error('Point altitude is not defined');\n }\n this.alt += elevation;\n }\n\n return this;\n }\n\n /**\n * Returns a distance between two points in meters\n */\n distanceTo(location2: Coordinates) {\n const lat1 = this.lat;\n const lng1 = this.lng;\n\n const lat2 = location2.lat;\n const lng2 = location2.lng;\n\n const dlat = deg2rad(lat2 - lat1);\n const dlng = deg2rad(lng2 - lng1);\n\n const dlngsin = Math.sin(dlng / 2);\n const dlatsin = Math.sin(dlat / 2);\n const lat1rad = deg2rad(lat1);\n const lat1cos = Math.cos(lat1rad);\n const lat2rad = deg2rad(lat2);\n const lat2cos = Math.cos(lat2rad);\n const angle = dlatsin * dlatsin + lat1cos * lat2cos * dlngsin * dlngsin;\n\n // arctangent\n const tangy = Math.sqrt(angle);\n const tangx = Math.sqrt(1 - angle);\n const cosn = 2 * Math.atan2(tangy, tangx);\n\n return R_MAJOR * cosn;\n }\n\n static distanceBetween(point1: Coordinates, point2: Coordinates) {\n return point1.distanceTo(point2);\n }\n\n bearingTo(location2: Coordinates) {\n const lat1 = deg2rad(this.lat);\n const lat2 = deg2rad(location2.lat);\n const diffLng = deg2rad(location2.lng - this.lng);\n\n return Math.atan2(Math.sin(diffLng) * Math.cos(lat2),\n Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(diffLng));\n }\n\n static bearingTo(point1: Coordinates, point2: Coordinates) {\n return point1.bearingTo(point2);\n }\n\n\n /**\n * ECEF Transformations\n * Here we used a light version of ECEF considering earth\n * as a sphere instead of an ellipse\n */\n\n get enuToEcefRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + deg2rad(this.lng));\n const rot2 = Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - deg2rad(this.lat));\n return Quaternion.multiply(rot1, rot2);\n }\n\n get ecefToEnuRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([1, 0, 0], deg2rad(this.lat) - Math.PI / 2);\n const rot2 = Quaternion.fromAxisAngle([0, 0, 1], -deg2rad(this.lng) - Math.PI / 2);\n return Quaternion.multiply(rot1, rot2);\n }\n\n /**\n * https://gist.github.com/klucar/1536194\n * Adapted for spherical formula\n */\n get ecef(): Vector3_t {\n\n if (!this._ecef) {\n const lat = deg2rad(this.lat);\n const lng = deg2rad(this.lng);\n const alt = this.alt || 0;\n\n const x = (R_MAJOR + alt) * Math.cos(lat) * Math.cos(lng);\n const y = (R_MAJOR + alt) * Math.cos(lat) * Math.sin(lng);\n const z = (R_MAJOR + alt) * Math.sin(lat);\n\n this._ecef = [x, y, z];\n }\n\n return this._ecef;\n }\n\n\n static fromECEF(ecef: Vector3_t): Coordinates {\n\n const x = ecef[0];\n const y = ecef[1];\n const z = ecef[2];\n\n const p = Math.sqrt(x ** 2 + y ** 2);\n\n let lng = Math.atan2(y, x);\n const lat = Math.atan2(z, p);\n const alt = p / Math.cos(lat) - R_MAJOR;\n\n lng = lng % (2 * Math.PI);\n\n const newPoint = new Coordinates(rad2deg(lat), rad2deg(lng), alt);\n newPoint._ecef = ecef;\n return newPoint;\n }\n\n\n /**\n * https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere\n * Adapted to ECEF\n */\n getSegmentProjection(p1: Coordinates, p2: Coordinates): Coordinates | null {\n\n const a = Vector3.normalize(p1.ecef);\n const b = Vector3.normalize(p2.ecef);\n const c = Vector3.normalize(this.ecef);\n\n const G = Vector3.cross(a, b);\n if (Vector3.norm(G) === 0) {\n return null;\n }\n\n const F = Vector3.cross(c, G);\n const t = Vector3.normalize(Vector3.cross(G, F));\n\n const posECEF = Vector3.multiplyScalar(t, R_MAJOR);\n const poseCoordinates = Coordinates.fromECEF(posECEF);\n\n // poseCoordinates.alt is not 0 here due to the ECEF transformation residual.\n // So if p1.alt and p2.alt are defined we take the middle elevation between p1 and p2.\n // Otherwise we remove alt from projection because the residual has no sense.\n let alt;\n if (p1.alt !== null && p2.alt !== null) {\n // This formula is maybe not the best one.\n alt = (p1.alt + p2.alt) / 2;\n }\n const projection = new Coordinates(poseCoordinates.lat, poseCoordinates.lng,\n alt, Level.union(p1.level, p2.level));\n\n if (Math.abs((p1.distanceTo(p2) - p1.distanceTo(projection) - p2.distanceTo(projection))) > EPS_MM) {\n return null;\n }\n\n return projection;\n }\n\n /**\n * Input / Output\n */\n\n toString() {\n let str = '[' + this._lat.toFixed(7) + ', ' + this._lng.toFixed(7);\n if (this._alt !== null) {\n str += ', ' + this._alt.toFixed(2);\n }\n if (this._level !== null) {\n str += ', [' + Level.toString(this._level) + ']';\n }\n str += ']';\n return str;\n }\n\n toJson(): CoordinatesJson {\n return {\n lat: Number(this.lat.toFixed(8)),\n lng: Number(this.lng.toFixed(8)),\n ...(this.alt !== null && { alt: Number(this.alt.toFixed(3)) }),\n ...(this.level !== null && { level: this.level })\n };\n }\n\n static fromJson(json: CoordinatesJson) {\n return new Coordinates(json.lat, json.lng, json.alt, json.level);\n }\n\n\n toCompressedJson(): CoordinatesCompressedJson {\n if (this.level !== null) {\n return [\n Number(this.lat.toFixed(8)),\n Number(this.lng.toFixed(8)),\n this.level\n ];\n }\n return [Number(this.lat.toFixed(8)), Number(this.lng.toFixed(8))];\n }\n\n static fromCompressedJson(json: CoordinatesCompressedJson) {\n const coords = new Coordinates(json[0], json[1]);\n if (json.length > 2) {\n coords.level = json[2] as number | [number, number];\n }\n return coords;\n }\n}\n\nexport default Coordinates;\n","import Coordinates from './Coordinates.js';\nimport { Level_t, UserPositionJson } from '../types.js';\nimport { EPS_DEG_MM, EPS_MM } from '../Constants.js';\n\n/**\n * A Coordinates User Position is a Coordinates position with specific data related to user (bearing, time, accuracy)\n */\nclass UserPosition extends Coordinates {\n\n private _time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n lat: number, lng: number, alt: number | null = null, level: Level_t = null,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n super(lat, lng, alt, level);\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n move(distance: number, bearing: number, elevation: number | null = null) {\n super.move(distance, bearing, elevation);\n return this;\n }\n\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n\n // Create a UserPosition with lat, lng, alt from Coordinates coordinates and\n // other fields from another UserPosition\n static fromCoordinates(coordinates: Coordinates) {\n return new UserPosition(coordinates.lat, coordinates.lng,\n coordinates.alt, coordinates.level);\n }\n\n clone() {\n const cloned = UserPosition.fromCoordinates(super.clone());\n cloned.time = this.time;\n cloned.accuracy = this.accuracy;\n cloned.bearing = this.bearing;\n return cloned;\n }\n\n\n static equals(pos1: UserPosition | Coordinates | null,\n pos2: UserPosition | Coordinates | null,\n eps = EPS_DEG_MM, epsAlt = EPS_MM\n ) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof UserPosition) || !(pos2 instanceof UserPosition)) {\n return false;\n }\n\n if (!super.equals(pos1, pos2, eps, epsAlt)) {\n return false;\n }\n\n return pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: UserPosition | Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n return UserPosition.equals(this, other, eps, epsAlt);\n }\n\n\n toJson(): UserPositionJson {\n return {\n ...super.toJson(),\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: UserPositionJson) {\n const position = UserPosition.fromCoordinates(Coordinates.fromJson(json));\n if (typeof json.time !== 'undefined') {\n position.time = json.time;\n }\n if (typeof json.accuracy !== 'undefined') {\n position.accuracy = json.accuracy;\n }\n if (typeof json.bearing !== 'undefined') {\n position.bearing = json.bearing;\n }\n return position;\n }\n}\n\nexport default UserPosition;\n","/* eslint-disable max-statements */\n\nimport { deg2rad, positiveMod } from '@wemap/maths';\nimport { EPS_MM } from './Constants.js';\n\nimport Coordinates from './coordinates/Coordinates.js';\nimport UserPosition from './coordinates/UserPosition.js';\nimport Level from './coordinates/Level.js';\nimport { Level_t } from './types.js';\n\nexport type RouteSample = Coordinates & { bearing: number };\n\n/**\n * Sample a route of Coordinates\n * @param route ordered points\n * @param stepSize step size to sample\n * @param maxLength max route length to sample\n */\nexport function sampleRoute(\n route: Coordinates[],\n stepSize = 0.7,\n startSampling = 0,\n length = Number.MAX_VALUE\n) {\n\n const endSampling = startSampling + length;\n\n const sampledRoute = [];\n\n let lastSample: RouteSample;\n\n let totalDistanceTraveled = 0;\n let distanceToNextSample = 0;\n let startFound = false;\n\n for (let segmentIndex = 0; segmentIndex < route.length - 1; segmentIndex++) {\n\n const p1 = route[segmentIndex];\n const p2 = route[segmentIndex + 1];\n const segmentSize = p1.distanceTo(p2);\n const segmentBearing = p1.bearingTo(p2);\n\n let distanceTraveledOnSegment = 0;\n\n if (!startFound) {\n if (startSampling < totalDistanceTraveled + segmentSize) {\n startFound = true;\n distanceToNextSample = startSampling - totalDistanceTraveled;\n } else {\n totalDistanceTraveled += segmentSize;\n continue;\n }\n }\n\n lastSample = Object.assign(p1.clone(), { bearing: segmentBearing });\n while (distanceTraveledOnSegment + distanceToNextSample < segmentSize\n && totalDistanceTraveled + distanceToNextSample <= endSampling) {\n\n const newPoint = lastSample.destinationPoint(distanceToNextSample, segmentBearing) as RouteSample;\n newPoint.bearing = segmentBearing;\n sampledRoute.push(newPoint);\n lastSample = newPoint;\n\n distanceTraveledOnSegment += distanceToNextSample;\n totalDistanceTraveled += distanceToNextSample;\n distanceToNextSample = stepSize;\n }\n\n if (totalDistanceTraveled + distanceToNextSample > endSampling) {\n break;\n }\n\n const rest = segmentSize - distanceTraveledOnSegment;\n totalDistanceTraveled += rest;\n distanceToNextSample -= rest;\n }\n\n return sampledRoute;\n}\n\n/**\n * Trim a route of Coordinates\n * @param {Array.<Coordinates>} route ordered points\n * @param {Coordinates} startPosition position where the trim starts. startPosition has to be on the route.\n * @param {*} maxLength max route length\n */\nexport function trimRoute(route: Coordinates[], startPosition = route[0], length = Number.MAX_VALUE) {\n\n const newRoute = [];\n let previousPoint: Coordinates | null = null;\n\n let currentPointIndex;\n let cumulativeDistance = 0;\n\n if (route.length <= 1) {\n throw new Error('Route must have at least 2 points');\n }\n\n for (currentPointIndex = 1; currentPointIndex < route.length; currentPointIndex++) {\n\n const p1 = route[currentPointIndex - 1];\n const p2 = route[currentPointIndex];\n\n if (Coordinates.equals(startPosition, p1)) {\n newRoute.push(p1);\n previousPoint = p1;\n break;\n }\n\n const proj = startPosition.getSegmentProjection(p1, p2);\n if (proj && Coordinates.equals(startPosition, proj) && !proj.equals(p2)) {\n newRoute.push(proj);\n previousPoint = proj;\n break;\n }\n }\n\n if (!newRoute.length) {\n throw new Error('startPosition is not on the route');\n }\n\n while (previousPoint && currentPointIndex < route.length) {\n const currentPoint = route[currentPointIndex];\n const dist = previousPoint.distanceTo(currentPoint);\n if (cumulativeDistance + dist >= length\n || Math.abs(cumulativeDistance + dist - length) <= EPS_MM) {\n const bearing = previousPoint.bearingTo(currentPoint);\n const remainingLength = length - cumulativeDistance;\n const end = previousPoint.destinationPoint(remainingLength, bearing);\n newRoute.push(end);\n break;\n }\n newRoute.push(currentPoint);\n previousPoint = currentPoint;\n cumulativeDistance += dist;\n currentPointIndex++;\n }\n\n return newRoute;\n}\n\n\nexport function simplifyRoute(coords: Coordinates[], precisionAngle = deg2rad(5)) {\n\n const isClosed = (coords[0].equals(coords[coords.length - 1]));\n\n let newRoute = coords.slice(0, coords.length - (isClosed ? 1 : 0));\n\n const len = newRoute.length;\n for (let i = isClosed ? 0 : 1; i < len; i++) {\n\n const p0 = coords[positiveMod(i - 1, len)];\n const p1 = coords[i];\n const p2 = coords[positiveMod(i + 1, len)];\n\n const seg1Dir = p0.bearingTo(p1);\n const seg2Dir = p1.bearingTo(p2);\n\n if (Math.abs(seg2Dir - seg1Dir) < precisionAngle) {\n newRoute = newRoute.filter(coord => coord !== p1);\n }\n }\n\n if (isClosed) {\n newRoute.push(newRoute[0]);\n }\n\n return newRoute;\n}\n\nexport function geolocationPositionToUserPosition(geolocationPosition: GeolocationPosition) {\n if (geolocationPosition === null) {\n return null;\n }\n\n const { latitude, longitude, accuracy, heading } = geolocationPosition.coords;\n\n const userPosition = new UserPosition(latitude, longitude);\n userPosition.time = geolocationPosition.timestamp;\n userPosition.accuracy = accuracy;\n userPosition.bearing = heading ? deg2rad(heading) : null;\n return userPosition;\n}\n\nexport function calcDistance(coords: Coordinates[]) {\n return coords.reduce((acc, coords, idx, arr) =>\n acc + (idx ? arr[idx - 1].distanceTo(coords) : 0), 0);\n}\n\n\nexport function createSegmentsAtLevel(itineraryCoords: Coordinates[], segmentsLevel: Level_t, useMultiLevelSegments = true) {\n\n const itineraryCoordsLength = itineraryCoords.length;\n let previousLevelCorrespond = false;\n\n const segments: Coordinates[][] = [];\n let coordinates: Coordinates[] = [];\n for (let i = 0; i < itineraryCoordsLength; i++) {\n const coords = itineraryCoords[i];\n const levelCorrespond = Level.intersect(segmentsLevel, coords.level);\n\n if (useMultiLevelSegments && !levelCorrespond && previousLevelCorrespond) {\n coordinates.push(coords);\n } else if (levelCorrespond) {\n if (!previousLevelCorrespond) {\n coordinates = [];\n segments.push(coordinates);\n if (useMultiLevelSegments && i !== 0) {\n coordinates.push(itineraryCoords[i - 1]);\n }\n }\n coordinates.push(coords);\n }\n\n previousLevelCorrespond = levelCorrespond;\n }\n return segments;\n}","import Coordinates from './Coordinates.js';\n\nclass BoundingBox {\n\n northEast: Coordinates;\n southWest: Coordinates;\n\n constructor(northEast: Coordinates, southWest: Coordinates) {\n this.northEast = northEast;\n this.southWest = southWest;\n\n if (this.northEast && this.southWest && this.getNorth() < this.getSouth()) {\n throw new Error('Incorrect bounding box');\n }\n }\n\n /**\n * Returns the geographical coordinate equidistant from the bounding box's corners.\n */\n get center(): Coordinates {\n const latCenter = (this.southWest.lat + this.northEast.lat) / 2;\n const lngCenter = (this.northEast.lng + this.southWest.lng) / 2;\n return new Coordinates(latCenter, lngCenter);\n }\n\n /**\n * Check if a point is contained in the bounding box.\n */\n contains(point: Coordinates): boolean {\n return point.lat <= this.northEast.lat\n && point.lat >= this.southWest.lat\n && point.lng <= this.northEast.lng\n && point.lng >= this.southWest.lng;\n }\n\n /**\n * Extend the bounds to include a given LngLat or LngLatBounds.\n */\n extend(obj: Coordinates | BoundingBox): BoundingBox {\n const sw = this.southWest,\n ne = this.northEast;\n let sw2, ne2;\n\n if (obj instanceof Coordinates) {\n sw2 = obj;\n ne2 = obj;\n\n } else if (obj instanceof BoundingBox) {\n sw2 = obj.southWest;\n ne2 = obj.northEast;\n } else {\n throw new Error('Unknown parameter');\n }\n\n this.southWest = new Coordinates(\n Math.min(sw2.lat, sw.lat),\n Math.min(sw2.lng, sw.lng)\n );\n this.northEast = new Coordinates(\n Math.max(ne2.lat, ne.lat),\n Math.max(ne2.lng, ne.lng)\n );\n\n return this;\n }\n\n /**\n * This method extends the bounding box with a value in meters\n * /*\\ This method is not precise as distance differs in function of latitude\n */\n extendsWithMeasure(measure: number): BoundingBox {\n\n if (typeof measure !== 'number') {\n throw new Error('measure is not a number');\n }\n\n this.northEast = this.northEast\n .destinationPoint(measure, 0)\n .move(measure, Math.PI / 2);\n\n this.southWest = this.southWest.clone()\n .destinationPoint(measure, -Math.PI / 2)\n .destinationPoint(measure, Math.PI);\n\n return this;\n }\n\n /**\n * Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\n * For example, a ratio of 0.5 extends the bounds by 50% in each direction.\n * Negative values will retract the bounds.\n */\n pad(bufferRatio: number): BoundingBox {\n const sw = this.southWest;\n const ne = this.northEast;\n\n const heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio;\n const widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\n\n this.southWest = new Coordinates(sw.lat - heightBuffer, sw.lng - widthBuffer);\n this.northEast = new Coordinates(ne.lat + heightBuffer, ne.lng + widthBuffer);\n\n return this;\n }\n\n /**\n * Returns the southwest corner of the bounding box.\n */\n getSouthWest() {\n return this.southWest;\n }\n\n /**\n * Returns the northeast corner of the bounding box.\n */\n getNorthEast() {\n return this.northEast;\n }\n\n /**\n * Returns the northwest corner of the bounding box.\n */\n getNorthWest() {\n return new Coordinates(this.getNorth(), this.getWest());\n }\n\n /**\n * Returns the southeast corner of the bounding box.\n */\n getSouthEast() {\n return new Coordinates(this.getSouth(), this.getEast());\n }\n\n /**\n * Returns the west edge of the bounding box.\n */\n getWest() {\n return this.southWest.lng;\n }\n\n /**\n * Returns the south edge of the bounding box.\n */\n getSouth() {\n return this.southWest.lat;\n }\n\n /**\n * Returns the east edge of the bounding box.\n */\n getEast() {\n return this.northEast.lng;\n }\n\n /**\n * Returns the north edge of the bounding box.\n */\n getNorth() {\n return this.northEast.lat;\n }\n\n static equals(bb1: BoundingBox, bb2: BoundingBox) {\n return Coordinates.equals(bb1.northEast, bb2.northEast)\n && Coordinates.equals(bb1.southWest, bb2.southWest);\n }\n\n equals(other: BoundingBox) {\n return BoundingBox.equals(this, other);\n }\n\n /**\n * Create a BoundingBox from a WSEN array\n */\n static fromArray(bounds: [number, number, number, number]) {\n return new BoundingBox(\n new Coordinates(bounds[3], bounds[2]),\n new Coordinates(bounds[1], bounds[0])\n );\n }\n\n static fromCoordinates(coords: Coordinates[]) {\n if (coords.length === 0) {\n return null;\n }\n return coords.reduce(\n (acc, _coords) => acc.extend(_coords),\n new BoundingBox(coords[0], coords[0])\n );\n }\n\n /**\n * Returns the WSEN array\n */\n toArray(): [number, number, number, number] {\n return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()];\n }\n}\n\nexport default BoundingBox;\n","import { EPS_MM } from '../Constants.js';\nimport { RelativePositionJson } from '../types.js';\n\nclass RelativePosition {\n\n x: number;\n y: number;\n z: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n x: number, y: number, z: number,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n clone() {\n return new RelativePosition(this.x, this.y, this.z, this.time, this.accuracy, this.bearing);\n }\n\n\n /**\n * Compares two RelativePosition\n * @param {RelativePosition} pos1 position 1\n * @param {RelativePosition} pos2 position 2\n * @param {Number} eps x, y, z epsilon in meters (default: 1e-3 [= 1mm])\n */\n static equals(pos1: RelativePosition | null, pos2: RelativePosition | null, eps = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof RelativePosition) || !(pos2 instanceof RelativePosition)) {\n return false;\n }\n\n return Math.abs(pos2.x - pos1.x) < eps\n && Math.abs(pos2.y - pos1.y) < eps\n && Math.abs(pos2.z - pos1.z) < eps\n && pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: RelativePosition) {\n return RelativePosition.equals(this, other);\n }\n\n toJson(): RelativePositionJson {\n return {\n x: this.x,\n y: this.y,\n z: this.z,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: RelativePositionJson) {\n return new RelativePosition(json.x, json.y, json.z, json.time, json.accuracy, json.bearing);\n }\n}\n\nexport default RelativePosition;\n","import RelativePosition from './RelativePosition.js';\n\n/**\n * Position is defined in EUS (East-Up-South) frame with: x pointing to East, y pointing to Up, z pointing to South\n * This frame is close to ThreeJS / OpenGL frame.\n */\nclass GeoRelativePosition extends RelativePosition { }\n\nexport default GeoRelativePosition;\n","import booleanPointInPolygon from '@turf/boolean-point-in-polygon';\n\nimport { Quaternion, Vector3, Vector3_t } from '@wemap/maths';\nimport { BuildingLevel, GeoRefJson } from '../types.js';\n\nimport Coordinates from './Coordinates.js';\n\nclass GeoRef {\n\n scale = 1;\n heading = 0;\n\n constructor(public origin: Coordinates, public buildingLevels: BuildingLevel[] = []) { }\n\n /**\n * LocalPosition in ENU frame\n */\n localToWorld(localPosition: Vector3_t) {\n const enuTranslationScaled = Vector3.multiplyScalar(localPosition, this.scale);\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);\n const enuToEcefRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.enuToEcefRotation);\n const ecefTranslation = Quaternion.rotate(enuToEcefRotationOrigin, enuTranslationScaled);\n const ecef = Vector3.sum(this.origin.ecef, ecefTranslation);\n const coordinates = Coordinates.fromECEF(ecef);\n\n const alt = coordinates.alt!;\n coordinates.heightFromGround = coordinates.alt! - this.origin.alt!\n\n /*\n * Retrieve level and altitude\n */\n\n const updateLevelAndHeightFromFloor = (buildingLevel: BuildingLevel) => {\n coordinates.level = buildingLevel.id;\n coordinates.heightFromFloor = alt - buildingLevel.floorAltitude;\n }\n\n // 1. If georef does not have buildings level, do not update level field.\n if (!this.buildingLevels.length) {\n return coordinates;\n }\n \n // 2. Find building levels which corresponds to coordinates altitude\n const buildingLevelsByAltitude = this.buildingLevels.filter(buildingLevel => buildingLevel.floorAltitude <= alt && buildingLevel.ceilingAltitude >= alt)\n // If no intersection, the position is outdoor\n if (!buildingLevelsByAltitude.length) {\n return coordinates;\n }\n\n // 3. Find building levels which also includes coordinates 2D position\n const geojsonPt = [coordinates.lng, coordinates.lat];\n let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometry && booleanPointInPolygon(geojsonPt, buildingLevel.geometry));\n \n // If intersection is found, take the first and update level by its id\n if (buildingLevel) {\n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // If there is no interesection and levels have geometry, the position is outdoor\n if (buildingLevelsByAltitude.every(bl => Boolean(bl.geometry))) {\n return coordinates;\n }\n\n // 4. Try fallbacks because geometry is optionnal for the moment (March 2024)\n \n // If building geometries does not exist, let's consider the level geometry as global/infinity.\n if (buildingLevelsByAltitude.every(bl => !Boolean(bl.geometry))) {\n // As we cannot decide which building level should be selected, take the first!\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // This means some buildings levels have geometry and some others not. This means there is a data problem.\n // Anyway takes first\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n /**\n * LocalPosition in ENU frame\n */\n worldToLocal(coords: Coordinates) {\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], -this.heading);\n const ecefToEnuRotationOrigin = Quaternion.multiply(this.origin.ecefToEnuRotation, rotationOffset);\n const ecefTranslation = Vector3.subtract(coords.ecef, this.origin.ecef);\n const ecefTranslationScaled = Vector3.multiplyScalar(ecefTranslation, 1 / this.scale);\n return Quaternion.rotate(ecefToEnuRotationOrigin, ecefTranslationScaled);\n }\n\n toJson(): GeoRefJson {\n return {\n origin: this.origin.toJson(),\n ...(this.scale !== 1 && { scale: this.scale }),\n ...(this.heading !== 0 && { heading: this.heading })\n };\n }\n\n static fromJson(json: GeoRefJson) {\n const geoRef = new GeoRef(Coordinates.fromJson(json.origin));\n geoRef.scale = typeof json.scale !== 'undefined' ? json.scale : 1;\n geoRef.heading = typeof json.heading !== 'undefined' ? json.heading : 0;\n return geoRef;\n }\n}\n\nexport default GeoRef;\n","import {\n Rotations, Quaternion, rad2deg, deg2rad,\n Quaternion_t, EulerAngles_t, EulerAnglesDegrees_t\n} from '@wemap/maths';\nimport { AttitudeJson } from '../types';\n\nclass Attitude {\n\n _quaternion: Quaternion_t = [1, 0, 0, 0];\n _heading: number | null = null;\n _eulerAngles: EulerAngles_t | null = null;\n _time: number | null = null;\n _accuracy: number | null = null;\n\n constructor(quaternion: Quaternion_t,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.quaternion = quaternion;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n static unitary() {\n return new Attitude([1, 0, 0, 0]);\n }\n\n\n get quaternion() {\n return this._quaternion;\n }\n\n set quaternion(quaternion) {\n if (Math.abs(1 - Quaternion.norm(quaternion)) > 1e-4) {\n throw new Error('quaternion is not a unit quaternion');\n }\n this._quaternion = quaternion;\n this._heading = null;\n this._eulerAngles = null;\n }\n\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n get eulerAngles(): EulerAngles_t {\n if (this._eulerAngles === null) {\n this._eulerAngles = Rotations.quaternionToEulerZXY(this.quaternion);\n }\n return this._eulerAngles;\n }\n\n get eulerAnglesDegrees(): EulerAnglesDegrees_t {\n return this.eulerAngles.map(x => rad2deg(x)) as EulerAnglesDegrees_t;\n }\n\n get heading() {\n if (this._heading === null) {\n let offset = 0;\n if (typeof (window) !== 'undefined' && window && window.orientation) {\n offset = deg2rad(window.orientation);\n }\n this._heading = Rotations.getHeadingFromQuaternion(this.quaternion) + offset;\n }\n return this._heading;\n }\n\n get headingDegrees() {\n return rad2deg(this.heading);\n }\n\n\n static equals(att1: Attitude | null, att2: Attitude | null) {\n\n // Handle null comparison\n if (att1 === null && att1 === att2) {\n // TODO not sure to return true here.\n return true;\n }\n\n if (!(att1 instanceof Attitude) || !(att2 instanceof Attitude)) {\n return false;\n }\n\n if (att1 === att2) {\n return true;\n }\n\n return Quaternion.equals(att1.quaternion, att2.quaternion);\n }\n\n equals(other: Attitude) {\n return Attitude.equals(this, other);\n }\n\n toJson(): AttitudeJson {\n if (this.time === null && this.accuracy === null) {\n return this.quaternion;\n }\n return {\n q: this.quaternion,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n\n static fromJson(json: AttitudeJson) {\n if (Array.isArray(json)) {\n return new Attitude(json, null, null);\n }\n return new Attitude(json.q, json.time, json.accuracy);\n }\n\n\n clone() {\n return new Attitude(this.quaternion.slice(0) as Quaternion_t, this.time, this.accuracy);\n }\n\n /**\n * Calculate the relative attitude between two given attitudes\n */\n static diff(attitudeStart: Attitude, attitudeEnd: Attitude) {\n\n const quaternionDiff = Quaternion.multiply(\n Quaternion.inverse(attitudeStart.quaternion),\n attitudeEnd.quaternion\n );\n\n let timeDiff = null;\n if (attitudeEnd.time !== null && attitudeStart.time !== null) {\n timeDiff = attitudeEnd.time - attitudeStart.time;\n }\n\n let accuracyDiff = null;\n if (attitudeStart.accuracy !== null && attitudeEnd.accuracy !== null) {\n // Approximation\n accuracyDiff = Math.max(attitudeEnd.accuracy - attitudeStart.accuracy);\n }\n\n return new Attitude(quaternionDiff, timeDiff, accuracyDiff);\n }\n}\n\nexport default Attitude;\n","import { Quaternion } from '@wemap/maths';\nimport { AbsoluteHeadingJson } from '../types.js';\n\nimport Attitude from './Attitude.js';\n\nclass AbsoluteHeading {\n\n heading: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n\n constructor(heading: number,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.heading = heading;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n toAttitude() {\n /**\n * Heading is given around z-axis in NED frame and our attitude in ENU frame, that is why\n * -1* is applied to heading.\n */\n return new Attitude(\n Quaternion.fromAxisAngle([0, 0, 1], -this.heading),\n this.time,\n this.accuracy\n );\n }\n\n\n /**\n * Compares two AbsoluteHeading\n * @param {AbsoluteHeading} heading1 heading 1\n * @param {AbsoluteHeading} heading2 heading 2\n */\n static equals(heading1: AbsoluteHeading | null, heading2: AbsoluteHeading | null) {\n\n // Handle null comparison\n if (heading1 === null && heading1 === heading2) {\n return true;\n }\n\n if (!(heading1 instanceof AbsoluteHeading) || !(heading2 instanceof AbsoluteHeading)) {\n return false;\n }\n\n return Math.abs(heading1.heading - heading2.heading) < 1e-8;\n }\n\n equals(other: AbsoluteHeading | null) {\n return AbsoluteHeading.equals(this, other);\n }\n\n toJson(): AbsoluteHeadingJson {\n return {\n heading: this.heading,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n static fromJson(json: AbsoluteHeadingJson) {\n return new AbsoluteHeading(json.heading, json.time, json.accuracy);\n }\n\n clone() {\n return new AbsoluteHeading(this.heading, this.time, this.accuracy);\n }\n}\n\nexport default AbsoluteHeading;\n"],"names":["str","wrap","deg2rad","rad2deg","Quaternion","Vector3","positiveMod","coords","buildingLevel","Rotations"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/Constants.ts","../src/coordinates/Level.ts","../src/coordinates/Coordinates.ts","../src/coordinates/UserPosition.ts","../src/Utils.ts","../src/coordinates/BoundingBox.ts","../src/coordinates/RelativePosition.ts","../src/coordinates/GeoRelativePosition.ts","../src/coordinates/GeoRef.ts","../src/rotations/Attitude.ts","../src/rotations/AbsoluteHeading.ts"],"sourcesContent":["export const R_MAJOR = 6378137.0;\nexport const R_MINOR = 6356752.3142;\nexport const EARTH_GRAVITY = 9.80665;\n\n/**\n * latitude and longitude epsilon in degrees\n * 1e-8° correspond to ~1mm at latitude = 0\n */\nexport const EPS_DEG_MM = 1e-8;\n\n/**\n * epsilon in meters which corresponds to 1 millimeter\n */\nexport const EPS_MM = 1e-3;\n\n\nexport const ELLIPSOID_FLATNESS = (R_MAJOR - R_MINOR) / R_MAJOR;\n\nexport const ECCENTRICITY = Math.sqrt(ELLIPSOID_FLATNESS * (2 - ELLIPSOID_FLATNESS));\nexport const ECCENTRICITY_2 = ECCENTRICITY * ECCENTRICITY;\n\nexport const R_MAJOR_2 = R_MAJOR * R_MAJOR;\nexport const R_MAJOR_4 = R_MAJOR_2 * R_MAJOR_2;\nexport const R_MINOR_2 = R_MINOR * R_MINOR;\nexport const R_MINOR_4 = R_MINOR_2 * R_MINOR_2;\nexport const CIRCUMFERENCE = R_MAJOR * 2 * Math.PI;\n","import { Level_t } from \"../types\";\n\n/**\n * A Level is the representation of a building floor number\n * A level can be a simple number or a range (low, up)\n * The range is an array of two numbers\n */\nclass Level {\n\n static VERIFY_TYPING = false;\n\n static checkType(level: Level_t) {\n if (level === null) {\n return;\n }\n if (typeof level === 'number' && !isNaN(level)) {\n return;\n }\n if (Array.isArray(level) && level.length === 2) {\n const [low, up] = level;\n if (typeof low === 'number' && !isNaN(low)\n && typeof up === 'number' && !isNaN(up)) {\n if (low > up || low === up) {\n throw Error(`Invalid level range: [${low}, ${up}]`);\n }\n return;\n }\n }\n throw Error(`Unknown level format: ${level}`);\n }\n\n /**\n * Return true if the level is a range, false otherwise\n */\n static isRange(level: Level_t): level is [number, number] {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n return Array.isArray(level);\n }\n\n static clone(level: Level_t): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n if (typeof level === 'number') {\n return level;\n }\n\n return [level[0], level[1]];\n }\n\n /**\n * Create a level from a string (eg. 1, -2, 1;2, -2;3, 2;-1, 0.5;1 ...)\n */\n static fromString(str: string | null): Level_t {\n\n if (str === null) {\n return null;\n }\n\n if (typeof str !== 'string' || !str.length) {\n throw Error(`argument must be a non empty string, got ${typeof str}`);\n }\n\n if (!isNaN(Number(str))) {\n return parseFloat(str);\n }\n\n const splited = str.split(';');\n if (splited.length > 1) {\n const levels = splited.map(str => Number(str));\n const low = Math.min(...levels);\n const up = Math.max(...levels);\n Level.checkType([low, up]);\n return [low, up];\n } else {\n const rangeSeparator = str.substring(1).indexOf('-') + 1;\n if (rangeSeparator > 0) {\n const low = Number(str.substring(0, rangeSeparator));\n const up = Number(str.substring(rangeSeparator + 1));\n Level.checkType([low, up]);\n return [low, up];\n }\n }\n\n throw Error(`Cannot parse following level: ${str}`);\n }\n\n\n /**\n * Returns if a level is contained in another\n * @param {null|number|[number, number]} container The container level\n * @param {null|number|[number, number]} targeted The targeted level\n */\n static contains(container: Level_t, targeted: Level_t): boolean {\n if (Level.VERIFY_TYPING) {\n Level.checkType(container);\n Level.checkType(targeted);\n }\n\n // Covers null and number\n if (container === targeted) {\n return true;\n }\n\n if (Array.isArray(container)) {\n if (Array.isArray(targeted)) {\n return container[0] <= targeted[0] && container[1] >= targeted[1];\n }\n if (targeted === null) {\n return false;\n }\n return container[0] <= targeted && container[1] >= targeted;\n }\n if (container === null || targeted === null) {\n return false;\n }\n return container <= (targeted as [number, number])[0]\n && container >= (targeted as [number, number])[1];\n }\n\n /**\n * Retrieve the intersection of two levels\n * null n null => null\n * null n 1 => null // Conception choice\n * null n [1,2] => null // Conception choice\n * 1 n 1 => 1\n * 1 n 2 => null\n * 1 n [1,2] => 1\n * 1 n [0,2] => 1\n * 1 n [2,3] => null\n * [1,2] n [1,2] => [1,2]\n * [1,2] n [2,3] => 2\n * [1,2] n [3,4] => null\n */\n static intersection(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (Level.equals(first, second)) {\n return Level.clone(first);\n }\n\n if (typeof first === 'number' && typeof second === 'number') {\n return first === second ? first : null;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (Level.contains(first, second)) {\n return second;\n }\n return null;\n }\n if (!Array.isArray(first) && Array.isArray(second)) {\n if (Level.contains(second, first)) {\n return first;\n }\n return null;\n }\n\n // There are two ranges\n const low = Math.max((first as [number, number])[0], (second as [number, number])[0]);\n const up = Math.min((first as [number, number])[1], (second as [number, number])[1]);\n if (up === low) {\n return up;\n }\n return up < low ? null : [low, up];\n }\n\n /**\n * Retrieve the intersection of two levels\n * @param {null|number|[number, number]} first The first level\n * @param {null|number|[number, number]} second The second level\n * @returns {boolean}\n */\n static intersect(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null && second === null) {\n return true;\n }\n\n return Level.intersection(first, second) !== null;\n }\n\n /**\n * Retrieve the union of two levels\n * null u null => null\n * null u 1 => null // Conception choice\n * null u [1,2] => null // Conception choice\n * 1 u 1 => 1\n * 1 u 2 => [1,2]\n * 1 u [1,2] => [1,2]\n * 1 u [0,2] => [0,2]\n * 1 u [2,3] => [1,3]\n * [1,2] u [1,2] => [1,2]\n * [1,2] u [2,3] => [1,3]\n * [1,2] u [3,4] => [1,4]\n */\n static union(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return Level.clone(first);\n }\n\n if (second === null) {\n return null;\n // return Level.clone(first);\n }\n\n if (first === null) {\n return null;\n // return Level.clone(second);\n }\n\n let low, up;\n if (!Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first, second);\n up = Math.max(first, second);\n } else if (Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first[0], second);\n up = Math.max(first[1], second);\n } else if (!Array.isArray(first) && Array.isArray(second)) {\n low = Math.min(second[0], first);\n up = Math.max(second[1], first);\n } else {\n /* if (Array.isArray(first) && Array.isArray(second)) */\n low = Math.min((first as [number, number])[0], (second as [number, number])[0]);\n up = Math.max((first as [number, number])[1], (second as [number, number])[1]);\n }\n\n if (low === up) {\n return low;\n }\n return [low, up];\n }\n\n /**\n * Multiply a level by a factor\n * @param {null|number|[number, number]} level the level to multiply\n * @param {number} factor\n * @returns {null|number|[number, number]}\n */\n static multiplyBy(level: Level_t, factor: number): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n\n if (level === null) {\n return null;\n }\n\n return Array.isArray(level) ? [level[0] * factor, level[1] * factor] : level * factor;\n }\n\n static toString(level: Level_t): string | null {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n return Array.isArray(level) ? level[0] + ';' + level[1] : String(level);\n }\n\n static equals(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return true;\n }\n\n if (Array.isArray(first) && Array.isArray(second)) {\n return first[0] === second[0] && first[1] === second[1];\n }\n\n return false;\n }\n\n\n static diff(first: Level_t, second: Level_t): null | number {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (!Array.isArray(first) && !Array.isArray(second)) {\n return second - first;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (first[0] === second) {\n return second - first[1];\n }\n if (first[1] === second) {\n return second - first[0];\n }\n return null;\n }\n\n if (Array.isArray(second) && !Array.isArray(first)) {\n if (first === second[0]) {\n return second[1] - first;\n }\n if (first === second[1]) {\n return second[0] - first;\n }\n return null;\n }\n\n if (Level.equals(first, second)) {\n return 0;\n }\n\n return null;\n }\n}\n\nexport default Level;\n","import {\n deg2rad, Vector3, Quaternion, rad2deg, wrap, Vector3_t, Quaternion_t\n} from '@wemap/maths';\nimport { EPS_DEG_MM, EPS_MM, R_MAJOR } from '../Constants.js';\n\nimport { CoordinatesCompressedJson, CoordinatesJson, Level_t } from '../types.js';\nimport Level from './Level.js';\n\n/**\n * A Coordinates position using at least latitude (lat) and longitude (lng).\n * Optionnal fields are: altitude (alt) and level.\n *\n * Basic geo methods are directly accessibles from here:\n * distanceTo, bearingTo, toEcef...\n *\n * /!\\ This class has been adapted to use earth as a sphere and not as an ellipsoid\n * /!\\ So, this class does not stricly represent WGS84 coordinates anymore\n * /!\\ This modifications have been made for computational improvements.\n */\nclass Coordinates {\n\n private _lat!: number;\n private _lng!: number;\n private _alt: number | null = null;\n private _level: Level_t | null = null;\n private _heightFromFloor: number | null = null;\n private _heightFromGround: number | null = null;\n\n private _ecef: Vector3_t | null;\n\n autoWrap = true;\n\n constructor(lat: number, lng: number, alt: number | null = null, level: Level_t | null = null) {\n this.lat = lat;\n this.lng = lng;\n this.alt = alt;\n this.level = level;\n this._ecef = null;\n }\n\n get lat() {\n return this._lat;\n }\n\n set lat(lat: number) {\n if (Math.abs(lat) <= 90) {\n this._lat = lat;\n } else {\n throw new Error(`lat argument is not in [-90; 90], value is ${lat}`);\n }\n this._ecef = null;\n }\n\n get latitude() {\n return this._lat;\n }\n\n set latitude(_) {\n throw new Error('Please use Coordinates#lat setter instead of Coordinate#latitude');\n }\n\n get lng() {\n return this._lng;\n }\n\n set lng(lng) {\n this._lng = lng;\n if (this.autoWrap) {\n this.wrap();\n }\n this._ecef = null;\n }\n\n get longitude() {\n return this._lng;\n }\n\n set longitude(_) {\n throw new Error('Please use Coordinates#lng setter instead of Coordinate#longitude');\n }\n\n /**\n * alt does not denote the altitude of a point but its height from\n * the \"level\" field (if defined) or from the ground\n */\n get alt() {\n return this._alt;\n }\n\n set alt(alt) {\n this._alt = alt;\n this._ecef = null;\n }\n\n get level() {\n return this._level;\n }\n\n set level(level) {\n Level.checkType(level);\n this._level = level;\n }\n\n get heightFromFloor() {\n return this._heightFromFloor;\n }\n\n set heightFromFloor(heightFromFloor) {\n this._heightFromFloor = heightFromFloor;\n }\n\n get heightFromGround() {\n return this._heightFromGround;\n }\n\n set heightFromGround(heightFromGround) {\n this._heightFromGround = heightFromGround;\n }\n\n /**\n * Deep clone coordinates\n */\n clone() {\n const output = new Coordinates(this.lat, this.lng, this.alt);\n if (this.level !== null) {\n output.level = Level.clone(this.level);\n }\n return output;\n }\n\n wrap() {\n if (this._lng <= -180 || this._lng > 180) {\n this._lng = wrap(this._lng, -180, 180);\n }\n }\n\n\n static equals(pos1: Coordinates | null, pos2: Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof Coordinates) || !(pos2 instanceof Coordinates)) {\n return false;\n }\n\n return Math.abs(pos2.lat - pos1.lat) < eps\n && Math.abs(pos2.lng - pos1.lng) < eps\n && (pos1.alt === pos2.alt\n || pos1.alt !== null && pos2.alt !== null\n && Math.abs(pos2.alt - pos1.alt) < epsAlt)\n && Level.equals(pos1.level, pos2.level);\n }\n\n equals(other: Coordinates) {\n return Coordinates.equals(this, other);\n }\n\n /**\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n /**\n * Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n move(distance: number, bearing: number, elevation: number | null = null) {\n\n const dR = distance / R_MAJOR;\n const cosDr = Math.cos(dR);\n const sinDr = Math.sin(dR);\n\n const phi1 = deg2rad(this.lat);\n const lambda1 = deg2rad(this.lng);\n\n const phi2 = Math.asin(\n Math.sin(phi1) * cosDr\n + Math.cos(phi1) * sinDr * Math.cos(bearing)\n );\n const lambda2 = lambda1 + Math.atan2(\n Math.sin(bearing) * sinDr * Math.cos(phi1),\n cosDr - Math.sin(phi1) * Math.sin(phi2)\n );\n\n this.lat = rad2deg(phi2);\n this.lng = rad2deg(lambda2);\n\n if (elevation !== null) {\n if (this.alt === null) {\n throw new Error('Point altitude is not defined');\n }\n this.alt += elevation;\n }\n\n return this;\n }\n\n /**\n * Returns a distance between two points in meters\n */\n distanceTo(location2: Coordinates) {\n const lat1 = this.lat;\n const lng1 = this.lng;\n\n const lat2 = location2.lat;\n const lng2 = location2.lng;\n\n const dlat = deg2rad(lat2 - lat1);\n const dlng = deg2rad(lng2 - lng1);\n\n const dlngsin = Math.sin(dlng / 2);\n const dlatsin = Math.sin(dlat / 2);\n const lat1rad = deg2rad(lat1);\n const lat1cos = Math.cos(lat1rad);\n const lat2rad = deg2rad(lat2);\n const lat2cos = Math.cos(lat2rad);\n const angle = dlatsin * dlatsin + lat1cos * lat2cos * dlngsin * dlngsin;\n\n // arctangent\n const tangy = Math.sqrt(angle);\n const tangx = Math.sqrt(1 - angle);\n const cosn = 2 * Math.atan2(tangy, tangx);\n\n return R_MAJOR * cosn;\n }\n\n static distanceBetween(point1: Coordinates, point2: Coordinates) {\n return point1.distanceTo(point2);\n }\n\n bearingTo(location2: Coordinates) {\n const lat1 = deg2rad(this.lat);\n const lat2 = deg2rad(location2.lat);\n const diffLng = deg2rad(location2.lng - this.lng);\n\n return Math.atan2(Math.sin(diffLng) * Math.cos(lat2),\n Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(diffLng));\n }\n\n static bearingTo(point1: Coordinates, point2: Coordinates) {\n return point1.bearingTo(point2);\n }\n\n\n /**\n * ECEF Transformations\n * Here we used a light version of ECEF considering earth\n * as a sphere instead of an ellipse\n */\n\n get enuToEcefRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + deg2rad(this.lng));\n const rot2 = Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - deg2rad(this.lat));\n return Quaternion.multiply(rot1, rot2);\n }\n\n get ecefToEnuRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([1, 0, 0], deg2rad(this.lat) - Math.PI / 2);\n const rot2 = Quaternion.fromAxisAngle([0, 0, 1], -deg2rad(this.lng) - Math.PI / 2);\n return Quaternion.multiply(rot1, rot2);\n }\n\n /**\n * https://gist.github.com/klucar/1536194\n * Adapted for spherical formula\n */\n get ecef(): Vector3_t {\n\n if (!this._ecef) {\n const lat = deg2rad(this.lat);\n const lng = deg2rad(this.lng);\n const alt = this.alt || 0;\n\n const x = (R_MAJOR + alt) * Math.cos(lat) * Math.cos(lng);\n const y = (R_MAJOR + alt) * Math.cos(lat) * Math.sin(lng);\n const z = (R_MAJOR + alt) * Math.sin(lat);\n\n this._ecef = [x, y, z];\n }\n\n return this._ecef;\n }\n\n\n static fromECEF(ecef: Vector3_t): Coordinates {\n\n const x = ecef[0];\n const y = ecef[1];\n const z = ecef[2];\n\n const p = Math.sqrt(x ** 2 + y ** 2);\n\n let lng = Math.atan2(y, x);\n const lat = Math.atan2(z, p);\n const alt = p / Math.cos(lat) - R_MAJOR;\n\n lng = lng % (2 * Math.PI);\n\n const newPoint = new Coordinates(rad2deg(lat), rad2deg(lng), alt);\n newPoint._ecef = ecef;\n return newPoint;\n }\n\n\n /**\n * https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere\n * Adapted to ECEF\n */\n getSegmentProjection(p1: Coordinates, p2: Coordinates): Coordinates | null {\n\n const a = Vector3.normalize(p1.ecef);\n const b = Vector3.normalize(p2.ecef);\n const c = Vector3.normalize(this.ecef);\n\n const G = Vector3.cross(a, b);\n if (Vector3.norm(G) === 0) {\n return null;\n }\n\n const F = Vector3.cross(c, G);\n const t = Vector3.normalize(Vector3.cross(G, F));\n\n const posECEF = Vector3.multiplyScalar(t, R_MAJOR);\n const poseCoordinates = Coordinates.fromECEF(posECEF);\n\n // poseCoordinates.alt is not 0 here due to the ECEF transformation residual.\n // So if p1.alt and p2.alt are defined we take the middle elevation between p1 and p2.\n // Otherwise we remove alt from projection because the residual has no sense.\n let alt;\n if (p1.alt !== null && p2.alt !== null) {\n // This formula is maybe not the best one.\n alt = (p1.alt + p2.alt) / 2;\n }\n const projection = new Coordinates(poseCoordinates.lat, poseCoordinates.lng,\n alt, Level.union(p1.level, p2.level));\n\n if (Math.abs((p1.distanceTo(p2) - p1.distanceTo(projection) - p2.distanceTo(projection))) > EPS_MM) {\n return null;\n }\n\n return projection;\n }\n\n /**\n * Input / Output\n */\n\n toString() {\n let str = '[' + this._lat.toFixed(7) + ', ' + this._lng.toFixed(7);\n if (this._alt !== null) {\n str += ', ' + this._alt.toFixed(2);\n }\n if (this._level !== null) {\n str += ', [' + Level.toString(this._level) + ']';\n }\n str += ']';\n return str;\n }\n\n toJson(): CoordinatesJson {\n return {\n lat: Number(this.lat.toFixed(8)),\n lng: Number(this.lng.toFixed(8)),\n ...(this.alt !== null && { alt: Number(this.alt.toFixed(3)) }),\n ...(this.level !== null && { level: this.level })\n };\n }\n\n static fromJson(json: CoordinatesJson) {\n return new Coordinates(json.lat, json.lng, json.alt, json.level);\n }\n\n\n toCompressedJson(): CoordinatesCompressedJson {\n if (this.level !== null) {\n return [\n Number(this.lat.toFixed(8)),\n Number(this.lng.toFixed(8)),\n this.level\n ];\n }\n return [Number(this.lat.toFixed(8)), Number(this.lng.toFixed(8))];\n }\n\n static fromCompressedJson(json: CoordinatesCompressedJson) {\n const coords = new Coordinates(json[0], json[1]);\n if (json.length > 2) {\n coords.level = json[2] as number | [number, number];\n }\n return coords;\n }\n}\n\nexport default Coordinates;\n","import Coordinates from './Coordinates.js';\nimport { Level_t, UserPositionJson } from '../types.js';\nimport { EPS_DEG_MM, EPS_MM } from '../Constants.js';\n\n/**\n * A Coordinates User Position is a Coordinates position with specific data related to user (bearing, time, accuracy)\n */\nclass UserPosition extends Coordinates {\n\n private _time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n lat: number, lng: number, alt: number | null = null, level: Level_t = null,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n super(lat, lng, alt, level);\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n move(distance: number, bearing: number, elevation: number | null = null) {\n super.move(distance, bearing, elevation);\n return this;\n }\n\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n\n // Create a UserPosition with lat, lng, alt from Coordinates coordinates and\n // other fields from another UserPosition\n static fromCoordinates(coordinates: Coordinates) {\n return new UserPosition(coordinates.lat, coordinates.lng,\n coordinates.alt, coordinates.level);\n }\n\n clone() {\n const cloned = UserPosition.fromCoordinates(super.clone());\n cloned.time = this.time;\n cloned.accuracy = this.accuracy;\n cloned.bearing = this.bearing;\n return cloned;\n }\n\n\n static equals(pos1: UserPosition | Coordinates | null,\n pos2: UserPosition | Coordinates | null,\n eps = EPS_DEG_MM, epsAlt = EPS_MM\n ) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof UserPosition) || !(pos2 instanceof UserPosition)) {\n return false;\n }\n\n if (!super.equals(pos1, pos2, eps, epsAlt)) {\n return false;\n }\n\n return pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: UserPosition | Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n return UserPosition.equals(this, other, eps, epsAlt);\n }\n\n\n toJson(): UserPositionJson {\n return {\n ...super.toJson(),\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: UserPositionJson) {\n const position = UserPosition.fromCoordinates(Coordinates.fromJson(json));\n if (typeof json.time !== 'undefined') {\n position.time = json.time;\n }\n if (typeof json.accuracy !== 'undefined') {\n position.accuracy = json.accuracy;\n }\n if (typeof json.bearing !== 'undefined') {\n position.bearing = json.bearing;\n }\n return position;\n }\n}\n\nexport default UserPosition;\n","/* eslint-disable max-statements */\n\nimport { deg2rad, positiveMod } from '@wemap/maths';\nimport { EPS_MM } from './Constants.js';\n\nimport Coordinates from './coordinates/Coordinates.js';\nimport UserPosition from './coordinates/UserPosition.js';\nimport Level from './coordinates/Level.js';\nimport { Level_t } from './types.js';\n\nexport type RouteSample = Coordinates & { bearing: number };\n\n/**\n * Sample a route of Coordinates\n * @param route ordered points\n * @param stepSize step size to sample\n * @param maxLength max route length to sample\n */\nexport function sampleRoute(\n route: Coordinates[],\n stepSize = 0.7,\n startSampling = 0,\n length = Number.MAX_VALUE\n) {\n\n const endSampling = startSampling + length;\n\n const sampledRoute = [];\n\n let lastSample: RouteSample;\n\n let totalDistanceTraveled = 0;\n let distanceToNextSample = 0;\n let startFound = false;\n\n for (let segmentIndex = 0; segmentIndex < route.length - 1; segmentIndex++) {\n\n const p1 = route[segmentIndex];\n const p2 = route[segmentIndex + 1];\n const segmentSize = p1.distanceTo(p2);\n const segmentBearing = p1.bearingTo(p2);\n\n let distanceTraveledOnSegment = 0;\n\n if (!startFound) {\n if (startSampling < totalDistanceTraveled + segmentSize) {\n startFound = true;\n distanceToNextSample = startSampling - totalDistanceTraveled;\n } else {\n totalDistanceTraveled += segmentSize;\n continue;\n }\n }\n\n lastSample = Object.assign(p1.clone(), { bearing: segmentBearing });\n while (distanceTraveledOnSegment + distanceToNextSample < segmentSize\n && totalDistanceTraveled + distanceToNextSample <= endSampling) {\n\n const newPoint = lastSample.destinationPoint(distanceToNextSample, segmentBearing) as RouteSample;\n newPoint.bearing = segmentBearing;\n sampledRoute.push(newPoint);\n lastSample = newPoint;\n\n distanceTraveledOnSegment += distanceToNextSample;\n totalDistanceTraveled += distanceToNextSample;\n distanceToNextSample = stepSize;\n }\n\n if (totalDistanceTraveled + distanceToNextSample > endSampling) {\n break;\n }\n\n const rest = segmentSize - distanceTraveledOnSegment;\n totalDistanceTraveled += rest;\n distanceToNextSample -= rest;\n }\n\n return sampledRoute;\n}\n\n/**\n * Trim a route of Coordinates\n * @param {Array.<Coordinates>} route ordered points\n * @param {Coordinates} startPosition position where the trim starts. startPosition has to be on the route.\n * @param {*} maxLength max route length\n */\nexport function trimRoute(route: Coordinates[], startPosition = route[0], length = Number.MAX_VALUE) {\n\n const newRoute = [];\n let previousPoint: Coordinates | null = null;\n\n let currentPointIndex;\n let cumulativeDistance = 0;\n\n if (route.length <= 1) {\n throw new Error('Route must have at least 2 points');\n }\n\n for (currentPointIndex = 1; currentPointIndex < route.length; currentPointIndex++) {\n\n const p1 = route[currentPointIndex - 1];\n const p2 = route[currentPointIndex];\n\n if (Coordinates.equals(startPosition, p1)) {\n newRoute.push(p1);\n previousPoint = p1;\n break;\n }\n\n const proj = startPosition.getSegmentProjection(p1, p2);\n if (proj && Coordinates.equals(startPosition, proj) && !proj.equals(p2)) {\n newRoute.push(proj);\n previousPoint = proj;\n break;\n }\n }\n\n if (!newRoute.length) {\n throw new Error('startPosition is not on the route');\n }\n\n while (previousPoint && currentPointIndex < route.length) {\n const currentPoint = route[currentPointIndex];\n const dist = previousPoint.distanceTo(currentPoint);\n if (cumulativeDistance + dist >= length\n || Math.abs(cumulativeDistance + dist - length) <= EPS_MM) {\n const bearing = previousPoint.bearingTo(currentPoint);\n const remainingLength = length - cumulativeDistance;\n const end = previousPoint.destinationPoint(remainingLength, bearing);\n newRoute.push(end);\n break;\n }\n newRoute.push(currentPoint);\n previousPoint = currentPoint;\n cumulativeDistance += dist;\n currentPointIndex++;\n }\n\n return newRoute;\n}\n\n\nexport function simplifyRoute(coords: Coordinates[], precisionAngle = deg2rad(5)) {\n\n const isClosed = (coords[0].equals(coords[coords.length - 1]));\n\n let newRoute = coords.slice(0, coords.length - (isClosed ? 1 : 0));\n\n const len = newRoute.length;\n for (let i = isClosed ? 0 : 1; i < len; i++) {\n\n const p0 = coords[positiveMod(i - 1, len)];\n const p1 = coords[i];\n const p2 = coords[positiveMod(i + 1, len)];\n\n const seg1Dir = p0.bearingTo(p1);\n const seg2Dir = p1.bearingTo(p2);\n\n if (Math.abs(seg2Dir - seg1Dir) < precisionAngle) {\n newRoute = newRoute.filter(coord => coord !== p1);\n }\n }\n\n if (isClosed) {\n newRoute.push(newRoute[0]);\n }\n\n return newRoute;\n}\n\nexport function geolocationPositionToUserPosition(geolocationPosition: GeolocationPosition) {\n if (geolocationPosition === null) {\n return null;\n }\n\n const { latitude, longitude, accuracy, heading } = geolocationPosition.coords;\n\n const userPosition = new UserPosition(latitude, longitude);\n userPosition.time = geolocationPosition.timestamp;\n userPosition.accuracy = accuracy;\n userPosition.bearing = heading ? deg2rad(heading) : null;\n return userPosition;\n}\n\nexport function calcDistance(coords: Coordinates[]) {\n return coords.reduce((acc, coords, idx, arr) =>\n acc + (idx ? arr[idx - 1].distanceTo(coords) : 0), 0);\n}\n\n\nexport function createSegmentsAtLevel(itineraryCoords: Coordinates[], segmentsLevel: Level_t, useMultiLevelSegments = true) {\n\n const itineraryCoordsLength = itineraryCoords.length;\n let previousLevelCorrespond = false;\n\n const segments: Coordinates[][] = [];\n let coordinates: Coordinates[] = [];\n for (let i = 0; i < itineraryCoordsLength; i++) {\n const coords = itineraryCoords[i];\n const levelCorrespond = Level.intersect(segmentsLevel, coords.level);\n\n if (useMultiLevelSegments && !levelCorrespond && previousLevelCorrespond) {\n coordinates.push(coords);\n } else if (levelCorrespond) {\n if (!previousLevelCorrespond) {\n coordinates = [];\n segments.push(coordinates);\n if (useMultiLevelSegments && i !== 0) {\n coordinates.push(itineraryCoords[i - 1]);\n }\n }\n coordinates.push(coords);\n }\n\n previousLevelCorrespond = levelCorrespond;\n }\n return segments;\n}","import Coordinates from './Coordinates.js';\n\nclass BoundingBox {\n\n northEast: Coordinates;\n southWest: Coordinates;\n\n constructor(northEast: Coordinates, southWest: Coordinates) {\n this.northEast = northEast;\n this.southWest = southWest;\n\n if (this.northEast && this.southWest && this.getNorth() < this.getSouth()) {\n throw new Error('Incorrect bounding box');\n }\n }\n\n /**\n * Returns the geographical coordinate equidistant from the bounding box's corners.\n */\n get center(): Coordinates {\n const latCenter = (this.southWest.lat + this.northEast.lat) / 2;\n const lngCenter = (this.northEast.lng + this.southWest.lng) / 2;\n return new Coordinates(latCenter, lngCenter);\n }\n\n /**\n * Check if a point is contained in the bounding box.\n */\n contains(point: Coordinates): boolean {\n return point.lat <= this.northEast.lat\n && point.lat >= this.southWest.lat\n && point.lng <= this.northEast.lng\n && point.lng >= this.southWest.lng;\n }\n\n /**\n * Extend the bounds to include a given LngLat or LngLatBounds.\n */\n extend(obj: Coordinates | BoundingBox): BoundingBox {\n const sw = this.southWest,\n ne = this.northEast;\n let sw2, ne2;\n\n if (obj instanceof Coordinates) {\n sw2 = obj;\n ne2 = obj;\n\n } else if (obj instanceof BoundingBox) {\n sw2 = obj.southWest;\n ne2 = obj.northEast;\n } else {\n throw new Error('Unknown parameter');\n }\n\n this.southWest = new Coordinates(\n Math.min(sw2.lat, sw.lat),\n Math.min(sw2.lng, sw.lng)\n );\n this.northEast = new Coordinates(\n Math.max(ne2.lat, ne.lat),\n Math.max(ne2.lng, ne.lng)\n );\n\n return this;\n }\n\n /**\n * This method extends the bounding box with a value in meters\n * /*\\ This method is not precise as distance differs in function of latitude\n */\n extendsWithMeasure(measure: number): BoundingBox {\n\n if (typeof measure !== 'number') {\n throw new Error('measure is not a number');\n }\n\n this.northEast = this.northEast\n .destinationPoint(measure, 0)\n .move(measure, Math.PI / 2);\n\n this.southWest = this.southWest.clone()\n .destinationPoint(measure, -Math.PI / 2)\n .destinationPoint(measure, Math.PI);\n\n return this;\n }\n\n /**\n * Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\n * For example, a ratio of 0.5 extends the bounds by 50% in each direction.\n * Negative values will retract the bounds.\n */\n pad(bufferRatio: number): BoundingBox {\n const sw = this.southWest;\n const ne = this.northEast;\n\n const heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio;\n const widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\n\n this.southWest = new Coordinates(sw.lat - heightBuffer, sw.lng - widthBuffer);\n this.northEast = new Coordinates(ne.lat + heightBuffer, ne.lng + widthBuffer);\n\n return this;\n }\n\n /**\n * Returns the southwest corner of the bounding box.\n */\n getSouthWest() {\n return this.southWest;\n }\n\n /**\n * Returns the northeast corner of the bounding box.\n */\n getNorthEast() {\n return this.northEast;\n }\n\n /**\n * Returns the northwest corner of the bounding box.\n */\n getNorthWest() {\n return new Coordinates(this.getNorth(), this.getWest());\n }\n\n /**\n * Returns the southeast corner of the bounding box.\n */\n getSouthEast() {\n return new Coordinates(this.getSouth(), this.getEast());\n }\n\n /**\n * Returns the west edge of the bounding box.\n */\n getWest() {\n return this.southWest.lng;\n }\n\n /**\n * Returns the south edge of the bounding box.\n */\n getSouth() {\n return this.southWest.lat;\n }\n\n /**\n * Returns the east edge of the bounding box.\n */\n getEast() {\n return this.northEast.lng;\n }\n\n /**\n * Returns the north edge of the bounding box.\n */\n getNorth() {\n return this.northEast.lat;\n }\n\n static equals(bb1: BoundingBox, bb2: BoundingBox) {\n return Coordinates.equals(bb1.northEast, bb2.northEast)\n && Coordinates.equals(bb1.southWest, bb2.southWest);\n }\n\n equals(other: BoundingBox) {\n return BoundingBox.equals(this, other);\n }\n\n /**\n * Create a BoundingBox from a WSEN array\n */\n static fromArray(bounds: [number, number, number, number]) {\n return new BoundingBox(\n new Coordinates(bounds[3], bounds[2]),\n new Coordinates(bounds[1], bounds[0])\n );\n }\n\n static fromCoordinates(coords: Coordinates[]) {\n if (coords.length === 0) {\n return null;\n }\n return coords.reduce(\n (acc, _coords) => acc.extend(_coords),\n new BoundingBox(coords[0], coords[0])\n );\n }\n\n /**\n * Returns the WSEN array\n */\n toArray(): [number, number, number, number] {\n return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()];\n }\n}\n\nexport default BoundingBox;\n","import { EPS_MM } from '../Constants.js';\nimport { RelativePositionJson } from '../types.js';\n\nclass RelativePosition {\n\n x: number;\n y: number;\n z: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n x: number, y: number, z: number,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n clone() {\n return new RelativePosition(this.x, this.y, this.z, this.time, this.accuracy, this.bearing);\n }\n\n\n /**\n * Compares two RelativePosition\n * @param {RelativePosition} pos1 position 1\n * @param {RelativePosition} pos2 position 2\n * @param {Number} eps x, y, z epsilon in meters (default: 1e-3 [= 1mm])\n */\n static equals(pos1: RelativePosition | null, pos2: RelativePosition | null, eps = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof RelativePosition) || !(pos2 instanceof RelativePosition)) {\n return false;\n }\n\n return Math.abs(pos2.x - pos1.x) < eps\n && Math.abs(pos2.y - pos1.y) < eps\n && Math.abs(pos2.z - pos1.z) < eps\n && pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: RelativePosition) {\n return RelativePosition.equals(this, other);\n }\n\n toJson(): RelativePositionJson {\n return {\n x: this.x,\n y: this.y,\n z: this.z,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: RelativePositionJson) {\n return new RelativePosition(json.x, json.y, json.z, json.time, json.accuracy, json.bearing);\n }\n}\n\nexport default RelativePosition;\n","import RelativePosition from './RelativePosition.js';\n\n/**\n * Position is defined in EUS (East-Up-South) frame with: x pointing to East, y pointing to Up, z pointing to South\n * This frame is close to ThreeJS / OpenGL frame.\n */\nclass GeoRelativePosition extends RelativePosition { }\n\nexport default GeoRelativePosition;\n","import booleanPointInPolygon from '@turf/boolean-point-in-polygon';\n\nimport { Quaternion, Vector3, Vector3_t } from '@wemap/maths';\nimport { BuildingLevel, GeoRefJson } from '../types.js';\n\nimport Coordinates from './Coordinates.js';\n\nclass GeoRef {\n\n scale = 1;\n heading = 0;\n\n constructor(public origin: Coordinates, public buildingLevels: BuildingLevel[] = []) { }\n\n /**\n * LocalPosition in ENU frame\n */\n localToWorld(localPosition: Vector3_t) {\n const enuTranslationScaled = Vector3.multiplyScalar(localPosition, this.scale);\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);\n const enuToEcefRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.enuToEcefRotation);\n const ecefTranslation = Quaternion.rotate(enuToEcefRotationOrigin, enuTranslationScaled);\n const ecef = Vector3.sum(this.origin.ecef, ecefTranslation);\n const coordinates = Coordinates.fromECEF(ecef);\n\n const alt = coordinates.alt!;\n coordinates.heightFromGround = coordinates.alt! - this.origin.alt!\n\n /*\n * Retrieve level and altitude\n */\n\n const updateLevelAndHeightFromFloor = (buildingLevel: BuildingLevel) => {\n coordinates.level = buildingLevel.id;\n coordinates.heightFromFloor = alt - buildingLevel.floorAltitude;\n }\n\n // 1. If georef does not have buildings level, do not update level field.\n if (!this.buildingLevels.length) {\n return coordinates;\n }\n \n // 2. Find building levels which corresponds to coordinates altitude\n const buildingLevelsByAltitude = this.buildingLevels.filter(buildingLevel => buildingLevel.floorAltitude <= alt && buildingLevel.ceilingAltitude >= alt)\n // If no intersection, the position is outdoor\n if (!buildingLevelsByAltitude.length) {\n return coordinates;\n }\n\n // 3. Find building levels which also includes coordinates 2D position\n const geojsonPt = [coordinates.lng, coordinates.lat];\n let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometries.some(geom => booleanPointInPolygon(geojsonPt, geom)));\n \n // If intersection is found, take the first and update level by its id\n if (buildingLevel) {\n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // If there is no interesection and levels have geometry, the position is outdoor\n const hasLevelGeometries = (bl : BuildingLevel) => bl.geometries.length !== 0;\n if (buildingLevelsByAltitude.every(hasLevelGeometries)) {\n return coordinates;\n }\n\n // 4. Try fallbacks because geometry is optionnal for the moment (March 2024)\n \n // If building geometries does not exist, let's consider the level geometry as global/infinity.\n if (buildingLevelsByAltitude.every(bl => !hasLevelGeometries(bl))) {\n // As we cannot decide which building level should be selected, take the first!\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // This means some buildings levels have geometry and some others not. This means there is a data problem.\n // Anyway takes first\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n /**\n * LocalPosition in ENU frame\n */\n worldToLocal(coords: Coordinates) {\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], -this.heading);\n const ecefToEnuRotationOrigin = Quaternion.multiply(this.origin.ecefToEnuRotation, rotationOffset);\n const ecefTranslation = Vector3.subtract(coords.ecef, this.origin.ecef);\n const ecefTranslationScaled = Vector3.multiplyScalar(ecefTranslation, 1 / this.scale);\n return Quaternion.rotate(ecefToEnuRotationOrigin, ecefTranslationScaled);\n }\n\n toJson(): GeoRefJson {\n return {\n origin: this.origin.toJson(),\n ...(this.scale !== 1 && { scale: this.scale }),\n ...(this.heading !== 0 && { heading: this.heading })\n };\n }\n\n static fromJson(json: GeoRefJson) {\n const geoRef = new GeoRef(Coordinates.fromJson(json.origin));\n geoRef.scale = typeof json.scale !== 'undefined' ? json.scale : 1;\n geoRef.heading = typeof json.heading !== 'undefined' ? json.heading : 0;\n return geoRef;\n }\n}\n\nexport default GeoRef;\n","import {\n Rotations, Quaternion, rad2deg, deg2rad,\n Quaternion_t, EulerAngles_t, EulerAnglesDegrees_t\n} from '@wemap/maths';\nimport { AttitudeJson } from '../types';\n\nclass Attitude {\n\n _quaternion: Quaternion_t = [1, 0, 0, 0];\n _heading: number | null = null;\n _eulerAngles: EulerAngles_t | null = null;\n _time: number | null = null;\n _accuracy: number | null = null;\n\n constructor(quaternion: Quaternion_t,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.quaternion = quaternion;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n static unitary() {\n return new Attitude([1, 0, 0, 0]);\n }\n\n\n get quaternion() {\n return this._quaternion;\n }\n\n set quaternion(quaternion) {\n if (Math.abs(1 - Quaternion.norm(quaternion)) > 1e-4) {\n throw new Error('quaternion is not a unit quaternion');\n }\n this._quaternion = quaternion;\n this._heading = null;\n this._eulerAngles = null;\n }\n\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n get eulerAngles(): EulerAngles_t {\n if (this._eulerAngles === null) {\n this._eulerAngles = Rotations.quaternionToEulerZXY(this.quaternion);\n }\n return this._eulerAngles;\n }\n\n get eulerAnglesDegrees(): EulerAnglesDegrees_t {\n return this.eulerAngles.map(x => rad2deg(x)) as EulerAnglesDegrees_t;\n }\n\n get heading() {\n if (this._heading === null) {\n let offset = 0;\n if (typeof (window) !== 'undefined' && window && window.orientation) {\n offset = deg2rad(window.orientation);\n }\n this._heading = Rotations.getHeadingFromQuaternion(this.quaternion) + offset;\n }\n return this._heading;\n }\n\n get headingDegrees() {\n return rad2deg(this.heading);\n }\n\n\n static equals(att1: Attitude | null, att2: Attitude | null) {\n\n // Handle null comparison\n if (att1 === null && att1 === att2) {\n // TODO not sure to return true here.\n return true;\n }\n\n if (!(att1 instanceof Attitude) || !(att2 instanceof Attitude)) {\n return false;\n }\n\n if (att1 === att2) {\n return true;\n }\n\n return Quaternion.equals(att1.quaternion, att2.quaternion);\n }\n\n equals(other: Attitude) {\n return Attitude.equals(this, other);\n }\n\n toJson(): AttitudeJson {\n if (this.time === null && this.accuracy === null) {\n return this.quaternion;\n }\n return {\n q: this.quaternion,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n\n static fromJson(json: AttitudeJson) {\n if (Array.isArray(json)) {\n return new Attitude(json, null, null);\n }\n return new Attitude(json.q, json.time, json.accuracy);\n }\n\n\n clone() {\n return new Attitude(this.quaternion.slice(0) as Quaternion_t, this.time, this.accuracy);\n }\n\n /**\n * Calculate the relative attitude between two given attitudes\n */\n static diff(attitudeStart: Attitude, attitudeEnd: Attitude) {\n\n const quaternionDiff = Quaternion.multiply(\n Quaternion.inverse(attitudeStart.quaternion),\n attitudeEnd.quaternion\n );\n\n let timeDiff = null;\n if (attitudeEnd.time !== null && attitudeStart.time !== null) {\n timeDiff = attitudeEnd.time - attitudeStart.time;\n }\n\n let accuracyDiff = null;\n if (attitudeStart.accuracy !== null && attitudeEnd.accuracy !== null) {\n // Approximation\n accuracyDiff = Math.max(attitudeEnd.accuracy - attitudeStart.accuracy);\n }\n\n return new Attitude(quaternionDiff, timeDiff, accuracyDiff);\n }\n}\n\nexport default Attitude;\n","import { Quaternion } from '@wemap/maths';\nimport { AbsoluteHeadingJson } from '../types.js';\n\nimport Attitude from './Attitude.js';\n\nclass AbsoluteHeading {\n\n heading: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n\n constructor(heading: number,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.heading = heading;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n toAttitude() {\n /**\n * Heading is given around z-axis in NED frame and our attitude in ENU frame, that is why\n * -1* is applied to heading.\n */\n return new Attitude(\n Quaternion.fromAxisAngle([0, 0, 1], -this.heading),\n this.time,\n this.accuracy\n );\n }\n\n\n /**\n * Compares two AbsoluteHeading\n * @param {AbsoluteHeading} heading1 heading 1\n * @param {AbsoluteHeading} heading2 heading 2\n */\n static equals(heading1: AbsoluteHeading | null, heading2: AbsoluteHeading | null) {\n\n // Handle null comparison\n if (heading1 === null && heading1 === heading2) {\n return true;\n }\n\n if (!(heading1 instanceof AbsoluteHeading) || !(heading2 instanceof AbsoluteHeading)) {\n return false;\n }\n\n return Math.abs(heading1.heading - heading2.heading) < 1e-8;\n }\n\n equals(other: AbsoluteHeading | null) {\n return AbsoluteHeading.equals(this, other);\n }\n\n toJson(): AbsoluteHeadingJson {\n return {\n heading: this.heading,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n static fromJson(json: AbsoluteHeadingJson) {\n return new AbsoluteHeading(json.heading, json.time, json.accuracy);\n }\n\n clone() {\n return new AbsoluteHeading(this.heading, this.time, this.accuracy);\n }\n}\n\nexport default AbsoluteHeading;\n"],"names":["str","wrap","deg2rad","rad2deg","Quaternion","Vector3","positiveMod","coords","buildingLevel","Rotations"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -340,7 +340,7 @@ class Coordinates {
340
340
  if (Math.abs(lat) <= 90) {
341
341
  this._lat = lat;
342
342
  } else {
343
- throw new Error("lat argument is not in [-90; 90]");
343
+ throw new Error(`lat argument is not in [-90; 90], value is ${lat}`);
344
344
  }
345
345
  this._ecef = null;
346
346
  }
@@ -1109,15 +1109,16 @@ class GeoRef {
1109
1109
  return coordinates;
1110
1110
  }
1111
1111
  const geojsonPt = [coordinates.lng, coordinates.lat];
1112
- let buildingLevel = buildingLevelsByAltitude.find((buildingLevel2) => buildingLevel2.geometry && booleanPointInPolygon(geojsonPt, buildingLevel2.geometry));
1112
+ let buildingLevel = buildingLevelsByAltitude.find((buildingLevel2) => buildingLevel2.geometries.some((geom) => booleanPointInPolygon(geojsonPt, geom)));
1113
1113
  if (buildingLevel) {
1114
1114
  updateLevelAndHeightFromFloor(buildingLevel);
1115
1115
  return coordinates;
1116
1116
  }
1117
- if (buildingLevelsByAltitude.every((bl) => Boolean(bl.geometry))) {
1117
+ const hasLevelGeometries = (bl) => bl.geometries.length !== 0;
1118
+ if (buildingLevelsByAltitude.every(hasLevelGeometries)) {
1118
1119
  return coordinates;
1119
1120
  }
1120
- if (buildingLevelsByAltitude.every((bl) => !Boolean(bl.geometry))) {
1121
+ if (buildingLevelsByAltitude.every((bl) => !hasLevelGeometries(bl))) {
1121
1122
  buildingLevel = buildingLevelsByAltitude[0];
1122
1123
  updateLevelAndHeightFromFloor(buildingLevel);
1123
1124
  return coordinates;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/Constants.ts","../src/coordinates/Level.ts","../src/coordinates/Coordinates.ts","../src/coordinates/UserPosition.ts","../src/Utils.ts","../src/coordinates/BoundingBox.ts","../src/coordinates/RelativePosition.ts","../src/coordinates/GeoRelativePosition.ts","../src/coordinates/GeoRef.ts","../src/rotations/Attitude.ts","../src/rotations/AbsoluteHeading.ts"],"sourcesContent":["export const R_MAJOR = 6378137.0;\nexport const R_MINOR = 6356752.3142;\nexport const EARTH_GRAVITY = 9.80665;\n\n/**\n * latitude and longitude epsilon in degrees\n * 1e-8° correspond to ~1mm at latitude = 0\n */\nexport const EPS_DEG_MM = 1e-8;\n\n/**\n * epsilon in meters which corresponds to 1 millimeter\n */\nexport const EPS_MM = 1e-3;\n\n\nexport const ELLIPSOID_FLATNESS = (R_MAJOR - R_MINOR) / R_MAJOR;\n\nexport const ECCENTRICITY = Math.sqrt(ELLIPSOID_FLATNESS * (2 - ELLIPSOID_FLATNESS));\nexport const ECCENTRICITY_2 = ECCENTRICITY * ECCENTRICITY;\n\nexport const R_MAJOR_2 = R_MAJOR * R_MAJOR;\nexport const R_MAJOR_4 = R_MAJOR_2 * R_MAJOR_2;\nexport const R_MINOR_2 = R_MINOR * R_MINOR;\nexport const R_MINOR_4 = R_MINOR_2 * R_MINOR_2;\nexport const CIRCUMFERENCE = R_MAJOR * 2 * Math.PI;\n","import { Level_t } from \"../types\";\n\n/**\n * A Level is the representation of a building floor number\n * A level can be a simple number or a range (low, up)\n * The range is an array of two numbers\n */\nclass Level {\n\n static VERIFY_TYPING = false;\n\n static checkType(level: Level_t) {\n if (level === null) {\n return;\n }\n if (typeof level === 'number' && !isNaN(level)) {\n return;\n }\n if (Array.isArray(level) && level.length === 2) {\n const [low, up] = level;\n if (typeof low === 'number' && !isNaN(low)\n && typeof up === 'number' && !isNaN(up)) {\n if (low > up || low === up) {\n throw Error(`Invalid level range: [${low}, ${up}]`);\n }\n return;\n }\n }\n throw Error(`Unknown level format: ${level}`);\n }\n\n /**\n * Return true if the level is a range, false otherwise\n */\n static isRange(level: Level_t): level is [number, number] {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n return Array.isArray(level);\n }\n\n static clone(level: Level_t): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n if (typeof level === 'number') {\n return level;\n }\n\n return [level[0], level[1]];\n }\n\n /**\n * Create a level from a string (eg. 1, -2, 1;2, -2;3, 2;-1, 0.5;1 ...)\n */\n static fromString(str: string | null): Level_t {\n\n if (str === null) {\n return null;\n }\n\n if (typeof str !== 'string' || !str.length) {\n throw Error(`argument must be a non empty string, got ${typeof str}`);\n }\n\n if (!isNaN(Number(str))) {\n return parseFloat(str);\n }\n\n const splited = str.split(';');\n if (splited.length > 1) {\n const levels = splited.map(str => Number(str));\n const low = Math.min(...levels);\n const up = Math.max(...levels);\n Level.checkType([low, up]);\n return [low, up];\n } else {\n const rangeSeparator = str.substring(1).indexOf('-') + 1;\n if (rangeSeparator > 0) {\n const low = Number(str.substring(0, rangeSeparator));\n const up = Number(str.substring(rangeSeparator + 1));\n Level.checkType([low, up]);\n return [low, up];\n }\n }\n\n throw Error(`Cannot parse following level: ${str}`);\n }\n\n\n /**\n * Returns if a level is contained in another\n * @param {null|number|[number, number]} container The container level\n * @param {null|number|[number, number]} targeted The targeted level\n */\n static contains(container: Level_t, targeted: Level_t): boolean {\n if (Level.VERIFY_TYPING) {\n Level.checkType(container);\n Level.checkType(targeted);\n }\n\n // Covers null and number\n if (container === targeted) {\n return true;\n }\n\n if (Array.isArray(container)) {\n if (Array.isArray(targeted)) {\n return container[0] <= targeted[0] && container[1] >= targeted[1];\n }\n if (targeted === null) {\n return false;\n }\n return container[0] <= targeted && container[1] >= targeted;\n }\n if (container === null || targeted === null) {\n return false;\n }\n return container <= (targeted as [number, number])[0]\n && container >= (targeted as [number, number])[1];\n }\n\n /**\n * Retrieve the intersection of two levels\n * null n null => null\n * null n 1 => null // Conception choice\n * null n [1,2] => null // Conception choice\n * 1 n 1 => 1\n * 1 n 2 => null\n * 1 n [1,2] => 1\n * 1 n [0,2] => 1\n * 1 n [2,3] => null\n * [1,2] n [1,2] => [1,2]\n * [1,2] n [2,3] => 2\n * [1,2] n [3,4] => null\n */\n static intersection(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (Level.equals(first, second)) {\n return Level.clone(first);\n }\n\n if (typeof first === 'number' && typeof second === 'number') {\n return first === second ? first : null;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (Level.contains(first, second)) {\n return second;\n }\n return null;\n }\n if (!Array.isArray(first) && Array.isArray(second)) {\n if (Level.contains(second, first)) {\n return first;\n }\n return null;\n }\n\n // There are two ranges\n const low = Math.max((first as [number, number])[0], (second as [number, number])[0]);\n const up = Math.min((first as [number, number])[1], (second as [number, number])[1]);\n if (up === low) {\n return up;\n }\n return up < low ? null : [low, up];\n }\n\n /**\n * Retrieve the intersection of two levels\n * @param {null|number|[number, number]} first The first level\n * @param {null|number|[number, number]} second The second level\n * @returns {boolean}\n */\n static intersect(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null && second === null) {\n return true;\n }\n\n return Level.intersection(first, second) !== null;\n }\n\n /**\n * Retrieve the union of two levels\n * null u null => null\n * null u 1 => null // Conception choice\n * null u [1,2] => null // Conception choice\n * 1 u 1 => 1\n * 1 u 2 => [1,2]\n * 1 u [1,2] => [1,2]\n * 1 u [0,2] => [0,2]\n * 1 u [2,3] => [1,3]\n * [1,2] u [1,2] => [1,2]\n * [1,2] u [2,3] => [1,3]\n * [1,2] u [3,4] => [1,4]\n */\n static union(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return Level.clone(first);\n }\n\n if (second === null) {\n return null;\n // return Level.clone(first);\n }\n\n if (first === null) {\n return null;\n // return Level.clone(second);\n }\n\n let low, up;\n if (!Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first, second);\n up = Math.max(first, second);\n } else if (Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first[0], second);\n up = Math.max(first[1], second);\n } else if (!Array.isArray(first) && Array.isArray(second)) {\n low = Math.min(second[0], first);\n up = Math.max(second[1], first);\n } else {\n /* if (Array.isArray(first) && Array.isArray(second)) */\n low = Math.min((first as [number, number])[0], (second as [number, number])[0]);\n up = Math.max((first as [number, number])[1], (second as [number, number])[1]);\n }\n\n if (low === up) {\n return low;\n }\n return [low, up];\n }\n\n /**\n * Multiply a level by a factor\n * @param {null|number|[number, number]} level the level to multiply\n * @param {number} factor\n * @returns {null|number|[number, number]}\n */\n static multiplyBy(level: Level_t, factor: number): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n\n if (level === null) {\n return null;\n }\n\n return Array.isArray(level) ? [level[0] * factor, level[1] * factor] : level * factor;\n }\n\n static toString(level: Level_t): string | null {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n return Array.isArray(level) ? level[0] + ';' + level[1] : String(level);\n }\n\n static equals(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return true;\n }\n\n if (Array.isArray(first) && Array.isArray(second)) {\n return first[0] === second[0] && first[1] === second[1];\n }\n\n return false;\n }\n\n\n static diff(first: Level_t, second: Level_t): null | number {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (!Array.isArray(first) && !Array.isArray(second)) {\n return second - first;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (first[0] === second) {\n return second - first[1];\n }\n if (first[1] === second) {\n return second - first[0];\n }\n return null;\n }\n\n if (Array.isArray(second) && !Array.isArray(first)) {\n if (first === second[0]) {\n return second[1] - first;\n }\n if (first === second[1]) {\n return second[0] - first;\n }\n return null;\n }\n\n if (Level.equals(first, second)) {\n return 0;\n }\n\n return null;\n }\n}\n\nexport default Level;\n","import {\n deg2rad, Vector3, Quaternion, rad2deg, wrap, Vector3_t, Quaternion_t\n} from '@wemap/maths';\nimport { EPS_DEG_MM, EPS_MM, R_MAJOR } from '../Constants.js';\n\nimport { CoordinatesCompressedJson, CoordinatesJson, Level_t } from '../types.js';\nimport Level from './Level.js';\n\n/**\n * A Coordinates position using at least latitude (lat) and longitude (lng).\n * Optionnal fields are: altitude (alt) and level.\n *\n * Basic geo methods are directly accessibles from here:\n * distanceTo, bearingTo, toEcef...\n *\n * /!\\ This class has been adapted to use earth as a sphere and not as an ellipsoid\n * /!\\ So, this class does not stricly represent WGS84 coordinates anymore\n * /!\\ This modifications have been made for computational improvements.\n */\nclass Coordinates {\n\n private _lat!: number;\n private _lng!: number;\n private _alt: number | null = null;\n private _level: Level_t | null = null;\n private _heightFromFloor: number | null = null;\n private _heightFromGround: number | null = null;\n\n private _ecef: Vector3_t | null;\n\n autoWrap = true;\n\n constructor(lat: number, lng: number, alt: number | null = null, level: Level_t | null = null) {\n this.lat = lat;\n this.lng = lng;\n this.alt = alt;\n this.level = level;\n this._ecef = null;\n }\n\n get lat() {\n return this._lat;\n }\n\n set lat(lat: number) {\n if (Math.abs(lat) <= 90) {\n this._lat = lat;\n } else {\n throw new Error('lat argument is not in [-90; 90]');\n }\n this._ecef = null;\n }\n\n get latitude() {\n return this._lat;\n }\n\n set latitude(_) {\n throw new Error('Please use Coordinates#lat setter instead of Coordinate#latitude');\n }\n\n get lng() {\n return this._lng;\n }\n\n set lng(lng) {\n this._lng = lng;\n if (this.autoWrap) {\n this.wrap();\n }\n this._ecef = null;\n }\n\n get longitude() {\n return this._lng;\n }\n\n set longitude(_) {\n throw new Error('Please use Coordinates#lng setter instead of Coordinate#longitude');\n }\n\n /**\n * alt does not denote the altitude of a point but its height from\n * the \"level\" field (if defined) or from the ground\n */\n get alt() {\n return this._alt;\n }\n\n set alt(alt) {\n this._alt = alt;\n this._ecef = null;\n }\n\n get level() {\n return this._level;\n }\n\n set level(level) {\n Level.checkType(level);\n this._level = level;\n }\n\n get heightFromFloor() {\n return this._heightFromFloor;\n }\n\n set heightFromFloor(heightFromFloor) {\n this._heightFromFloor = heightFromFloor;\n }\n\n get heightFromGround() {\n return this._heightFromGround;\n }\n\n set heightFromGround(heightFromGround) {\n this._heightFromGround = heightFromGround;\n }\n\n /**\n * Deep clone coordinates\n */\n clone() {\n const output = new Coordinates(this.lat, this.lng, this.alt);\n if (this.level !== null) {\n output.level = Level.clone(this.level);\n }\n return output;\n }\n\n wrap() {\n if (this._lng <= -180 || this._lng > 180) {\n this._lng = wrap(this._lng, -180, 180);\n }\n }\n\n\n static equals(pos1: Coordinates | null, pos2: Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof Coordinates) || !(pos2 instanceof Coordinates)) {\n return false;\n }\n\n return Math.abs(pos2.lat - pos1.lat) < eps\n && Math.abs(pos2.lng - pos1.lng) < eps\n && (pos1.alt === pos2.alt\n || pos1.alt !== null && pos2.alt !== null\n && Math.abs(pos2.alt - pos1.alt) < epsAlt)\n && Level.equals(pos1.level, pos2.level);\n }\n\n equals(other: Coordinates) {\n return Coordinates.equals(this, other);\n }\n\n /**\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n /**\n * Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n move(distance: number, bearing: number, elevation: number | null = null) {\n\n const dR = distance / R_MAJOR;\n const cosDr = Math.cos(dR);\n const sinDr = Math.sin(dR);\n\n const phi1 = deg2rad(this.lat);\n const lambda1 = deg2rad(this.lng);\n\n const phi2 = Math.asin(\n Math.sin(phi1) * cosDr\n + Math.cos(phi1) * sinDr * Math.cos(bearing)\n );\n const lambda2 = lambda1 + Math.atan2(\n Math.sin(bearing) * sinDr * Math.cos(phi1),\n cosDr - Math.sin(phi1) * Math.sin(phi2)\n );\n\n this.lat = rad2deg(phi2);\n this.lng = rad2deg(lambda2);\n\n if (elevation !== null) {\n if (this.alt === null) {\n throw new Error('Point altitude is not defined');\n }\n this.alt += elevation;\n }\n\n return this;\n }\n\n /**\n * Returns a distance between two points in meters\n */\n distanceTo(location2: Coordinates) {\n const lat1 = this.lat;\n const lng1 = this.lng;\n\n const lat2 = location2.lat;\n const lng2 = location2.lng;\n\n const dlat = deg2rad(lat2 - lat1);\n const dlng = deg2rad(lng2 - lng1);\n\n const dlngsin = Math.sin(dlng / 2);\n const dlatsin = Math.sin(dlat / 2);\n const lat1rad = deg2rad(lat1);\n const lat1cos = Math.cos(lat1rad);\n const lat2rad = deg2rad(lat2);\n const lat2cos = Math.cos(lat2rad);\n const angle = dlatsin * dlatsin + lat1cos * lat2cos * dlngsin * dlngsin;\n\n // arctangent\n const tangy = Math.sqrt(angle);\n const tangx = Math.sqrt(1 - angle);\n const cosn = 2 * Math.atan2(tangy, tangx);\n\n return R_MAJOR * cosn;\n }\n\n static distanceBetween(point1: Coordinates, point2: Coordinates) {\n return point1.distanceTo(point2);\n }\n\n bearingTo(location2: Coordinates) {\n const lat1 = deg2rad(this.lat);\n const lat2 = deg2rad(location2.lat);\n const diffLng = deg2rad(location2.lng - this.lng);\n\n return Math.atan2(Math.sin(diffLng) * Math.cos(lat2),\n Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(diffLng));\n }\n\n static bearingTo(point1: Coordinates, point2: Coordinates) {\n return point1.bearingTo(point2);\n }\n\n\n /**\n * ECEF Transformations\n * Here we used a light version of ECEF considering earth\n * as a sphere instead of an ellipse\n */\n\n get enuToEcefRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + deg2rad(this.lng));\n const rot2 = Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - deg2rad(this.lat));\n return Quaternion.multiply(rot1, rot2);\n }\n\n get ecefToEnuRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([1, 0, 0], deg2rad(this.lat) - Math.PI / 2);\n const rot2 = Quaternion.fromAxisAngle([0, 0, 1], -deg2rad(this.lng) - Math.PI / 2);\n return Quaternion.multiply(rot1, rot2);\n }\n\n /**\n * https://gist.github.com/klucar/1536194\n * Adapted for spherical formula\n */\n get ecef(): Vector3_t {\n\n if (!this._ecef) {\n const lat = deg2rad(this.lat);\n const lng = deg2rad(this.lng);\n const alt = this.alt || 0;\n\n const x = (R_MAJOR + alt) * Math.cos(lat) * Math.cos(lng);\n const y = (R_MAJOR + alt) * Math.cos(lat) * Math.sin(lng);\n const z = (R_MAJOR + alt) * Math.sin(lat);\n\n this._ecef = [x, y, z];\n }\n\n return this._ecef;\n }\n\n\n static fromECEF(ecef: Vector3_t): Coordinates {\n\n const x = ecef[0];\n const y = ecef[1];\n const z = ecef[2];\n\n const p = Math.sqrt(x ** 2 + y ** 2);\n\n let lng = Math.atan2(y, x);\n const lat = Math.atan2(z, p);\n const alt = p / Math.cos(lat) - R_MAJOR;\n\n lng = lng % (2 * Math.PI);\n\n const newPoint = new Coordinates(rad2deg(lat), rad2deg(lng), alt);\n newPoint._ecef = ecef;\n return newPoint;\n }\n\n\n /**\n * https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere\n * Adapted to ECEF\n */\n getSegmentProjection(p1: Coordinates, p2: Coordinates): Coordinates | null {\n\n const a = Vector3.normalize(p1.ecef);\n const b = Vector3.normalize(p2.ecef);\n const c = Vector3.normalize(this.ecef);\n\n const G = Vector3.cross(a, b);\n if (Vector3.norm(G) === 0) {\n return null;\n }\n\n const F = Vector3.cross(c, G);\n const t = Vector3.normalize(Vector3.cross(G, F));\n\n const posECEF = Vector3.multiplyScalar(t, R_MAJOR);\n const poseCoordinates = Coordinates.fromECEF(posECEF);\n\n // poseCoordinates.alt is not 0 here due to the ECEF transformation residual.\n // So if p1.alt and p2.alt are defined we take the middle elevation between p1 and p2.\n // Otherwise we remove alt from projection because the residual has no sense.\n let alt;\n if (p1.alt !== null && p2.alt !== null) {\n // This formula is maybe not the best one.\n alt = (p1.alt + p2.alt) / 2;\n }\n const projection = new Coordinates(poseCoordinates.lat, poseCoordinates.lng,\n alt, Level.union(p1.level, p2.level));\n\n if (Math.abs((p1.distanceTo(p2) - p1.distanceTo(projection) - p2.distanceTo(projection))) > EPS_MM) {\n return null;\n }\n\n return projection;\n }\n\n /**\n * Input / Output\n */\n\n toString() {\n let str = '[' + this._lat.toFixed(7) + ', ' + this._lng.toFixed(7);\n if (this._alt !== null) {\n str += ', ' + this._alt.toFixed(2);\n }\n if (this._level !== null) {\n str += ', [' + Level.toString(this._level) + ']';\n }\n str += ']';\n return str;\n }\n\n toJson(): CoordinatesJson {\n return {\n lat: Number(this.lat.toFixed(8)),\n lng: Number(this.lng.toFixed(8)),\n ...(this.alt !== null && { alt: Number(this.alt.toFixed(3)) }),\n ...(this.level !== null && { level: this.level })\n };\n }\n\n static fromJson(json: CoordinatesJson) {\n return new Coordinates(json.lat, json.lng, json.alt, json.level);\n }\n\n\n toCompressedJson(): CoordinatesCompressedJson {\n if (this.level !== null) {\n return [\n Number(this.lat.toFixed(8)),\n Number(this.lng.toFixed(8)),\n this.level\n ];\n }\n return [Number(this.lat.toFixed(8)), Number(this.lng.toFixed(8))];\n }\n\n static fromCompressedJson(json: CoordinatesCompressedJson) {\n const coords = new Coordinates(json[0], json[1]);\n if (json.length > 2) {\n coords.level = json[2] as number | [number, number];\n }\n return coords;\n }\n}\n\nexport default Coordinates;\n","import Coordinates from './Coordinates.js';\nimport { Level_t, UserPositionJson } from '../types.js';\nimport { EPS_DEG_MM, EPS_MM } from '../Constants.js';\n\n/**\n * A Coordinates User Position is a Coordinates position with specific data related to user (bearing, time, accuracy)\n */\nclass UserPosition extends Coordinates {\n\n private _time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n lat: number, lng: number, alt: number | null = null, level: Level_t = null,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n super(lat, lng, alt, level);\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n move(distance: number, bearing: number, elevation: number | null = null) {\n super.move(distance, bearing, elevation);\n return this;\n }\n\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n\n // Create a UserPosition with lat, lng, alt from Coordinates coordinates and\n // other fields from another UserPosition\n static fromCoordinates(coordinates: Coordinates) {\n return new UserPosition(coordinates.lat, coordinates.lng,\n coordinates.alt, coordinates.level);\n }\n\n clone() {\n const cloned = UserPosition.fromCoordinates(super.clone());\n cloned.time = this.time;\n cloned.accuracy = this.accuracy;\n cloned.bearing = this.bearing;\n return cloned;\n }\n\n\n static equals(pos1: UserPosition | Coordinates | null,\n pos2: UserPosition | Coordinates | null,\n eps = EPS_DEG_MM, epsAlt = EPS_MM\n ) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof UserPosition) || !(pos2 instanceof UserPosition)) {\n return false;\n }\n\n if (!super.equals(pos1, pos2, eps, epsAlt)) {\n return false;\n }\n\n return pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: UserPosition | Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n return UserPosition.equals(this, other, eps, epsAlt);\n }\n\n\n toJson(): UserPositionJson {\n return {\n ...super.toJson(),\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: UserPositionJson) {\n const position = UserPosition.fromCoordinates(Coordinates.fromJson(json));\n if (typeof json.time !== 'undefined') {\n position.time = json.time;\n }\n if (typeof json.accuracy !== 'undefined') {\n position.accuracy = json.accuracy;\n }\n if (typeof json.bearing !== 'undefined') {\n position.bearing = json.bearing;\n }\n return position;\n }\n}\n\nexport default UserPosition;\n","/* eslint-disable max-statements */\n\nimport { deg2rad, positiveMod } from '@wemap/maths';\nimport { EPS_MM } from './Constants.js';\n\nimport Coordinates from './coordinates/Coordinates.js';\nimport UserPosition from './coordinates/UserPosition.js';\nimport Level from './coordinates/Level.js';\nimport { Level_t } from './types.js';\n\nexport type RouteSample = Coordinates & { bearing: number };\n\n/**\n * Sample a route of Coordinates\n * @param route ordered points\n * @param stepSize step size to sample\n * @param maxLength max route length to sample\n */\nexport function sampleRoute(\n route: Coordinates[],\n stepSize = 0.7,\n startSampling = 0,\n length = Number.MAX_VALUE\n) {\n\n const endSampling = startSampling + length;\n\n const sampledRoute = [];\n\n let lastSample: RouteSample;\n\n let totalDistanceTraveled = 0;\n let distanceToNextSample = 0;\n let startFound = false;\n\n for (let segmentIndex = 0; segmentIndex < route.length - 1; segmentIndex++) {\n\n const p1 = route[segmentIndex];\n const p2 = route[segmentIndex + 1];\n const segmentSize = p1.distanceTo(p2);\n const segmentBearing = p1.bearingTo(p2);\n\n let distanceTraveledOnSegment = 0;\n\n if (!startFound) {\n if (startSampling < totalDistanceTraveled + segmentSize) {\n startFound = true;\n distanceToNextSample = startSampling - totalDistanceTraveled;\n } else {\n totalDistanceTraveled += segmentSize;\n continue;\n }\n }\n\n lastSample = Object.assign(p1.clone(), { bearing: segmentBearing });\n while (distanceTraveledOnSegment + distanceToNextSample < segmentSize\n && totalDistanceTraveled + distanceToNextSample <= endSampling) {\n\n const newPoint = lastSample.destinationPoint(distanceToNextSample, segmentBearing) as RouteSample;\n newPoint.bearing = segmentBearing;\n sampledRoute.push(newPoint);\n lastSample = newPoint;\n\n distanceTraveledOnSegment += distanceToNextSample;\n totalDistanceTraveled += distanceToNextSample;\n distanceToNextSample = stepSize;\n }\n\n if (totalDistanceTraveled + distanceToNextSample > endSampling) {\n break;\n }\n\n const rest = segmentSize - distanceTraveledOnSegment;\n totalDistanceTraveled += rest;\n distanceToNextSample -= rest;\n }\n\n return sampledRoute;\n}\n\n/**\n * Trim a route of Coordinates\n * @param {Array.<Coordinates>} route ordered points\n * @param {Coordinates} startPosition position where the trim starts. startPosition has to be on the route.\n * @param {*} maxLength max route length\n */\nexport function trimRoute(route: Coordinates[], startPosition = route[0], length = Number.MAX_VALUE) {\n\n const newRoute = [];\n let previousPoint: Coordinates | null = null;\n\n let currentPointIndex;\n let cumulativeDistance = 0;\n\n if (route.length <= 1) {\n throw new Error('Route must have at least 2 points');\n }\n\n for (currentPointIndex = 1; currentPointIndex < route.length; currentPointIndex++) {\n\n const p1 = route[currentPointIndex - 1];\n const p2 = route[currentPointIndex];\n\n if (Coordinates.equals(startPosition, p1)) {\n newRoute.push(p1);\n previousPoint = p1;\n break;\n }\n\n const proj = startPosition.getSegmentProjection(p1, p2);\n if (proj && Coordinates.equals(startPosition, proj) && !proj.equals(p2)) {\n newRoute.push(proj);\n previousPoint = proj;\n break;\n }\n }\n\n if (!newRoute.length) {\n throw new Error('startPosition is not on the route');\n }\n\n while (previousPoint && currentPointIndex < route.length) {\n const currentPoint = route[currentPointIndex];\n const dist = previousPoint.distanceTo(currentPoint);\n if (cumulativeDistance + dist >= length\n || Math.abs(cumulativeDistance + dist - length) <= EPS_MM) {\n const bearing = previousPoint.bearingTo(currentPoint);\n const remainingLength = length - cumulativeDistance;\n const end = previousPoint.destinationPoint(remainingLength, bearing);\n newRoute.push(end);\n break;\n }\n newRoute.push(currentPoint);\n previousPoint = currentPoint;\n cumulativeDistance += dist;\n currentPointIndex++;\n }\n\n return newRoute;\n}\n\n\nexport function simplifyRoute(coords: Coordinates[], precisionAngle = deg2rad(5)) {\n\n const isClosed = (coords[0].equals(coords[coords.length - 1]));\n\n let newRoute = coords.slice(0, coords.length - (isClosed ? 1 : 0));\n\n const len = newRoute.length;\n for (let i = isClosed ? 0 : 1; i < len; i++) {\n\n const p0 = coords[positiveMod(i - 1, len)];\n const p1 = coords[i];\n const p2 = coords[positiveMod(i + 1, len)];\n\n const seg1Dir = p0.bearingTo(p1);\n const seg2Dir = p1.bearingTo(p2);\n\n if (Math.abs(seg2Dir - seg1Dir) < precisionAngle) {\n newRoute = newRoute.filter(coord => coord !== p1);\n }\n }\n\n if (isClosed) {\n newRoute.push(newRoute[0]);\n }\n\n return newRoute;\n}\n\nexport function geolocationPositionToUserPosition(geolocationPosition: GeolocationPosition) {\n if (geolocationPosition === null) {\n return null;\n }\n\n const { latitude, longitude, accuracy, heading } = geolocationPosition.coords;\n\n const userPosition = new UserPosition(latitude, longitude);\n userPosition.time = geolocationPosition.timestamp;\n userPosition.accuracy = accuracy;\n userPosition.bearing = heading ? deg2rad(heading) : null;\n return userPosition;\n}\n\nexport function calcDistance(coords: Coordinates[]) {\n return coords.reduce((acc, coords, idx, arr) =>\n acc + (idx ? arr[idx - 1].distanceTo(coords) : 0), 0);\n}\n\n\nexport function createSegmentsAtLevel(itineraryCoords: Coordinates[], segmentsLevel: Level_t, useMultiLevelSegments = true) {\n\n const itineraryCoordsLength = itineraryCoords.length;\n let previousLevelCorrespond = false;\n\n const segments: Coordinates[][] = [];\n let coordinates: Coordinates[] = [];\n for (let i = 0; i < itineraryCoordsLength; i++) {\n const coords = itineraryCoords[i];\n const levelCorrespond = Level.intersect(segmentsLevel, coords.level);\n\n if (useMultiLevelSegments && !levelCorrespond && previousLevelCorrespond) {\n coordinates.push(coords);\n } else if (levelCorrespond) {\n if (!previousLevelCorrespond) {\n coordinates = [];\n segments.push(coordinates);\n if (useMultiLevelSegments && i !== 0) {\n coordinates.push(itineraryCoords[i - 1]);\n }\n }\n coordinates.push(coords);\n }\n\n previousLevelCorrespond = levelCorrespond;\n }\n return segments;\n}","import Coordinates from './Coordinates.js';\n\nclass BoundingBox {\n\n northEast: Coordinates;\n southWest: Coordinates;\n\n constructor(northEast: Coordinates, southWest: Coordinates) {\n this.northEast = northEast;\n this.southWest = southWest;\n\n if (this.northEast && this.southWest && this.getNorth() < this.getSouth()) {\n throw new Error('Incorrect bounding box');\n }\n }\n\n /**\n * Returns the geographical coordinate equidistant from the bounding box's corners.\n */\n get center(): Coordinates {\n const latCenter = (this.southWest.lat + this.northEast.lat) / 2;\n const lngCenter = (this.northEast.lng + this.southWest.lng) / 2;\n return new Coordinates(latCenter, lngCenter);\n }\n\n /**\n * Check if a point is contained in the bounding box.\n */\n contains(point: Coordinates): boolean {\n return point.lat <= this.northEast.lat\n && point.lat >= this.southWest.lat\n && point.lng <= this.northEast.lng\n && point.lng >= this.southWest.lng;\n }\n\n /**\n * Extend the bounds to include a given LngLat or LngLatBounds.\n */\n extend(obj: Coordinates | BoundingBox): BoundingBox {\n const sw = this.southWest,\n ne = this.northEast;\n let sw2, ne2;\n\n if (obj instanceof Coordinates) {\n sw2 = obj;\n ne2 = obj;\n\n } else if (obj instanceof BoundingBox) {\n sw2 = obj.southWest;\n ne2 = obj.northEast;\n } else {\n throw new Error('Unknown parameter');\n }\n\n this.southWest = new Coordinates(\n Math.min(sw2.lat, sw.lat),\n Math.min(sw2.lng, sw.lng)\n );\n this.northEast = new Coordinates(\n Math.max(ne2.lat, ne.lat),\n Math.max(ne2.lng, ne.lng)\n );\n\n return this;\n }\n\n /**\n * This method extends the bounding box with a value in meters\n * /*\\ This method is not precise as distance differs in function of latitude\n */\n extendsWithMeasure(measure: number): BoundingBox {\n\n if (typeof measure !== 'number') {\n throw new Error('measure is not a number');\n }\n\n this.northEast = this.northEast\n .destinationPoint(measure, 0)\n .move(measure, Math.PI / 2);\n\n this.southWest = this.southWest.clone()\n .destinationPoint(measure, -Math.PI / 2)\n .destinationPoint(measure, Math.PI);\n\n return this;\n }\n\n /**\n * Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\n * For example, a ratio of 0.5 extends the bounds by 50% in each direction.\n * Negative values will retract the bounds.\n */\n pad(bufferRatio: number): BoundingBox {\n const sw = this.southWest;\n const ne = this.northEast;\n\n const heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio;\n const widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\n\n this.southWest = new Coordinates(sw.lat - heightBuffer, sw.lng - widthBuffer);\n this.northEast = new Coordinates(ne.lat + heightBuffer, ne.lng + widthBuffer);\n\n return this;\n }\n\n /**\n * Returns the southwest corner of the bounding box.\n */\n getSouthWest() {\n return this.southWest;\n }\n\n /**\n * Returns the northeast corner of the bounding box.\n */\n getNorthEast() {\n return this.northEast;\n }\n\n /**\n * Returns the northwest corner of the bounding box.\n */\n getNorthWest() {\n return new Coordinates(this.getNorth(), this.getWest());\n }\n\n /**\n * Returns the southeast corner of the bounding box.\n */\n getSouthEast() {\n return new Coordinates(this.getSouth(), this.getEast());\n }\n\n /**\n * Returns the west edge of the bounding box.\n */\n getWest() {\n return this.southWest.lng;\n }\n\n /**\n * Returns the south edge of the bounding box.\n */\n getSouth() {\n return this.southWest.lat;\n }\n\n /**\n * Returns the east edge of the bounding box.\n */\n getEast() {\n return this.northEast.lng;\n }\n\n /**\n * Returns the north edge of the bounding box.\n */\n getNorth() {\n return this.northEast.lat;\n }\n\n static equals(bb1: BoundingBox, bb2: BoundingBox) {\n return Coordinates.equals(bb1.northEast, bb2.northEast)\n && Coordinates.equals(bb1.southWest, bb2.southWest);\n }\n\n equals(other: BoundingBox) {\n return BoundingBox.equals(this, other);\n }\n\n /**\n * Create a BoundingBox from a WSEN array\n */\n static fromArray(bounds: [number, number, number, number]) {\n return new BoundingBox(\n new Coordinates(bounds[3], bounds[2]),\n new Coordinates(bounds[1], bounds[0])\n );\n }\n\n static fromCoordinates(coords: Coordinates[]) {\n if (coords.length === 0) {\n return null;\n }\n return coords.reduce(\n (acc, _coords) => acc.extend(_coords),\n new BoundingBox(coords[0], coords[0])\n );\n }\n\n /**\n * Returns the WSEN array\n */\n toArray(): [number, number, number, number] {\n return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()];\n }\n}\n\nexport default BoundingBox;\n","import { EPS_MM } from '../Constants.js';\nimport { RelativePositionJson } from '../types.js';\n\nclass RelativePosition {\n\n x: number;\n y: number;\n z: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n x: number, y: number, z: number,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n clone() {\n return new RelativePosition(this.x, this.y, this.z, this.time, this.accuracy, this.bearing);\n }\n\n\n /**\n * Compares two RelativePosition\n * @param {RelativePosition} pos1 position 1\n * @param {RelativePosition} pos2 position 2\n * @param {Number} eps x, y, z epsilon in meters (default: 1e-3 [= 1mm])\n */\n static equals(pos1: RelativePosition | null, pos2: RelativePosition | null, eps = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof RelativePosition) || !(pos2 instanceof RelativePosition)) {\n return false;\n }\n\n return Math.abs(pos2.x - pos1.x) < eps\n && Math.abs(pos2.y - pos1.y) < eps\n && Math.abs(pos2.z - pos1.z) < eps\n && pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: RelativePosition) {\n return RelativePosition.equals(this, other);\n }\n\n toJson(): RelativePositionJson {\n return {\n x: this.x,\n y: this.y,\n z: this.z,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: RelativePositionJson) {\n return new RelativePosition(json.x, json.y, json.z, json.time, json.accuracy, json.bearing);\n }\n}\n\nexport default RelativePosition;\n","import RelativePosition from './RelativePosition.js';\n\n/**\n * Position is defined in EUS (East-Up-South) frame with: x pointing to East, y pointing to Up, z pointing to South\n * This frame is close to ThreeJS / OpenGL frame.\n */\nclass GeoRelativePosition extends RelativePosition { }\n\nexport default GeoRelativePosition;\n","import booleanPointInPolygon from '@turf/boolean-point-in-polygon';\n\nimport { Quaternion, Vector3, Vector3_t } from '@wemap/maths';\nimport { BuildingLevel, GeoRefJson } from '../types.js';\n\nimport Coordinates from './Coordinates.js';\n\nclass GeoRef {\n\n scale = 1;\n heading = 0;\n\n constructor(public origin: Coordinates, public buildingLevels: BuildingLevel[] = []) { }\n\n /**\n * LocalPosition in ENU frame\n */\n localToWorld(localPosition: Vector3_t) {\n const enuTranslationScaled = Vector3.multiplyScalar(localPosition, this.scale);\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);\n const enuToEcefRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.enuToEcefRotation);\n const ecefTranslation = Quaternion.rotate(enuToEcefRotationOrigin, enuTranslationScaled);\n const ecef = Vector3.sum(this.origin.ecef, ecefTranslation);\n const coordinates = Coordinates.fromECEF(ecef);\n\n const alt = coordinates.alt!;\n coordinates.heightFromGround = coordinates.alt! - this.origin.alt!\n\n /*\n * Retrieve level and altitude\n */\n\n const updateLevelAndHeightFromFloor = (buildingLevel: BuildingLevel) => {\n coordinates.level = buildingLevel.id;\n coordinates.heightFromFloor = alt - buildingLevel.floorAltitude;\n }\n\n // 1. If georef does not have buildings level, do not update level field.\n if (!this.buildingLevels.length) {\n return coordinates;\n }\n \n // 2. Find building levels which corresponds to coordinates altitude\n const buildingLevelsByAltitude = this.buildingLevels.filter(buildingLevel => buildingLevel.floorAltitude <= alt && buildingLevel.ceilingAltitude >= alt)\n // If no intersection, the position is outdoor\n if (!buildingLevelsByAltitude.length) {\n return coordinates;\n }\n\n // 3. Find building levels which also includes coordinates 2D position\n const geojsonPt = [coordinates.lng, coordinates.lat];\n let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometry && booleanPointInPolygon(geojsonPt, buildingLevel.geometry));\n \n // If intersection is found, take the first and update level by its id\n if (buildingLevel) {\n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // If there is no interesection and levels have geometry, the position is outdoor\n if (buildingLevelsByAltitude.every(bl => Boolean(bl.geometry))) {\n return coordinates;\n }\n\n // 4. Try fallbacks because geometry is optionnal for the moment (March 2024)\n \n // If building geometries does not exist, let's consider the level geometry as global/infinity.\n if (buildingLevelsByAltitude.every(bl => !Boolean(bl.geometry))) {\n // As we cannot decide which building level should be selected, take the first!\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // This means some buildings levels have geometry and some others not. This means there is a data problem.\n // Anyway takes first\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n /**\n * LocalPosition in ENU frame\n */\n worldToLocal(coords: Coordinates) {\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], -this.heading);\n const ecefToEnuRotationOrigin = Quaternion.multiply(this.origin.ecefToEnuRotation, rotationOffset);\n const ecefTranslation = Vector3.subtract(coords.ecef, this.origin.ecef);\n const ecefTranslationScaled = Vector3.multiplyScalar(ecefTranslation, 1 / this.scale);\n return Quaternion.rotate(ecefToEnuRotationOrigin, ecefTranslationScaled);\n }\n\n toJson(): GeoRefJson {\n return {\n origin: this.origin.toJson(),\n ...(this.scale !== 1 && { scale: this.scale }),\n ...(this.heading !== 0 && { heading: this.heading })\n };\n }\n\n static fromJson(json: GeoRefJson) {\n const geoRef = new GeoRef(Coordinates.fromJson(json.origin));\n geoRef.scale = typeof json.scale !== 'undefined' ? json.scale : 1;\n geoRef.heading = typeof json.heading !== 'undefined' ? json.heading : 0;\n return geoRef;\n }\n}\n\nexport default GeoRef;\n","import {\n Rotations, Quaternion, rad2deg, deg2rad,\n Quaternion_t, EulerAngles_t, EulerAnglesDegrees_t\n} from '@wemap/maths';\nimport { AttitudeJson } from '../types';\n\nclass Attitude {\n\n _quaternion: Quaternion_t = [1, 0, 0, 0];\n _heading: number | null = null;\n _eulerAngles: EulerAngles_t | null = null;\n _time: number | null = null;\n _accuracy: number | null = null;\n\n constructor(quaternion: Quaternion_t,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.quaternion = quaternion;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n static unitary() {\n return new Attitude([1, 0, 0, 0]);\n }\n\n\n get quaternion() {\n return this._quaternion;\n }\n\n set quaternion(quaternion) {\n if (Math.abs(1 - Quaternion.norm(quaternion)) > 1e-4) {\n throw new Error('quaternion is not a unit quaternion');\n }\n this._quaternion = quaternion;\n this._heading = null;\n this._eulerAngles = null;\n }\n\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n get eulerAngles(): EulerAngles_t {\n if (this._eulerAngles === null) {\n this._eulerAngles = Rotations.quaternionToEulerZXY(this.quaternion);\n }\n return this._eulerAngles;\n }\n\n get eulerAnglesDegrees(): EulerAnglesDegrees_t {\n return this.eulerAngles.map(x => rad2deg(x)) as EulerAnglesDegrees_t;\n }\n\n get heading() {\n if (this._heading === null) {\n let offset = 0;\n if (typeof (window) !== 'undefined' && window && window.orientation) {\n offset = deg2rad(window.orientation);\n }\n this._heading = Rotations.getHeadingFromQuaternion(this.quaternion) + offset;\n }\n return this._heading;\n }\n\n get headingDegrees() {\n return rad2deg(this.heading);\n }\n\n\n static equals(att1: Attitude | null, att2: Attitude | null) {\n\n // Handle null comparison\n if (att1 === null && att1 === att2) {\n // TODO not sure to return true here.\n return true;\n }\n\n if (!(att1 instanceof Attitude) || !(att2 instanceof Attitude)) {\n return false;\n }\n\n if (att1 === att2) {\n return true;\n }\n\n return Quaternion.equals(att1.quaternion, att2.quaternion);\n }\n\n equals(other: Attitude) {\n return Attitude.equals(this, other);\n }\n\n toJson(): AttitudeJson {\n if (this.time === null && this.accuracy === null) {\n return this.quaternion;\n }\n return {\n q: this.quaternion,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n\n static fromJson(json: AttitudeJson) {\n if (Array.isArray(json)) {\n return new Attitude(json, null, null);\n }\n return new Attitude(json.q, json.time, json.accuracy);\n }\n\n\n clone() {\n return new Attitude(this.quaternion.slice(0) as Quaternion_t, this.time, this.accuracy);\n }\n\n /**\n * Calculate the relative attitude between two given attitudes\n */\n static diff(attitudeStart: Attitude, attitudeEnd: Attitude) {\n\n const quaternionDiff = Quaternion.multiply(\n Quaternion.inverse(attitudeStart.quaternion),\n attitudeEnd.quaternion\n );\n\n let timeDiff = null;\n if (attitudeEnd.time !== null && attitudeStart.time !== null) {\n timeDiff = attitudeEnd.time - attitudeStart.time;\n }\n\n let accuracyDiff = null;\n if (attitudeStart.accuracy !== null && attitudeEnd.accuracy !== null) {\n // Approximation\n accuracyDiff = Math.max(attitudeEnd.accuracy - attitudeStart.accuracy);\n }\n\n return new Attitude(quaternionDiff, timeDiff, accuracyDiff);\n }\n}\n\nexport default Attitude;\n","import { Quaternion } from '@wemap/maths';\nimport { AbsoluteHeadingJson } from '../types.js';\n\nimport Attitude from './Attitude.js';\n\nclass AbsoluteHeading {\n\n heading: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n\n constructor(heading: number,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.heading = heading;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n toAttitude() {\n /**\n * Heading is given around z-axis in NED frame and our attitude in ENU frame, that is why\n * -1* is applied to heading.\n */\n return new Attitude(\n Quaternion.fromAxisAngle([0, 0, 1], -this.heading),\n this.time,\n this.accuracy\n );\n }\n\n\n /**\n * Compares two AbsoluteHeading\n * @param {AbsoluteHeading} heading1 heading 1\n * @param {AbsoluteHeading} heading2 heading 2\n */\n static equals(heading1: AbsoluteHeading | null, heading2: AbsoluteHeading | null) {\n\n // Handle null comparison\n if (heading1 === null && heading1 === heading2) {\n return true;\n }\n\n if (!(heading1 instanceof AbsoluteHeading) || !(heading2 instanceof AbsoluteHeading)) {\n return false;\n }\n\n return Math.abs(heading1.heading - heading2.heading) < 1e-8;\n }\n\n equals(other: AbsoluteHeading | null) {\n return AbsoluteHeading.equals(this, other);\n }\n\n toJson(): AbsoluteHeadingJson {\n return {\n heading: this.heading,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n static fromJson(json: AbsoluteHeadingJson) {\n return new AbsoluteHeading(json.heading, json.time, json.accuracy);\n }\n\n clone() {\n return new AbsoluteHeading(this.heading, this.time, this.accuracy);\n }\n}\n\nexport default AbsoluteHeading;\n"],"names":["str","coords","buildingLevel"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/Constants.ts","../src/coordinates/Level.ts","../src/coordinates/Coordinates.ts","../src/coordinates/UserPosition.ts","../src/Utils.ts","../src/coordinates/BoundingBox.ts","../src/coordinates/RelativePosition.ts","../src/coordinates/GeoRelativePosition.ts","../src/coordinates/GeoRef.ts","../src/rotations/Attitude.ts","../src/rotations/AbsoluteHeading.ts"],"sourcesContent":["export const R_MAJOR = 6378137.0;\nexport const R_MINOR = 6356752.3142;\nexport const EARTH_GRAVITY = 9.80665;\n\n/**\n * latitude and longitude epsilon in degrees\n * 1e-8° correspond to ~1mm at latitude = 0\n */\nexport const EPS_DEG_MM = 1e-8;\n\n/**\n * epsilon in meters which corresponds to 1 millimeter\n */\nexport const EPS_MM = 1e-3;\n\n\nexport const ELLIPSOID_FLATNESS = (R_MAJOR - R_MINOR) / R_MAJOR;\n\nexport const ECCENTRICITY = Math.sqrt(ELLIPSOID_FLATNESS * (2 - ELLIPSOID_FLATNESS));\nexport const ECCENTRICITY_2 = ECCENTRICITY * ECCENTRICITY;\n\nexport const R_MAJOR_2 = R_MAJOR * R_MAJOR;\nexport const R_MAJOR_4 = R_MAJOR_2 * R_MAJOR_2;\nexport const R_MINOR_2 = R_MINOR * R_MINOR;\nexport const R_MINOR_4 = R_MINOR_2 * R_MINOR_2;\nexport const CIRCUMFERENCE = R_MAJOR * 2 * Math.PI;\n","import { Level_t } from \"../types\";\n\n/**\n * A Level is the representation of a building floor number\n * A level can be a simple number or a range (low, up)\n * The range is an array of two numbers\n */\nclass Level {\n\n static VERIFY_TYPING = false;\n\n static checkType(level: Level_t) {\n if (level === null) {\n return;\n }\n if (typeof level === 'number' && !isNaN(level)) {\n return;\n }\n if (Array.isArray(level) && level.length === 2) {\n const [low, up] = level;\n if (typeof low === 'number' && !isNaN(low)\n && typeof up === 'number' && !isNaN(up)) {\n if (low > up || low === up) {\n throw Error(`Invalid level range: [${low}, ${up}]`);\n }\n return;\n }\n }\n throw Error(`Unknown level format: ${level}`);\n }\n\n /**\n * Return true if the level is a range, false otherwise\n */\n static isRange(level: Level_t): level is [number, number] {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n return Array.isArray(level);\n }\n\n static clone(level: Level_t): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n if (typeof level === 'number') {\n return level;\n }\n\n return [level[0], level[1]];\n }\n\n /**\n * Create a level from a string (eg. 1, -2, 1;2, -2;3, 2;-1, 0.5;1 ...)\n */\n static fromString(str: string | null): Level_t {\n\n if (str === null) {\n return null;\n }\n\n if (typeof str !== 'string' || !str.length) {\n throw Error(`argument must be a non empty string, got ${typeof str}`);\n }\n\n if (!isNaN(Number(str))) {\n return parseFloat(str);\n }\n\n const splited = str.split(';');\n if (splited.length > 1) {\n const levels = splited.map(str => Number(str));\n const low = Math.min(...levels);\n const up = Math.max(...levels);\n Level.checkType([low, up]);\n return [low, up];\n } else {\n const rangeSeparator = str.substring(1).indexOf('-') + 1;\n if (rangeSeparator > 0) {\n const low = Number(str.substring(0, rangeSeparator));\n const up = Number(str.substring(rangeSeparator + 1));\n Level.checkType([low, up]);\n return [low, up];\n }\n }\n\n throw Error(`Cannot parse following level: ${str}`);\n }\n\n\n /**\n * Returns if a level is contained in another\n * @param {null|number|[number, number]} container The container level\n * @param {null|number|[number, number]} targeted The targeted level\n */\n static contains(container: Level_t, targeted: Level_t): boolean {\n if (Level.VERIFY_TYPING) {\n Level.checkType(container);\n Level.checkType(targeted);\n }\n\n // Covers null and number\n if (container === targeted) {\n return true;\n }\n\n if (Array.isArray(container)) {\n if (Array.isArray(targeted)) {\n return container[0] <= targeted[0] && container[1] >= targeted[1];\n }\n if (targeted === null) {\n return false;\n }\n return container[0] <= targeted && container[1] >= targeted;\n }\n if (container === null || targeted === null) {\n return false;\n }\n return container <= (targeted as [number, number])[0]\n && container >= (targeted as [number, number])[1];\n }\n\n /**\n * Retrieve the intersection of two levels\n * null n null => null\n * null n 1 => null // Conception choice\n * null n [1,2] => null // Conception choice\n * 1 n 1 => 1\n * 1 n 2 => null\n * 1 n [1,2] => 1\n * 1 n [0,2] => 1\n * 1 n [2,3] => null\n * [1,2] n [1,2] => [1,2]\n * [1,2] n [2,3] => 2\n * [1,2] n [3,4] => null\n */\n static intersection(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (Level.equals(first, second)) {\n return Level.clone(first);\n }\n\n if (typeof first === 'number' && typeof second === 'number') {\n return first === second ? first : null;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (Level.contains(first, second)) {\n return second;\n }\n return null;\n }\n if (!Array.isArray(first) && Array.isArray(second)) {\n if (Level.contains(second, first)) {\n return first;\n }\n return null;\n }\n\n // There are two ranges\n const low = Math.max((first as [number, number])[0], (second as [number, number])[0]);\n const up = Math.min((first as [number, number])[1], (second as [number, number])[1]);\n if (up === low) {\n return up;\n }\n return up < low ? null : [low, up];\n }\n\n /**\n * Retrieve the intersection of two levels\n * @param {null|number|[number, number]} first The first level\n * @param {null|number|[number, number]} second The second level\n * @returns {boolean}\n */\n static intersect(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null && second === null) {\n return true;\n }\n\n return Level.intersection(first, second) !== null;\n }\n\n /**\n * Retrieve the union of two levels\n * null u null => null\n * null u 1 => null // Conception choice\n * null u [1,2] => null // Conception choice\n * 1 u 1 => 1\n * 1 u 2 => [1,2]\n * 1 u [1,2] => [1,2]\n * 1 u [0,2] => [0,2]\n * 1 u [2,3] => [1,3]\n * [1,2] u [1,2] => [1,2]\n * [1,2] u [2,3] => [1,3]\n * [1,2] u [3,4] => [1,4]\n */\n static union(first: Level_t, second: Level_t): Level_t {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return Level.clone(first);\n }\n\n if (second === null) {\n return null;\n // return Level.clone(first);\n }\n\n if (first === null) {\n return null;\n // return Level.clone(second);\n }\n\n let low, up;\n if (!Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first, second);\n up = Math.max(first, second);\n } else if (Array.isArray(first) && !Array.isArray(second)) {\n low = Math.min(first[0], second);\n up = Math.max(first[1], second);\n } else if (!Array.isArray(first) && Array.isArray(second)) {\n low = Math.min(second[0], first);\n up = Math.max(second[1], first);\n } else {\n /* if (Array.isArray(first) && Array.isArray(second)) */\n low = Math.min((first as [number, number])[0], (second as [number, number])[0]);\n up = Math.max((first as [number, number])[1], (second as [number, number])[1]);\n }\n\n if (low === up) {\n return low;\n }\n return [low, up];\n }\n\n /**\n * Multiply a level by a factor\n * @param {null|number|[number, number]} level the level to multiply\n * @param {number} factor\n * @returns {null|number|[number, number]}\n */\n static multiplyBy(level: Level_t, factor: number): Level_t {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n\n if (level === null) {\n return null;\n }\n\n return Array.isArray(level) ? [level[0] * factor, level[1] * factor] : level * factor;\n }\n\n static toString(level: Level_t): string | null {\n if (Level.VERIFY_TYPING) {\n Level.checkType(level);\n }\n if (level === null) {\n return null;\n }\n return Array.isArray(level) ? level[0] + ';' + level[1] : String(level);\n }\n\n static equals(first: Level_t, second: Level_t): boolean {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === second) {\n return true;\n }\n\n if (Array.isArray(first) && Array.isArray(second)) {\n return first[0] === second[0] && first[1] === second[1];\n }\n\n return false;\n }\n\n\n static diff(first: Level_t, second: Level_t): null | number {\n\n if (Level.VERIFY_TYPING) {\n Level.checkType(first);\n Level.checkType(second);\n }\n\n if (first === null || second === null) {\n return null;\n }\n\n if (!Array.isArray(first) && !Array.isArray(second)) {\n return second - first;\n }\n\n if (Array.isArray(first) && !Array.isArray(second)) {\n if (first[0] === second) {\n return second - first[1];\n }\n if (first[1] === second) {\n return second - first[0];\n }\n return null;\n }\n\n if (Array.isArray(second) && !Array.isArray(first)) {\n if (first === second[0]) {\n return second[1] - first;\n }\n if (first === second[1]) {\n return second[0] - first;\n }\n return null;\n }\n\n if (Level.equals(first, second)) {\n return 0;\n }\n\n return null;\n }\n}\n\nexport default Level;\n","import {\n deg2rad, Vector3, Quaternion, rad2deg, wrap, Vector3_t, Quaternion_t\n} from '@wemap/maths';\nimport { EPS_DEG_MM, EPS_MM, R_MAJOR } from '../Constants.js';\n\nimport { CoordinatesCompressedJson, CoordinatesJson, Level_t } from '../types.js';\nimport Level from './Level.js';\n\n/**\n * A Coordinates position using at least latitude (lat) and longitude (lng).\n * Optionnal fields are: altitude (alt) and level.\n *\n * Basic geo methods are directly accessibles from here:\n * distanceTo, bearingTo, toEcef...\n *\n * /!\\ This class has been adapted to use earth as a sphere and not as an ellipsoid\n * /!\\ So, this class does not stricly represent WGS84 coordinates anymore\n * /!\\ This modifications have been made for computational improvements.\n */\nclass Coordinates {\n\n private _lat!: number;\n private _lng!: number;\n private _alt: number | null = null;\n private _level: Level_t | null = null;\n private _heightFromFloor: number | null = null;\n private _heightFromGround: number | null = null;\n\n private _ecef: Vector3_t | null;\n\n autoWrap = true;\n\n constructor(lat: number, lng: number, alt: number | null = null, level: Level_t | null = null) {\n this.lat = lat;\n this.lng = lng;\n this.alt = alt;\n this.level = level;\n this._ecef = null;\n }\n\n get lat() {\n return this._lat;\n }\n\n set lat(lat: number) {\n if (Math.abs(lat) <= 90) {\n this._lat = lat;\n } else {\n throw new Error(`lat argument is not in [-90; 90], value is ${lat}`);\n }\n this._ecef = null;\n }\n\n get latitude() {\n return this._lat;\n }\n\n set latitude(_) {\n throw new Error('Please use Coordinates#lat setter instead of Coordinate#latitude');\n }\n\n get lng() {\n return this._lng;\n }\n\n set lng(lng) {\n this._lng = lng;\n if (this.autoWrap) {\n this.wrap();\n }\n this._ecef = null;\n }\n\n get longitude() {\n return this._lng;\n }\n\n set longitude(_) {\n throw new Error('Please use Coordinates#lng setter instead of Coordinate#longitude');\n }\n\n /**\n * alt does not denote the altitude of a point but its height from\n * the \"level\" field (if defined) or from the ground\n */\n get alt() {\n return this._alt;\n }\n\n set alt(alt) {\n this._alt = alt;\n this._ecef = null;\n }\n\n get level() {\n return this._level;\n }\n\n set level(level) {\n Level.checkType(level);\n this._level = level;\n }\n\n get heightFromFloor() {\n return this._heightFromFloor;\n }\n\n set heightFromFloor(heightFromFloor) {\n this._heightFromFloor = heightFromFloor;\n }\n\n get heightFromGround() {\n return this._heightFromGround;\n }\n\n set heightFromGround(heightFromGround) {\n this._heightFromGround = heightFromGround;\n }\n\n /**\n * Deep clone coordinates\n */\n clone() {\n const output = new Coordinates(this.lat, this.lng, this.alt);\n if (this.level !== null) {\n output.level = Level.clone(this.level);\n }\n return output;\n }\n\n wrap() {\n if (this._lng <= -180 || this._lng > 180) {\n this._lng = wrap(this._lng, -180, 180);\n }\n }\n\n\n static equals(pos1: Coordinates | null, pos2: Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof Coordinates) || !(pos2 instanceof Coordinates)) {\n return false;\n }\n\n return Math.abs(pos2.lat - pos1.lat) < eps\n && Math.abs(pos2.lng - pos1.lng) < eps\n && (pos1.alt === pos2.alt\n || pos1.alt !== null && pos2.alt !== null\n && Math.abs(pos2.alt - pos1.alt) < epsAlt)\n && Level.equals(pos1.level, pos2.level);\n }\n\n equals(other: Coordinates) {\n return Coordinates.equals(this, other);\n }\n\n /**\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n /**\n * Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint\n * @throws {Error} if elevation is defined and point altitude is not defined\n */\n move(distance: number, bearing: number, elevation: number | null = null) {\n\n const dR = distance / R_MAJOR;\n const cosDr = Math.cos(dR);\n const sinDr = Math.sin(dR);\n\n const phi1 = deg2rad(this.lat);\n const lambda1 = deg2rad(this.lng);\n\n const phi2 = Math.asin(\n Math.sin(phi1) * cosDr\n + Math.cos(phi1) * sinDr * Math.cos(bearing)\n );\n const lambda2 = lambda1 + Math.atan2(\n Math.sin(bearing) * sinDr * Math.cos(phi1),\n cosDr - Math.sin(phi1) * Math.sin(phi2)\n );\n\n this.lat = rad2deg(phi2);\n this.lng = rad2deg(lambda2);\n\n if (elevation !== null) {\n if (this.alt === null) {\n throw new Error('Point altitude is not defined');\n }\n this.alt += elevation;\n }\n\n return this;\n }\n\n /**\n * Returns a distance between two points in meters\n */\n distanceTo(location2: Coordinates) {\n const lat1 = this.lat;\n const lng1 = this.lng;\n\n const lat2 = location2.lat;\n const lng2 = location2.lng;\n\n const dlat = deg2rad(lat2 - lat1);\n const dlng = deg2rad(lng2 - lng1);\n\n const dlngsin = Math.sin(dlng / 2);\n const dlatsin = Math.sin(dlat / 2);\n const lat1rad = deg2rad(lat1);\n const lat1cos = Math.cos(lat1rad);\n const lat2rad = deg2rad(lat2);\n const lat2cos = Math.cos(lat2rad);\n const angle = dlatsin * dlatsin + lat1cos * lat2cos * dlngsin * dlngsin;\n\n // arctangent\n const tangy = Math.sqrt(angle);\n const tangx = Math.sqrt(1 - angle);\n const cosn = 2 * Math.atan2(tangy, tangx);\n\n return R_MAJOR * cosn;\n }\n\n static distanceBetween(point1: Coordinates, point2: Coordinates) {\n return point1.distanceTo(point2);\n }\n\n bearingTo(location2: Coordinates) {\n const lat1 = deg2rad(this.lat);\n const lat2 = deg2rad(location2.lat);\n const diffLng = deg2rad(location2.lng - this.lng);\n\n return Math.atan2(Math.sin(diffLng) * Math.cos(lat2),\n Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(diffLng));\n }\n\n static bearingTo(point1: Coordinates, point2: Coordinates) {\n return point1.bearingTo(point2);\n }\n\n\n /**\n * ECEF Transformations\n * Here we used a light version of ECEF considering earth\n * as a sphere instead of an ellipse\n */\n\n get enuToEcefRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + deg2rad(this.lng));\n const rot2 = Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - deg2rad(this.lat));\n return Quaternion.multiply(rot1, rot2);\n }\n\n get ecefToEnuRotation(): Quaternion_t {\n const rot1 = Quaternion.fromAxisAngle([1, 0, 0], deg2rad(this.lat) - Math.PI / 2);\n const rot2 = Quaternion.fromAxisAngle([0, 0, 1], -deg2rad(this.lng) - Math.PI / 2);\n return Quaternion.multiply(rot1, rot2);\n }\n\n /**\n * https://gist.github.com/klucar/1536194\n * Adapted for spherical formula\n */\n get ecef(): Vector3_t {\n\n if (!this._ecef) {\n const lat = deg2rad(this.lat);\n const lng = deg2rad(this.lng);\n const alt = this.alt || 0;\n\n const x = (R_MAJOR + alt) * Math.cos(lat) * Math.cos(lng);\n const y = (R_MAJOR + alt) * Math.cos(lat) * Math.sin(lng);\n const z = (R_MAJOR + alt) * Math.sin(lat);\n\n this._ecef = [x, y, z];\n }\n\n return this._ecef;\n }\n\n\n static fromECEF(ecef: Vector3_t): Coordinates {\n\n const x = ecef[0];\n const y = ecef[1];\n const z = ecef[2];\n\n const p = Math.sqrt(x ** 2 + y ** 2);\n\n let lng = Math.atan2(y, x);\n const lat = Math.atan2(z, p);\n const alt = p / Math.cos(lat) - R_MAJOR;\n\n lng = lng % (2 * Math.PI);\n\n const newPoint = new Coordinates(rad2deg(lat), rad2deg(lng), alt);\n newPoint._ecef = ecef;\n return newPoint;\n }\n\n\n /**\n * https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere\n * Adapted to ECEF\n */\n getSegmentProjection(p1: Coordinates, p2: Coordinates): Coordinates | null {\n\n const a = Vector3.normalize(p1.ecef);\n const b = Vector3.normalize(p2.ecef);\n const c = Vector3.normalize(this.ecef);\n\n const G = Vector3.cross(a, b);\n if (Vector3.norm(G) === 0) {\n return null;\n }\n\n const F = Vector3.cross(c, G);\n const t = Vector3.normalize(Vector3.cross(G, F));\n\n const posECEF = Vector3.multiplyScalar(t, R_MAJOR);\n const poseCoordinates = Coordinates.fromECEF(posECEF);\n\n // poseCoordinates.alt is not 0 here due to the ECEF transformation residual.\n // So if p1.alt and p2.alt are defined we take the middle elevation between p1 and p2.\n // Otherwise we remove alt from projection because the residual has no sense.\n let alt;\n if (p1.alt !== null && p2.alt !== null) {\n // This formula is maybe not the best one.\n alt = (p1.alt + p2.alt) / 2;\n }\n const projection = new Coordinates(poseCoordinates.lat, poseCoordinates.lng,\n alt, Level.union(p1.level, p2.level));\n\n if (Math.abs((p1.distanceTo(p2) - p1.distanceTo(projection) - p2.distanceTo(projection))) > EPS_MM) {\n return null;\n }\n\n return projection;\n }\n\n /**\n * Input / Output\n */\n\n toString() {\n let str = '[' + this._lat.toFixed(7) + ', ' + this._lng.toFixed(7);\n if (this._alt !== null) {\n str += ', ' + this._alt.toFixed(2);\n }\n if (this._level !== null) {\n str += ', [' + Level.toString(this._level) + ']';\n }\n str += ']';\n return str;\n }\n\n toJson(): CoordinatesJson {\n return {\n lat: Number(this.lat.toFixed(8)),\n lng: Number(this.lng.toFixed(8)),\n ...(this.alt !== null && { alt: Number(this.alt.toFixed(3)) }),\n ...(this.level !== null && { level: this.level })\n };\n }\n\n static fromJson(json: CoordinatesJson) {\n return new Coordinates(json.lat, json.lng, json.alt, json.level);\n }\n\n\n toCompressedJson(): CoordinatesCompressedJson {\n if (this.level !== null) {\n return [\n Number(this.lat.toFixed(8)),\n Number(this.lng.toFixed(8)),\n this.level\n ];\n }\n return [Number(this.lat.toFixed(8)), Number(this.lng.toFixed(8))];\n }\n\n static fromCompressedJson(json: CoordinatesCompressedJson) {\n const coords = new Coordinates(json[0], json[1]);\n if (json.length > 2) {\n coords.level = json[2] as number | [number, number];\n }\n return coords;\n }\n}\n\nexport default Coordinates;\n","import Coordinates from './Coordinates.js';\nimport { Level_t, UserPositionJson } from '../types.js';\nimport { EPS_DEG_MM, EPS_MM } from '../Constants.js';\n\n/**\n * A Coordinates User Position is a Coordinates position with specific data related to user (bearing, time, accuracy)\n */\nclass UserPosition extends Coordinates {\n\n private _time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n lat: number, lng: number, alt: number | null = null, level: Level_t = null,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n super(lat, lng, alt, level);\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n move(distance: number, bearing: number, elevation: number | null = null) {\n super.move(distance, bearing, elevation);\n return this;\n }\n\n destinationPoint(distance: number, bearing: number, elevation: number | null = null) {\n const newPoint = this.clone();\n newPoint.move(distance, bearing, elevation);\n return newPoint;\n }\n\n\n // Create a UserPosition with lat, lng, alt from Coordinates coordinates and\n // other fields from another UserPosition\n static fromCoordinates(coordinates: Coordinates) {\n return new UserPosition(coordinates.lat, coordinates.lng,\n coordinates.alt, coordinates.level);\n }\n\n clone() {\n const cloned = UserPosition.fromCoordinates(super.clone());\n cloned.time = this.time;\n cloned.accuracy = this.accuracy;\n cloned.bearing = this.bearing;\n return cloned;\n }\n\n\n static equals(pos1: UserPosition | Coordinates | null,\n pos2: UserPosition | Coordinates | null,\n eps = EPS_DEG_MM, epsAlt = EPS_MM\n ) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof UserPosition) || !(pos2 instanceof UserPosition)) {\n return false;\n }\n\n if (!super.equals(pos1, pos2, eps, epsAlt)) {\n return false;\n }\n\n return pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: UserPosition | Coordinates | null, eps = EPS_DEG_MM, epsAlt = EPS_MM) {\n return UserPosition.equals(this, other, eps, epsAlt);\n }\n\n\n toJson(): UserPositionJson {\n return {\n ...super.toJson(),\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: UserPositionJson) {\n const position = UserPosition.fromCoordinates(Coordinates.fromJson(json));\n if (typeof json.time !== 'undefined') {\n position.time = json.time;\n }\n if (typeof json.accuracy !== 'undefined') {\n position.accuracy = json.accuracy;\n }\n if (typeof json.bearing !== 'undefined') {\n position.bearing = json.bearing;\n }\n return position;\n }\n}\n\nexport default UserPosition;\n","/* eslint-disable max-statements */\n\nimport { deg2rad, positiveMod } from '@wemap/maths';\nimport { EPS_MM } from './Constants.js';\n\nimport Coordinates from './coordinates/Coordinates.js';\nimport UserPosition from './coordinates/UserPosition.js';\nimport Level from './coordinates/Level.js';\nimport { Level_t } from './types.js';\n\nexport type RouteSample = Coordinates & { bearing: number };\n\n/**\n * Sample a route of Coordinates\n * @param route ordered points\n * @param stepSize step size to sample\n * @param maxLength max route length to sample\n */\nexport function sampleRoute(\n route: Coordinates[],\n stepSize = 0.7,\n startSampling = 0,\n length = Number.MAX_VALUE\n) {\n\n const endSampling = startSampling + length;\n\n const sampledRoute = [];\n\n let lastSample: RouteSample;\n\n let totalDistanceTraveled = 0;\n let distanceToNextSample = 0;\n let startFound = false;\n\n for (let segmentIndex = 0; segmentIndex < route.length - 1; segmentIndex++) {\n\n const p1 = route[segmentIndex];\n const p2 = route[segmentIndex + 1];\n const segmentSize = p1.distanceTo(p2);\n const segmentBearing = p1.bearingTo(p2);\n\n let distanceTraveledOnSegment = 0;\n\n if (!startFound) {\n if (startSampling < totalDistanceTraveled + segmentSize) {\n startFound = true;\n distanceToNextSample = startSampling - totalDistanceTraveled;\n } else {\n totalDistanceTraveled += segmentSize;\n continue;\n }\n }\n\n lastSample = Object.assign(p1.clone(), { bearing: segmentBearing });\n while (distanceTraveledOnSegment + distanceToNextSample < segmentSize\n && totalDistanceTraveled + distanceToNextSample <= endSampling) {\n\n const newPoint = lastSample.destinationPoint(distanceToNextSample, segmentBearing) as RouteSample;\n newPoint.bearing = segmentBearing;\n sampledRoute.push(newPoint);\n lastSample = newPoint;\n\n distanceTraveledOnSegment += distanceToNextSample;\n totalDistanceTraveled += distanceToNextSample;\n distanceToNextSample = stepSize;\n }\n\n if (totalDistanceTraveled + distanceToNextSample > endSampling) {\n break;\n }\n\n const rest = segmentSize - distanceTraveledOnSegment;\n totalDistanceTraveled += rest;\n distanceToNextSample -= rest;\n }\n\n return sampledRoute;\n}\n\n/**\n * Trim a route of Coordinates\n * @param {Array.<Coordinates>} route ordered points\n * @param {Coordinates} startPosition position where the trim starts. startPosition has to be on the route.\n * @param {*} maxLength max route length\n */\nexport function trimRoute(route: Coordinates[], startPosition = route[0], length = Number.MAX_VALUE) {\n\n const newRoute = [];\n let previousPoint: Coordinates | null = null;\n\n let currentPointIndex;\n let cumulativeDistance = 0;\n\n if (route.length <= 1) {\n throw new Error('Route must have at least 2 points');\n }\n\n for (currentPointIndex = 1; currentPointIndex < route.length; currentPointIndex++) {\n\n const p1 = route[currentPointIndex - 1];\n const p2 = route[currentPointIndex];\n\n if (Coordinates.equals(startPosition, p1)) {\n newRoute.push(p1);\n previousPoint = p1;\n break;\n }\n\n const proj = startPosition.getSegmentProjection(p1, p2);\n if (proj && Coordinates.equals(startPosition, proj) && !proj.equals(p2)) {\n newRoute.push(proj);\n previousPoint = proj;\n break;\n }\n }\n\n if (!newRoute.length) {\n throw new Error('startPosition is not on the route');\n }\n\n while (previousPoint && currentPointIndex < route.length) {\n const currentPoint = route[currentPointIndex];\n const dist = previousPoint.distanceTo(currentPoint);\n if (cumulativeDistance + dist >= length\n || Math.abs(cumulativeDistance + dist - length) <= EPS_MM) {\n const bearing = previousPoint.bearingTo(currentPoint);\n const remainingLength = length - cumulativeDistance;\n const end = previousPoint.destinationPoint(remainingLength, bearing);\n newRoute.push(end);\n break;\n }\n newRoute.push(currentPoint);\n previousPoint = currentPoint;\n cumulativeDistance += dist;\n currentPointIndex++;\n }\n\n return newRoute;\n}\n\n\nexport function simplifyRoute(coords: Coordinates[], precisionAngle = deg2rad(5)) {\n\n const isClosed = (coords[0].equals(coords[coords.length - 1]));\n\n let newRoute = coords.slice(0, coords.length - (isClosed ? 1 : 0));\n\n const len = newRoute.length;\n for (let i = isClosed ? 0 : 1; i < len; i++) {\n\n const p0 = coords[positiveMod(i - 1, len)];\n const p1 = coords[i];\n const p2 = coords[positiveMod(i + 1, len)];\n\n const seg1Dir = p0.bearingTo(p1);\n const seg2Dir = p1.bearingTo(p2);\n\n if (Math.abs(seg2Dir - seg1Dir) < precisionAngle) {\n newRoute = newRoute.filter(coord => coord !== p1);\n }\n }\n\n if (isClosed) {\n newRoute.push(newRoute[0]);\n }\n\n return newRoute;\n}\n\nexport function geolocationPositionToUserPosition(geolocationPosition: GeolocationPosition) {\n if (geolocationPosition === null) {\n return null;\n }\n\n const { latitude, longitude, accuracy, heading } = geolocationPosition.coords;\n\n const userPosition = new UserPosition(latitude, longitude);\n userPosition.time = geolocationPosition.timestamp;\n userPosition.accuracy = accuracy;\n userPosition.bearing = heading ? deg2rad(heading) : null;\n return userPosition;\n}\n\nexport function calcDistance(coords: Coordinates[]) {\n return coords.reduce((acc, coords, idx, arr) =>\n acc + (idx ? arr[idx - 1].distanceTo(coords) : 0), 0);\n}\n\n\nexport function createSegmentsAtLevel(itineraryCoords: Coordinates[], segmentsLevel: Level_t, useMultiLevelSegments = true) {\n\n const itineraryCoordsLength = itineraryCoords.length;\n let previousLevelCorrespond = false;\n\n const segments: Coordinates[][] = [];\n let coordinates: Coordinates[] = [];\n for (let i = 0; i < itineraryCoordsLength; i++) {\n const coords = itineraryCoords[i];\n const levelCorrespond = Level.intersect(segmentsLevel, coords.level);\n\n if (useMultiLevelSegments && !levelCorrespond && previousLevelCorrespond) {\n coordinates.push(coords);\n } else if (levelCorrespond) {\n if (!previousLevelCorrespond) {\n coordinates = [];\n segments.push(coordinates);\n if (useMultiLevelSegments && i !== 0) {\n coordinates.push(itineraryCoords[i - 1]);\n }\n }\n coordinates.push(coords);\n }\n\n previousLevelCorrespond = levelCorrespond;\n }\n return segments;\n}","import Coordinates from './Coordinates.js';\n\nclass BoundingBox {\n\n northEast: Coordinates;\n southWest: Coordinates;\n\n constructor(northEast: Coordinates, southWest: Coordinates) {\n this.northEast = northEast;\n this.southWest = southWest;\n\n if (this.northEast && this.southWest && this.getNorth() < this.getSouth()) {\n throw new Error('Incorrect bounding box');\n }\n }\n\n /**\n * Returns the geographical coordinate equidistant from the bounding box's corners.\n */\n get center(): Coordinates {\n const latCenter = (this.southWest.lat + this.northEast.lat) / 2;\n const lngCenter = (this.northEast.lng + this.southWest.lng) / 2;\n return new Coordinates(latCenter, lngCenter);\n }\n\n /**\n * Check if a point is contained in the bounding box.\n */\n contains(point: Coordinates): boolean {\n return point.lat <= this.northEast.lat\n && point.lat >= this.southWest.lat\n && point.lng <= this.northEast.lng\n && point.lng >= this.southWest.lng;\n }\n\n /**\n * Extend the bounds to include a given LngLat or LngLatBounds.\n */\n extend(obj: Coordinates | BoundingBox): BoundingBox {\n const sw = this.southWest,\n ne = this.northEast;\n let sw2, ne2;\n\n if (obj instanceof Coordinates) {\n sw2 = obj;\n ne2 = obj;\n\n } else if (obj instanceof BoundingBox) {\n sw2 = obj.southWest;\n ne2 = obj.northEast;\n } else {\n throw new Error('Unknown parameter');\n }\n\n this.southWest = new Coordinates(\n Math.min(sw2.lat, sw.lat),\n Math.min(sw2.lng, sw.lng)\n );\n this.northEast = new Coordinates(\n Math.max(ne2.lat, ne.lat),\n Math.max(ne2.lng, ne.lng)\n );\n\n return this;\n }\n\n /**\n * This method extends the bounding box with a value in meters\n * /*\\ This method is not precise as distance differs in function of latitude\n */\n extendsWithMeasure(measure: number): BoundingBox {\n\n if (typeof measure !== 'number') {\n throw new Error('measure is not a number');\n }\n\n this.northEast = this.northEast\n .destinationPoint(measure, 0)\n .move(measure, Math.PI / 2);\n\n this.southWest = this.southWest.clone()\n .destinationPoint(measure, -Math.PI / 2)\n .destinationPoint(measure, Math.PI);\n\n return this;\n }\n\n /**\n * Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\n * For example, a ratio of 0.5 extends the bounds by 50% in each direction.\n * Negative values will retract the bounds.\n */\n pad(bufferRatio: number): BoundingBox {\n const sw = this.southWest;\n const ne = this.northEast;\n\n const heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio;\n const widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\n\n this.southWest = new Coordinates(sw.lat - heightBuffer, sw.lng - widthBuffer);\n this.northEast = new Coordinates(ne.lat + heightBuffer, ne.lng + widthBuffer);\n\n return this;\n }\n\n /**\n * Returns the southwest corner of the bounding box.\n */\n getSouthWest() {\n return this.southWest;\n }\n\n /**\n * Returns the northeast corner of the bounding box.\n */\n getNorthEast() {\n return this.northEast;\n }\n\n /**\n * Returns the northwest corner of the bounding box.\n */\n getNorthWest() {\n return new Coordinates(this.getNorth(), this.getWest());\n }\n\n /**\n * Returns the southeast corner of the bounding box.\n */\n getSouthEast() {\n return new Coordinates(this.getSouth(), this.getEast());\n }\n\n /**\n * Returns the west edge of the bounding box.\n */\n getWest() {\n return this.southWest.lng;\n }\n\n /**\n * Returns the south edge of the bounding box.\n */\n getSouth() {\n return this.southWest.lat;\n }\n\n /**\n * Returns the east edge of the bounding box.\n */\n getEast() {\n return this.northEast.lng;\n }\n\n /**\n * Returns the north edge of the bounding box.\n */\n getNorth() {\n return this.northEast.lat;\n }\n\n static equals(bb1: BoundingBox, bb2: BoundingBox) {\n return Coordinates.equals(bb1.northEast, bb2.northEast)\n && Coordinates.equals(bb1.southWest, bb2.southWest);\n }\n\n equals(other: BoundingBox) {\n return BoundingBox.equals(this, other);\n }\n\n /**\n * Create a BoundingBox from a WSEN array\n */\n static fromArray(bounds: [number, number, number, number]) {\n return new BoundingBox(\n new Coordinates(bounds[3], bounds[2]),\n new Coordinates(bounds[1], bounds[0])\n );\n }\n\n static fromCoordinates(coords: Coordinates[]) {\n if (coords.length === 0) {\n return null;\n }\n return coords.reduce(\n (acc, _coords) => acc.extend(_coords),\n new BoundingBox(coords[0], coords[0])\n );\n }\n\n /**\n * Returns the WSEN array\n */\n toArray(): [number, number, number, number] {\n return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()];\n }\n}\n\nexport default BoundingBox;\n","import { EPS_MM } from '../Constants.js';\nimport { RelativePositionJson } from '../types.js';\n\nclass RelativePosition {\n\n x: number;\n y: number;\n z: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n private _bearing: number | null = null;\n\n constructor(\n x: number, y: number, z: number,\n time: number | null = null, accuracy: number | null = null, bearing: number | null = null\n ) {\n this.x = x;\n this.y = y;\n this.z = z;\n this.time = time;\n this.accuracy = accuracy;\n this.bearing = bearing;\n }\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && accuracy < 0) {\n throw new Error('accuracy argument is not a positive number');\n }\n this._accuracy = accuracy;\n }\n\n get bearing() {\n return this._bearing;\n }\n\n set bearing(bearing) {\n this._bearing = bearing !== null ? bearing % (2 * Math.PI) : null;\n }\n\n clone() {\n return new RelativePosition(this.x, this.y, this.z, this.time, this.accuracy, this.bearing);\n }\n\n\n /**\n * Compares two RelativePosition\n * @param {RelativePosition} pos1 position 1\n * @param {RelativePosition} pos2 position 2\n * @param {Number} eps x, y, z epsilon in meters (default: 1e-3 [= 1mm])\n */\n static equals(pos1: RelativePosition | null, pos2: RelativePosition | null, eps = EPS_MM) {\n\n // Handle null comparison\n if (pos1 === null && pos1 === pos2) {\n return true;\n }\n\n if (!(pos1 instanceof RelativePosition) || !(pos2 instanceof RelativePosition)) {\n return false;\n }\n\n return Math.abs(pos2.x - pos1.x) < eps\n && Math.abs(pos2.y - pos1.y) < eps\n && Math.abs(pos2.z - pos1.z) < eps\n && pos1.time === pos2.time\n && pos1.accuracy === pos2.accuracy\n && pos1.bearing === pos2.bearing;\n }\n\n equals(other: RelativePosition) {\n return RelativePosition.equals(this, other);\n }\n\n toJson(): RelativePositionJson {\n return {\n x: this.x,\n y: this.y,\n z: this.z,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy }),\n ...(this.bearing !== null && { bearing: this.bearing })\n };\n }\n\n static fromJson(json: RelativePositionJson) {\n return new RelativePosition(json.x, json.y, json.z, json.time, json.accuracy, json.bearing);\n }\n}\n\nexport default RelativePosition;\n","import RelativePosition from './RelativePosition.js';\n\n/**\n * Position is defined in EUS (East-Up-South) frame with: x pointing to East, y pointing to Up, z pointing to South\n * This frame is close to ThreeJS / OpenGL frame.\n */\nclass GeoRelativePosition extends RelativePosition { }\n\nexport default GeoRelativePosition;\n","import booleanPointInPolygon from '@turf/boolean-point-in-polygon';\n\nimport { Quaternion, Vector3, Vector3_t } from '@wemap/maths';\nimport { BuildingLevel, GeoRefJson } from '../types.js';\n\nimport Coordinates from './Coordinates.js';\n\nclass GeoRef {\n\n scale = 1;\n heading = 0;\n\n constructor(public origin: Coordinates, public buildingLevels: BuildingLevel[] = []) { }\n\n /**\n * LocalPosition in ENU frame\n */\n localToWorld(localPosition: Vector3_t) {\n const enuTranslationScaled = Vector3.multiplyScalar(localPosition, this.scale);\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);\n const enuToEcefRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.enuToEcefRotation);\n const ecefTranslation = Quaternion.rotate(enuToEcefRotationOrigin, enuTranslationScaled);\n const ecef = Vector3.sum(this.origin.ecef, ecefTranslation);\n const coordinates = Coordinates.fromECEF(ecef);\n\n const alt = coordinates.alt!;\n coordinates.heightFromGround = coordinates.alt! - this.origin.alt!\n\n /*\n * Retrieve level and altitude\n */\n\n const updateLevelAndHeightFromFloor = (buildingLevel: BuildingLevel) => {\n coordinates.level = buildingLevel.id;\n coordinates.heightFromFloor = alt - buildingLevel.floorAltitude;\n }\n\n // 1. If georef does not have buildings level, do not update level field.\n if (!this.buildingLevels.length) {\n return coordinates;\n }\n \n // 2. Find building levels which corresponds to coordinates altitude\n const buildingLevelsByAltitude = this.buildingLevels.filter(buildingLevel => buildingLevel.floorAltitude <= alt && buildingLevel.ceilingAltitude >= alt)\n // If no intersection, the position is outdoor\n if (!buildingLevelsByAltitude.length) {\n return coordinates;\n }\n\n // 3. Find building levels which also includes coordinates 2D position\n const geojsonPt = [coordinates.lng, coordinates.lat];\n let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometries.some(geom => booleanPointInPolygon(geojsonPt, geom)));\n \n // If intersection is found, take the first and update level by its id\n if (buildingLevel) {\n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // If there is no interesection and levels have geometry, the position is outdoor\n const hasLevelGeometries = (bl : BuildingLevel) => bl.geometries.length !== 0;\n if (buildingLevelsByAltitude.every(hasLevelGeometries)) {\n return coordinates;\n }\n\n // 4. Try fallbacks because geometry is optionnal for the moment (March 2024)\n \n // If building geometries does not exist, let's consider the level geometry as global/infinity.\n if (buildingLevelsByAltitude.every(bl => !hasLevelGeometries(bl))) {\n // As we cannot decide which building level should be selected, take the first!\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n // This means some buildings levels have geometry and some others not. This means there is a data problem.\n // Anyway takes first\n buildingLevel = buildingLevelsByAltitude[0]!; \n updateLevelAndHeightFromFloor(buildingLevel);\n return coordinates;\n }\n\n /**\n * LocalPosition in ENU frame\n */\n worldToLocal(coords: Coordinates) {\n const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], -this.heading);\n const ecefToEnuRotationOrigin = Quaternion.multiply(this.origin.ecefToEnuRotation, rotationOffset);\n const ecefTranslation = Vector3.subtract(coords.ecef, this.origin.ecef);\n const ecefTranslationScaled = Vector3.multiplyScalar(ecefTranslation, 1 / this.scale);\n return Quaternion.rotate(ecefToEnuRotationOrigin, ecefTranslationScaled);\n }\n\n toJson(): GeoRefJson {\n return {\n origin: this.origin.toJson(),\n ...(this.scale !== 1 && { scale: this.scale }),\n ...(this.heading !== 0 && { heading: this.heading })\n };\n }\n\n static fromJson(json: GeoRefJson) {\n const geoRef = new GeoRef(Coordinates.fromJson(json.origin));\n geoRef.scale = typeof json.scale !== 'undefined' ? json.scale : 1;\n geoRef.heading = typeof json.heading !== 'undefined' ? json.heading : 0;\n return geoRef;\n }\n}\n\nexport default GeoRef;\n","import {\n Rotations, Quaternion, rad2deg, deg2rad,\n Quaternion_t, EulerAngles_t, EulerAnglesDegrees_t\n} from '@wemap/maths';\nimport { AttitudeJson } from '../types';\n\nclass Attitude {\n\n _quaternion: Quaternion_t = [1, 0, 0, 0];\n _heading: number | null = null;\n _eulerAngles: EulerAngles_t | null = null;\n _time: number | null = null;\n _accuracy: number | null = null;\n\n constructor(quaternion: Quaternion_t,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.quaternion = quaternion;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n static unitary() {\n return new Attitude([1, 0, 0, 0]);\n }\n\n\n get quaternion() {\n return this._quaternion;\n }\n\n set quaternion(quaternion) {\n if (Math.abs(1 - Quaternion.norm(quaternion)) > 1e-4) {\n throw new Error('quaternion is not a unit quaternion');\n }\n this._quaternion = quaternion;\n this._heading = null;\n this._eulerAngles = null;\n }\n\n\n get time() {\n return this._time;\n }\n\n set time(time) {\n this._time = time;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n get eulerAngles(): EulerAngles_t {\n if (this._eulerAngles === null) {\n this._eulerAngles = Rotations.quaternionToEulerZXY(this.quaternion);\n }\n return this._eulerAngles;\n }\n\n get eulerAnglesDegrees(): EulerAnglesDegrees_t {\n return this.eulerAngles.map(x => rad2deg(x)) as EulerAnglesDegrees_t;\n }\n\n get heading() {\n if (this._heading === null) {\n let offset = 0;\n if (typeof (window) !== 'undefined' && window && window.orientation) {\n offset = deg2rad(window.orientation);\n }\n this._heading = Rotations.getHeadingFromQuaternion(this.quaternion) + offset;\n }\n return this._heading;\n }\n\n get headingDegrees() {\n return rad2deg(this.heading);\n }\n\n\n static equals(att1: Attitude | null, att2: Attitude | null) {\n\n // Handle null comparison\n if (att1 === null && att1 === att2) {\n // TODO not sure to return true here.\n return true;\n }\n\n if (!(att1 instanceof Attitude) || !(att2 instanceof Attitude)) {\n return false;\n }\n\n if (att1 === att2) {\n return true;\n }\n\n return Quaternion.equals(att1.quaternion, att2.quaternion);\n }\n\n equals(other: Attitude) {\n return Attitude.equals(this, other);\n }\n\n toJson(): AttitudeJson {\n if (this.time === null && this.accuracy === null) {\n return this.quaternion;\n }\n return {\n q: this.quaternion,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n\n static fromJson(json: AttitudeJson) {\n if (Array.isArray(json)) {\n return new Attitude(json, null, null);\n }\n return new Attitude(json.q, json.time, json.accuracy);\n }\n\n\n clone() {\n return new Attitude(this.quaternion.slice(0) as Quaternion_t, this.time, this.accuracy);\n }\n\n /**\n * Calculate the relative attitude between two given attitudes\n */\n static diff(attitudeStart: Attitude, attitudeEnd: Attitude) {\n\n const quaternionDiff = Quaternion.multiply(\n Quaternion.inverse(attitudeStart.quaternion),\n attitudeEnd.quaternion\n );\n\n let timeDiff = null;\n if (attitudeEnd.time !== null && attitudeStart.time !== null) {\n timeDiff = attitudeEnd.time - attitudeStart.time;\n }\n\n let accuracyDiff = null;\n if (attitudeStart.accuracy !== null && attitudeEnd.accuracy !== null) {\n // Approximation\n accuracyDiff = Math.max(attitudeEnd.accuracy - attitudeStart.accuracy);\n }\n\n return new Attitude(quaternionDiff, timeDiff, accuracyDiff);\n }\n}\n\nexport default Attitude;\n","import { Quaternion } from '@wemap/maths';\nimport { AbsoluteHeadingJson } from '../types.js';\n\nimport Attitude from './Attitude.js';\n\nclass AbsoluteHeading {\n\n heading: number;\n time: number | null = null;\n private _accuracy: number | null = null;\n\n constructor(heading: number,\n time: number | null = null,\n accuracy: number | null = null\n ) {\n this.heading = heading;\n this.time = time;\n this.accuracy = accuracy;\n }\n\n\n get accuracy() {\n return this._accuracy;\n }\n\n set accuracy(accuracy) {\n if (accuracy !== null && (accuracy < 0 || accuracy > Math.PI)) {\n throw new Error('accuracy argument (' + accuracy + ') is not in range [0; PI]');\n }\n this._accuracy = accuracy;\n }\n\n toAttitude() {\n /**\n * Heading is given around z-axis in NED frame and our attitude in ENU frame, that is why\n * -1* is applied to heading.\n */\n return new Attitude(\n Quaternion.fromAxisAngle([0, 0, 1], -this.heading),\n this.time,\n this.accuracy\n );\n }\n\n\n /**\n * Compares two AbsoluteHeading\n * @param {AbsoluteHeading} heading1 heading 1\n * @param {AbsoluteHeading} heading2 heading 2\n */\n static equals(heading1: AbsoluteHeading | null, heading2: AbsoluteHeading | null) {\n\n // Handle null comparison\n if (heading1 === null && heading1 === heading2) {\n return true;\n }\n\n if (!(heading1 instanceof AbsoluteHeading) || !(heading2 instanceof AbsoluteHeading)) {\n return false;\n }\n\n return Math.abs(heading1.heading - heading2.heading) < 1e-8;\n }\n\n equals(other: AbsoluteHeading | null) {\n return AbsoluteHeading.equals(this, other);\n }\n\n toJson(): AbsoluteHeadingJson {\n return {\n heading: this.heading,\n ...(this.time !== null && { time: this.time }),\n ...(this.accuracy !== null && { accuracy: this.accuracy })\n };\n }\n\n static fromJson(json: AbsoluteHeadingJson) {\n return new AbsoluteHeading(json.heading, json.time, json.accuracy);\n }\n\n clone() {\n return new AbsoluteHeading(this.heading, this.time, this.accuracy);\n }\n}\n\nexport default AbsoluteHeading;\n"],"names":["str","coords","buildingLevel"],"mappings":"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"}
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "directory": "packages/geo"
14
14
  },
15
15
  "name": "@wemap/geo",
16
- "version": "12.4.0",
16
+ "version": "12.8.9",
17
17
  "bugs": {
18
18
  "url": "https://github.com/wemap/wemap-modules-js/issues"
19
19
  },
@@ -47,5 +47,5 @@
47
47
  },
48
48
  "./tests/*": "./tests/*"
49
49
  },
50
- "gitHead": "3cf7b71eda1ece192aa41a33f3eb964b245d0889"
50
+ "gitHead": "653f93f7efb8585735ea406aac1ca96f89b4ee12"
51
51
  }
@@ -46,7 +46,7 @@ class Coordinates {
46
46
  if (Math.abs(lat) <= 90) {
47
47
  this._lat = lat;
48
48
  } else {
49
- throw new Error('lat argument is not in [-90; 90]');
49
+ throw new Error(`lat argument is not in [-90; 90], value is ${lat}`);
50
50
  }
51
51
  this._ecef = null;
52
52
  }
@@ -49,7 +49,7 @@ class GeoRef {
49
49
 
50
50
  // 3. Find building levels which also includes coordinates 2D position
51
51
  const geojsonPt = [coordinates.lng, coordinates.lat];
52
- let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometry && booleanPointInPolygon(geojsonPt, buildingLevel.geometry));
52
+ let buildingLevel = buildingLevelsByAltitude.find(buildingLevel => buildingLevel.geometries.some(geom => booleanPointInPolygon(geojsonPt, geom)));
53
53
 
54
54
  // If intersection is found, take the first and update level by its id
55
55
  if (buildingLevel) {
@@ -58,14 +58,15 @@ class GeoRef {
58
58
  }
59
59
 
60
60
  // If there is no interesection and levels have geometry, the position is outdoor
61
- if (buildingLevelsByAltitude.every(bl => Boolean(bl.geometry))) {
61
+ const hasLevelGeometries = (bl : BuildingLevel) => bl.geometries.length !== 0;
62
+ if (buildingLevelsByAltitude.every(hasLevelGeometries)) {
62
63
  return coordinates;
63
64
  }
64
65
 
65
66
  // 4. Try fallbacks because geometry is optionnal for the moment (March 2024)
66
67
 
67
68
  // If building geometries does not exist, let's consider the level geometry as global/infinity.
68
- if (buildingLevelsByAltitude.every(bl => !Boolean(bl.geometry))) {
69
+ if (buildingLevelsByAltitude.every(bl => !hasLevelGeometries(bl))) {
69
70
  // As we cannot decide which building level should be selected, take the first!
70
71
  buildingLevel = buildingLevelsByAltitude[0]!;
71
72
  updateLevelAndHeightFromFloor(buildingLevel);
package/src/types.ts CHANGED
@@ -57,5 +57,5 @@ export type BuildingLevel = {
57
57
  id: number;
58
58
  floorAltitude: number;
59
59
  ceilingAltitude: number;
60
- geometry?: Feature<Polygon | MultiPolygon>
60
+ geometries: (Polygon | MultiPolygon)[]
61
61
  };