Skip to content

Commit

Permalink
add lineSliceAlong, close #12
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Apr 24, 2016
1 parent 703c8b5 commit 263851d
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 15 deletions.
11 changes: 10 additions & 1 deletion README.md
Expand Up @@ -22,6 +22,7 @@ Compared to corresponding Turf methods (using Node v5.10):

Additional utility methods:

- `lineSliceAlong`: ~268x faster than `turf.lineSlice(turf.along(...`
- `bufferPoint`: ~210x faster than creating a bounding box with two diagonal `turf.destination` calls
- `bufferBBox`: ~210x faster (likewise)
- `insideBBox`: ~24x faster than `turf.inside(turf.point(p), turf.bboxPolygon(bbox))`
Expand Down Expand Up @@ -125,7 +126,15 @@ var point = ruler.pointOnLine(line, [-67.04, 50.5]).point;
Returns a part of the given line between the start and the stop points (or their closest points on the line).

```js
ruler.pointOnLine([-67.04, 50.5], [-67.05, 50.56], line)
ruler.lineSlice([-67.04, 50.5], [-67.05, 50.56], line);
```

#### lineSliceAlong(startDist, stopDist, line)

Returns a part of the given line between the start and the stop points indicated by distance along the line.

```js
ruler.lineSliceAlong(10, 20, line);
```

#### bufferPoint(p, buffer)
Expand Down
30 changes: 30 additions & 0 deletions bench/bench-line-slice-along.js
@@ -0,0 +1,30 @@
'use strict';

var runBench = require('./bench-run.js');

var cheapRuler = require('../');
var turf = require('turf');
var lines = require('../test/fixtures/lines.json');

var ruler = cheapRuler(32.8351);

var distances = lines.map(function (line) {
return ruler.lineDistance(line);
});

runBench({
'turf.along + turf.lineSlice': function () {
for (var i = 0; i < lines.length; i++) {
var feature = turf.linestring(lines[i]);
turf.lineSlice(
turf.along(feature, distances[i] * 0.3),
turf.along(feature, distances[i] * 0.7),
turf.linestring(lines[i]));
}
},
'ruler.lineSliceAlong': function () {
for (var i = 0; i < lines.length; i++) {
ruler.lineSliceAlong(distances[i] * 0.3, distances[i] * 0.7, lines[i]);
}
}
});
52 changes: 38 additions & 14 deletions index.js
Expand Up @@ -76,21 +76,10 @@ CheapRuler.prototype = {

for (var i = 0; i < line.length - 1; i++) {
var p0 = line[i];
var p = line[i + 1];
var d = this.distance(p0, p);

var p1 = line[i + 1];
var d = this.distance(p0, p1);
sum += d;

if (sum > dist) {
var t = (dist - (sum - d)) / d;
var dx = p[0] - p0[0];
var dy = p[1] - p0[1];

return [
p0[0] + dx * t,
p0[1] + dy * t
];
}
if (sum > dist) return interpolate(p0, p1, (dist - (sum - d)) / d);
}

return line[line.length - 1];
Expand Down Expand Up @@ -169,6 +158,32 @@ CheapRuler.prototype = {
return slice;
},

lineSliceAlong: function (start, stop, line) {
var sum = 0;
var slice = [];

for (var i = 0; i < line.length - 1; i++) {
var p0 = line[i];
var p1 = line[i + 1];
var d = this.distance(p0, p1);

sum += d;

if (sum > start && slice.length === 0) {
slice.push(interpolate(p0, p1, (start - (sum - d)) / d));
}

if (sum >= stop) {
slice.push(interpolate(p0, p1, (stop - (sum - d)) / d));
return slice;
}

if (sum > start) slice.push(p1);
}

return slice;
},

bufferPoint: function (p, buffer) {
var v = buffer / this.d;
var h = v / this.e;
Expand Down Expand Up @@ -202,3 +217,12 @@ CheapRuler.prototype = {
function equals(a, b) {
return a[0] === b[0] && a[1] === b[1];
}

function interpolate(a, b, t) {
var dx = b[0] - a[0];
var dy = b[1] - a[1];
return [
a[0] + dx * t,
a[1] + dy * t
];
}
19 changes: 19 additions & 0 deletions test/test.js
Expand Up @@ -126,6 +126,25 @@ test('lineSlice', function (t) {
t.end();
});

test('lineSliceAlong', function (t) {
for (var i = 0; i < lines.length; i++) {
if (i === 46) continue; // skip due to Turf bug https://github.com/Turfjs/turf/issues/351

var line = lines[i];
var dist = ruler.lineDistance(line);
var start = ruler.along(line, dist * 0.3);
var stop = ruler.along(line, dist * 0.7);

var expected = ruler.lineDistance(turf.lineSlice(
turf.point(start), turf.point(stop), turf.linestring(line)).geometry.coordinates);
var actual = ruler.lineDistance(ruler.lineSliceAlong(dist * 0.3, dist * 0.7, line));

assertErr(t, expected, actual, 0.001, 'lineSliceAlong length');
}
t.pass('lineSliceAlong length within 0.1%');
t.end();
});

test('lineSlice reverse', function (t) {
var line = lines[0];
var dist = ruler.lineDistance(line);
Expand Down

0 comments on commit 263851d

Please sign in to comment.