Skip to content

Commit

Permalink
Fix duplicate nodes from lineSegment #688 (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisCarriere authored Apr 30, 2017
1 parent 5a8e88b commit 30733ff
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 27 deletions.
19 changes: 10 additions & 9 deletions packages/turf-line-intersect/bench.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const Benchmark = require('benchmark');
const path = require('path');
const fs = require('fs');
const path = require('path');
const load = require('load-json-file');
const Benchmark = require('benchmark');
const lineIntersect = require('./');

const directory = path.join(__dirname, 'test', 'in') + path.sep;
Expand All @@ -16,18 +16,19 @@ const fixtures = fs.readdirSync(directory).map(filename => {
/**
* Benchmark Results
*
* 2-vertex-segment x 7,177,957 ops/sec ±0.83% (92 runs sampled)
* double-intersect x 88,165 ops/sec ±3.02% (78 runs sampled)
* multi-linestring x 19,554 ops/sec ±2.09% (77 runs sampled)
* multi-polygon x 11,149 ops/sec ±2.05% (74 runs sampled)
* same-coordinates x 67,439 ops/sec ±2.01% (73 runs sampled)
* 2-vertex-segment x 4,123,821 ops/sec ±12.92% (74 runs sampled)
* double-intersect x 53,118 ops/sec ±4.22% (72 runs sampled)
* multi-linestring x 16,417 ops/sec ±2.31% (77 runs sampled)
* polygons-with-holes x 9,739 ops/sec ±2.55% (85 runs sampled)
* same-coordinates x 51,303 ops/sec ±4.23% (71 runs sampled)
*/
const suite = new Benchmark.Suite('turf-line-intersect');
for (const {name, geojson} of fixtures) {
suite.add(name, () => lineIntersect(geojson.features[0], geojson.features[1]));
const [line1, line2] = geojson.features;
suite.add(name, () => lineIntersect(line1, line2));
}

suite
.on('cycle', e => { console.log(String(e.target)); })
.on('cycle', e => console.log(String(e.target)))
.on('complete', () => {})
.run();
19 changes: 14 additions & 5 deletions packages/turf-line-intersect/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
var helpers = require('@turf/helpers');
var meta = require('@turf/meta');
var lineSegment = require('@turf/line-segment');
var getCoords = require('@turf/invariant').getCoords;
var rbush = require('geojson-rbush');
var helpers = require('@turf/helpers');
var getCoords = require('@turf/invariant').getCoords;
var lineSegment = require('@turf/line-segment');
var point = helpers.point;
var featureCollection = helpers.featureCollection;
var featureEach = meta.featureEach;
var featureCollection = helpers.featureCollection;

/**
* Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).
Expand Down Expand Up @@ -37,7 +37,9 @@ var featureEach = meta.featureEach;
* var addToMap = [line, line2, intersects]
*/
module.exports = function (line1, line2) {
var unique = {};
var results = [];

// Handles simple 2-vertex segments
if (line1.geometry.type === 'LineString' &&
line2.geometry.type === 'LineString' &&
Expand All @@ -47,13 +49,20 @@ module.exports = function (line1, line2) {
if (intersect) results.push(intersect);
return featureCollection(results);
}

// Handles complex GeoJSON Geometries
var tree = rbush();
tree.load(lineSegment(line2));
featureEach(lineSegment(line1), function (segment) {
featureEach(tree.search(segment), function (match) {
var intersect = intersects(segment, match);
if (intersect) results.push(intersect);
if (intersect) {
var key = getCoords(intersect).join(',');
if (!unique[key]) {
unique[key] = true;
results.push(intersect);
}
}
});
});
return featureCollection(results);
Expand Down
18 changes: 13 additions & 5 deletions packages/turf-line-intersect/test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const test = require('tape');
const fs = require('fs');
const test = require('tape');
const path = require('path');
const load = require('load-json-file');
const write = require('write-json-file');
const featureEach = require('@turf/meta').featureEach;
const featureCollection = require('@turf/helpers').featureCollection;
const truncate = require('@turf/truncate');
const {featureEach} = require('@turf/meta');
const {featureCollection, lineString} = require('@turf/helpers');
const lineIntersect = require('./');

const directories = {
Expand All @@ -23,8 +23,7 @@ const fixtures = fs.readdirSync(directories.in).map(filename => {

test('turf-line-intersect', t => {
for (const {filename, name, geojson} of fixtures) {
const line1 = geojson.features[0];
const line2 = geojson.features[1];
const [line1, line2] = geojson.features;
const points = truncate(lineIntersect(line1, line2));
const results = featureCollection([line1, line2]);
featureEach(points, point => results.features.push(point));
Expand All @@ -34,3 +33,12 @@ test('turf-line-intersect', t => {
}
t.end();
});

test('turf-line-intersect - same point #688', t => {
const line1 = lineString([[7, 50], [8, 50], [9, 50]]);
const line2 = lineString([[8, 49], [8, 50], [8, 51]]);

var results = lineIntersect(line1, line2);
t.equal(results.features.length, 1, 'should return single point');
t.end();
});
16 changes: 11 additions & 5 deletions packages/turf-line-split/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,22 +142,28 @@ function splitLineWithPoint(line, splitter) {
// Initial value is the first point of the first segments (begining of line)
var initialValue = [getCoords(segments.features[0])[0]];
var lastCoords = featureReduce(segments, function (previous, current, index) {
var currentCoords = getCoords(current)[1];
var splitterCoords = getCoords(splitter);

// Location where segment intersects with line
if (index === closestSegment.id) {
var coords = getCoords(splitter);
previous.push(coords);
previous.push(splitterCoords);
results.push(lineString(previous));
return [coords, getCoords(current)[1]];
// Don't duplicate splitter coordinate (Issue #688)
if (splitterCoords[0] === currentCoords[0] &&
splitterCoords[1] === currentCoords[1]) return [splitterCoords];
return [splitterCoords, currentCoords];

// Keep iterating over coords until finished or intersection is found
} else {
previous.push(getCoords(current)[1]);
previous.push(currentCoords);
return previous;
}
}, initialValue);
// Append last line to final split results
results.push(lineString(lastCoords));
if (lastCoords.length > 1) {
results.push(lineString(lastCoords));
}
return featureCollection(results);
}

Expand Down
25 changes: 22 additions & 3 deletions packages/turf-line-split/test.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const test = require('tape');
const fs = require('fs');
const test = require('tape');
const path = require('path');
const load = require('load-json-file');
const write = require('write-json-file');
const featureEach = require('@turf/meta').featureEach;
const featureCollection = require('@turf/helpers').featureCollection;
const {featureEach} = require('@turf/meta');
const {point, lineString, featureCollection} = require('@turf/helpers');
const lineSplit = require('./');

const directories = {
Expand Down Expand Up @@ -33,6 +33,25 @@ test('turf-line-split', t => {
t.end();
});

test('turf-line-split - lines should only contain 2 vertices #688', t => {
const pt = point([8, 50]);
const line = lineString([[7, 50], [8, 50], [9, 50]]);
const [line1, line2] = lineSplit(line, pt).features;

t.deepEqual(line1, lineString([[7, 50], [8, 50]]), 'line1 should have 2 vertices');
t.deepEqual(line2, lineString([[8, 50], [9, 50]]), 'line2 should have 2 vertices');
t.end();
});

test('turf-line-split - splitter exactly on end of line', t => {
const pt = point([9, 50]);
const line = lineString([[7, 50], [8, 50], [9, 50]]);
const features = lineSplit(line, pt).features;

t.deepEqual(features, [line], 'should only contain 1 line of 3 vertices');
t.end();
});

/**
* Colorize FeatureCollection
*
Expand Down

0 comments on commit 30733ff

Please sign in to comment.