Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue #1075 #1078

Merged
merged 1 commit into from
Nov 6, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/turf-line-split/index.d.ts
Original file line number Diff line number Diff line change
@@ -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
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';

/**
@@ -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':
@@ -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);
@@ -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];

9 changes: 5 additions & 4 deletions packages/turf-line-split/package.json
Original file line number Diff line number Diff line change
@@ -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"
},
13 changes: 11 additions & 2 deletions packages/turf-line-split/test.js
Original file line number Diff line number Diff line change
@@ -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 '.';

@@ -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) {
@@ -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
@@ -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