/
index.mjs
79 lines (74 loc) · 2.45 KB
/
index.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import * as martinez from 'martinez-polygon-clipping';
import area from '@turf/area';
import { feature, multiPolygon, polygon } from '@turf/helpers';
import { getGeom } from '@turf/invariant';
import { flattenEach } from '@turf/meta';
/**
* Finds the difference between two {@link Polygon|polygons} by clipping the second polygon from the first.
*
* @name difference
* @param {Feature<Polygon|MultiPolygon>} polygon1 input Polygon feature
* @param {Feature<Polygon|MultiPolygon>} polygon2 Polygon feature to difference from polygon1
* @returns {Feature<Polygon|MultiPolygon>|null} a Polygon or MultiPolygon feature showing the area of `polygon1` excluding the area of `polygon2` (if empty returns `null`)
* @example
* var polygon1 = turf.polygon([[
* [128, -26],
* [141, -26],
* [141, -21],
* [128, -21],
* [128, -26]
* ]], {
* "fill": "#F00",
* "fill-opacity": 0.1
* });
* var polygon2 = turf.polygon([[
* [126, -28],
* [140, -28],
* [140, -20],
* [126, -20],
* [126, -28]
* ]], {
* "fill": "#00F",
* "fill-opacity": 0.1
* });
*
* var difference = turf.difference(polygon1, polygon2);
*
* //addToMap
* var addToMap = [polygon1, polygon2, difference];
*/
function difference(polygon1, polygon2) {
var geom1 = getGeom(polygon1);
var geom2 = getGeom(polygon2);
var properties = polygon1.properties || {};
// Issue #721 - JSTS/Martinez can't handle empty polygons
geom1 = removeEmptyPolygon(geom1);
geom2 = removeEmptyPolygon(geom2);
if (!geom1) return null;
if (!geom2) return feature(geom1, properties);
var differenced = martinez.diff(geom1.coordinates, geom2.coordinates);
if (differenced.length === 0) return null;
if (differenced.length === 1) return polygon(differenced[0], properties);
return multiPolygon(differenced, properties);
}
/**
* Detect Empty Polygon
*
* @private
* @param {Geometry<Polygon|MultiPolygon>} geom Geometry Object
* @returns {Geometry<Polygon|MultiPolygon>|null} removed any polygons with no areas
*/
function removeEmptyPolygon(geom) {
switch (geom.type) {
case 'Polygon':
if (area(geom) > 1) return geom;
return null;
case 'MultiPolygon':
var coordinates = [];
flattenEach(geom, function (feature) {
if (area(feature) > 1) coordinates.push(feature.geometry.coordinates);
});
if (coordinates.length) return {type: 'MultiPolygon', coordinates: coordinates};
}
}
export default difference;