{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-quadrat-analysis/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/turf/turf/packages/turf-quadrat-analysis/dist/cjs/index.cjs","sourcesContent":[null,"import { BBox, FeatureCollection, Point } from \"geojson\";\nimport { area } from \"@turf/area\";\nimport { bbox as turfBBox } from \"@turf/bbox\";\nimport { bboxPolygon } from \"@turf/bbox-polygon\";\nimport { getCoord } from \"@turf/invariant\";\nimport { squareGrid } from \"@turf/square-grid\";\n\ninterface QuadratAnalysisResult {\n criticalValue: number;\n maxAbsoluteDifference: number;\n isRandom: boolean;\n observedDistribution: number[];\n}\n\n/**\n * Quadrat analysis lays a set of equal-size areas(quadrat) over the study area and counts\n * the number of features in each quadrat and creates a frequency table.\n * The table lists the number of quadrats containing no features,\n * the number containing one feature, two features, and so on,\n * all the way up to the quadrat containing the most features.\n * The method then creates the frequency table for the random distribution, usually based on a Poisson distribution.\n * The method uses the distribution to calculate the probability for 0 feature occuring,\n * 1 feature occuring, 2 features, and so on,\n * and lists these probabilities in the frequency table.\n * By comparing the two frequency tables, you can see whether the features create a pattern.\n * If the table for the observed distribution has more quadrats containing many features than the\n * table for the random distribution dose, then the features create a clustered pattern.\n *\n * It is hard to judge the frequency tables are similar or different just by looking at them.\n * So, we can use serval statistical tests to find out how much the frequency tables differ.\n * We use Kolmogorov-Smirnov test.This method calculates cumulative probabilities for both distributions,\n * and then compares the cumulative probabilities at each class level and selects the largest absolute difference D.\n * Then, the test compares D to the critical value for a confidence level you specify.\n * If D is greater than the critical value, the difference between the observed distribution and\n * the random distribution is significant. The greater the value the bigger the difference.\n *\n * Traditionally, squares are used for the shape of the quadrats, in a regular grid(square-grid).\n * Some researchers suggest that the quadrat size equal twice the size of mean area per feature,\n * which is simply the area of the study area divided by the number of features.\n *\n *\n * @function\n * @param {FeatureCollection} pointFeatureSet point set to study\n * @param {Object} [options={}] optional parameters\n * @param {[number, number, number, number]} [options.studyBbox] bbox representing the study area\n * @param {20 | 15 | 10 | 5 | 2 | 1} [options.confidenceLevel=20] a confidence level.\n * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE}\n * @returns {QuadratAnalysisResult} result\n * @example\n *\n * var bbox = [-65, 40, -63, 42];\n * var dataset = turf.randomPoint(100, { bbox: bbox });\n * var result = turf.quadratAnalysis(dataset);\n *\n */\nfunction quadratAnalysis(\n pointFeatureSet: FeatureCollection,\n options: {\n studyBbox?: [number, number, number, number];\n confidenceLevel?: 20 | 15 | 10 | 5 | 2 | 1;\n }\n): QuadratAnalysisResult {\n options = options || {};\n const studyBbox = options.studyBbox || turfBBox(pointFeatureSet);\n const confidenceLevel = options.confidenceLevel || 20;\n const points = pointFeatureSet.features;\n\n // create square-grid\n const numOfPoints = points.length;\n const sizeOfArea = area(bboxPolygon(studyBbox));\n const lengthOfSide = Math.sqrt((sizeOfArea / numOfPoints) * 2);\n const grid = squareGrid(studyBbox, lengthOfSide, {\n units: \"meters\",\n });\n const quadrats = grid.features;\n\n // count the number of features in each quadrat\n const quadratIdDict: { [key: string]: { box: BBox; cnt: number } } = {};\n for (let i = 0; i < quadrats.length; i++) {\n quadratIdDict[i] = {\n box: turfBBox(quadrats[i]),\n cnt: 0,\n };\n }\n\n let sumOfPoint = 0;\n for (const pt of points) {\n for (const key of Object.keys(quadratIdDict)) {\n const box = quadratIdDict[key].box;\n if (inBBox(getCoord(pt), box)) {\n quadratIdDict[key].cnt += 1;\n sumOfPoint += 1;\n break;\n }\n }\n }\n\n // the most amount of features in quadrat\n let maxCnt = 0;\n for (const key of Object.keys(quadratIdDict)) {\n const cnt = quadratIdDict[key].cnt;\n if (cnt > maxCnt) {\n maxCnt = cnt;\n }\n }\n\n const expectedDistribution = [];\n const numOfQuadrat = Object.keys(quadratIdDict).length;\n const lambda = sumOfPoint / numOfQuadrat;\n\n // get the cumulative probability of the random distribution\n let cumulativeProbility = 0.0;\n for (let x = 0; x < maxCnt + 1; x++) {\n cumulativeProbility +=\n (Math.exp(-lambda) * Math.pow(lambda, x)) / factorial(x);\n expectedDistribution.push(cumulativeProbility);\n }\n\n // get the cumulative probability of the observed distribution\n const observedDistribution = [];\n let cumulativeObservedQuads = 0;\n for (let x = 0; x < maxCnt + 1; x++) {\n for (const key of Object.keys(quadratIdDict)) {\n if (quadratIdDict[key].cnt === x) {\n cumulativeObservedQuads += 1;\n }\n }\n const p = cumulativeObservedQuads / numOfQuadrat;\n observedDistribution.push(p);\n }\n\n // get the largest absolute difference between two distributions\n let maxDifference = 0;\n for (let x = 0; x < maxCnt + 1; x++) {\n const difference = Math.abs(\n expectedDistribution[x] - observedDistribution[x]\n );\n if (difference > maxDifference) {\n maxDifference = difference;\n }\n }\n\n const k = K_TABLE[confidenceLevel];\n\n // statistical test\n const criticalValue = k / Math.sqrt(numOfQuadrat);\n const result: QuadratAnalysisResult = {\n criticalValue,\n isRandom: true,\n maxAbsoluteDifference: maxDifference,\n observedDistribution,\n };\n\n if (maxDifference > criticalValue) {\n result.isRandom = false;\n }\n\n return result;\n}\n\n/**\n * the confidence level\n *\n * @constant\n * @type {Object}\n * @property {number} 20 1.07275\n * @property {number} 15 1.13795\n * @property {number} 10 1.22385\n * @property {number} 5 1.3581\n * @property {number} 2 1.51743\n * @property {number} 1 1.62762\n */\nconst K_TABLE = {\n 20: 1.07275,\n 15: 1.13795,\n 10: 1.22385,\n 5: 1.3581,\n 2: 1.51743,\n 1: 1.62762,\n};\n\n/**\n * the return type of the quadratAnalysis\n *\n * @typedef {object} QuadratAnalysisResult\n * @property {number} criticalValue\n * @property {number} maxAbsoluteDifference\n * @property {boolean} isRandom\n * @property {Array} observedDistribution the cumulative distribution of observed features,\n * the index represents the number of features in the quadrat.\n */\n\n/**\n * inBBox from @turf/boolean-point-in-polygon\n *\n * @private\n * @param {Array} pt point [x,y]\n * @param {BBox} bbox BBox [west, south, east, north]\n * @returns {boolean} true/false if point is inside BBox\n */\nfunction inBBox(pt: number[], bbox: BBox) {\n return (\n bbox[0] <= pt[0] && bbox[1] <= pt[1] && bbox[2] >= pt[0] && bbox[3] >= pt[1]\n );\n}\n\n/**\n * https://stackoverflow.com/questions/3959211/fast-factorial-function-in-javascript\n * @private\n * @param {number} num Number\n * @returns {number} the factorial of num\n */\nfunction factorial(num: number) {\n const f: number[] = [];\n function inner(n: number): number {\n if (n === 0 || n === 1) {\n return 1;\n }\n if (f[n] > 0) {\n return f[n];\n }\n return (f[n] = inner(n - 1) * n);\n }\n return inner(num);\n}\n\nexport { QuadratAnalysisResult, quadratAnalysis };\nexport default quadratAnalysis;\n"]}