Skip to content

Commit

Permalink
Merge pull request #1078 from Turfjs/issue-#1075
Browse files Browse the repository at this point in the history
Fix issue #1075
  • Loading branch information
DenisCarriere authored Nov 6, 2017
2 parents 4f5df51 + a454883 commit c8bbb90
Show file tree
Hide file tree
Showing 17 changed files with 532 additions and 41 deletions.
2 changes: 1 addition & 1 deletion packages/turf-line-split/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
MultiPolygon,
} from '@turf/helpers';

export type Splitter = Feature<Point|MultiPoint|LineString|MultiLineString|Polygon|MultiPolygon>
export type Splitter = Feature<Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon>

/**
* http://turfjs.org/docs/#linesplit
Expand Down
46 changes: 27 additions & 19 deletions packages/turf-line-split/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import rbush from 'geojson-rbush';
import flatten from '@turf/flatten';
import square from '@turf/square';
import bbox from '@turf/bbox';
import truncate from '@turf/truncate';
import lineSegment from '@turf/line-segment';
import nearestPointOnLine from '@turf/nearest-point-on-line';
import lineIntersect from '@turf/line-intersect';
import nearestPointOnLine from '@turf/nearest-point-on-line';
import { getCoords, getType } from '@turf/invariant';
import { featureEach, featureReduce} from '@turf/meta';
import { featureEach, featureReduce, flattenEach} from '@turf/meta';
import { lineString, featureCollection } from '@turf/helpers';

/**
Expand Down Expand Up @@ -43,7 +44,7 @@ function lineSplit(line, splitter) {
case 'Point':
return splitLineWithPoint(line, truncatedSplitter);
case 'MultiPoint':
return splitLineWithPoints(line, flatten(truncatedSplitter));
return splitLineWithPoints(line, truncatedSplitter);
case 'LineString':
case 'MultiLineString':
case 'Polygon':
Expand All @@ -64,33 +65,40 @@ function splitLineWithPoints(line, splitter) {
var results = [];
var tree = rbush();

featureEach(splitter, function (point) {
flattenEach(splitter, function (point) {
// Add index/id to features (needed for filter)
results.forEach(function (feature, index) {
feature.id = index;
});
// First Point - doesn't need to handle any previous line results
if (!results.length) {
results = splitLineWithPoint(line, point).features;

// Add Square BBox to each feature for GeoJSON-RBush
results.forEach(function (feature) {
if (!feature.bbox) feature.bbox = square(bbox(feature));
});
tree.load(featureCollection(results));
// Split with remaining points - lines might needed to be split multiple times
} else {
// Find all lines that are within the splitter's bbox
var search = tree.search(point);

// RBush might return multiple lines - only process the closest line to splitter
var closestLine = findClosestFeature(point, search);

// Remove closest line from results since this will be split into two lines
// This removes any duplicates inside the results & index
results = results.filter(function (feature) { return feature.id !== closestLine.id; });
tree.remove(closestLine);

// Append the two newly split lines into the results
featureEach(splitLineWithPoint(closestLine, point), function (line) {
results.push(line);
tree.insert(line);
});
if (search.features.length) {
// RBush might return multiple lines - only process the closest line to splitter
var closestLine = findClosestFeature(point, search);

// Remove closest line from results since this will be split into two lines
// This removes any duplicates inside the results & index
results = results.filter(function (feature) { return feature.id !== closestLine.id; });
tree.remove(closestLine);

// Append the two newly split lines into the results
featureEach(splitLineWithPoint(closestLine, point), function (line) {
results.push(line);
tree.insert(line);
});
}
}
});
return featureCollection(results);
Expand Down Expand Up @@ -164,7 +172,7 @@ function splitLineWithPoint(line, splitter) {
* @returns {Feature<LineString>} closest LineString
*/
function findClosestFeature(point, lines) {
if (!lines.features) throw new Error('<lines> must contain features');
if (!lines.features.length) throw new Error('lines must contain features');
// Filter to one segment that is the closest to the line
if (lines.features.length === 1) return lines.features[0];

Expand Down
9 changes: 5 additions & 4 deletions packages/turf-line-split/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,22 @@
},
"homepage": "https://github.com/Turfjs/turf",
"devDependencies": {
"@std/esm": "*",
"benchmark": "*",
"load-json-file": "*",
"tape": "*",
"write-json-file": "*",
"rollup": "*",
"@std/esm": "*"
"tape": "*",
"write-json-file": "*"
},
"dependencies": {
"@turf/flatten": "*",
"@turf/bbox": "*",
"@turf/helpers": "5.x",
"@turf/invariant": "5.x",
"@turf/line-intersect": "5.x",
"@turf/line-segment": "5.x",
"@turf/meta": "5.x",
"@turf/nearest-point-on-line": "5.x",
"@turf/square": "*",
"@turf/truncate": "5.x",
"geojson-rbush": "2.1.0"
},
Expand Down
13 changes: 11 additions & 2 deletions packages/turf-line-split/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'path';
import load from 'load-json-file';
import write from 'write-json-file';
import { featureEach } from '@turf/meta';
import { point, lineString, featureCollection, round } from '@turf/helpers';
import { point, lineString, multiPoint, featureCollection, round } from '@turf/helpers';
import { getCoords } from '@turf/invariant';
import lineSplit from '.';

Expand All @@ -13,13 +13,14 @@ const directories = {
out: path.join(__dirname, 'test', 'out') + path.sep
};

const fixtures = fs.readdirSync(directories.in).map(filename => {
let fixtures = fs.readdirSync(directories.in).map(filename => {
return {
filename,
name: path.parse(filename).name,
geojson: load.sync(directories.in + filename)
};
});
// fixtures = fixtures.filter(name => name === 'issue-#1075')

test('turf-line-split', t => {
for (const {filename, name, geojson} of fixtures) {
Expand Down Expand Up @@ -107,6 +108,13 @@ test('turf-line-split -- prevent input mutation', t => {
t.end();
});

test('turf-line-split -- issue #1075', t => {
const line = lineString([[-87.168433, 37.946093], [-87.168510, 37.960085]]);
const splitter = multiPoint([[-87.168446, 37.947929], [-87.168445, 37.948301]]);
const split = lineSplit(line, splitter);
t.assert(split);
t.end();
})

/**
* Colorize FeatureCollection
Expand All @@ -128,3 +136,4 @@ function colorize(geojson) {
});
return featureCollection(results);
}

24 changes: 24 additions & 0 deletions packages/turf-line-split/test/in/issue-#1075-1.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [[-87.168433, 37.946093], [-87.168510, 37.960085]]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-87.168446, 37.947929],
[-87.168445, 37.948301]
]
}
}
]
}
24 changes: 24 additions & 0 deletions packages/turf-line-split/test/in/issue-#1075-2.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [[-87.168433, 37.946093], [-87.168510, 37.960085]]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-87.1684431695,37.9479287543],
[-87.1684451512,37.9483010091]
]
}
}
]
}
24 changes: 24 additions & 0 deletions packages/turf-line-split/test/in/issue-#1075-3.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [[-87.168433, 37.946093], [-87.168510, 37.960085]]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-87.1684431695,37.9479287543],
[-87.161, 37.948]
]
}
}
]
}
93 changes: 93 additions & 0 deletions packages/turf-line-split/test/out/issue-#1075-1.geojson
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"stroke": "#F00",
"stroke-width": 10
},
"geometry": {
"type": "LineString",
"coordinates": [
[
-87.168433,
37.946093
],
[
-87.168446,
37.947929
]
]
},
"bbox": [
-87.1693575,
37.946093,
-87.1675215,
37.947929
],
"id": 0
},
{
"type": "Feature",
"properties": {
"stroke": "#00F",
"stroke-width": 10
},
"geometry": {
"type": "LineString",
"coordinates": [
[
-87.168446,
37.947929
],
[
-87.16851,
37.960085
]
]
},
"bbox": [
-87.174556,
37.947929,
-87.16239999999999,
37.960085
],
"id": 1
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[
-87.168433,
37.946093
],
[
-87.16851,
37.960085
]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-87.168446,
37.947929
],
[
-87.168445,
37.948301
]
]
}
}
]
}
Loading

0 comments on commit c8bbb90

Please sign in to comment.