{"version":3,"sources":["/home/runner/work/turf/turf/packages/turf-nearest-neighbor-analysis/dist/cjs/index.cjs","../../index.ts"],"names":[],"mappings":"AAAA;ACOA,kCAAqB;AACrB,kCAAqB;AACrB,iDAA4B;AAC5B,0CAAyB;AACzB,0CAAyB;AACzB,mDAA6B;AAC7B,kCAA4B;AAC5B;AACE;AACA;AAAA,wCAGK;AAwFP,SAAS,uBAAA,CACP,OAAA,EACA,OAAA,EAK0B;AAE1B,EAAA,QAAA,EAAU,QAAA,GAAW,CAAC,CAAA;AACtB,EAAA,MAAM,UAAA,EAAY,OAAA,CAAQ,UAAA,GAAa,sCAAA,wBAAY,OAAY,CAAC,CAAA;AAChE,EAAA,MAAM,WAAA,EAAa,OAAA,CAAQ,WAAA,GAAc,CAAC,CAAA;AAC1C,EAAA,MAAM,MAAA,EAAQ,OAAA,CAAQ,MAAA,GAAS,YAAA;AAE/B,EAAA,MAAM,SAAA,EAAkC,CAAC,CAAA;AACzC,EAAA,+BAAA,OAAY,EAAS,CAAC,OAAA,EAAA,GAAY;AAChC,IAAA,QAAA,CAAS,IAAA,CAAK,gCAAA,OAAgB,CAAC,CAAA;AAAA,EACjC,CAAC,CAAA;AACD,EAAA,MAAM,EAAA,EAAI,QAAA,CAAS,MAAA;AACnB,EAAA,MAAM,qBAAA,EACJ,QAAA,CACG,GAAA,CAAI,CAAC,OAAA,EAAS,KAAA,EAAA,GAAU;AACvB,IAAA,MAAM,cAAA,EAAgB,wCAAA;AAAA,MACpB,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,EAAG,CAAA,EAAA,GAAM;AACxB,QAAA,OAAO,EAAA,IAAM,KAAA;AAAA,MACf,CAAC;AAAA,IACH,CAAA;AAGA,IAAA,OAAO,gCAAA;AAAA,MACL,OAAA;AAAA,MACA,wCAAA,OAAa,EAAS,aAAa,CAAA,CAAE,QAAA,CAAU,WAAA;AAAA,MAC/C,EAAE,MAAM;AAAA,IACV,CAAA;AAAA,EACF,CAAC,CAAA,CACA,MAAA,CAAO,CAAC,GAAA,EAAK,KAAA,EAAA,GAAU;AACtB,IAAA,OAAO,IAAA,EAAM,KAAA;AAAA,EACf,CAAA,EAAG,CAAC,EAAA,EAAI,CAAA;AAEZ,EAAA,MAAM,kBAAA,EAAoB,EAAA,EAAI,kCAAA,wBAAY,SAAc,CAAA,EAAG,QAAA,EAAU,KAAK,CAAA;AAC1E,EAAA,MAAM,qBAAA,EAAuB,EAAA,EAAA,CAAK,EAAA,EAAI,IAAA,CAAK,IAAA,CAAK,iBAAiB,CAAA,CAAA;AACjE,EAAA,MAAM,SAAA,EAAW,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,iBAAiB,CAAA;AAC1D,EAAA,UAAA,CAAW,wBAAA,EAA0B;AAAA,IACnC,KAAA;AAAA,IACA,UAAA,EAAY,MAAA,EAAQ,MAAA;AAAA,IACpB,oBAAA;AAAA,IACA,oBAAA;AAAA,IACA,oBAAA,EAAsB,qBAAA,EAAuB,oBAAA;AAAA,IAC7C,cAAA,EAAgB,CAAA;AAAA,IAChB,MAAA,EAAA,CAAS,qBAAA,EAAuB,oBAAA,EAAA,EAAwB;AAAA,EAC1D,CAAA;AACA,EAAA,SAAA,CAAU,WAAA,EAAa,UAAA;AAEvB,EAAA,OAAO,SAAA;AACT;AAOA,IAAO,uCAAA,EAAQ,uBAAA;ADpHf;AACE;AACA;AACF,oHAAC","file":"/home/runner/work/turf/turf/packages/turf-nearest-neighbor-analysis/dist/cjs/index.cjs","sourcesContent":[null,"import {\n FeatureCollection,\n Feature,\n Point,\n Polygon,\n GeoJsonProperties,\n} from \"geojson\";\nimport { area } from \"@turf/area\";\nimport { bbox } from \"@turf/bbox\";\nimport { bboxPolygon } from \"@turf/bbox-polygon\";\nimport { centroid } from \"@turf/centroid\";\nimport { distance } from \"@turf/distance\";\nimport { nearestPoint } from \"@turf/nearest-point\";\nimport { featureEach } from \"@turf/meta\";\nimport {\n convertArea,\n featureCollection,\n Units,\n AreaUnits,\n} from \"@turf/helpers\";\n\n/**\n * Nearest neighbour statistics.\n *\n * @typedef {object} NearestNeighborStatistics\n * @property {(Units & AreaUnits)} units\n * @property {string} arealUnits\n * @property {number} observedMeanDistance\n * @property {number} expectedMeanDistance\n * @property {number} numberOfPoints\n * @property {number} zScore\n */\ninterface NearestNeighborStatistics {\n units: Units & AreaUnits;\n arealUnits: string;\n observedMeanDistance: number;\n expectedMeanDistance: number;\n numberOfPoints: number;\n zScore: number;\n}\n\n/**\n * Nearest neighbour study area polygon feature.\n *\n * @typedef {object} NearestNeighborStudyArea\n * @extends Feature\n * @property {GeoJsonProperties} properties\n * @property {NearestNeighborStatistics} properties.nearestNeighborAnalysis\n */\ninterface NearestNeighborStudyArea extends Feature {\n properties: {\n nearestNeighborAnalysis: NearestNeighborStatistics;\n [key: string]: any;\n };\n}\n\n/**\n * Nearest Neighbor Analysis calculates an index based the average distances\n * between points in the dataset, thereby providing inference as to whether the\n * data is clustered, dispersed, or randomly distributed within the study area.\n *\n * It returns a {@link Feature}<{@link Polygon}> of the study area, with the results of\n * the analysis attached as part of of the `nearestNeighborAnalysis` property\n * of the study area's `properties`. The attached\n * [_z_-score](https://en.wikipedia.org/wiki/Standard_score) indicates how many\n * standard deviations above or below the expected mean distance the data's\n * observed mean distance is. The more negative, the more clustered. The more\n * positive, the more evenly dispersed. A _z_-score between -2 and 2 indicates\n * a seemingly random distribution. That is, within _p_ of less than 0.05, the\n * distribution appears statistically significantly neither clustered nor\n * dispersed.\n *\n * **Remarks**\n *\n * - Though the analysis will work on any {@link FeatureCollection} type, it\n * works best with {@link Point} collections.\n *\n * - This analysis is _very_ sensitive to the study area provided.\n * If no {@link Feature}<{@link Polygon}> is passed as the study area, the function draws a box\n * around the data, which may distort the findings. This analysis works best\n * with a bounded area of interest within with the data is either clustered,\n * dispersed, or randomly distributed. For example, a city's subway stops may\n * look extremely clustered if the study area is an entire state. On the other\n * hand, they may look rather evenly dispersed if the study area is limited to\n * the city's downtown.\n *\n * **Bibliography**\n *\n * Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a\n * Measure of Spatial Relationships in Populations,” _Ecology_ 35, no. 4\n * (1954): 445–453, doi:[10.2307/1931034](http://doi.org/10.2307/1931034).\n *\n * @function\n * @param {FeatureCollection} dataset FeatureCollection (pref. of points) to study\n * @param {Object} [options={}] Optional parameters\n * @param {Feature} [options.studyArea] polygon representing the study area\n * @param {Units & AreaUnits} [options.units='kilometers'] unit of measurement for distances and, squared, area.\n * @param {GeoJsonProperties} [options.properties={}] properties\n * @returns {NearestNeighborStudyArea} A polygon of the study area or an approximation of one.\n * @example\n * var bbox = [-65, 40, -63, 42];\n * var dataset = turf.randomPoint(100, { bbox: bbox });\n * var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset);\n *\n * //addToMap\n * var addToMap = [dataset, nearestNeighborStudyArea];\n */\nfunction nearestNeighborAnalysis(\n dataset: FeatureCollection,\n options?: {\n studyArea?: Feature;\n units?: Units & AreaUnits;\n properties?: GeoJsonProperties;\n }\n): NearestNeighborStudyArea {\n // Optional params\n options = options || {};\n const studyArea = options.studyArea || bboxPolygon(bbox(dataset));\n const properties = options.properties || {};\n const units = options.units || \"kilometers\";\n\n const features: Array> = [];\n featureEach(dataset, (feature) => {\n features.push(centroid(feature));\n });\n const n = features.length;\n const observedMeanDistance =\n features\n .map((feature, index) => {\n const otherFeatures = featureCollection(\n features.filter((f, i) => {\n return i !== index;\n })\n );\n // Have to add the ! to make typescript validation pass\n // see https://stackoverflow.com/a/40350534/1979085\n return distance(\n feature,\n nearestPoint(feature, otherFeatures).geometry!.coordinates,\n { units }\n );\n })\n .reduce((sum, value) => {\n return sum + value;\n }, 0) / n;\n\n const populationDensity = n / convertArea(area(studyArea), \"meters\", units);\n const expectedMeanDistance = 1 / (2 * Math.sqrt(populationDensity));\n const variance = 0.26136 / Math.sqrt(n * populationDensity);\n properties.nearestNeighborAnalysis = {\n units: units,\n arealUnits: units + \"²\",\n observedMeanDistance: observedMeanDistance,\n expectedMeanDistance: expectedMeanDistance,\n nearestNeighborIndex: observedMeanDistance / expectedMeanDistance,\n numberOfPoints: n,\n zScore: (observedMeanDistance - expectedMeanDistance) / variance,\n };\n studyArea.properties = properties;\n\n return studyArea as NearestNeighborStudyArea;\n}\n\nexport {\n nearestNeighborAnalysis,\n NearestNeighborStatistics,\n NearestNeighborStudyArea,\n};\nexport default nearestNeighborAnalysis;\n"]}