@turf/mask
Advanced tools
Comparing version 3.12.2 to 3.13.0
142
index.js
@@ -1,3 +0,6 @@ | ||
const helpers = require('@turf/helpers'); | ||
const featureEach = require('@turf/meta').featureEach; | ||
var featureEach = require('@turf/meta').featureEach; | ||
var rbush = require('rbush'); | ||
var turfBBox = require('@turf/bbox'); | ||
var helpers = require('@turf/helpers'); | ||
var union = require('@turf/union'); | ||
@@ -27,13 +30,15 @@ /** | ||
// Define mask | ||
var maskCoordinates = createMask(mask); | ||
var maskOuter = maskCoordinates[0]; | ||
var maskInners = maskCoordinates.slice(1); | ||
var maskPolygon = createMask(mask); | ||
// Define polygon | ||
var separated = separatePolygonToLines(polygon); | ||
var separated = separatePolygons(polygon); | ||
var polygonOuters = separated[0]; | ||
var polygonInners = separated[1]; | ||
// Union Outers & Inners | ||
polygonOuters = unionPolygons(polygonOuters); | ||
polygonInners = unionPolygons(polygonInners); | ||
// Create masked area | ||
var masked = buildMask(maskOuter, maskInners, polygonOuters, polygonInners); | ||
var masked = buildMask(maskPolygon, polygonOuters, polygonInners); | ||
return masked; | ||
@@ -46,13 +51,18 @@ }; | ||
* @private | ||
* @param {line} maskOuter Mask Outer | ||
* @param {Array<line>} maskInners Mask Inners | ||
* @param {Array<line>} polygonOuters Polygon Outers | ||
* @param {Array<line>} polygonInners Polygon Inners | ||
* @param {Feature<Polygon>} maskPolygon Mask Outer | ||
* @param {FeatureCollection<Polygon>} polygonOuters Polygon Outers | ||
* @param {FeatureCollection<Polygon>} polygonInners Polygon Inners | ||
* @returns {Feature<Polygon>} Feature Polygon | ||
*/ | ||
function buildMask(maskOuter, maskInners, polygonOuters) { | ||
var coordinates = [maskOuter]; | ||
polygonOuters.forEach(function (outer) { | ||
coordinates.push(outer); | ||
function buildMask(maskPolygon, polygonOuters, polygonInners) { | ||
var coordinates = []; | ||
coordinates.push(maskPolygon.geometry.coordinates[0]); | ||
featureEach(polygonOuters, function (feature) { | ||
coordinates.push(feature.geometry.coordinates[0]); | ||
}); | ||
featureEach(polygonInners, function (feature) { | ||
coordinates.push(feature.geometry.coordinates[0]); | ||
}); | ||
return helpers.polygon(coordinates); | ||
@@ -62,9 +72,9 @@ } | ||
/** | ||
* Separate Polygons to inner & outer lines | ||
* Separate Polygons to inners & outers | ||
* | ||
* @private | ||
* @param {FeatureCollection|Feature<Polygon|MultiPolygon>} polygon GeoJSON Feature | ||
* @returns {Array<line[], line[]>} Outer & Inner lines | ||
* @returns {Array<FeatureCollection<Polygon>, FeatureCollection<Polygon>>} Outer & Inner lines | ||
*/ | ||
function separatePolygonToLines(polygon) { | ||
function separatePolygons(polygon) { | ||
var outers = []; | ||
@@ -80,9 +90,9 @@ var inners = []; | ||
var featureInner = coordinates.slice(1); | ||
outers.push(featureOuter); | ||
outers.push(helpers.polygon([featureOuter])); | ||
featureInner.forEach(function (inner) { | ||
inners.push(inner); | ||
inners.push(helpers.polygon([inner])); | ||
}); | ||
}); | ||
}); | ||
return [outers, inners]; | ||
return [helpers.featureCollection(outers), helpers.featureCollection(inners)]; | ||
} | ||
@@ -110,3 +120,3 @@ | ||
* @param {Feature<Polygon>} [mask] default to world if undefined | ||
* @returns {coordinates} mask coordinate | ||
* @returns {Feature<Polygon>} mask coordinate | ||
*/ | ||
@@ -116,3 +126,89 @@ function createMask(mask) { | ||
var coordinates = mask && mask.geometry.coordinates || world; | ||
return coordinates; | ||
return helpers.polygon(coordinates); | ||
} | ||
/** | ||
* Union Polygons | ||
* | ||
* @private | ||
* @param {FeatureCollection<Polygon>} polygons collection of polygons | ||
* @returns {FeatureCollection<Polygon>} polygons only apply union if they collide | ||
*/ | ||
function unionPolygons(polygons) { | ||
if (polygons.features.length <= 1) return polygons; | ||
var tree = createIndex(polygons); | ||
var results = []; | ||
var removed = {}; | ||
featureEach(polygons, function (currentFeature, currentIndex) { | ||
// Exclude any removed features | ||
if (removed[currentIndex]) return true; | ||
// Don't search for itself | ||
tree.remove({index: currentIndex}, filterByIndex); | ||
removed[currentIndex] = true; | ||
// Keep applying the union operation until no more overlapping features | ||
while (true) { | ||
var bbox = turfBBox(currentFeature); | ||
var search = tree.search({ | ||
minX: bbox[0], | ||
minY: bbox[1], | ||
maxX: bbox[2], | ||
maxY: bbox[3] | ||
}); | ||
if (search.length > 0) { | ||
var polys = search.map(function (item) { | ||
removed[item.index] = true; | ||
tree.remove({index: item.index}, filterByIndex); | ||
return item.geojson; | ||
}); | ||
polys.push(currentFeature); | ||
currentFeature = union.apply(this, polys); | ||
} | ||
// Done | ||
if (search.length === 0) break; | ||
} | ||
results.push(currentFeature); | ||
}); | ||
return helpers.featureCollection(results); | ||
} | ||
/** | ||
* Filter by Index - RBush helper function | ||
* | ||
* @private | ||
* @param {Object} a remove item | ||
* @param {Object} b search item | ||
* @returns {boolean} true if matches | ||
*/ | ||
function filterByIndex(a, b) { | ||
return a.index === b.index; | ||
} | ||
/** | ||
* Create RBush Tree Index | ||
* | ||
* @private | ||
* @param {FeatureCollection<any>} features GeoJSON FeatureCollection | ||
* @returns {RBush} RBush Tree | ||
*/ | ||
function createIndex(features) { | ||
var tree = rbush(); | ||
var load = []; | ||
featureEach(features, function (feature, index) { | ||
var bbox = turfBBox(feature); | ||
load.push({ | ||
minX: bbox[0], | ||
minY: bbox[1], | ||
maxX: bbox[2], | ||
maxY: bbox[3], | ||
geojson: feature, | ||
index: index | ||
}); | ||
}); | ||
tree.load(load); | ||
return tree; | ||
} |
{ | ||
"name": "@turf/mask", | ||
"version": "3.12.2", | ||
"description": "Takes a Polygon and an optional mask and returns the outside area.", | ||
"version": "3.13.0", | ||
"description": "turf mask module", | ||
"main": "index.js", | ||
@@ -30,6 +30,2 @@ "types": "index.d.ts", | ||
"homepage": "https://github.com/Turfjs/turf", | ||
"dependencies": { | ||
"@turf/helpers": "^3.10.5", | ||
"@turf/meta": "^3.10.5" | ||
}, | ||
"devDependencies": { | ||
@@ -43,3 +39,10 @@ "benchmark": "^2.1.3", | ||
"write-json-file": "^2.0.0" | ||
}, | ||
"dependencies": { | ||
"@turf/bbox": "^3.13.0", | ||
"@turf/helpers": "^3.13.0", | ||
"@turf/meta": "^3.13.0", | ||
"@turf/union": "^3.13.0", | ||
"rbush": "^2.0.1" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10507
198
5
+ Added@turf/bbox@^3.13.0
+ Added@turf/union@^3.13.0
+ Addedrbush@^2.0.1
+ Added@turf/bbox@3.14.0(transitive)
+ Added@turf/union@3.14.0(transitive)
+ Addedjsts@1.3.0(transitive)
+ Addedquickselect@1.1.1(transitive)
+ Addedrbush@2.0.2(transitive)
Updated@turf/helpers@^3.13.0
Updated@turf/meta@^3.13.0