Skip to content

Commit

Permalink
Point on line fix (#689)
Browse files Browse the repository at this point in the history
* Replace custom lineIntersects function with @turf/line-intersects, resolves #344

* Fixing missing semi-colon

* Add dynamic outputs for expectedLocation

* Update benchmark

* Add dynamic geojson tests in/out

* Truncate dynamic geojson test/out

* Round precision & dist

* Add test case for #344

* Add between line (helps visualize line between both points)
  • Loading branch information
rowanwins authored and DenisCarriere committed Apr 25, 2017
1 parent d103758 commit 2263a80
Show file tree
Hide file tree
Showing 19 changed files with 68,760 additions and 34,460 deletions.
61 changes: 34 additions & 27 deletions packages/turf-point-on-line/bench.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
var pointOnLine = require('./');
var Benchmark = require('benchmark');
var fs = require('fs');
var point = require('@turf/helpers').point;
const Benchmark = require('benchmark');
const path = require('path');
const fs = require('fs');
const load = require('load-json-file');
const pointOnLine = require('./');

var route1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route1.geojson'));
var route2 = JSON.parse(fs.readFileSync(__dirname + '/test/in/route2.geojson'));
var line1 = JSON.parse(fs.readFileSync(__dirname + '/test/in/line1.geojson'));
const directory = path.join(__dirname, 'test', 'in') + path.sep;
const fixtures = fs.readdirSync(directory).map(filename => {
return {
filename,
name: path.parse(filename).name,
geojson: load.sync(directory + filename)
};
});

var pt1 = point([-97.79617309570312,22.254624939561698]);
var pt2 = point([-79.0850830078125,37.60117623656667]);
var pt3 = point([-112.60660171508789,45.96021963947196]);
/**
* Benchmark Results
*
* ==after (@turf/line-intersect)==
* line1 x 234,231 ops/sec ±1.78% (88 runs sampled)
* route1 x 161 ops/sec ±1.53% (80 runs sampled)
* route2 x 184 ops/sec ±1.96% (80 runs sampled)
*
* ==before (original)==
* line1 x 272,785 ops/sec ±1.29% (87 runs sampled)
* route1 x 195 ops/sec ±2.23% (80 runs sampled)
* route2 x 218 ops/sec ±2.42% (78 runs sampled)
*/
const suite = new Benchmark.Suite('turf-linestring-to-polygon');
for (const {name, geojson} of fixtures) {
const [line, point] = geojson.features;
suite.add(name, () => pointOnLine(line, point));
}

var suite = new Benchmark.Suite('turf-point-on-line');
suite
.add('turf-point-on-line#simple',function () {
pointOnLine(line1, pt1);
})
.add('turf-point-on-line#route1',function () {
pointOnLine(route1, pt2);
})
.add('turf-point-on-line#route2',function () {
pointOnLine(route2, pt3);
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.on('complete', function () {

})
.run();
.on('cycle', e => console.log(String(e.target)))
.on('complete', () => {})
.run();
68 changes: 8 additions & 60 deletions packages/turf-point-on-line/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
var distance = require('@turf/distance');
var point = require('@turf/helpers').point;
var helpers = require('@turf/helpers');
var bearing = require('@turf/bearing');
var destination = require('@turf/destination');

var lineIntersects = require('@turf/line-intersect');
var point = helpers.point;
var lineString = helpers.lineString;
/**
* Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the LineString.
*
Expand Down Expand Up @@ -71,19 +73,10 @@ module.exports = function (line, pt, units) {
var direction = bearing(start, stop);
var perpendicularPt1 = destination(pt, heightDistance, direction + 90, units);
var perpendicularPt2 = destination(pt, heightDistance, direction - 90, units);
var intersect = lineIntersects(
perpendicularPt1.geometry.coordinates[0],
perpendicularPt1.geometry.coordinates[1],
perpendicularPt2.geometry.coordinates[0],
perpendicularPt2.geometry.coordinates[1],
start.geometry.coordinates[0],
start.geometry.coordinates[1],
stop.geometry.coordinates[0],
stop.geometry.coordinates[1]
);
var intersectPt;
if (intersect) {
intersectPt = point(intersect);
var intersect = lineIntersects(lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]), lineString([start.geometry.coordinates, stop.geometry.coordinates]));
var intersectPt = null;
if (intersect.features.length > 0) {
intersectPt = intersect.features[0];
intersectPt.properties.dist = distance(pt, intersectPt, units);
intersectPt.properties.location = length + distance(start, closestPt, units);
}
Expand All @@ -108,48 +101,3 @@ module.exports = function (line, pt, units) {

return closestPt;
};

// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/
function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
// if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
var denominator, a, b, numerator1, numerator2;
var result = {
x: null,
y: null,
onLine1: false,
onLine2: false
};
denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
if (denominator === 0) {
if (result.x !== null && result.y !== null) {
return result;
} else {
return false;
}
}
a = line1StartY - line2StartY;
b = line1StartX - line2StartX;
numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
a = numerator1 / denominator;
b = numerator2 / denominator;

// if we cast these lines infinitely in both directions, they intersect here:
result.x = line1StartX + (a * (line1EndX - line1StartX));
result.y = line1StartY + (a * (line1EndY - line1StartY));

// if line1 is a segment and line2 is infinite, they intersect if:
if (a > 0 && a < 1) {
result.onLine1 = true;
}
// if line2 is a segment and line1 is infinite, they intersect if:
if (b > 0 && b < 1) {
result.onLine2 = true;
}
// if line1 and line2 are segments, they intersect if both of the above are true
if (result.onLine1 && result.onLine2) {
return [result.x, result.y];
} else {
return false;
}
}
13 changes: 8 additions & 5 deletions packages/turf-point-on-line/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,20 @@
},
"homepage": "https://github.com/Turfjs/turf",
"devDependencies": {
"benchmark": "^1.0.0",
"tape": "^3.5.0",
"@turf/along": "^4.1.0",
"@turf/distance": "^4.1.0",
"@turf/helpers": "^4.1.0",
"@turf/line-distance": "^4.1.0"
"@turf/line-distance": "^4.1.0",
"@turf/truncate": "^4.1.0",
"benchmark": "^2.1.4",
"load-json-file": "^2.0.0",
"tape": "^4.6.3",
"write-json-file": "^2.0.0"
},
"dependencies": {
"@turf/bearing": "^4.1.0",
"@turf/destination": "^4.1.0",
"@turf/distance": "^4.1.0",
"@turf/helpers": "^4.1.0"
"@turf/helpers": "^4.1.0",
"@turf/line-intersect": "^4.1.0"
}
}
Loading

0 comments on commit 2263a80

Please sign in to comment.