@turf/quadrat-analysis 7.1.0-alpha.70 → 7.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,8 +34,8 @@ which is simply the area of the study area divided by the number of features.
34
34
  * `pointFeatureSet` **[FeatureCollection][1]<[Point][2]>** point set to study
35
35
  * `options` **[Object][3]** optional parameters (optional, default `{}`)
36
36
 
37
- * `options.studyBbox` **bbox?** bbox representing the study area
38
- * `options.confidenceLevel` **[number][4]** a confidence level.
37
+ * `options.studyBbox` **\[[number][4], [number][4], [number][4], [number][4]]?** bbox representing the study area
38
+ * `options.confidenceLevel` **(`20` | `15` | `10` | `5` | `2` | `1`)** a confidence level.
39
39
  The unit is percentage . 5 means 95%, value must be in [K\_TABLE][5] (optional, default `20`)
40
40
 
41
41
  ### Examples
@@ -46,7 +46,7 @@ var dataset = turf.randomPoint(100, { bbox: bbox });
46
46
  var result = turf.quadratAnalysis(dataset);
47
47
  ```
48
48
 
49
- Returns **[Object][3]** result [QuadratAnalysisResult][6]
49
+ Returns **[QuadratAnalysisResult][6]** result
50
50
 
51
51
  ## K\_TABLE
52
52
 
@@ -56,18 +56,18 @@ Type: [Object][3]
56
56
 
57
57
  ### Properties
58
58
 
59
- * `20` **[number][4]**&#x20;
60
- * `15` **[number][4]**&#x20;
61
- * `10` **[number][4]**&#x20;
62
- * `5` **[number][4]**&#x20;
63
- * `2` **[number][4]**&#x20;
64
- * `1` **[number][4]**&#x20;
59
+ * `20` **[number][4]** 1.07275
60
+ * `15` **[number][4]** 1.13795
61
+ * `10` **[number][4]** 1.22385
62
+ * `5` **[number][4]** 1.3581
63
+ * `2` **[number][4]** 1.51743
64
+ * `1` **[number][4]** 1.62762
65
65
 
66
66
  ## QuadratAnalysisResult
67
67
 
68
68
  the return type of the quadratAnalysis
69
69
 
70
- Type: [Object][3]
70
+ Type: [object][3]
71
71
 
72
72
  ### Properties
73
73
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts"],"names":[],"mappings":"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","sourcesContent":["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 * @name quadratAnalysis\n * @param {FeatureCollection<Point>} pointFeatureSet point set to study\n * @param {Object} [options={}] optional parameters\n * @param {bbox} [options.studyBbox] bbox representing the study area\n * @param {number} [options.confidenceLevel=20] a confidence level.\n * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE}\n * @returns {Object} result {@link QuadratAnalysisResult}\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<Point>,\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 * @type {Object} K_TABLE\n * @property {number} 20\n * @property {number} 15\n * @property {number} 10\n * @property {number} 5\n * @property {number} 2\n * @property {number} 1\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 * @typedef {Object} QuadratAnalysisResult\n * @property {number} criticalValue\n * @property {number} maxAbsoluteDifference\n * @property {boolean} isRandom\n * @property {Array.<number>} 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<number>} 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"]}
1
+ {"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-quadrat-analysis/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"AAAA;ACCA,kCAAqB;AACrB,kCAAiC;AACjC,iDAA4B;AAC5B,4CAAyB;AACzB,+CAA2B;AAkD3B,SAAS,eAAA,CACP,eAAA,EACA,OAAA,EAIuB;AACvB,EAAA,QAAA,EAAU,QAAA,GAAW,CAAC,CAAA;AACtB,EAAA,MAAM,UAAA,EAAY,OAAA,CAAQ,UAAA,GAAa,wBAAA,eAAwB,CAAA;AAC/D,EAAA,MAAM,gBAAA,EAAkB,OAAA,CAAQ,gBAAA,GAAmB,EAAA;AACnD,EAAA,MAAM,OAAA,EAAS,eAAA,CAAgB,QAAA;AAG/B,EAAA,MAAM,YAAA,EAAc,MAAA,CAAO,MAAA;AAC3B,EAAA,MAAM,WAAA,EAAa,wBAAA,sCAAK,SAAqB,CAAC,CAAA;AAC9C,EAAA,MAAM,aAAA,EAAe,IAAA,CAAK,IAAA,CAAM,WAAA,EAAa,YAAA,EAAe,CAAC,CAAA;AAC7D,EAAA,MAAM,KAAA,EAAO,oCAAA,SAAW,EAAW,YAAA,EAAc;AAAA,IAC/C,KAAA,EAAO;AAAA,EACT,CAAC,CAAA;AACD,EAAA,MAAM,SAAA,EAAW,IAAA,CAAK,QAAA;AAGtB,EAAA,MAAM,cAAA,EAA+D,CAAC,CAAA;AACtE,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,QAAA,CAAS,MAAA,EAAQ,CAAA,EAAA,EAAK;AACxC,IAAA,aAAA,CAAc,CAAC,EAAA,EAAI;AAAA,MACjB,GAAA,EAAK,wBAAA,QAAS,CAAS,CAAC,CAAC,CAAA;AAAA,MACzB,GAAA,EAAK;AAAA,IACP,CAAA;AAAA,EACF;AAEA,EAAA,IAAI,WAAA,EAAa,CAAA;AACjB,EAAA,IAAA,CAAA,MAAW,GAAA,GAAM,MAAA,EAAQ;AACvB,IAAA,IAAA,CAAA,MAAW,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,EAAG;AAC5C,MAAA,MAAM,IAAA,EAAM,aAAA,CAAc,GAAG,CAAA,CAAE,GAAA;AAC/B,MAAA,GAAA,CAAI,MAAA,CAAO,iCAAA,EAAW,CAAA,EAAG,GAAG,CAAA,EAAG;AAC7B,QAAA,aAAA,CAAc,GAAG,CAAA,CAAE,IAAA,GAAO,CAAA;AAC1B,QAAA,WAAA,GAAc,CAAA;AACd,QAAA,KAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,OAAA,EAAS,CAAA;AACb,EAAA,IAAA,CAAA,MAAW,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,EAAG;AAC5C,IAAA,MAAM,IAAA,EAAM,aAAA,CAAc,GAAG,CAAA,CAAE,GAAA;AAC/B,IAAA,GAAA,CAAI,IAAA,EAAM,MAAA,EAAQ;AAChB,MAAA,OAAA,EAAS,GAAA;AAAA,IACX;AAAA,EACF;AAEA,EAAA,MAAM,qBAAA,EAAuB,CAAC,CAAA;AAC9B,EAAA,MAAM,aAAA,EAAe,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,CAAE,MAAA;AAChD,EAAA,MAAM,OAAA,EAAS,WAAA,EAAa,YAAA;AAG5B,EAAA,IAAI,oBAAA,EAAsB,CAAA;AAC1B,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,OAAA,EAAS,CAAA,EAAG,CAAA,EAAA,EAAK;AACnC,IAAA,oBAAA,GACG,IAAA,CAAK,GAAA,CAAI,CAAC,MAAM,EAAA,EAAI,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,CAAC,EAAA,EAAK,SAAA,CAAU,CAAC,CAAA;AACzD,IAAA,oBAAA,CAAqB,IAAA,CAAK,mBAAmB,CAAA;AAAA,EAC/C;AAGA,EAAA,MAAM,qBAAA,EAAuB,CAAC,CAAA;AAC9B,EAAA,IAAI,wBAAA,EAA0B,CAAA;AAC9B,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,OAAA,EAAS,CAAA,EAAG,CAAA,EAAA,EAAK;AACnC,IAAA,IAAA,CAAA,MAAW,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,aAAa,CAAA,EAAG;AAC5C,MAAA,GAAA,CAAI,aAAA,CAAc,GAAG,CAAA,CAAE,IAAA,IAAQ,CAAA,EAAG;AAChC,QAAA,wBAAA,GAA2B,CAAA;AAAA,MAC7B;AAAA,IACF;AACA,IAAA,MAAM,EAAA,EAAI,wBAAA,EAA0B,YAAA;AACpC,IAAA,oBAAA,CAAqB,IAAA,CAAK,CAAC,CAAA;AAAA,EAC7B;AAGA,EAAA,IAAI,cAAA,EAAgB,CAAA;AACpB,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,OAAA,EAAS,CAAA,EAAG,CAAA,EAAA,EAAK;AACnC,IAAA,MAAM,WAAA,EAAa,IAAA,CAAK,GAAA;AAAA,MACtB,oBAAA,CAAqB,CAAC,EAAA,EAAI,oBAAA,CAAqB,CAAC;AAAA,IAClD,CAAA;AACA,IAAA,GAAA,CAAI,WAAA,EAAa,aAAA,EAAe;AAC9B,MAAA,cAAA,EAAgB,UAAA;AAAA,IAClB;AAAA,EACF;AAEA,EAAA,MAAM,EAAA,EAAI,OAAA,CAAQ,eAAe,CAAA;AAGjC,EAAA,MAAM,cAAA,EAAgB,EAAA,EAAI,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA;AAChD,EAAA,MAAM,OAAA,EAAgC;AAAA,IACpC,aAAA;AAAA,IACA,QAAA,EAAU,IAAA;AAAA,IACV,qBAAA,EAAuB,aAAA;AAAA,IACvB;AAAA,EACF,CAAA;AAEA,EAAA,GAAA,CAAI,cAAA,EAAgB,aAAA,EAAe;AACjC,IAAA,MAAA,CAAO,SAAA,EAAW,KAAA;AAAA,EACpB;AAEA,EAAA,OAAO,MAAA;AACT;AAcA,IAAM,QAAA,EAAU;AAAA,EACd,EAAA,EAAI,OAAA;AAAA,EACJ,EAAA,EAAI,OAAA;AAAA,EACJ,EAAA,EAAI,OAAA;AAAA,EACJ,CAAA,EAAG,MAAA;AAAA,EACH,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAqBA,SAAS,MAAA,CAAO,EAAA,EAAc,IAAA,EAAY;AACxC,EAAA,OACE,IAAA,CAAK,CAAC,EAAA,GAAK,EAAA,CAAG,CAAC,EAAA,GAAK,IAAA,CAAK,CAAC,EAAA,GAAK,EAAA,CAAG,CAAC,EAAA,GAAK,IAAA,CAAK,CAAC,EAAA,GAAK,EAAA,CAAG,CAAC,EAAA,GAAK,IAAA,CAAK,CAAC,EAAA,GAAK,EAAA,CAAG,CAAC,CAAA;AAE/E;AAQA,SAAS,SAAA,CAAU,GAAA,EAAa;AAC9B,EAAA,MAAM,EAAA,EAAc,CAAC,CAAA;AACrB,EAAA,SAAS,KAAA,CAAM,CAAA,EAAmB;AAChC,IAAA,GAAA,CAAI,EAAA,IAAM,EAAA,GAAK,EAAA,IAAM,CAAA,EAAG;AACtB,MAAA,OAAO,CAAA;AAAA,IACT;AACA,IAAA,GAAA,CAAI,CAAA,CAAE,CAAC,EAAA,EAAI,CAAA,EAAG;AACZ,MAAA,OAAO,CAAA,CAAE,CAAC,CAAA;AAAA,IACZ;AACA,IAAA,OAAQ,CAAA,CAAE,CAAC,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,CAAC,EAAA,EAAI,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,KAAA,CAAM,GAAG,CAAA;AAClB;AAGA,IAAO,8BAAA,EAAQ,eAAA;ADtHf;AACE;AACA;AACF,2FAAC","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<Point>} 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<Point>,\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<number>} 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<number>} 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"]}
@@ -33,13 +33,13 @@ interface QuadratAnalysisResult {
33
33
  * which is simply the area of the study area divided by the number of features.
34
34
  *
35
35
  *
36
- * @name quadratAnalysis
36
+ * @function
37
37
  * @param {FeatureCollection<Point>} pointFeatureSet point set to study
38
38
  * @param {Object} [options={}] optional parameters
39
- * @param {bbox} [options.studyBbox] bbox representing the study area
40
- * @param {number} [options.confidenceLevel=20] a confidence level.
39
+ * @param {[number, number, number, number]} [options.studyBbox] bbox representing the study area
40
+ * @param {20 | 15 | 10 | 5 | 2 | 1} [options.confidenceLevel=20] a confidence level.
41
41
  * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE}
42
- * @returns {Object} result {@link QuadratAnalysisResult}
42
+ * @returns {QuadratAnalysisResult} result
43
43
  * @example
44
44
  *
45
45
  * var bbox = [-65, 40, -63, 42];
@@ -33,13 +33,13 @@ interface QuadratAnalysisResult {
33
33
  * which is simply the area of the study area divided by the number of features.
34
34
  *
35
35
  *
36
- * @name quadratAnalysis
36
+ * @function
37
37
  * @param {FeatureCollection<Point>} pointFeatureSet point set to study
38
38
  * @param {Object} [options={}] optional parameters
39
- * @param {bbox} [options.studyBbox] bbox representing the study area
40
- * @param {number} [options.confidenceLevel=20] a confidence level.
39
+ * @param {[number, number, number, number]} [options.studyBbox] bbox representing the study area
40
+ * @param {20 | 15 | 10 | 5 | 2 | 1} [options.confidenceLevel=20] a confidence level.
41
41
  * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE}
42
- * @returns {Object} result {@link QuadratAnalysisResult}
42
+ * @returns {QuadratAnalysisResult} result
43
43
  * @example
44
44
  *
45
45
  * var bbox = [-65, 40, -63, 42];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../index.ts"],"sourcesContent":["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 * @name quadratAnalysis\n * @param {FeatureCollection<Point>} pointFeatureSet point set to study\n * @param {Object} [options={}] optional parameters\n * @param {bbox} [options.studyBbox] bbox representing the study area\n * @param {number} [options.confidenceLevel=20] a confidence level.\n * The unit is percentage . 5 means 95%, value must be in {@link K_TABLE}\n * @returns {Object} result {@link QuadratAnalysisResult}\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<Point>,\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 * @type {Object} K_TABLE\n * @property {number} 20\n * @property {number} 15\n * @property {number} 10\n * @property {number} 5\n * @property {number} 2\n * @property {number} 1\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 * @typedef {Object} QuadratAnalysisResult\n * @property {number} criticalValue\n * @property {number} maxAbsoluteDifference\n * @property {boolean} isRandom\n * @property {Array.<number>} 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<number>} 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"],"mappings":";AACA,SAAS,YAAY;AACrB,SAAS,QAAQ,gBAAgB;AACjC,SAAS,mBAAmB;AAC5B,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAkD3B,SAAS,gBACP,iBACA,SAIuB;AACvB,YAAU,WAAW,CAAC;AACtB,QAAM,YAAY,QAAQ,aAAa,SAAS,eAAe;AAC/D,QAAM,kBAAkB,QAAQ,mBAAmB;AACnD,QAAM,SAAS,gBAAgB;AAG/B,QAAM,cAAc,OAAO;AAC3B,QAAM,aAAa,KAAK,YAAY,SAAS,CAAC;AAC9C,QAAM,eAAe,KAAK,KAAM,aAAa,cAAe,CAAC;AAC7D,QAAM,OAAO,WAAW,WAAW,cAAc;AAAA,IAC/C,OAAO;AAAA,EACT,CAAC;AACD,QAAM,WAAW,KAAK;AAGtB,QAAM,gBAA+D,CAAC;AACtE,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,kBAAc,CAAC,IAAI;AAAA,MACjB,KAAK,SAAS,SAAS,CAAC,CAAC;AAAA,MACzB,KAAK;AAAA,IACP;AAAA,EACF;AAEA,MAAI,aAAa;AACjB,aAAW,MAAM,QAAQ;AACvB,eAAW,OAAO,OAAO,KAAK,aAAa,GAAG;AAC5C,YAAM,MAAM,cAAc,GAAG,EAAE;AAC/B,UAAI,OAAO,SAAS,EAAE,GAAG,GAAG,GAAG;AAC7B,sBAAc,GAAG,EAAE,OAAO;AAC1B,sBAAc;AACd;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS;AACb,aAAW,OAAO,OAAO,KAAK,aAAa,GAAG;AAC5C,UAAM,MAAM,cAAc,GAAG,EAAE;AAC/B,QAAI,MAAM,QAAQ;AAChB,eAAS;AAAA,IACX;AAAA,EACF;AAEA,QAAM,uBAAuB,CAAC;AAC9B,QAAM,eAAe,OAAO,KAAK,aAAa,EAAE;AAChD,QAAM,SAAS,aAAa;AAG5B,MAAI,sBAAsB;AAC1B,WAAS,IAAI,GAAG,IAAI,SAAS,GAAG,KAAK;AACnC,2BACG,KAAK,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,QAAQ,CAAC,IAAK,UAAU,CAAC;AACzD,yBAAqB,KAAK,mBAAmB;AAAA,EAC/C;AAGA,QAAM,uBAAuB,CAAC;AAC9B,MAAI,0BAA0B;AAC9B,WAAS,IAAI,GAAG,IAAI,SAAS,GAAG,KAAK;AACnC,eAAW,OAAO,OAAO,KAAK,aAAa,GAAG;AAC5C,UAAI,cAAc,GAAG,EAAE,QAAQ,GAAG;AAChC,mCAA2B;AAAA,MAC7B;AAAA,IACF;AACA,UAAM,IAAI,0BAA0B;AACpC,yBAAqB,KAAK,CAAC;AAAA,EAC7B;AAGA,MAAI,gBAAgB;AACpB,WAAS,IAAI,GAAG,IAAI,SAAS,GAAG,KAAK;AACnC,UAAM,aAAa,KAAK;AAAA,MACtB,qBAAqB,CAAC,IAAI,qBAAqB,CAAC;AAAA,IAClD;AACA,QAAI,aAAa,eAAe;AAC9B,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,IAAI,QAAQ,eAAe;AAGjC,QAAM,gBAAgB,IAAI,KAAK,KAAK,YAAY;AAChD,QAAM,SAAgC;AAAA,IACpC;AAAA,IACA,UAAU;AAAA,IACV,uBAAuB;AAAA,IACvB;AAAA,EACF;AAEA,MAAI,gBAAgB,eAAe;AACjC,WAAO,WAAW;AAAA,EACpB;AAEA,SAAO;AACT;AAYA,IAAM,UAAU;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAoBA,SAAS,OAAO,IAAc,MAAY;AACxC,SACE,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,GAAG,CAAC;AAE/E;AAQA,SAAS,UAAU,KAAa;AAC9B,QAAM,IAAc,CAAC;AACrB,WAAS,MAAM,GAAmB;AAChC,QAAI,MAAM,KAAK,MAAM,GAAG;AACtB,aAAO;AAAA,IACT;AACA,QAAI,EAAE,CAAC,IAAI,GAAG;AACZ,aAAO,EAAE,CAAC;AAAA,IACZ;AACA,WAAQ,EAAE,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI;AAAA,EAChC;AACA,SAAO,MAAM,GAAG;AAClB;AAGA,IAAO,gCAAQ;","names":[]}
1
+ {"version":3,"sources":["../../index.ts"],"sourcesContent":["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<Point>} 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<Point>,\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<number>} 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<number>} 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"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turf/quadrat-analysis",
3
- "version": "7.1.0-alpha.70+948cdafaf",
3
+ "version": "7.2.0",
4
4
  "description": "turf quadrat-analysis module",
5
5
  "author": "Turf Authors",
6
6
  "contributors": [
@@ -52,30 +52,30 @@
52
52
  "test:tape": "tsx test.ts"
53
53
  },
54
54
  "devDependencies": {
55
- "@turf/nearest-neighbor-analysis": "^7.1.0-alpha.70+948cdafaf",
55
+ "@turf/nearest-neighbor-analysis": "^7.2.0",
56
56
  "@types/benchmark": "^2.1.5",
57
- "@types/tape": "^4.2.32",
57
+ "@types/tape": "^4.13.4",
58
58
  "benchmark": "^2.1.4",
59
59
  "load-json-file": "^7.0.1",
60
60
  "npm-run-all": "^4.1.5",
61
- "tape": "^5.7.2",
62
- "tsup": "^8.0.1",
63
- "tsx": "^4.6.2",
64
- "typescript": "^5.2.2",
61
+ "tape": "^5.9.0",
62
+ "tsup": "^8.3.5",
63
+ "tsx": "^4.19.2",
64
+ "typescript": "^5.5.4",
65
65
  "write-json-file": "^5.0.0"
66
66
  },
67
67
  "dependencies": {
68
- "@turf/area": "^7.1.0-alpha.70+948cdafaf",
69
- "@turf/bbox": "^7.1.0-alpha.70+948cdafaf",
70
- "@turf/bbox-polygon": "^7.1.0-alpha.70+948cdafaf",
71
- "@turf/centroid": "^7.1.0-alpha.70+948cdafaf",
72
- "@turf/helpers": "^7.1.0-alpha.70+948cdafaf",
73
- "@turf/invariant": "^7.1.0-alpha.70+948cdafaf",
74
- "@turf/point-grid": "^7.1.0-alpha.70+948cdafaf",
75
- "@turf/random": "^7.1.0-alpha.70+948cdafaf",
76
- "@turf/square-grid": "^7.1.0-alpha.70+948cdafaf",
68
+ "@turf/area": "^7.2.0",
69
+ "@turf/bbox": "^7.2.0",
70
+ "@turf/bbox-polygon": "^7.2.0",
71
+ "@turf/centroid": "^7.2.0",
72
+ "@turf/helpers": "^7.2.0",
73
+ "@turf/invariant": "^7.2.0",
74
+ "@turf/point-grid": "^7.2.0",
75
+ "@turf/random": "^7.2.0",
76
+ "@turf/square-grid": "^7.2.0",
77
77
  "@types/geojson": "^7946.0.10",
78
- "tslib": "^2.6.2"
78
+ "tslib": "^2.8.1"
79
79
  },
80
- "gitHead": "948cdafaf70606d2e27fcc79973fa48ee1182067"
80
+ "gitHead": "7b0f0374c4668cd569f8904c71e2ae7d941be867"
81
81
  }