// index.ts
import { area } from "@turf/area";
import { bbox as turfBBox } from "@turf/bbox";
import { bboxPolygon } from "@turf/bbox-polygon";
import { getCoord } from "@turf/invariant";
import { squareGrid } from "@turf/square-grid";
function quadratAnalysis(pointFeatureSet, options) {
  options = options || {};
  const studyBbox = options.studyBbox || turfBBox(pointFeatureSet);
  const confidenceLevel = options.confidenceLevel || 20;
  const points = pointFeatureSet.features;
  const numOfPoints = points.length;
  const sizeOfArea = area(bboxPolygon(studyBbox));
  const lengthOfSide = Math.sqrt(sizeOfArea / numOfPoints * 2);
  const grid = squareGrid(studyBbox, lengthOfSide, {
    units: "meters"
  });
  const quadrats = grid.features;
  const quadratIdDict = {};
  for (let i = 0; i < quadrats.length; i++) {
    quadratIdDict[i] = {
      box: turfBBox(quadrats[i]),
      cnt: 0
    };
  }
  let sumOfPoint = 0;
  for (const pt of points) {
    for (const key of Object.keys(quadratIdDict)) {
      const box = quadratIdDict[key].box;
      if (inBBox(getCoord(pt), box)) {
        quadratIdDict[key].cnt += 1;
        sumOfPoint += 1;
        break;
      }
    }
  }
  let maxCnt = 0;
  for (const key of Object.keys(quadratIdDict)) {
    const cnt = quadratIdDict[key].cnt;
    if (cnt > maxCnt) {
      maxCnt = cnt;
    }
  }
  const expectedDistribution = [];
  const numOfQuadrat = Object.keys(quadratIdDict).length;
  const lambda = sumOfPoint / numOfQuadrat;
  let cumulativeProbility = 0;
  for (let x = 0; x < maxCnt + 1; x++) {
    cumulativeProbility += Math.exp(-lambda) * Math.pow(lambda, x) / factorial(x);
    expectedDistribution.push(cumulativeProbility);
  }
  const observedDistribution = [];
  let cumulativeObservedQuads = 0;
  for (let x = 0; x < maxCnt + 1; x++) {
    for (const key of Object.keys(quadratIdDict)) {
      if (quadratIdDict[key].cnt === x) {
        cumulativeObservedQuads += 1;
      }
    }
    const p = cumulativeObservedQuads / numOfQuadrat;
    observedDistribution.push(p);
  }
  let maxDifference = 0;
  for (let x = 0; x < maxCnt + 1; x++) {
    const difference = Math.abs(
      expectedDistribution[x] - observedDistribution[x]
    );
    if (difference > maxDifference) {
      maxDifference = difference;
    }
  }
  const k = K_TABLE[confidenceLevel];
  const criticalValue = k / Math.sqrt(numOfQuadrat);
  const result = {
    criticalValue,
    isRandom: true,
    maxAbsoluteDifference: maxDifference,
    observedDistribution
  };
  if (maxDifference > criticalValue) {
    result.isRandom = false;
  }
  return result;
}
var K_TABLE = {
  20: 1.07275,
  15: 1.13795,
  10: 1.22385,
  5: 1.3581,
  2: 1.51743,
  1: 1.62762
};
function inBBox(pt, bbox) {
  return bbox[0] <= pt[0] && bbox[1] <= pt[1] && bbox[2] >= pt[0] && bbox[3] >= pt[1];
}
function factorial(num) {
  const f = [];
  function inner(n) {
    if (n === 0 || n === 1) {
      return 1;
    }
    if (f[n] > 0) {
      return f[n];
    }
    return f[n] = inner(n - 1) * n;
  }
  return inner(num);
}
var turf_quadrat_analysis_default = quadratAnalysis;
export {
  turf_quadrat_analysis_default as default,
  quadratAnalysis
};
//# sourceMappingURL=index.js.map