diff --git a/packages/turf-boolean-equal/LICENSE b/packages/turf-boolean-equal/LICENSE
new file mode 100644
index 0000000000..96ce51b76f
--- /dev/null
+++ b/packages/turf-boolean-equal/LICENSE
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 TurfJS
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/turf-boolean-equal/README.md b/packages/turf-boolean-equal/README.md
new file mode 100644
index 0000000000..4e96ab3c1b
--- /dev/null
+++ b/packages/turf-boolean-equal/README.md
@@ -0,0 +1,49 @@
+# @turf/boolean-equal
+
+# booleanEqual
+
+Determine whether two geometries of the same type have identical X,Y coordinate values. See [spatial relations](http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm).
+
+**Parameters**
+
+- `feature1` **([Geometry](http://geojson.org/geojson-spec.html#geometry) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<any>)** GeoJSON Feature or Geometry
+- `feature2` **([Geometry](http://geojson.org/geojson-spec.html#geometry) \| [Feature](http://geojson.org/geojson-spec.html#feature-objects)<any>)** GeoJSON Feature or Geometry
+
+**Examples**
+```javascript
+var pt1 = turf.point([0, 0]);
+var pt2 = turf.point([0, 0]);
+var pt3 = turf.point([1, 1]);
+
+turf.equal(pt1, pt2);
+//= true
+turf.equal(pt2, pt3);
+//= false
+```
+
+Returns **[Boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true/false
+
+
+
+---
+
+This module is part of the [Turfjs project](http://turfjs.org/), an open source
+module collection dedicated to geographic algorithms. It is maintained in the
+[Turfjs/turf](https://github.com/Turfjs/turf) repository, where you can create
+PRs and issues.
+
+### Installation
+
+Install this module individually:
+
+```sh
+$ npm install @turf/boolean-equal
+```
+
+Or install the Turf module that includes it as a function:
+
+```sh
+$ npm install @turf/turf
+```
diff --git a/packages/turf-boolean-equal/bench.js b/packages/turf-boolean-equal/bench.js
new file mode 100644
index 0000000000..a93a45d30f
--- /dev/null
+++ b/packages/turf-boolean-equal/bench.js
@@ -0,0 +1,50 @@
+const path = require('path');
+const glob = require('glob');
+const load = require('load-json-file');
+const equal = require('./');
+const Benchmark = require('benchmark');
+
+/**
+ * Benchmark Results
+ *
+ * linear-rings: 1.167ms
+ * lines: 0.132ms
+ * multipoints: 1.283ms
+ * points: 0.043ms
+ * polygons: 0.387ms
+ * linear-rings: 0.166ms
+ * lines: 0.068ms
+ * multipoints: 0.148ms
+ * points: 0.029ms
+ * polygons: 0.131ms
+ * reverse-lines: 0.711ms
+ * reverse-polygons: 0.090ms
+ * linear-rings x 337,778 ops/sec ±2.95% (76 runs sampled)
+ * lines x 367,227 ops/sec ±2.50% (78 runs sampled)
+ * multipoints x 54,325 ops/sec ±1.71% (80 runs sampled)
+ * points x 529,881 ops/sec ±3.62% (74 runs sampled)
+ * polygons x 177,515 ops/sec ±2.34% (80 runs sampled)
+ * linear-rings x 92,709 ops/sec ±1.51% (82 runs sampled)
+ * lines x 94,539 ops/sec ±2.52% (81 runs sampled)
+ * multipoints x 34,458 ops/sec ±2.21% (81 runs sampled)
+ * points x 384,832 ops/sec ±2.74% (81 runs sampled)
+ * polygons x 71,289 ops/sec ±2.67% (77 runs sampled)
+ * reverse-lines x 83,612 ops/sec ±3.31% (77 runs sampled)
+ * reverse-polygons x 64,686 ops/sec ±1.91% (76 runs sampled)
+ */
+const suite = new Benchmark.Suite('turf-boolean-equal');
+glob.sync(path.join(__dirname, 'test', '**', '*.geojson')).forEach(filepath => {
+ const {name} = path.parse(filepath);
+ const geojson = load.sync(filepath);
+ const [feature1, feature2] = geojson.features;
+ console.time(name);
+ equal(feature1, feature2);
+ console.timeEnd(name);
+ suite.add(name, () => equal(feature1, feature2));
+});
+
+suite
+ .on('cycle', e => console.log(String(e.target)))
+ .on('complete', () => {})
+ .run();
+
diff --git a/packages/turf-boolean-equal/index.d.ts b/packages/turf-boolean-equal/index.d.ts
new file mode 100644
index 0000000000..c60f5839ed
--- /dev/null
+++ b/packages/turf-boolean-equal/index.d.ts
@@ -0,0 +1,10 @@
+///
+
+type Feature = GeoJSON.Feature | GeoJSON.GeometryObject
+
+/**
+ * http://turfjs.org/docs/#boolean-equal
+ */
+declare function equal(feature1: Feature, feature2: Feature): boolean;
+declare namespace equal {}
+export = equal;
diff --git a/packages/turf-boolean-equal/index.js b/packages/turf-boolean-equal/index.js
new file mode 100644
index 0000000000..fb4fc2feb8
--- /dev/null
+++ b/packages/turf-boolean-equal/index.js
@@ -0,0 +1,34 @@
+var GeojsonEquality = require('geojson-equality');
+var cleanCoords = require('@turf/clean-coords');
+var invariant = require('@turf/invariant');
+var getGeomType = invariant.getGeomType;
+
+/**
+ * Determine whether two geometries of the same type have identical X,Y coordinate values.
+ * See http://edndoc.esri.com/arcsde/9.0/general_topics/understand_spatial_relations.htm
+ *
+ * @name booleanEqual
+ * @param {Geometry|Feature} feature1 GeoJSON input
+ * @param {Geometry|Feature} feature2 GeoJSON input
+ * @returns {boolean} true if the objects are equal, false otherwise
+ * @example
+ * var pt1 = turf.point([0, 0]);
+ * var pt2 = turf.point([0, 0]);
+ * var pt3 = turf.point([1, 1]);
+ *
+ * turf.equal(pt1, pt2);
+ * //= true
+ * turf.equal(pt2, pt3);
+ * //= false
+ */
+module.exports = function (feature1, feature2) {
+ // validation
+ if (!feature1) throw new Error('feature1 is required');
+ if (!feature2) throw new Error('feature2 is required');
+ var type1 = getGeomType(feature1);
+ var type2 = getGeomType(feature2);
+ if (type1 !== type2) return false;
+
+ var equality = new GeojsonEquality({precision: 6});
+ return equality.compare(cleanCoords(feature1), cleanCoords(feature2));
+};
diff --git a/packages/turf-boolean-equal/package.json b/packages/turf-boolean-equal/package.json
new file mode 100644
index 0000000000..19068d8cdb
--- /dev/null
+++ b/packages/turf-boolean-equal/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@turf/boolean-equal",
+ "version": "4.5.0",
+ "description": "turf boolean-equal module",
+ "main": "index.js",
+ "types": "index.d.ts",
+ "files": [
+ "index.js",
+ "index.d.ts"
+ ],
+ "scripts": {
+ "test": "node test.js",
+ "bench": "node bench.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/Turfjs/turf.git"
+ },
+ "keywords": [
+ "turf",
+ "gis",
+ "boolean",
+ "de-9im",
+ "equal",
+ "boolean-equal"
+ ],
+ "author": "Turf Authors",
+ "contributors": [
+ "Tom MacWright <@tmcw>",
+ "Tim Channell <@tcql>",
+ "Stefano Borghi <@stebogit>"
+ ],
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/Turfjs/turf/issues"
+ },
+ "homepage": "https://github.com/Turfjs/turf",
+ "devDependencies": {
+ "@turf/helpers": "^4.5.2",
+ "benchmark": "^2.1.4",
+ "boolean-shapely": "^0.1.2",
+ "glob": "^7.1.1",
+ "load-json-file": "^2.0.0",
+ "tape": "^4.6.3"
+ },
+ "dependencies": {
+ "@turf/clean-coords": "^4.5.0",
+ "@turf/invariant": "^4.5.2",
+ "geojson-equality": "0.1.6"
+ }
+}
diff --git a/packages/turf-boolean-equal/test.js b/packages/turf-boolean-equal/test.js
new file mode 100644
index 0000000000..01f7b6911a
--- /dev/null
+++ b/packages/turf-boolean-equal/test.js
@@ -0,0 +1,53 @@
+const glob = require('glob');
+const path = require('path');
+const test = require('tape');
+const load = require('load-json-file');
+const shapely = require('boolean-shapely');
+const {point, lineString, polygon} = require('@turf/helpers');
+const equal = require('./');
+
+test('turf-boolean-equal', t => {
+ // True Fixtures
+ glob.sync(path.join(__dirname, 'test', 'true', '**', '*.geojson')).forEach(filepath => {
+ const {name} = path.parse(filepath);
+ const geojson = load.sync(filepath);
+ const [feature1, feature2] = geojson.features;
+ const result = equal(feature1, feature2);
+
+ if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.true(result, '[true] shapely - ' + name));
+ t.true(result, '[true] ' + name);
+ });
+ // False Fixtures
+ glob.sync(path.join(__dirname, 'test', 'false', '**', '*.geojson')).forEach(filepath => {
+ const {name} = path.parse(filepath);
+ const geojson = load.sync(filepath);
+ const [feature1, feature2] = geojson.features;
+ const result = equal(feature1, feature2);
+
+ if (process.env.SHAPELY) shapely.contains(feature1, feature2).then(result => t.false(result, '[false] shapely - ' + name));
+ t.false(result, '[false] ' + name);
+ });
+ t.end();
+});
+
+const pt = point([9, 50]);
+const line1 = lineString([[7, 50], [8, 50], [9, 50]]);
+const line2 = lineString([[7, 50], [8, 50], [9, 50]]);
+const poly1 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]);
+const poly2 = polygon([[[8.5, 50], [9.5, 50], [9.5, 49], [8.5, 49], [8.5, 50]]]);
+const poly3 = polygon([[[10, 50], [10.5, 50], [10.5, 49], [10, 49], [10, 50]]]);
+
+test('turf-boolean-equal -- geometries', t => {
+ t.true(equal(line1.geometry, line2.geometry), '[true] LineString geometry');
+ t.true(equal(poly1.geometry, poly2.geometry), '[true] Polygon geometry');
+ t.false(equal(poly1.geometry, poly3.geometry), '[false] Polygon geometry');
+ t.false(equal(pt, line1), '[false] different types');
+ t.end();
+});
+
+
+test('turf-boolean-equal -- throws', t => {
+ t.throws(() => equal(null, line1), /feature1 is required/, 'missing feature1');
+ t.throws(() => equal(line1, null), /feature2 is required/, 'missing feature2');
+ t.end();
+});
diff --git a/packages/turf-boolean-equal/test/false/linear-rings.geojson b/packages/turf-boolean-equal/test/false/linear-rings.geojson
new file mode 100644
index 0000000000..97327d61f7
--- /dev/null
+++ b/packages/turf-boolean-equal/test/false/linear-rings.geojson
@@ -0,0 +1,55 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ],
+ [
+ -53.337249755859375,
+ 28.47412369059679
+ ],
+ [
+ -53.524017333984375,
+ 28.17492820114568
+ ],
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -55.674866943359375,
+ 28.30135788537988
+ ],
+ [
+ -55.337249755859375,
+ 28.47412369059679
+ ],
+ [
+ -55.524017333984375,
+ 28.17492820114568
+ ],
+ [
+ -55.674866943359375,
+ 28.30135788537988
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/false/lines.geojson b/packages/turf-boolean-equal/test/false/lines.geojson
new file mode 100644
index 0000000000..3193849f78
--- /dev/null
+++ b/packages/turf-boolean-equal/test/false/lines.geojson
@@ -0,0 +1,55 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 5
+ ],
+ [
+ 5,
+ 5
+ ],
+ [
+ 5,
+ 0
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 1,
+ 0
+ ],
+ [
+ 1,
+ 5
+ ],
+ [
+ 6,
+ 5
+ ],
+ [
+ 6,
+ 0
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/false/multipoints.geojson b/packages/turf-boolean-equal/test/false/multipoints.geojson
new file mode 100644
index 0000000000..e45c73cf14
--- /dev/null
+++ b/packages/turf-boolean-equal/test/false/multipoints.geojson
@@ -0,0 +1,63 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "MultiPoint",
+ "coordinates": [
+ [
+ -35.5638671875,
+ 27.254629577800063
+ ],
+ [
+ -35.6462646484375,
+ 26.86328062676624
+ ],
+ [
+ -35,
+ 26
+ ],
+ [
+ -35.1001953125,
+ 26.12091815959972
+ ],
+ [
+ -34.8969482421875,
+ 26.455820238459893
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "MultiPoint",
+ "coordinates": [
+ [
+ -35.5638671875,
+ 27.254629577800063
+ ],
+ [
+ -35.6462646484375,
+ 26.86328062676624
+ ],
+ [
+ -35.4924560546875,
+ 26.504988828743404
+ ],
+ [
+ -35.1001953125,
+ 26.12091815959972
+ ],
+ [
+ -34.8969482421875,
+ 26.455820238459893
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/false/points.geojson b/packages/turf-boolean-equal/test/false/points.geojson
new file mode 100644
index 0000000000..e2d224acf6
--- /dev/null
+++ b/packages/turf-boolean-equal/test/false/points.geojson
@@ -0,0 +1,27 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 1,
+ 0
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/false/polygons.geojson b/packages/turf-boolean-equal/test/false/polygons.geojson
new file mode 100644
index 0000000000..7655d4baed
--- /dev/null
+++ b/packages/turf-boolean-equal/test/false/polygons.geojson
@@ -0,0 +1,59 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53,
+ 28.287451910503744
+ ],
+ [
+ -53.33038330078125,
+ 28.29228897739706
+ ],
+ [
+ -53.34136962890625,
+ 28.430052892335723
+ ],
+ [
+ -53,
+ 28.287451910503744
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ],
+ [
+ -53.33038330078125,
+ 28.29228897739706
+ ],
+ [
+ -53.34136962890625,
+ 28.430052892335723
+ ],
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ]
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/linear-rings.geojson b/packages/turf-boolean-equal/test/true/linear-rings.geojson
new file mode 100644
index 0000000000..9391d5829a
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/linear-rings.geojson
@@ -0,0 +1,55 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ],
+ [
+ -53.337249755859375,
+ 28.47412369059679
+ ],
+ [
+ -53.524017333984375,
+ 28.17492820114568
+ ],
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ],
+ [
+ -53.337249755859375,
+ 28.47412369059679
+ ],
+ [
+ -53.524017333984375,
+ 28.17492820114568
+ ],
+ [
+ -53.674866943359375,
+ 28.30135788537988
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/lines-extra-vertices.geojson b/packages/turf-boolean-equal/test/true/lines-extra-vertices.geojson
new file mode 100644
index 0000000000..c976d92770
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/lines-extra-vertices.geojson
@@ -0,0 +1,40 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 2,
+ 2
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,0
+ ],
+ [
+ 1,1
+ ],
+ [
+ 2,2
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/lines-reverse.geojson b/packages/turf-boolean-equal/test/true/lines-reverse.geojson
new file mode 100644
index 0000000000..6d40db896c
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/lines-reverse.geojson
@@ -0,0 +1,21 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [[2, 2], [1, 1], [0, 0]]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [[0, 0], [1, 1], [2, 2]]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/lines.geojson b/packages/turf-boolean-equal/test/true/lines.geojson
new file mode 100644
index 0000000000..ce6f2443f6
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/lines.geojson
@@ -0,0 +1,55 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 5
+ ],
+ [
+ 5,
+ 5
+ ],
+ [
+ 5,
+ 0
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 5
+ ],
+ [
+ 5,
+ 5
+ ],
+ [
+ 5,
+ 0
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/multipoints.geojson b/packages/turf-boolean-equal/test/true/multipoints.geojson
new file mode 100644
index 0000000000..e3f85eb8a9
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/multipoints.geojson
@@ -0,0 +1,63 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "MultiPoint",
+ "coordinates": [
+ [
+ -35.5638671875,
+ 27.254629577800063
+ ],
+ [
+ -35.6462646484375,
+ 26.86328062676624
+ ],
+ [
+ -35.4924560546875,
+ 26.504988828743404
+ ],
+ [
+ -35.1001953125,
+ 26.12091815959972
+ ],
+ [
+ -34.8969482421875,
+ 26.455820238459893
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "MultiPoint",
+ "coordinates": [
+ [
+ -35.5638671875,
+ 27.254629577800063
+ ],
+ [
+ -35.6462646484375,
+ 26.86328062676624
+ ],
+ [
+ -35.4924560546875,
+ 26.504988828743404
+ ],
+ [
+ -35.1001953125,
+ 26.12091815959972
+ ],
+ [
+ -34.8969482421875,
+ 26.455820238459893
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/points.geojson b/packages/turf-boolean-equal/test/true/points.geojson
new file mode 100644
index 0000000000..f80705c93f
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/points.geojson
@@ -0,0 +1,27 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0,
+ 0
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Point",
+ "coordinates": [
+ 0,
+ 0
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/polygons.geojson b/packages/turf-boolean-equal/test/true/polygons.geojson
new file mode 100644
index 0000000000..e29b12caa2
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/polygons.geojson
@@ -0,0 +1,59 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ],
+ [
+ -53.33038330078125,
+ 28.29228897739706
+ ],
+ [
+ -53.34136962890625,
+ 28.430052892335723
+ ],
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ],
+ [
+ -53.33038330078125,
+ 28.29228897739706
+ ],
+ [
+ -53.34136962890625,
+ 28.430052892335723
+ ],
+ [
+ -53.57208251953125,
+ 28.287451910503744
+ ]
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/reverse-lines.geojson b/packages/turf-boolean-equal/test/true/reverse-lines.geojson
new file mode 100644
index 0000000000..b30676add3
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/reverse-lines.geojson
@@ -0,0 +1,55 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 5
+ ],
+ [
+ 5,
+ 5
+ ],
+ [
+ 5,
+ 0
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ 5,
+ 0
+ ],
+ [
+ 5,
+ 5
+ ],
+ [
+ 0,
+ 5
+ ],
+ [
+ 0,
+ 0
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/test/true/reverse-polygons.geojson b/packages/turf-boolean-equal/test/true/reverse-polygons.geojson
new file mode 100644
index 0000000000..0e17ec33d4
--- /dev/null
+++ b/packages/turf-boolean-equal/test/true/reverse-polygons.geojson
@@ -0,0 +1,59 @@
+{
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53.57,
+ 28.28
+ ],
+ [
+ -53.33,
+ 28.29
+ ],
+ [
+ -53.34,
+ 28.43
+ ],
+ [
+ -53.57,
+ 28.28
+ ]
+ ]
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [
+ -53.57,
+ 28.28
+ ],
+ [
+ -53.34,
+ 28.43
+ ],
+ [
+ -53.33,
+ 28.29
+ ],
+ [
+ -53.57,
+ 28.28
+ ]
+ ]
+ ]
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/turf-boolean-equal/yarn.lock b/packages/turf-boolean-equal/yarn.lock
new file mode 100644
index 0000000000..1b597ba023
--- /dev/null
+++ b/packages/turf-boolean-equal/yarn.lock
@@ -0,0 +1,279 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@turf/clean-coords@^4.5.0":
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/@turf/clean-coords/-/clean-coords-4.5.0.tgz#3de0ee57e91d373d2bd5937c88282c583589b1be"
+ dependencies:
+ "@turf/helpers" "^4.5.2"
+ "@turf/invariant" "^4.5.2"
+
+"@turf/helpers@^4.5.2":
+ version "4.5.2"
+ resolved "https://registry.yarnpkg.com/@turf/helpers/-/helpers-4.5.2.tgz#6fc6772a7b301f277b49732925c354c7fb85d1df"
+
+"@turf/invariant@^4.5.2":
+ version "4.5.2"
+ resolved "https://registry.yarnpkg.com/@turf/invariant/-/invariant-4.5.2.tgz#0642ee1e6bca531be3f6f9292d590155f2fb9604"
+
+balanced-match@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
+
+benchmark@^2.1.4:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629"
+ dependencies:
+ lodash "^4.17.4"
+ platform "^1.3.3"
+
+boolean-shapely@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/boolean-shapely/-/boolean-shapely-0.1.2.tgz#465fe962c99c35d4c7a6a4978da0d1df95b81b7b"
+ dependencies:
+ python-shell "^0.4.0"
+
+brace-expansion@^1.1.7:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
+ dependencies:
+ balanced-match "^1.0.0"
+ concat-map "0.0.1"
+
+concat-map@0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+deep-equal@^1.0.0, deep-equal@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
+
+define-properties@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+ dependencies:
+ foreach "^2.0.5"
+ object-keys "^1.0.8"
+
+defined@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
+
+error-ex@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
+ dependencies:
+ is-arrayish "^0.2.1"
+
+es-abstract@^1.5.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
+ dependencies:
+ es-to-primitive "^1.1.1"
+ function-bind "^1.1.0"
+ is-callable "^1.1.3"
+ is-regex "^1.0.3"
+
+es-to-primitive@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+ dependencies:
+ is-callable "^1.1.1"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.1"
+
+for-each@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4"
+ dependencies:
+ is-function "~1.0.0"
+
+foreach@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+function-bind@^1.0.2, function-bind@^1.1.0, function-bind@~1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
+
+geojson-equality@0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/geojson-equality/-/geojson-equality-0.1.6.tgz#a171374ef043e5d4797995840bae4648e0752d72"
+ dependencies:
+ deep-equal "^1.0.0"
+
+glob@^7.1.1, glob@~7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^3.0.4"
+ once "^1.3.0"
+ path-is-absolute "^1.0.0"
+
+graceful-fs@^4.1.2:
+ version "4.1.11"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+has@^1.0.1, has@~1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
+ dependencies:
+ function-bind "^1.0.2"
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@~2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+
+is-callable@^1.1.1, is-callable@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+
+is-date-object@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+
+is-function@~1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
+
+is-regex@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
+ dependencies:
+ has "^1.0.1"
+
+is-symbol@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+
+load-json-file@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8"
+ dependencies:
+ graceful-fs "^4.1.2"
+ parse-json "^2.2.0"
+ pify "^2.0.0"
+ strip-bom "^3.0.0"
+
+lodash@^4.17.4:
+ version "4.17.4"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+minimatch@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
+ dependencies:
+ brace-expansion "^1.1.7"
+
+minimist@~1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+object-inspect@~1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.2.2.tgz#c82115e4fcc888aea14d64c22e4f17f6a70d5e5a"
+
+object-keys@^1.0.8:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ dependencies:
+ wrappy "1"
+
+parse-json@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
+ dependencies:
+ error-ex "^1.2.0"
+
+path-is-absolute@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-parse@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+pify@^2.0.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+platform@^1.3.3:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.4.tgz#6f0fb17edaaa48f21442b3a975c063130f1c3ebd"
+
+python-shell@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/python-shell/-/python-shell-0.4.0.tgz#259c5470d885292b22e906a57b085f651752f956"
+
+resolve@~1.3.3:
+ version "1.3.3"
+ resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+ dependencies:
+ path-parse "^1.0.5"
+
+resumer@~0.0.0:
+ version "0.0.0"
+ resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759"
+ dependencies:
+ through "~2.3.4"
+
+string.prototype.trim@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
+ dependencies:
+ define-properties "^1.1.2"
+ es-abstract "^1.5.0"
+ function-bind "^1.0.2"
+
+strip-bom@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
+tape@^4.6.3:
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/tape/-/tape-4.7.0.tgz#f3ebb214fef3d6907e5a57dbaafe3bd8a7cbed88"
+ dependencies:
+ deep-equal "~1.0.1"
+ defined "~1.0.0"
+ for-each "~0.3.2"
+ function-bind "~1.1.0"
+ glob "~7.1.2"
+ has "~1.0.1"
+ inherits "~2.0.3"
+ minimist "~1.2.0"
+ object-inspect "~1.2.2"
+ resolve "~1.3.3"
+ resumer "~0.0.0"
+ string.prototype.trim "~1.1.2"
+ through "~2.3.8"
+
+through@~2.3.4, through@~2.3.8:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
diff --git a/packages/turf/index.d.ts b/packages/turf/index.d.ts
index 9652a23647..f5563a6874 100644
--- a/packages/turf/index.d.ts
+++ b/packages/turf/index.d.ts
@@ -119,6 +119,7 @@ import * as booleanDisjoint from '@turf/boolean-disjoint';
import * as booleanContains from '@turf/boolean-contains';
import * as booleanCrosses from '@turf/boolean-crosses';
import * as booleanClockwise from '@turf/boolean-clockwise';
+import * as booleanEqual from '@turf/boolean-equal';
import * as clone from '@turf/clone';
import * as cleanCoords from '@turf/clean-coords';
export {
@@ -238,6 +239,7 @@ export {
booleanContains,
booleanCrosses,
booleanClockwise,
+ booleanEqual,
clone,
segmentEach,
segmentReduce,
diff --git a/packages/turf/index.js b/packages/turf/index.js
index 74fcd05d7d..5945069cc5 100644
--- a/packages/turf/index.js
+++ b/packages/turf/index.js
@@ -90,6 +90,7 @@ var turf = {
booleanContains: require('@turf/boolean-contains'),
booleanCrosses: require('@turf/boolean-crosses'),
booleanClockwise: require('@turf/boolean-clockwise'),
+ booleanEqual: require('@turf/boolean-equal'),
clone: require('@turf/clone'),
cleanCoords: require('@turf/clean-coords'),
point: helpers.point,
diff --git a/packages/turf/module.js b/packages/turf/module.js
index 9652a23647..f5563a6874 100644
--- a/packages/turf/module.js
+++ b/packages/turf/module.js
@@ -119,6 +119,7 @@ import * as booleanDisjoint from '@turf/boolean-disjoint';
import * as booleanContains from '@turf/boolean-contains';
import * as booleanCrosses from '@turf/boolean-crosses';
import * as booleanClockwise from '@turf/boolean-clockwise';
+import * as booleanEqual from '@turf/boolean-equal';
import * as clone from '@turf/clone';
import * as cleanCoords from '@turf/clean-coords';
export {
@@ -238,6 +239,7 @@ export {
booleanContains,
booleanCrosses,
booleanClockwise,
+ booleanEqual,
clone,
segmentEach,
segmentReduce,
diff --git a/packages/turf/package.json b/packages/turf/package.json
index fd606c260c..3bcfeece7b 100644
--- a/packages/turf/package.json
+++ b/packages/turf/package.json
@@ -67,6 +67,7 @@
"@turf/boolean-contains": "^4.5.2",
"@turf/boolean-crosses": "^4.5.2",
"@turf/boolean-disjoint": "^4.5.2",
+ "@turf/boolean-equal": "^4.5.0",
"@turf/buffer": "^4.5.2",
"@turf/center": "^4.5.2",
"@turf/center-of-mass": "^4.5.2",
diff --git a/packages/turf/yarn.lock b/packages/turf/yarn.lock
index 5be831b892..26235305b3 100644
--- a/packages/turf/yarn.lock
+++ b/packages/turf/yarn.lock
@@ -102,6 +102,14 @@
"@turf/meta" "^4.5.2"
"@turf/polygon-to-linestring" "^4.5.2"
+"@turf/boolean-equal@^4.5.0":
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/@turf/boolean-equal/-/boolean-equal-4.5.0.tgz#71ab0a221714b9360426a09e1644add5127fe2da"
+ dependencies:
+ "@turf/clean-coords" "^4.5.0"
+ "@turf/invariant" "^4.5.2"
+ geojson-equality "0.1.6"
+
"@turf/buffer@^4.5.2":
version "4.5.2"
resolved "https://registry.yarnpkg.com/@turf/buffer/-/buffer-4.5.2.tgz#4c19514d157e4181d2170bcbc8b603411a991363"
@@ -2617,6 +2625,12 @@ geodesy@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/geodesy/-/geodesy-1.1.1.tgz#918c414a5cc247c8128332b7624050c467e98a5d"
+geojson-equality@0.1.6:
+ version "0.1.6"
+ resolved "https://registry.yarnpkg.com/geojson-equality/-/geojson-equality-0.1.6.tgz#a171374ef043e5d4797995840bae4648e0752d72"
+ dependencies:
+ deep-equal "^1.0.0"
+
geojson-polygon-self-intersections@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/geojson-polygon-self-intersections/-/geojson-polygon-self-intersections-1.1.1.tgz#4943db21a62063c2325bdbce0133523551142d83"