@turf/nearest-neighbor-analysis 6.5.0 → 7.0.0-alpha.1
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 +26 -22
- package/dist/es/index.js +15 -15
- package/dist/js/index.d.ts +5 -4
- package/dist/js/index.js +23 -25
- package/package.json +17 -15
package/README.md
CHANGED
|
@@ -8,45 +8,49 @@ Nearest Neighbor Analysis calculates an index based the average distances
|
|
|
8
8
|
between points in the dataset, thereby providing inference as to whether the
|
|
9
9
|
data is clustered, dispersed, or randomly distributed within the study area.
|
|
10
10
|
|
|
11
|
-
It returns a [Feature
|
|
11
|
+
It returns a [Feature\<Polygon>][1] of the study area, with the results of
|
|
12
12
|
the analysis attached as part of of the `nearestNeighborAnalysis` property
|
|
13
13
|
of the study area's `properties`. The attached
|
|
14
|
-
[
|
|
14
|
+
[*z*-score][2] indicates how many
|
|
15
15
|
standard deviations above or below the expected mean distance the data's
|
|
16
16
|
observed mean distance is. The more negative, the more clustered. The more
|
|
17
|
-
positive, the more evenly dispersed. A
|
|
18
|
-
a seemingly random distribution. That is, within
|
|
17
|
+
positive, the more evenly dispersed. A *z*-score between -2 and 2 indicates
|
|
18
|
+
a seemingly random distribution. That is, within *p* of less than 0.05, the
|
|
19
19
|
distribution appears statistically significantly neither clustered nor
|
|
20
20
|
dispersed.
|
|
21
21
|
|
|
22
22
|
**Remarks**
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
works best with [Point][4] collections.
|
|
24
|
+
* Though the analysis will work on any [FeatureCollection][3] type, it
|
|
26
25
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
works best with [Point][4] collections.
|
|
27
|
+
|
|
28
|
+
* This analysis is *very* sensitive to the study area provided.
|
|
29
|
+
|
|
30
|
+
If no [Feature\<Polygon>][1] is passed as the study area, the function draws a box
|
|
31
|
+
around the data, which may distort the findings. This analysis works best
|
|
32
|
+
with a bounded area of interest within with the data is either clustered,
|
|
33
|
+
dispersed, or randomly distributed. For example, a city's subway stops may
|
|
34
|
+
look extremely clustered if the study area is an entire state. On the other
|
|
35
|
+
hand, they may look rather evenly dispersed if the study area is limited to
|
|
36
|
+
the city's downtown.
|
|
34
37
|
|
|
35
38
|
**Bibliography**
|
|
36
39
|
|
|
37
40
|
Philip J. Clark and Francis C. Evans, “Distance to Nearest Neighbor as a
|
|
38
|
-
Measure of Spatial Relationships in Populations,”
|
|
41
|
+
Measure of Spatial Relationships in Populations,” *Ecology* 35, no. 4
|
|
39
42
|
(1954): 445–453, doi:[10.2307/1931034][5].
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
### Parameters
|
|
45
|
+
|
|
46
|
+
* `dataset` **[FeatureCollection][6]\<any>** FeatureCollection (pref. of points) to study
|
|
47
|
+
* `options` **[Object][7]** Optional parameters (optional, default `{}`)
|
|
42
48
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
- `options.units` **[string][10]** unit of measurement for distances and, squared, area. (optional, default `'kilometers'`)
|
|
47
|
-
- `options.properties` **[Object][7]** properties (optional, default `{}`)
|
|
49
|
+
* `options.studyArea` **[Feature][8]<[Polygon][9]>?** polygon representing the study area
|
|
50
|
+
* `options.units` **[string][10]** unit of measurement for distances and, squared, area. (optional, default `'kilometers'`)
|
|
51
|
+
* `options.properties` **[Object][7]** properties (optional, default `{}`)
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
### Examples
|
|
50
54
|
|
|
51
55
|
```javascript
|
|
52
56
|
var bbox = [-65, 40, -63, 42];
|
|
@@ -57,7 +61,7 @@ var nearestNeighborStudyArea = turf.nearestNeighborAnalysis(dataset);
|
|
|
57
61
|
var addToMap = [dataset, nearestNeighborStudyArea];
|
|
58
62
|
```
|
|
59
63
|
|
|
60
|
-
Returns **[Feature][8]
|
|
64
|
+
Returns **[Feature][8]<[Polygon][9]>** A polygon of the study area or an approximation of one.
|
|
61
65
|
|
|
62
66
|
[1]: Feature<Polygon>
|
|
63
67
|
|
package/dist/es/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import centroid from "@turf/centroid";
|
|
|
5
5
|
import distance from "@turf/distance";
|
|
6
6
|
import nearestPoint from "@turf/nearest-point";
|
|
7
7
|
import { featureEach } from "@turf/meta";
|
|
8
|
-
import { convertArea, featureCollection } from "@turf/helpers";
|
|
8
|
+
import { convertArea, featureCollection, } from "@turf/helpers";
|
|
9
9
|
/**
|
|
10
10
|
* Nearest Neighbor Analysis calculates an index based the average distances
|
|
11
11
|
* between points in the dataset, thereby providing inference as to whether the
|
|
@@ -60,29 +60,29 @@ import { convertArea, featureCollection } from "@turf/helpers";
|
|
|
60
60
|
function nearestNeighborAnalysis(dataset, options) {
|
|
61
61
|
// Optional params
|
|
62
62
|
options = options || {};
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
featureEach(dataset,
|
|
63
|
+
const studyArea = options.studyArea || bboxPolygon(bbox(dataset));
|
|
64
|
+
const properties = options.properties || {};
|
|
65
|
+
const units = options.units || "kilometers";
|
|
66
|
+
const features = [];
|
|
67
|
+
featureEach(dataset, (feature) => {
|
|
68
68
|
features.push(centroid(feature));
|
|
69
69
|
});
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.map(
|
|
73
|
-
|
|
70
|
+
const n = features.length;
|
|
71
|
+
const observedMeanDistance = features
|
|
72
|
+
.map((feature, index) => {
|
|
73
|
+
const otherFeatures = featureCollection(features.filter((f, i) => {
|
|
74
74
|
return i !== index;
|
|
75
75
|
}));
|
|
76
76
|
// Have to add the ! to make typescript validation pass
|
|
77
77
|
// see https://stackoverflow.com/a/40350534/1979085
|
|
78
|
-
return distance(feature, nearestPoint(feature, otherFeatures).geometry.coordinates, { units
|
|
78
|
+
return distance(feature, nearestPoint(feature, otherFeatures).geometry.coordinates, { units });
|
|
79
79
|
})
|
|
80
|
-
.reduce(
|
|
80
|
+
.reduce((sum, value) => {
|
|
81
81
|
return sum + value;
|
|
82
82
|
}, 0) / n;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
const populationDensity = n / convertArea(area(studyArea), "meters", units);
|
|
84
|
+
const expectedMeanDistance = 1 / (2 * Math.sqrt(populationDensity));
|
|
85
|
+
const variance = 0.26136 / Math.sqrt(n * populationDensity);
|
|
86
86
|
properties.nearestNeighborAnalysis = {
|
|
87
87
|
units: units,
|
|
88
88
|
arealUnits: units + "²",
|
package/dist/js/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { FeatureCollection, Feature, Polygon,
|
|
1
|
+
import { FeatureCollection, Feature, Polygon, GeoJsonProperties } from "geojson";
|
|
2
|
+
import { Units, AreaUnits } from "@turf/helpers";
|
|
2
3
|
export interface NearestNeighborStatistics {
|
|
3
|
-
units: Units;
|
|
4
|
+
units: Units & AreaUnits;
|
|
4
5
|
arealUnits: string;
|
|
5
6
|
observedMeanDistance: number;
|
|
6
7
|
expectedMeanDistance: number;
|
|
@@ -66,7 +67,7 @@ export interface NearestNeighborStudyArea extends Feature<Polygon> {
|
|
|
66
67
|
*/
|
|
67
68
|
declare function nearestNeighborAnalysis(dataset: FeatureCollection<any>, options?: {
|
|
68
69
|
studyArea?: Feature<Polygon>;
|
|
69
|
-
units?: Units;
|
|
70
|
-
properties?:
|
|
70
|
+
units?: Units & AreaUnits;
|
|
71
|
+
properties?: GeoJsonProperties;
|
|
71
72
|
}): NearestNeighborStudyArea;
|
|
72
73
|
export default nearestNeighborAnalysis;
|
package/dist/js/index.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const area_1 = tslib_1.__importDefault(require("@turf/area"));
|
|
5
|
+
const bbox_1 = tslib_1.__importDefault(require("@turf/bbox"));
|
|
6
|
+
const bbox_polygon_1 = tslib_1.__importDefault(require("@turf/bbox-polygon"));
|
|
7
|
+
const centroid_1 = tslib_1.__importDefault(require("@turf/centroid"));
|
|
8
|
+
const distance_1 = tslib_1.__importDefault(require("@turf/distance"));
|
|
9
|
+
const nearest_point_1 = tslib_1.__importDefault(require("@turf/nearest-point"));
|
|
10
|
+
const meta_1 = require("@turf/meta");
|
|
11
|
+
const helpers_1 = require("@turf/helpers");
|
|
14
12
|
/**
|
|
15
13
|
* Nearest Neighbor Analysis calculates an index based the average distances
|
|
16
14
|
* between points in the dataset, thereby providing inference as to whether the
|
|
@@ -65,29 +63,29 @@ var helpers_1 = require("@turf/helpers");
|
|
|
65
63
|
function nearestNeighborAnalysis(dataset, options) {
|
|
66
64
|
// Optional params
|
|
67
65
|
options = options || {};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
meta_1.featureEach(dataset,
|
|
66
|
+
const studyArea = options.studyArea || bbox_polygon_1.default(bbox_1.default(dataset));
|
|
67
|
+
const properties = options.properties || {};
|
|
68
|
+
const units = options.units || "kilometers";
|
|
69
|
+
const features = [];
|
|
70
|
+
meta_1.featureEach(dataset, (feature) => {
|
|
73
71
|
features.push(centroid_1.default(feature));
|
|
74
72
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
.map(
|
|
78
|
-
|
|
73
|
+
const n = features.length;
|
|
74
|
+
const observedMeanDistance = features
|
|
75
|
+
.map((feature, index) => {
|
|
76
|
+
const otherFeatures = helpers_1.featureCollection(features.filter((f, i) => {
|
|
79
77
|
return i !== index;
|
|
80
78
|
}));
|
|
81
79
|
// Have to add the ! to make typescript validation pass
|
|
82
80
|
// see https://stackoverflow.com/a/40350534/1979085
|
|
83
|
-
return distance_1.default(feature, nearest_point_1.default(feature, otherFeatures).geometry.coordinates, { units
|
|
81
|
+
return distance_1.default(feature, nearest_point_1.default(feature, otherFeatures).geometry.coordinates, { units });
|
|
84
82
|
})
|
|
85
|
-
.reduce(
|
|
83
|
+
.reduce((sum, value) => {
|
|
86
84
|
return sum + value;
|
|
87
85
|
}, 0) / n;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
const populationDensity = n / helpers_1.convertArea(area_1.default(studyArea), "meters", units);
|
|
87
|
+
const expectedMeanDistance = 1 / (2 * Math.sqrt(populationDensity));
|
|
88
|
+
const variance = 0.26136 / Math.sqrt(n * populationDensity);
|
|
91
89
|
properties.nearestNeighborAnalysis = {
|
|
92
90
|
units: units,
|
|
93
91
|
arealUnits: units + "²",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turf/nearest-neighbor-analysis",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0-alpha.1",
|
|
4
4
|
"description": "turf nearest-neighbor-analysis module",
|
|
5
5
|
"author": "Turf Authors",
|
|
6
6
|
"contributors": [
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"exports": {
|
|
29
29
|
"./package.json": "./package.json",
|
|
30
30
|
".": {
|
|
31
|
+
"types": "./dist/js/index.d.ts",
|
|
31
32
|
"import": "./dist/es/index.js",
|
|
32
33
|
"require": "./dist/js/index.js"
|
|
33
34
|
}
|
|
@@ -38,35 +39,36 @@
|
|
|
38
39
|
"dist"
|
|
39
40
|
],
|
|
40
41
|
"scripts": {
|
|
41
|
-
"bench": "
|
|
42
|
+
"bench": "tsx bench.js",
|
|
42
43
|
"build": "npm-run-all build:*",
|
|
43
44
|
"build:es": "tsc --outDir dist/es --module esnext --declaration false && echo '{\"type\":\"module\"}' > dist/es/package.json",
|
|
44
45
|
"build:js": "tsc",
|
|
45
|
-
"docs": "
|
|
46
|
+
"docs": "tsx ../../scripts/generate-readmes",
|
|
46
47
|
"test": "npm-run-all test:*",
|
|
47
|
-
"test:tape": "
|
|
48
|
+
"test:tape": "tsx test.js"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@turf/truncate": "^
|
|
51
|
+
"@turf/truncate": "^7.0.0-alpha.1",
|
|
51
52
|
"@types/tape": "*",
|
|
52
53
|
"benchmark": "*",
|
|
53
54
|
"load-json-file": "*",
|
|
54
55
|
"npm-run-all": "*",
|
|
55
56
|
"tape": "*",
|
|
56
|
-
"ts-node": "*",
|
|
57
57
|
"tslint": "*",
|
|
58
|
+
"tsx": "*",
|
|
58
59
|
"typescript": "*",
|
|
59
60
|
"write-json-file": "*"
|
|
60
61
|
},
|
|
61
62
|
"dependencies": {
|
|
62
|
-
"@turf/area": "^
|
|
63
|
-
"@turf/bbox": "^
|
|
64
|
-
"@turf/bbox-polygon": "^
|
|
65
|
-
"@turf/centroid": "^
|
|
66
|
-
"@turf/distance": "^
|
|
67
|
-
"@turf/helpers": "^
|
|
68
|
-
"@turf/meta": "^
|
|
69
|
-
"@turf/nearest-point": "^
|
|
63
|
+
"@turf/area": "^7.0.0-alpha.1",
|
|
64
|
+
"@turf/bbox": "^7.0.0-alpha.1",
|
|
65
|
+
"@turf/bbox-polygon": "^7.0.0-alpha.1",
|
|
66
|
+
"@turf/centroid": "^7.0.0-alpha.1",
|
|
67
|
+
"@turf/distance": "^7.0.0-alpha.1",
|
|
68
|
+
"@turf/helpers": "^7.0.0-alpha.1",
|
|
69
|
+
"@turf/meta": "^7.0.0-alpha.1",
|
|
70
|
+
"@turf/nearest-point": "^7.0.0-alpha.1",
|
|
71
|
+
"tslib": "^2.3.0"
|
|
70
72
|
},
|
|
71
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "cf7a0c507b017ca066acffd0ce23bda5b393fb5a"
|
|
72
74
|
}
|