@turf/dissolve 6.4.0 → 7.0.0-alpha.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
@@ -7,13 +7,14 @@
7
7
  Dissolves a FeatureCollection of [polygon][1] features, filtered by an optional property name:value.
8
8
  Note that [mulitpolygon][2] features within the collection are not supported
9
9
 
10
- **Parameters**
10
+ ### Parameters
11
11
 
12
- - `featureCollection` **[FeatureCollection][3]<[Polygon][4]>** input feature collection to be dissolved
13
- - `options` **[Object][5]** Optional parameters (optional, default `{}`)
14
- - `options.propertyName` **[string][6]?** features with equals 'propertyName' in `properties` will be merged
12
+ * `featureCollection` **[FeatureCollection][3]<[Polygon][4]>** input feature collection to be dissolved
13
+ * `options` **[Object][5]** Optional parameters (optional, default `{}`)
15
14
 
16
- **Examples**
15
+ * `options.propertyName` **[string][6]?** features with the same `propertyName` value will be dissolved.
16
+
17
+ ### Examples
17
18
 
18
19
  ```javascript
19
20
  var features = turf.featureCollection([
@@ -28,7 +29,7 @@ var dissolved = turf.dissolve(features, {propertyName: 'combine'});
28
29
  var addToMap = [features, dissolved]
29
30
  ```
30
31
 
31
- Returns **[FeatureCollection][3]&lt;[Polygon][4]>** a FeatureCollection containing the dissolved polygons
32
+ Returns **[FeatureCollection][3]<[Polygon][4]>** a FeatureCollection containing the dissolved polygons
32
33
 
33
34
  [1]: polygon
34
35
 
package/dist/es/index.js CHANGED
@@ -1,113 +1,8 @@
1
- import rbush from 'geojson-rbush';
2
- import clone from '@turf/clone';
3
- import overlap from '@turf/boolean-overlap';
4
- import turfUnion from '@turf/union';
5
- import lineIntersect from '@turf/line-intersect';
6
- import { coordAll } from '@turf/meta';
1
+ import { isObject, multiPolygon, featureCollection } from '@turf/helpers';
7
2
  import { collectionOf } from '@turf/invariant';
8
- import { lineString, isObject } from '@turf/helpers';
9
-
10
- /**
11
- * @license get-closest https://github.com/cosmosio/get-closest
12
- *
13
- * The MIT License (MIT)
14
- *
15
- * Copyright (c) 2014-2017 Olivier Scherrer <pode.fr@gmail.com>
16
- */
17
-
18
- /**
19
- * Get the closest number in an array
20
- *
21
- * @private
22
- * @param {number} item the base number
23
- * @param {Array} array the array to search into
24
- * @param {Function} getDiff returns the difference between the base number and
25
- * and the currently read item in the array. The item which returned the smallest difference wins.
26
- * @returns {Object} Get Closest
27
- */
28
- function _getClosest(item, array, getDiff) {
29
- var closest, diff;
30
-
31
- if (!Array.isArray(array)) {
32
- throw new Error("Get closest expects an array as second argument");
33
- }
34
-
35
- array.forEach(function (comparedItem, comparedItemIndex) {
36
- var thisDiff = getDiff(comparedItem, item);
37
-
38
- if (thisDiff >= 0 && (typeof diff == "undefined" || thisDiff < diff)) {
39
- diff = thisDiff;
40
- closest = comparedItemIndex;
41
- }
42
- });
43
-
44
- return closest;
45
- }
46
-
47
- /**
48
- * Get the closest number in an array given a base number
49
- *
50
- * @private
51
- * @param {number} item the base number
52
- * @param {Array<number>} array the array of numbers to search into
53
- * @returns {number} the index of the closest item in the array
54
- * @example
55
- * closestNumber(30, [20, 0, 50, 29])
56
- * //= will return 3 as 29 is the closest item
57
- */
58
-
59
-
60
- /**
61
- * Get the closest greater number in an array given a base number
62
- *
63
- * @private
64
- * @param {number} item the base number
65
- * @param {Array<number>} array the array of numbers to search into
66
- * @returns {number} the index of the closest item in the array
67
- * @example
68
- * closestGreaterNumber(30, [20, 0, 50, 29])
69
- * //= will return 2 as 50 is the closest greater item
70
- */
71
- function closestGreaterNumber(item, array) {
72
- return _getClosest(item, array, function (comparedItem, item) {
73
- return comparedItem - item;
74
- });
75
- }
76
-
77
- /**
78
- * Get the closest lower number in an array given a base number
79
- *
80
- * @private
81
- * @param {number} item the base number
82
- * @param {Array<number>} array the array of numbers to search into
83
- * @returns {number} the index of the closest item in the array
84
- * @example
85
- * closestLowerNumber(30, [20, 0, 50, 29])
86
- * //= will return 0 as 20 is the closest lower item
87
- */
88
-
89
-
90
- /**
91
- * Get the closest item in an array given a base item and a comparator function
92
- *
93
- * @private
94
- * @param {*} item the base item
95
- * @param {Array} array an array of items
96
- * @param {Function} comparator a comparatof function to compare the items
97
- * @returns {Object} Closest Custom
98
- * @example
99
- * closestCustom("lundi", ["mundi", "mardi"], getLevenshteinDistance)
100
- * //= will return 0 for "lundi"
101
- *
102
- * // The function looks like:
103
- *
104
- * // comparedItem comes from the array
105
- * // baseItem is the item to compare the others to
106
- * // It returns a number
107
- * function comparator(comparedItem, baseItem) {
108
- * return comparedItem - baseItem;
109
- * }
110
- */
3
+ import { featureEach } from '@turf/meta';
4
+ import flatten from '@turf/flatten';
5
+ import polygonClipping from 'polygon-clipping';
111
6
 
112
7
  /**
113
8
  * Dissolves a FeatureCollection of {@link polygon} features, filtered by an optional property name:value.
@@ -116,7 +11,7 @@ function closestGreaterNumber(item, array) {
116
11
  * @name dissolve
117
12
  * @param {FeatureCollection<Polygon>} featureCollection input feature collection to be dissolved
118
13
  * @param {Object} [options={}] Optional parameters
119
- * @param {string} [options.propertyName] features with equals 'propertyName' in `properties` will be merged
14
+ * @param {string} [options.propertyName] features with the same `propertyName` value will be dissolved.
120
15
  * @returns {FeatureCollection<Polygon>} a FeatureCollection containing the dissolved polygons
121
16
  * @example
122
17
  * var features = turf.featureCollection([
@@ -130,118 +25,57 @@ function closestGreaterNumber(item, array) {
130
25
  * //addToMap
131
26
  * var addToMap = [features, dissolved]
132
27
  */
133
- function dissolve(featureCollection, options) {
28
+ function dissolve(fc, options) {
134
29
  // Optional parameters
135
30
  options = options || {};
136
31
  if (!isObject(options)) throw new Error("options is invalid");
137
32
  var propertyName = options.propertyName;
138
33
 
139
34
  // Input validation
140
- collectionOf(featureCollection, "Polygon", "dissolve");
35
+ collectionOf(fc, "Polygon", "dissolve");
141
36
 
142
37
  // Main
143
- var fc = clone(featureCollection);
144
- var features = fc.features;
145
-
146
- var originalIndexOfItemsRemoved = [];
147
-
148
- features.forEach(function (f, i) {
149
- f.properties.origIndexPosition = i;
150
- });
151
- var tree = rbush();
152
- tree.load(fc);
153
-
154
- for (var i in features) {
155
- var polygon = features[i];
156
-
157
- var featureChanged = false;
158
-
159
- tree.search(polygon).features.forEach(function (potentialMatchingFeature) {
160
- polygon = features[i];
161
-
162
- var matchFeaturePosition =
163
- potentialMatchingFeature.properties.origIndexPosition;
164
-
38
+ var outFeatures = [];
39
+ if (!options.propertyName) {
40
+ return flatten(
41
+ multiPolygon(
42
+ polygonClipping.union.apply(
43
+ null,
44
+ fc.features.map(function (f) {
45
+ return f.geometry.coordinates;
46
+ })
47
+ )
48
+ )
49
+ );
50
+ } else {
51
+ var uniquePropertyVals = {};
52
+ featureEach(fc, function (feature) {
165
53
  if (
166
- originalIndexOfItemsRemoved.length > 0 &&
167
- matchFeaturePosition !== 0
54
+ !Object.prototype.hasOwnProperty.call(
55
+ uniquePropertyVals,
56
+ feature.properties[propertyName]
57
+ )
168
58
  ) {
169
- if (
170
- matchFeaturePosition >
171
- originalIndexOfItemsRemoved[originalIndexOfItemsRemoved.length - 1]
172
- ) {
173
- matchFeaturePosition =
174
- matchFeaturePosition - originalIndexOfItemsRemoved.length;
175
- } else {
176
- var closestNumber$$1 = closestGreaterNumber(
177
- matchFeaturePosition,
178
- originalIndexOfItemsRemoved
179
- );
180
- if (closestNumber$$1 !== 0) {
181
- matchFeaturePosition = matchFeaturePosition - closestNumber$$1;
182
- }
183
- }
59
+ uniquePropertyVals[feature.properties[propertyName]] = [];
184
60
  }
185
-
186
- if (matchFeaturePosition === +i) return;
187
-
188
- var matchFeature = features[matchFeaturePosition];
189
- if (!matchFeature || !polygon) return;
190
-
191
- if (
192
- propertyName !== undefined &&
193
- matchFeature.properties[propertyName] !==
194
- polygon.properties[propertyName]
195
- )
196
- return;
197
-
198
- if (
199
- !overlap(polygon, matchFeature) ||
200
- !ringsIntersect(polygon, matchFeature)
201
- )
202
- return;
203
-
204
- features[i] = turfUnion(polygon, matchFeature);
205
-
206
- originalIndexOfItemsRemoved.push(
207
- potentialMatchingFeature.properties.origIndexPosition
208
- );
209
- originalIndexOfItemsRemoved.sort(function (a, b) {
210
- return a - b;
211
- });
212
-
213
- tree.remove(potentialMatchingFeature);
214
- features.splice(matchFeaturePosition, 1);
215
- polygon.properties.origIndexPosition = i;
216
- tree.remove(polygon, function (a, b) {
217
- return (
218
- a.properties.origIndexPosition === b.properties.origIndexPosition
219
- );
220
- });
221
- featureChanged = true;
61
+ uniquePropertyVals[feature.properties[propertyName]].push(feature);
222
62
  });
223
-
224
- if (featureChanged) {
225
- if (!polygon) continue;
226
- polygon.properties.origIndexPosition = i;
227
- tree.insert(polygon);
228
- i--;
63
+ var vals = Object.keys(uniquePropertyVals);
64
+ for (var i = 0; i < vals.length; i++) {
65
+ var mp = multiPolygon(
66
+ polygonClipping.union.apply(
67
+ null,
68
+ uniquePropertyVals[vals[i]].map(function (f) {
69
+ return f.geometry.coordinates;
70
+ })
71
+ )
72
+ );
73
+ mp.properties[propertyName] = vals[i];
74
+ outFeatures.push(mp);
229
75
  }
230
76
  }
231
77
 
232
- features.forEach(function (f) {
233
- delete f.properties.origIndexPosition;
234
- delete f.bbox;
235
- });
236
-
237
- return fc;
238
- }
239
-
240
- function ringsIntersect(poly1, poly2) {
241
- var line1 = lineString(coordAll(poly1));
242
- var line2 = lineString(coordAll(poly2));
243
- var points = lineIntersect(line1, line2).features;
244
- return points.length > 0;
78
+ return flatten(featureCollection(outFeatures));
245
79
  }
246
80
 
247
81
  export default dissolve;
package/dist/js/index.js CHANGED
@@ -1,117 +1,15 @@
1
1
  'use strict';
2
2
 
3
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
4
-
5
- var rbush = _interopDefault(require('geojson-rbush'));
6
- var clone = _interopDefault(require('@turf/clone'));
7
- var overlap = _interopDefault(require('@turf/boolean-overlap'));
8
- var turfUnion = _interopDefault(require('@turf/union'));
9
- var lineIntersect = _interopDefault(require('@turf/line-intersect'));
10
- var meta = require('@turf/meta');
11
- var invariant = require('@turf/invariant');
12
3
  var helpers = require('@turf/helpers');
4
+ var invariant = require('@turf/invariant');
5
+ var meta = require('@turf/meta');
6
+ var flatten = require('@turf/flatten');
7
+ var polygonClipping = require('polygon-clipping');
13
8
 
14
- /**
15
- * @license get-closest https://github.com/cosmosio/get-closest
16
- *
17
- * The MIT License (MIT)
18
- *
19
- * Copyright (c) 2014-2017 Olivier Scherrer <pode.fr@gmail.com>
20
- */
21
-
22
- /**
23
- * Get the closest number in an array
24
- *
25
- * @private
26
- * @param {number} item the base number
27
- * @param {Array} array the array to search into
28
- * @param {Function} getDiff returns the difference between the base number and
29
- * and the currently read item in the array. The item which returned the smallest difference wins.
30
- * @returns {Object} Get Closest
31
- */
32
- function _getClosest(item, array, getDiff) {
33
- var closest, diff;
34
-
35
- if (!Array.isArray(array)) {
36
- throw new Error("Get closest expects an array as second argument");
37
- }
38
-
39
- array.forEach(function (comparedItem, comparedItemIndex) {
40
- var thisDiff = getDiff(comparedItem, item);
41
-
42
- if (thisDiff >= 0 && (typeof diff == "undefined" || thisDiff < diff)) {
43
- diff = thisDiff;
44
- closest = comparedItemIndex;
45
- }
46
- });
47
-
48
- return closest;
49
- }
50
-
51
- /**
52
- * Get the closest number in an array given a base number
53
- *
54
- * @private
55
- * @param {number} item the base number
56
- * @param {Array<number>} array the array of numbers to search into
57
- * @returns {number} the index of the closest item in the array
58
- * @example
59
- * closestNumber(30, [20, 0, 50, 29])
60
- * //= will return 3 as 29 is the closest item
61
- */
62
-
63
-
64
- /**
65
- * Get the closest greater number in an array given a base number
66
- *
67
- * @private
68
- * @param {number} item the base number
69
- * @param {Array<number>} array the array of numbers to search into
70
- * @returns {number} the index of the closest item in the array
71
- * @example
72
- * closestGreaterNumber(30, [20, 0, 50, 29])
73
- * //= will return 2 as 50 is the closest greater item
74
- */
75
- function closestGreaterNumber(item, array) {
76
- return _getClosest(item, array, function (comparedItem, item) {
77
- return comparedItem - item;
78
- });
79
- }
80
-
81
- /**
82
- * Get the closest lower number in an array given a base number
83
- *
84
- * @private
85
- * @param {number} item the base number
86
- * @param {Array<number>} array the array of numbers to search into
87
- * @returns {number} the index of the closest item in the array
88
- * @example
89
- * closestLowerNumber(30, [20, 0, 50, 29])
90
- * //= will return 0 as 20 is the closest lower item
91
- */
92
-
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
93
10
 
94
- /**
95
- * Get the closest item in an array given a base item and a comparator function
96
- *
97
- * @private
98
- * @param {*} item the base item
99
- * @param {Array} array an array of items
100
- * @param {Function} comparator a comparatof function to compare the items
101
- * @returns {Object} Closest Custom
102
- * @example
103
- * closestCustom("lundi", ["mundi", "mardi"], getLevenshteinDistance)
104
- * //= will return 0 for "lundi"
105
- *
106
- * // The function looks like:
107
- *
108
- * // comparedItem comes from the array
109
- * // baseItem is the item to compare the others to
110
- * // It returns a number
111
- * function comparator(comparedItem, baseItem) {
112
- * return comparedItem - baseItem;
113
- * }
114
- */
11
+ var flatten__default = /*#__PURE__*/_interopDefaultLegacy(flatten);
12
+ var polygonClipping__default = /*#__PURE__*/_interopDefaultLegacy(polygonClipping);
115
13
 
116
14
  /**
117
15
  * Dissolves a FeatureCollection of {@link polygon} features, filtered by an optional property name:value.
@@ -120,7 +18,7 @@ function closestGreaterNumber(item, array) {
120
18
  * @name dissolve
121
19
  * @param {FeatureCollection<Polygon>} featureCollection input feature collection to be dissolved
122
20
  * @param {Object} [options={}] Optional parameters
123
- * @param {string} [options.propertyName] features with equals 'propertyName' in `properties` will be merged
21
+ * @param {string} [options.propertyName] features with the same `propertyName` value will be dissolved.
124
22
  * @returns {FeatureCollection<Polygon>} a FeatureCollection containing the dissolved polygons
125
23
  * @example
126
24
  * var features = turf.featureCollection([
@@ -134,118 +32,58 @@ function closestGreaterNumber(item, array) {
134
32
  * //addToMap
135
33
  * var addToMap = [features, dissolved]
136
34
  */
137
- function dissolve(featureCollection, options) {
35
+ function dissolve(fc, options) {
138
36
  // Optional parameters
139
37
  options = options || {};
140
38
  if (!helpers.isObject(options)) throw new Error("options is invalid");
141
39
  var propertyName = options.propertyName;
142
40
 
143
41
  // Input validation
144
- invariant.collectionOf(featureCollection, "Polygon", "dissolve");
42
+ invariant.collectionOf(fc, "Polygon", "dissolve");
145
43
 
146
44
  // Main
147
- var fc = clone(featureCollection);
148
- var features = fc.features;
149
-
150
- var originalIndexOfItemsRemoved = [];
151
-
152
- features.forEach(function (f, i) {
153
- f.properties.origIndexPosition = i;
154
- });
155
- var tree = rbush();
156
- tree.load(fc);
157
-
158
- for (var i in features) {
159
- var polygon = features[i];
160
-
161
- var featureChanged = false;
162
-
163
- tree.search(polygon).features.forEach(function (potentialMatchingFeature) {
164
- polygon = features[i];
165
-
166
- var matchFeaturePosition =
167
- potentialMatchingFeature.properties.origIndexPosition;
168
-
45
+ var outFeatures = [];
46
+ if (!options.propertyName) {
47
+ return flatten__default['default'](
48
+ helpers.multiPolygon(
49
+ polygonClipping__default['default'].union.apply(
50
+ null,
51
+ fc.features.map(function (f) {
52
+ return f.geometry.coordinates;
53
+ })
54
+ )
55
+ )
56
+ );
57
+ } else {
58
+ var uniquePropertyVals = {};
59
+ meta.featureEach(fc, function (feature) {
169
60
  if (
170
- originalIndexOfItemsRemoved.length > 0 &&
171
- matchFeaturePosition !== 0
61
+ !Object.prototype.hasOwnProperty.call(
62
+ uniquePropertyVals,
63
+ feature.properties[propertyName]
64
+ )
172
65
  ) {
173
- if (
174
- matchFeaturePosition >
175
- originalIndexOfItemsRemoved[originalIndexOfItemsRemoved.length - 1]
176
- ) {
177
- matchFeaturePosition =
178
- matchFeaturePosition - originalIndexOfItemsRemoved.length;
179
- } else {
180
- var closestNumber$$1 = closestGreaterNumber(
181
- matchFeaturePosition,
182
- originalIndexOfItemsRemoved
183
- );
184
- if (closestNumber$$1 !== 0) {
185
- matchFeaturePosition = matchFeaturePosition - closestNumber$$1;
186
- }
187
- }
66
+ uniquePropertyVals[feature.properties[propertyName]] = [];
188
67
  }
189
-
190
- if (matchFeaturePosition === +i) return;
191
-
192
- var matchFeature = features[matchFeaturePosition];
193
- if (!matchFeature || !polygon) return;
194
-
195
- if (
196
- propertyName !== undefined &&
197
- matchFeature.properties[propertyName] !==
198
- polygon.properties[propertyName]
199
- )
200
- return;
201
-
202
- if (
203
- !overlap(polygon, matchFeature) ||
204
- !ringsIntersect(polygon, matchFeature)
205
- )
206
- return;
207
-
208
- features[i] = turfUnion(polygon, matchFeature);
209
-
210
- originalIndexOfItemsRemoved.push(
211
- potentialMatchingFeature.properties.origIndexPosition
212
- );
213
- originalIndexOfItemsRemoved.sort(function (a, b) {
214
- return a - b;
215
- });
216
-
217
- tree.remove(potentialMatchingFeature);
218
- features.splice(matchFeaturePosition, 1);
219
- polygon.properties.origIndexPosition = i;
220
- tree.remove(polygon, function (a, b) {
221
- return (
222
- a.properties.origIndexPosition === b.properties.origIndexPosition
223
- );
224
- });
225
- featureChanged = true;
68
+ uniquePropertyVals[feature.properties[propertyName]].push(feature);
226
69
  });
227
-
228
- if (featureChanged) {
229
- if (!polygon) continue;
230
- polygon.properties.origIndexPosition = i;
231
- tree.insert(polygon);
232
- i--;
70
+ var vals = Object.keys(uniquePropertyVals);
71
+ for (var i = 0; i < vals.length; i++) {
72
+ var mp = helpers.multiPolygon(
73
+ polygonClipping__default['default'].union.apply(
74
+ null,
75
+ uniquePropertyVals[vals[i]].map(function (f) {
76
+ return f.geometry.coordinates;
77
+ })
78
+ )
79
+ );
80
+ mp.properties[propertyName] = vals[i];
81
+ outFeatures.push(mp);
233
82
  }
234
83
  }
235
84
 
236
- features.forEach(function (f) {
237
- delete f.properties.origIndexPosition;
238
- delete f.bbox;
239
- });
240
-
241
- return fc;
242
- }
243
-
244
- function ringsIntersect(poly1, poly2) {
245
- var line1 = helpers.lineString(meta.coordAll(poly1));
246
- var line2 = helpers.lineString(meta.coordAll(poly2));
247
- var points = lineIntersect(line1, line2).features;
248
- return points.length > 0;
85
+ return flatten__default['default'](helpers.featureCollection(outFeatures));
249
86
  }
250
87
 
251
88
  module.exports = dissolve;
89
+ module.exports.default = dissolve;
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FeatureCollection, Polygon } from "@turf/helpers";
1
+ import { FeatureCollection, Polygon } from "geojson";
2
2
 
3
3
  /**
4
4
  * http://turfjs.org/docs.html#dissolve
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@turf/dissolve",
3
- "version": "6.4.0",
3
+ "version": "7.0.0-alpha.0",
4
4
  "description": "turf dissolve module",
5
5
  "author": "Turf Authors",
6
6
  "license": "MIT",
@@ -12,6 +12,7 @@
12
12
  "type": "git",
13
13
  "url": "git://github.com/Turfjs/turf.git"
14
14
  },
15
+ "funding": "https://opencollective.com/turf",
15
16
  "publishConfig": {
16
17
  "access": "public"
17
18
  },
@@ -53,15 +54,11 @@
53
54
  "write-json-file": "*"
54
55
  },
55
56
  "dependencies": {
56
- "@turf/boolean-overlap": "^6.4.0",
57
- "@turf/clone": "^6.4.0",
58
- "@turf/helpers": "^6.4.0",
59
- "@turf/invariant": "^6.4.0",
60
- "@turf/line-intersect": "^6.4.0",
61
- "@turf/meta": "^6.4.0",
62
- "@turf/union": "^6.4.0",
63
- "geojson-rbush": "3.x",
64
- "get-closest": "*"
57
+ "@turf/flatten": "^7.0.0-alpha.0",
58
+ "@turf/helpers": "^7.0.0-alpha.0",
59
+ "@turf/invariant": "^7.0.0-alpha.0",
60
+ "@turf/meta": "^7.0.0-alpha.0",
61
+ "polygon-clipping": "^0.15.3"
65
62
  },
66
- "gitHead": "1e62773cfc88c627cca8effcb5c14cfb65a905ac"
63
+ "gitHead": "0edc4c491b999e5ace770a61e1cf549f7c004189"
67
64
  }