{"version":3,"file":"Douglas.mjs","sources":["../../../../../packages/sdk/utils/Douglas.ts"],"sourcesContent":["// Helper function to convert degrees to radians\nconst degreeToRadian = (degree: number) => (degree * Math.PI) / 180.0\n\n// Calculates the Euclidean distance between two geographical points\nconst calculateDistanceBetweenPoints = (\n  point1: { latitude: any; longitude: any },\n  point2: { latitude: any; longitude: any }\n) => {\n  // Convert latitude and longitude from degrees to radians\n  const radLat1 = degreeToRadian(point1.latitude)\n  const radLat2 = degreeToRadian(point2.latitude)\n  const radLon1 = degreeToRadian(point1.longitude)\n  const radLon2 = degreeToRadian(point2.longitude)\n\n  const deltaLat = radLat1 - radLat2\n  const deltaLon = radLon1 - radLon2\n\n  // Haversine formula\n  const s =\n    2 *\n    Math.asin(\n      Math.sqrt(\n        Math.sin(deltaLat / 2) ** 2 +\n          Math.cos(radLat1) * Math.cos(radLat2) * Math.sin(deltaLon / 2) ** 2\n      )\n    )\n\n  // Return the distance in meters\n  return s * 6370996.81\n}\n\n// Calculates the perpendicular distance from a point to a line segment\nconst calculatePerpendicularDistance = (start: any, end: any, center: any) => {\n  const a = Math.abs(calculateDistanceBetweenPoints(start, end))\n  const b = Math.abs(calculateDistanceBetweenPoints(start, center))\n  const c = Math.abs(calculateDistanceBetweenPoints(end, center))\n\n  // Heron's formula for the area of a triangle\n  const semiPerimeter = (a + b + c) / 2.0\n  const area = Math.sqrt(\n    semiPerimeter *\n      (semiPerimeter - a) *\n      (semiPerimeter - b) *\n      (semiPerimeter - c)\n  )\n\n  // The perpendicular distance from center to the line segment (start, end) is twice the area divided by the base length a\n  return (2.0 * area) / a\n}\n\n// Recursively compress the trajectory\nconst compressLine = (\n  coordinate: { point: any }[],\n  start: number,\n  end: number,\n  dMax: number\n): any => {\n  // Initialize the result array\n  let result: any = []\n\n  // We only proceed if the start index is less than the end index\n  if (start < end) {\n    let maxDist = 0\n    let currentIndex = 0\n    const startPoint = coordinate[start].point\n    const endPoint = coordinate[end].point\n\n    // Find the point with the greatest distance from the line segment (startPoint, endPoint)\n    for (let i = start + 1; i < end; i++) {\n      const currentDist = calculatePerpendicularDistance(\n        startPoint,\n        endPoint,\n        coordinate[i].point\n      )\n      if (currentDist > maxDist) {\n        maxDist = currentDist\n        currentIndex = i\n      }\n    }\n\n    // If the maximum distance is greater than the threshold, recursively simplify the trajectory\n    if (maxDist >= dMax) {\n      result.push(coordinate[currentIndex].point)\n\n      // Concatenate the results of the recursive calls\n      result = result.concat(\n        compressLine(coordinate, start, currentIndex, dMax),\n        compressLine(coordinate, currentIndex, end, dMax)\n      )\n    }\n  }\n\n  // Return the simplified trajectory\n  return result\n}\n\n/**\n * Simplifies a given trajectory using the Douglas-Peucker algorithm.\n * @param {Array} coordinate - The original trajectory coordinates.\n * @param {number} [dMax=10] - The maximum allowable perpendicular distance (in meters) from a point to the line segment connecting its neighboring points in the simplified trajectory.\n * @return {Array} - The simplified\n trajectory.\n\n @throws {Error} If the input coordinates array is null or has fewer than two points.\n */\nconst douglasPeucker = (coordinate: any[], dMax = 10) => {\n  if (!coordinate || coordinate.length < 2) {\n    throw new Error(\n      'Invalid input: coordinates array must have at least two points.'\n    )\n  }\n\n  // We create a new array of objects, adding the index and the original point to each coordinate\n  const indexedCoordinates = coordinate.map((item: any, index: any) => ({\n    index,\n    point: item,\n  }))\n\n  // Initialize the result array with the first and last points\n  let result = [\n    indexedCoordinates[0].point,\n    indexedCoordinates[indexedCoordinates.length - 1].point,\n  ]\n\n  // Recursively simplify the trajectory\n  result = result.concat(\n    compressLine(indexedCoordinates, 0, indexedCoordinates.length - 1, dMax)\n  )\n\n  // Sort the result array by the original indices to maintain the trajectory's order\n  return result.sort(\n    (a, b) =>\n      indexedCoordinates.find((item: { point: any }) => item.point === a)\n        ?.index -\n      indexedCoordinates.find((item: { point: any }) => item.point === b)?.index\n  )\n}\n\nexport const Douglas = {\n  douglasPeucker,\n}\n\n// module.exports = { douglasPeucker };\n"],"names":["u","t","Math","PI","h","o","n","latitude","a","e","c","longitude","asin","sqrt","sin","cos","y","abs","s","i","p","point","r","l","d","push","concat","Douglas","douglasPeucker","length","Error","map","index","sort","find"],"mappings":"AAAA,MAAMA,EAAEC,GAAGA,EAAEC,KAAKC,GAAG,IAAIC,EAAE,CAACH,EAAEI,KAAK,MAAMC,EAAEN,EAAEC,EAAEM,UAAUC,EAAER,EAAEK,EAAEE,UAA4CE,EAAEH,EAAEE,EAAEE,EAAtCV,EAAEC,EAAEU,WAAaX,EAAEK,EAAEM,WAAuB,OAAO,EAAET,KAAKU,KAAKV,KAAKW,KAAKX,KAAKY,IAAIL,EAAE,IAAI,EAAEP,KAAKa,IAAIT,GAAGJ,KAAKa,IAAIP,GAAGN,KAAKY,IAAIJ,EAAE,IAAI,IAAI,YAAcM,EAAE,CAACf,EAAEI,EAAEC,KAAK,MAAME,EAAEN,KAAKe,IAAIb,EAAEH,EAAEI,IAAIa,EAAEhB,KAAKe,IAAIb,EAAEH,EAAEK,IAAIa,EAAEjB,KAAKe,IAAIb,EAAEC,EAAEC,IAAIG,GAAGD,EAAEU,EAAEC,GAAG,EAAmC,OAAO,EAAtCjB,KAAKW,KAAKJ,GAAGA,EAAED,IAAIC,EAAES,IAAIT,EAAEU,IAAeX,GAAGY,EAAE,CAACnB,EAAEI,EAAEC,EAAEE,KAAK,IAAIU,EAAE,GAAG,GAAGb,EAAEC,EAAE,CAAC,IAAIa,EAAE,EAAEV,EAAE,EAAE,MAAMC,EAAET,EAAEI,GAAGgB,MAAMC,EAAErB,EAAEK,GAAGe,MAAM,IAAI,IAAIE,EAAElB,EAAE,EAAEkB,EAAEjB,EAAEiB,IAAI,CAAC,MAAMC,EAAER,EAAEN,EAAEY,EAAErB,EAAEsB,GAAGF,OAAOG,EAAEL,IAAIA,EAAEK,EAAEf,EAAEc,EAAE,CAACJ,GAAGX,IAAIU,EAAEO,KAAKxB,EAAEQ,GAAGY,OAAOH,EAAEA,EAAEQ,OAAON,EAAEnB,EAAEI,EAAEI,EAAED,GAAGY,EAAEnB,EAAEQ,EAAEH,EAAEE,IAAI,CAAC,OAAOU,GAA8XS,EAAQ,CAACC,eAAlY,CAAC3B,EAAEI,EAAE,MAAM,IAAIJ,GAAGA,EAAE4B,OAAO,EAAE,MAAM,IAAIC,MAAM,mEAAmE,MAAMxB,EAAEL,EAAE8B,KAAI,CAACb,EAAEC,KAAK,CAACa,MAAMb,EAAEE,MAAMH,MAAK,IAAIV,EAAE,CAACF,EAAE,GAAGe,MAAMf,EAAEA,EAAEuB,OAAO,GAAGR,OAAO,OAAOb,EAAEA,EAAEkB,OAAON,EAAEd,EAAE,EAAEA,EAAEuB,OAAO,EAAExB,IAAIG,EAAEyB,MAAK,CAACf,EAAEC,KAAK,IAAIV,EAAEC,EAAE,OAAmC,OAA3BD,EAAEH,EAAE4B,MAAKZ,GAAGA,EAAED,QAAQH,UAAU,EAAOT,EAAEuB,QAAoC,OAA3BtB,EAAEJ,EAAE4B,MAAKZ,GAAGA,EAAED,QAAQF,UAAU,EAAOT,EAAEsB"}