@turf/kinks
Advanced tools
Comparing version 3.7.3 to 3.7.5
/// <reference types="geojson" /> | ||
type Polygon = GeoJSON.Feature<GeoJSON.Polygon> | Array<Array<Array<number>>>; | ||
type LineString = GeoJSON.Feature<GeoJSON.LineString> | GeoJSON.LineString; | ||
type MultiLineString = GeoJSON.Feature<GeoJSON.MultiLineString> | GeoJSON.MultiLineString; | ||
type Polygon = GeoJSON.Feature<GeoJSON.Polygon> | GeoJSON.Polygon; | ||
type MultiPolygon = GeoJSON.Feature<GeoJSON.MultiPolygon> | GeoJSON.MultiPolygon; | ||
type Points = GeoJSON.FeatureCollection<GeoJSON.Point>; | ||
/** | ||
* http://turfjs.org/docs/#kinks | ||
*/ | ||
declare function kinks(polygon: Polygon): Points; | ||
declare namespace kinks { } | ||
interface Kinks { | ||
/** | ||
* http://turfjs.org/docs/#kinks | ||
*/ | ||
(featureIn: LineString): Points; | ||
(featureIn: MultiLineString): Points; | ||
(featureIn: Polygon): Points; | ||
(featureIn: MultiPolygon): Points; | ||
} | ||
declare const kinks: Kinks; | ||
export = kinks; |
45
index.js
/** | ||
* Takes a {@link Polygon|polygon} and returns {@link Point|points} at all self-intersections. | ||
* Takes a {@link LineString|linestring}, {@link MultiLineString|multi-linestring}, {@link MultiPolygon|multi-polygon}, or {@link Polygon|polygon} and returns {@link Point|points} at all self-intersections. | ||
* | ||
* @name kinks | ||
* @param {Feature<Polygon>|Polygon} polygon input polygon | ||
* @param {Feature<LineString|MultiLineString|MultiPolygon|Polygon>} feature input feature | ||
* @returns {FeatureCollection<Point>} self-intersections | ||
@@ -25,3 +25,3 @@ * @example | ||
* | ||
* var resultFeatures = kinks.intersections.features.concat(poly); | ||
* var resultFeatures = kinks.features.concat(poly); | ||
* var result = { | ||
@@ -37,4 +37,5 @@ * "type": "FeatureCollection", | ||
module.exports = function (polyIn) { | ||
var poly; | ||
module.exports = function (featureIn) { | ||
var coordinates; | ||
var feature; | ||
var results = { | ||
@@ -44,18 +45,30 @@ type: 'FeatureCollection', | ||
}; | ||
if (polyIn.type === 'Feature') { | ||
poly = polyIn.geometry; | ||
if (featureIn.type === 'Feature') { | ||
feature = featureIn.geometry; | ||
} else { | ||
poly = polyIn; | ||
feature = featureIn; | ||
} | ||
poly.coordinates.forEach(function (ring1) { | ||
poly.coordinates.forEach(function (ring2) { | ||
for (var i = 0; i < ring1.length - 1; i++) { | ||
for (var k = 0; k < ring2.length - 1; k++) { | ||
// don't check adjacent sides of a given ring, since of course they intersect in a vertex. | ||
if (ring1 === ring2 && (Math.abs(i - k) === 1 || Math.abs(i - k) === ring1.length - 2)) { | ||
if (feature.type === 'LineString') { | ||
coordinates = [feature.coordinates]; | ||
} else if (feature.type === 'MultiLineString') { | ||
coordinates = feature.coordinates; | ||
} else if (feature.type === 'MultiPolygon') { | ||
coordinates = [].concat.apply([], feature.coordinates); | ||
} else if (feature.type === 'Polygon') { | ||
coordinates = feature.coordinates; | ||
} else { | ||
throw new Error('Input must be a LineString, MultiLineString, ' + | ||
'Polygon, or MultiPolygon Feature or Geometry'); | ||
} | ||
coordinates.forEach(function (segment1) { | ||
coordinates.forEach(function (segment2) { | ||
for (var i = 0; i < segment1.length - 1; i++) { | ||
for (var k = 0; k < segment2.length - 1; k++) { | ||
// don't check adjacent sides of a given segment, since of course they intersect in a vertex. | ||
if (segment1 === segment2 && (Math.abs(i - k) === 1 || Math.abs(i - k) === segment1.length - 2)) { | ||
continue; | ||
} | ||
var intersection = lineIntersects(ring1[i][0], ring1[i][1], ring1[i + 1][0], ring1[i + 1][1], | ||
ring2[k][0], ring2[k][1], ring2[k + 1][0], ring2[k + 1][1]); | ||
var intersection = lineIntersects(segment1[i][0], segment1[i][1], segment1[i + 1][0], segment1[i + 1][1], | ||
segment2[k][0], segment2[k][1], segment2[k + 1][0], segment2[k + 1][1]); | ||
if (intersection) { | ||
@@ -62,0 +75,0 @@ results.features.push(point([intersection[0], intersection[1]])); |
{ | ||
"name": "@turf/kinks", | ||
"version": "3.7.3", | ||
"version": "3.7.5", | ||
"description": "turf kinks module", | ||
"main": "index.js", | ||
"dependencies": { | ||
"@turf/helpers": "^3.7.3" | ||
"@turf/helpers": "^3.7.5" | ||
}, | ||
@@ -9,0 +9,0 @@ "devDependencies": { |
@@ -5,7 +5,7 @@ # @turf/kinks | ||
Takes a [polygon](http://geojson.org/geojson-spec.html#polygon) and returns [points](http://geojson.org/geojson-spec.html#point) at all self-intersections. | ||
Takes a [linestring](http://geojson.org/geojson-spec.html#linestring), [multi-linestring](http://geojson.org/geojson-spec.html#multilinestring), [multi-polygon](http://geojson.org/geojson-spec.html#multipolygon), or [polygon](http://geojson.org/geojson-spec.html#polygon) and returns [points](http://geojson.org/geojson-spec.html#point) at all self-intersections. | ||
**Parameters** | ||
- `polygon` **([Feature](http://geojson.org/geojson-spec.html#feature-objects)<[Polygon](http://geojson.org/geojson-spec.html#polygon)> | [Polygon](http://geojson.org/geojson-spec.html#polygon))** input polygon | ||
- `feature` **[Feature](http://geojson.org/geojson-spec.html#feature-objects)<([LineString](http://geojson.org/geojson-spec.html#linestring) \| [MultiLineString](http://geojson.org/geojson-spec.html#multilinestring) \| [MultiPolygon](http://geojson.org/geojson-spec.html#multipolygon) \| [Polygon](http://geojson.org/geojson-spec.html#polygon))>** input feature | ||
@@ -32,3 +32,3 @@ **Examples** | ||
var resultFeatures = kinks.intersections.features.concat(poly); | ||
var resultFeatures = kinks.features.concat(poly); | ||
var result = { | ||
@@ -35,0 +35,0 @@ "type": "FeatureCollection", |
433
test.js
@@ -5,81 +5,150 @@ var test = require('tape'); | ||
test('kinks', function(t){ | ||
var hourglass = { | ||
type: "Polygon", | ||
coordinates: [ | ||
[ | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
], | ||
[ | ||
-12.060413360595701, | ||
8.899826693726117 | ||
], | ||
[ | ||
-12.036380767822266, | ||
8.873199368734273 | ||
], | ||
[ | ||
-12.059383392333983, | ||
8.871418491385919 | ||
], | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
] | ||
] | ||
] | ||
}; | ||
var hourglassKinks = kinks(hourglass); | ||
t.ok(hourglassKinks, 'get self intersection from hourglass polygon'); | ||
t.deepEqual(hourglassKinks, { | ||
features: [ { geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' }, { geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' } ], | ||
var hourglassCoordinates = [ | ||
[ | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
], | ||
[ | ||
-12.060413360595701, | ||
8.899826693726117 | ||
], | ||
[ | ||
-12.036380767822266, | ||
8.873199368734273 | ||
], | ||
[ | ||
-12.059383392333983, | ||
8.871418491385919 | ||
], | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
] | ||
] | ||
]; | ||
var expected = { | ||
features: [ | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' } ], | ||
type: 'FeatureCollection' | ||
}); | ||
}; | ||
var triple = { | ||
type: "Polygon", | ||
coordinates: [ | ||
[ | ||
[ | ||
-44.384765625, | ||
1.0106897682409128 | ||
], | ||
[ | ||
-53.4375, | ||
0.4833927027896987 | ||
], | ||
[ | ||
-43.154296875, | ||
-6.402648405963884 | ||
], | ||
[ | ||
-53.173828125, | ||
-6.708253968671543 | ||
], | ||
[ | ||
-43.857421875, | ||
-13.752724664396975 | ||
], | ||
[ | ||
-54.09667968749999, | ||
-14.944784875088372 | ||
], | ||
[ | ||
-53.3935546875, | ||
-11.867350911459308 | ||
], | ||
[ | ||
-44.384765625, | ||
1.0106897682409128 | ||
] | ||
] | ||
] | ||
}; | ||
// Test LineString | ||
var hourglassLineString = { | ||
type: "LineString", | ||
coordinates: hourglassCoordinates[0] | ||
}; | ||
var tripleKinks = kinks(triple); | ||
t.ok(tripleKinks, 'get self intersection from triple intersecting polygon'); | ||
t.equal(tripleKinks.features.length, 6); | ||
var hourglassLineStringKinks = kinks(hourglassLineString); | ||
t.ok(hourglassLineStringKinks, 'get self intersection from hourglass line string'); | ||
t.deepEqual(hourglassLineStringKinks, expected); | ||
// Test MultiLineString | ||
var hourglassMultiLineString = { | ||
type: "MultiLineString", | ||
coordinates: hourglassCoordinates | ||
}; | ||
var hourglassMultiLineStringKinks = kinks(hourglassMultiLineString); | ||
t.ok(hourglassMultiLineStringKinks, 'get self intersection from hourglass multi line string'); | ||
t.deepEqual(hourglassMultiLineStringKinks, expected); | ||
// Test MultiPolygon | ||
var hourglassMultiPolygon = { | ||
type: "MultiPolygon", | ||
coordinates: [hourglassCoordinates] | ||
}; | ||
var hourglassMultiPolygonKinks = kinks(hourglassMultiPolygon); | ||
t.ok(hourglassMultiPolygonKinks, 'get self intersection from hourglass multi polygon'); | ||
t.deepEqual(hourglassMultiPolygonKinks, expected); | ||
// Test Polygon | ||
var hourglassPolygon = { | ||
type: "Polygon", | ||
coordinates: hourglassCoordinates | ||
}; | ||
var hourglassPolygonKinks = kinks(hourglassPolygon); | ||
t.ok(hourglassPolygonKinks, 'get self intersection from hourglass polygon'); | ||
t.deepEqual(hourglassPolygonKinks, expected); | ||
var tripleCoordinates = [ | ||
[ | ||
[ | ||
-44.384765625, | ||
1.0106897682409128 | ||
], | ||
[ | ||
-53.4375, | ||
0.4833927027896987 | ||
], | ||
[ | ||
-43.154296875, | ||
-6.402648405963884 | ||
], | ||
[ | ||
-53.173828125, | ||
-6.708253968671543 | ||
], | ||
[ | ||
-43.857421875, | ||
-13.752724664396975 | ||
], | ||
[ | ||
-54.09667968749999, | ||
-14.944784875088372 | ||
], | ||
[ | ||
-53.3935546875, | ||
-11.867350911459308 | ||
], | ||
[ | ||
-44.384765625, | ||
1.0106897682409128 | ||
] | ||
] | ||
]; | ||
// Test LineString | ||
var tripleLineString = { | ||
type: "LineString", | ||
coordinates: tripleCoordinates[0] | ||
}; | ||
var tripleLineStringKinks = kinks(tripleLineString); | ||
t.ok(tripleLineStringKinks, 'get self intersection from triple intersecting line string'); | ||
t.equal(tripleLineStringKinks.features.length, 6); | ||
// Test MultiLineString | ||
var tripleMultiLineString = { | ||
type: "MultiLineString", | ||
coordinates: tripleCoordinates | ||
}; | ||
var tripleMultiLineStringKinks = kinks(tripleMultiLineString); | ||
t.ok(tripleMultiLineStringKinks, 'get self intersection from triple intersecting multi line string'); | ||
t.equal(tripleMultiLineStringKinks.features.length, 6); | ||
// Test MultiPolygon | ||
var tripleMultiPolygon = { | ||
type: "MultiPolygon", | ||
coordinates: [tripleCoordinates] | ||
}; | ||
var tripleMultiPolygonKinks = kinks(tripleMultiPolygon); | ||
t.ok(tripleMultiPolygonKinks, 'get self intersection from triple intersecting multi polygon'); | ||
t.equal(tripleMultiPolygonKinks.features.length, 6); | ||
// Test Polygon | ||
var triplePolygon = { | ||
type: "Polygon", | ||
coordinates: tripleCoordinates | ||
}; | ||
var triplePolygonKinks = kinks(triplePolygon); | ||
t.ok(triplePolygonKinks, 'get self intersection from triple intersecting polygon'); | ||
t.equal(triplePolygonKinks.features.length, 6); | ||
t.end(); | ||
@@ -89,41 +158,81 @@ }); | ||
test('kinks', function (t) { | ||
var feature = { | ||
var featureCoordinates = [ | ||
[ | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
], | ||
[ | ||
-12.060413360595701, | ||
8.899826693726117 | ||
], | ||
[ | ||
-12.036380767822266, | ||
8.873199368734273 | ||
], | ||
[ | ||
-12.059383392333983, | ||
8.871418491385919 | ||
], | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
] | ||
] | ||
]; | ||
var expected = { | ||
features: [ | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' } ], | ||
type: 'FeatureCollection' | ||
}; | ||
// Test LineString | ||
var featureLineString = { | ||
type: 'Feature', | ||
geometry: { | ||
type: 'LineString', | ||
coordinates: featureCoordinates[0] | ||
} | ||
}; | ||
var featureLineStringKinks = kinks(featureLineString); | ||
t.ok(featureLineStringKinks, 'get self intersection from hourglass line string feature'); | ||
t.deepEqual(featureLineStringKinks, expected); | ||
// Test MultiLineString | ||
var featureMultiLineString = { | ||
type: 'Feature', | ||
geometry: { | ||
type: 'MultiLineString', | ||
coordinates: featureCoordinates | ||
} | ||
}; | ||
var featureMultiLineStringKinks = kinks(featureMultiLineString); | ||
t.ok(featureMultiLineStringKinks, 'get self intersection from hourglass multi line string feature'); | ||
t.deepEqual(featureMultiLineStringKinks, expected); | ||
// Test MultiPolygon | ||
var featureMultiPolygon = { | ||
type: 'Feature', | ||
geometry: { | ||
type: 'MultiPolygon', | ||
coordinates: [featureCoordinates] | ||
} | ||
}; | ||
var featureMultiPolygonKinks = kinks(featureMultiPolygon); | ||
t.ok(featureMultiPolygonKinks, 'get self intersection from hourglass multi polygon feature'); | ||
t.deepEqual(featureMultiPolygonKinks, expected); | ||
// Test Polygon | ||
var featurePolygon = { | ||
type: 'Feature', | ||
geometry: { | ||
type: 'Polygon', | ||
coordinates: [ | ||
[ | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
], | ||
[ | ||
-12.060413360595701, | ||
8.899826693726117 | ||
], | ||
[ | ||
-12.036380767822266, | ||
8.873199368734273 | ||
], | ||
[ | ||
-12.059383392333983, | ||
8.871418491385919 | ||
], | ||
[ | ||
-12.034835815429688, | ||
8.901183448260598 | ||
] | ||
] | ||
] | ||
coordinates: featureCoordinates | ||
} | ||
}; | ||
var featureKinks = kinks(feature); | ||
t.ok(featureKinks, 'get self intersection from hourglass polygon feature'); | ||
t.deepEqual(featureKinks, { | ||
features: [ | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ -12.047632938440815, 8.885666404927512 ], type: 'Point' }, properties: {}, type: 'Feature' } ], | ||
type: 'FeatureCollection' | ||
}); | ||
var featurePolygonKinks = kinks(featurePolygon); | ||
t.ok(featurePolygonKinks, 'get self intersection from hourglass polygon feature'); | ||
t.deepEqual(featurePolygonKinks, expected); | ||
@@ -135,3 +244,27 @@ t.end(); | ||
test('kinks', function (t) { | ||
var feature = { | ||
var featureCoordinates = [ | ||
[ | ||
[0, 0], | ||
[0, 1], | ||
[0.25, 1], | ||
[0.25, 0], | ||
[0.5, 0], | ||
[0.5, 1], | ||
[1, 1], | ||
[1, 0], | ||
[0, 0] | ||
] | ||
]; | ||
var expected = { | ||
type: 'FeatureCollection', | ||
features: [ | ||
{ geometry: { coordinates: [ 0.25, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.5, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.25, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.5, 0 ], type: 'Point' }, properties: {}, type: 'Feature' } | ||
] | ||
}; | ||
// Test LineString | ||
var featureLineString = { | ||
type: "Feature", | ||
@@ -142,34 +275,64 @@ properties: { | ||
geometry: { | ||
type: "LineString", | ||
coordinates: featureCoordinates[0] | ||
} | ||
}; | ||
var featureLineStringKinks = kinks(featureLineString); | ||
t.ok(featureLineStringKinks, 'get self-intersection when vertex hits another side in a line string'); | ||
t.equal(featureLineStringKinks.features.length, 4); | ||
t.deepEqual(featureLineStringKinks, expected); | ||
// Test MultiLineString | ||
var featureMultiLineString = { | ||
type: "Feature", | ||
properties: { | ||
DN: 1 | ||
}, | ||
geometry: { | ||
type: "MultiLineString", | ||
coordinates: featureCoordinates | ||
} | ||
}; | ||
var featureMultiLineStringKinks = kinks(featureMultiLineString); | ||
t.ok(featureMultiLineStringKinks, 'get self-intersection when vertex hits another side in a multi line string'); | ||
t.equal(featureMultiLineStringKinks.features.length, 4); | ||
t.deepEqual(featureMultiLineStringKinks, expected); | ||
// Test MultiPolygon | ||
var featureMultiPolygon = { | ||
type: "Feature", | ||
properties: { | ||
DN: 1 | ||
}, | ||
geometry: { | ||
type: "MultiPolygon", | ||
coordinates: [featureCoordinates] | ||
} | ||
}; | ||
var featureMultiPolygonKinks = kinks(featureMultiPolygon); | ||
t.ok(featureMultiPolygonKinks, 'get self-intersection when vertex hits another side in a multi polygon'); | ||
t.equal(featureMultiPolygonKinks.features.length, 4); | ||
t.deepEqual(featureMultiPolygonKinks, expected); | ||
// Test Polygon | ||
var featurePolygon = { | ||
type: "Feature", | ||
properties: { | ||
DN: 1 | ||
}, | ||
geometry: { | ||
type: "Polygon", | ||
coordinates: [ | ||
[ | ||
[0, 0], | ||
[0, 1], | ||
[0.25, 1], | ||
[0.25, 0], | ||
[0.5, 0], | ||
[0.5, 1], | ||
[1, 1], | ||
[1, 0], | ||
[0, 0] | ||
] | ||
] | ||
coordinates: featureCoordinates | ||
} | ||
}; | ||
var featureKinks = kinks(feature); | ||
t.ok(featureKinks, 'get self-intersection when vertex hits another side'); | ||
t.equal(featureKinks.features.length, 4); | ||
t.deepEqual(featureKinks, { | ||
type: 'FeatureCollection', | ||
features: [ | ||
{ geometry: { coordinates: [ 0.25, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.5, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.25, 0 ], type: 'Point' }, properties: {}, type: 'Feature' }, | ||
{ geometry: { coordinates: [ 0.5, 0 ], type: 'Point' }, properties: {}, type: 'Feature' } | ||
] | ||
}); | ||
var featurePolygonKinks = kinks(featurePolygon); | ||
t.ok(featurePolygonKinks, 'get self-intersection when vertex hits another side in a polygon'); | ||
t.equal(featurePolygonKinks.features.length, 4); | ||
t.deepEqual(featurePolygonKinks, expected); | ||
t.end(); | ||
}); |
19693
514
Updated@turf/helpers@^3.7.5