Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

cheap-ruler

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cheap-ruler - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

bench/bench-inside-bbox.js

29

bench/bench-along.js
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -11,4 +11,2 @@ var cheapRuler = require('../');

var suite = new Benchmark.Suite();
var distances = lines.map(function (line) {

@@ -18,16 +16,13 @@ return ruler.lineDistance(line);

suite
.add('turf.along', function () {
for (var i = 0; i < lines.length; i++) {
turf.along(turf.linestring(lines[i]), distances[i], 'kilometers');
runBench({
'turf.along': function () {
for (var i = 0; i < lines.length; i++) {
turf.along(turf.linestring(lines[i]), distances[i], 'kilometers');
}
},
'ruler.along': function () {
for (var i = 0; i < lines.length; i++) {
ruler.along(lines[i], distances[i]);
}
}
})
.add('ruler.along', function () {
for (var i = 0; i < lines.length; i++) {
ruler.along(lines[i], distances[i]);
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -11,4 +11,2 @@ var cheapRuler = require('../');

var suite = new Benchmark.Suite();
var polygons = [];

@@ -22,16 +20,13 @@

suite
.add('turf.area', function () {
for (var i = 0; i < polygons.length; i++) {
turf.area(turf.polygon(polygons[i]));
runBench({
'turf.area': function () {
for (var i = 0; i < polygons.length; i++) {
turf.area(turf.polygon(polygons[i]));
}
},
'ruler.area': function () {
for (var i = 0; i < polygons.length; i++) {
ruler.area(polygons[i]);
}
}
})
.add('ruler.area', function () {
for (var i = 0; i < polygons.length; i++) {
ruler.area(polygons[i]);
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -8,27 +8,17 @@ var cheapRuler = require('../');

var lines = require('../test/fixtures/lines.json');
var points = Array.prototype.concat.apply([], lines);
var ruler = cheapRuler(32.8351);
var suite = new Benchmark.Suite();
suite
.add('turf.bearing', function () {
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length - 1; j++) {
turf.bearing(turf.point(lines[i][j]), turf.point(lines[i][j + 1]));
runBench({
'turf.bearing': function () {
for (var i = 0; i < points.length - 1; i++) {
turf.bearing(turf.point(points[i]), turf.point(points[i + 1]));
}
}
})
.add('ruler.bearing', function () {
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length - 1; j++) {
ruler.bearing(lines[i][j], lines[i][j + 1]);
},
'ruler.bearing': function () {
for (var i = 0; i < points.length - 1; i++) {
ruler.bearing(points[i], points[i + 1]);
}
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -8,28 +8,18 @@ var cheapRuler = require('../');

var lines = require('../test/fixtures/lines.json');
var points = Array.prototype.concat.apply([], lines);
var ruler = cheapRuler(32.8351);
var suite = new Benchmark.Suite();
suite
.add('turf.destination-based bbox', function () {
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length; j++) {
bboxBuffer(turf.point(line[j]), 0.01);
runBench({
'turf.destination-based bbox': function () {
for (var i = 0; i < points.length; i++) {
bboxBuffer(turf.point(points[i]), 0.01);
}
}
})
.add('ruler.bufferPoint', function () {
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length; j++) {
ruler.bufferPoint(line[j], 0.01);
},
'ruler.bufferPoint': function () {
for (var i = 0; i < points.length; i++) {
ruler.bufferPoint(points[i], 0.01);
}
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});

@@ -36,0 +26,0 @@ function bboxBuffer(pt, distance) {

'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -8,31 +8,17 @@ var cheapRuler = require('../');

var lines = require('../test/fixtures/lines.json');
var points = Array.prototype.concat.apply([], lines);
var ruler = cheapRuler(32.8351);
var suite = new Benchmark.Suite();
suite
.add('turf.destination', function () {
var k = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length; j++) {
k++;
turf.destination(turf.point(lines[i][j]), 1, (k % 360) - 180, 'kilometers');
runBench({
'turf.destination': function () {
for (var i = 0; i < points.length; i++) {
turf.destination(turf.point(points[i]), 1, (i % 360) - 180, 'kilometers');
}
}
})
.add('ruler.destination', function () {
var k = 0;
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
for (var j = 0; j < line.length; j++) {
k++;
ruler.destination(lines[i][j], 1, (k % 360) - 180);
},
'ruler.destination': function () {
for (var i = 0; i < points.length; i++) {
ruler.destination(points[i], 1, (i % 360) - 180);
}
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -11,18 +11,13 @@ var cheapRuler = require('../');

var suite = new Benchmark.Suite();
suite
.add('turf.lineDistance', function () {
for (var i = 0; i < lines.length; i++) {
turf.lineDistance(turf.linestring(lines[i]));
runBench({
'turf.lineDistance': function () {
for (var i = 0; i < lines.length; i++) {
turf.lineDistance(turf.linestring(lines[i]));
}
},
'ruler.lineDistance': function () {
for (var i = 0; i < lines.length; i++) {
ruler.lineDistance(lines[i]);
}
}
})
.add('ruler.lineDistance', function () {
for (var i = 0; i < lines.length; i++) {
ruler.lineDistance(lines[i]);
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -11,4 +11,2 @@ var cheapRuler = require('../');

var suite = new Benchmark.Suite();
var endpoints = lines.map(function (line) {

@@ -22,19 +20,16 @@ var dist = ruler.lineDistance(line);

suite
.add('turf.lineSlice', function () {
for (var i = 0; i < lines.length; i++) {
turf.lineSlice(
turf.point(endpoints[i].start),
turf.point(endpoints[i].stop),
turf.linestring(lines[i]));
runBench({
'turf.lineSlice': function () {
for (var i = 0; i < lines.length; i++) {
turf.lineSlice(
turf.point(endpoints[i].start),
turf.point(endpoints[i].stop),
turf.linestring(lines[i]));
}
},
'ruler.lineSlice': function () {
for (var i = 0; i < lines.length; i++) {
ruler.lineSlice(endpoints[i].start, endpoints[i].stop, lines[i]);
}
}
})
.add('ruler.lineSlice', function () {
for (var i = 0; i < lines.length; i++) {
ruler.lineSlice(endpoints[i].start, endpoints[i].stop, lines[i]);
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});
'use strict';
var Benchmark = require('benchmark');
var runBench = require('./bench-run.js');

@@ -12,18 +12,13 @@ var cheapRuler = require('../');

var suite = new Benchmark.Suite();
suite
.add('turf.pointOnLine', function () {
for (var i = 0; i < lines.length; i++) {
turf.pointOnLine(turf.linestring(lines[i]), turf.point(p));
runBench({
'turf.pointOnLine': function () {
for (var i = 0; i < lines.length; i++) {
turf.pointOnLine(turf.linestring(lines[i]), turf.point(p));
}
},
'ruler.pointOnLine': function () {
for (var i = 0; i < lines.length; i++) {
ruler.pointOnLine(lines[i], p);
}
}
})
.add('ruler.pointOnLine', function () {
for (var i = 0; i < lines.length; i++) {
ruler.pointOnLine(lines[i], p);
}
})
.on('cycle', function (event) {
console.log(String(event.target));
})
.run();
});

@@ -33,2 +33,20 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cheapRuler = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){

bearing: function (a, b) {
var dx = (b[0] - a[0]) * this.e;
var dy = b[1] - a[1];
if (!dx && !dy) return 0;
var bearing = Math.atan2(-dy, dx) * 180 / Math.PI + 90;
if (bearing > 180) bearing -= 360;
return bearing;
},
destination: function (p, dist, bearing) {
var a = (90 - bearing) * Math.PI / 180;
var d = dist / this.d;
return [
p[0] + d * Math.cos(a) / this.e,
p[1] + d * Math.sin(a)
];
},
lineDistance: function (points) {

@@ -56,38 +74,16 @@ var total = 0;

bearing: function (a, b) {
var dx = (b[0] - a[0]) * this.e;
var dy = b[1] - a[1];
if (!dx && !dy) return 0;
var bearing = Math.atan2(-dy, dx) * 180 / Math.PI + 90;
if (bearing > 180) bearing -= 360;
return bearing;
},
along: function (line, dist) {
var sum = 0;
bufferPoint: function (p, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
p[0] - h,
p[1] - v,
p[0] + h,
p[1] + v
];
},
if (dist <= 0) return line[0];
bufferBBox: function (bbox, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
bbox[0] - h,
bbox[1] - v,
bbox[2] + h,
bbox[3] + v
];
},
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 > dist) return interpolate(p0, p1, (dist - (sum - d)) / d);
}
insideBBox: function (p, bbox) {
return p[0] >= bbox[0] &&
p[0] <= bbox[2] &&
p[1] >= bbox[1] &&
p[1] <= bbox[3];
return line[line.length - 1];
},

@@ -168,36 +164,55 @@

along: function (line, dist) {
lineSliceAlong: function (start, stop, line) {
var sum = 0;
var slice = [];
if (dist <= 0) return line[0];
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];
if (sum > start && slice.length === 0) {
slice.push(interpolate(p0, p1, (start - (sum - d)) / d));
}
return [
p0[0] + dx * t,
p0[1] + dy * t
];
if (sum >= stop) {
slice.push(interpolate(p0, p1, (stop - (sum - d)) / d));
return slice;
}
if (sum > start) slice.push(p1);
}
return line[line.length - 1];
return slice;
},
destination: function (p, dist, bearing) {
var a = (90 - bearing) * Math.PI / 180;
var d = dist / this.d;
bufferPoint: function (p, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
p[0] + d * Math.cos(a) / this.e,
p[1] + d * Math.sin(a)
p[0] - h,
p[1] - v,
p[0] + h,
p[1] + v
];
},
bufferBBox: function (bbox, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
bbox[0] - h,
bbox[1] - v,
bbox[2] + h,
bbox[3] + v
];
},
insideBBox: function (p, bbox) {
return p[0] >= bbox[0] &&
p[0] <= bbox[2] &&
p[1] >= bbox[1] &&
p[1] <= bbox[3];
}

@@ -210,3 +225,12 @@ };

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
];
}
},{}]},{},[1])(1)
});

@@ -5,22 +5,36 @@ 'use strict';

var turf = require('turf');
var vincenty = require('node-vincenty');
var p = [-96.914526,32.836763];
var ruler = createRuler(32.83);
process.stdout.write('| lat | ');
var p2 = ruler.destination(p, 1, 90);
for (var lat = 0; lat <= 80; lat += 10) {
process.stdout.write(lat + '&deg; | ');
}
// console.log(ruler.distance(p, p2));
process.stdout.write('\n| --- | ');
for (var lat = 0; lat <= 80; lat += 10) process.stdout.write(' --- |');
process.stdout.write('\n');
console.log(JSON.stringify(turf.featurecollection([
turf.point(p, {start: true}),
turf.point(p2, {stop: true, color: 'red'})
])));
var distances = [1, 100, 1000, 5000];
// var turfSlice = turf.lineSlice(turf.point(start), turf.point(stop), turf.linestring(line)).geometry.coordinates;
for (var i = 0; i < distances.length; i++) {
var dist = distances[i];
process.stdout.write('| ' + dist + 'km | ');
// console.log(JSON.stringify(turf.featurecollection([
// turf.linestring(line),
// turf.point(start, {start: true}),
// turf.point(stop, {stop: true}),
// turf.linestring(slice, {slice: true, stroke: 'red'})
// ])));
for (var lat = 0; lat <= 80; lat += 10) {
var ruler = createRuler(lat);
var p1 = ruler.destination([0, lat], dist / 2, 90);
var p2 = ruler.destination([0, lat], dist / 2, 90 - 180);
var d = ruler.distance(p1, p2);
var d2 = turf.distance(turf.point(p1), turf.point(p2));
// var d2 = vincenty.distVincenty(p1[1], p1[0], p2[1], p2[0]).distance / 1000;
var err = Math.abs((d - d2) / d2);
var errStr = (Math.round(100 * 1e2 * err) / 1e2) + '%';
process.stdout.write(errStr + ' | ');
// console.log('distance: %dkm, latitude: %d, error: %d%', dist, lat, errStr);
}
process.stdout.write('\n');
}

@@ -32,2 +32,20 @@ 'use strict';

bearing: function (a, b) {
var dx = (b[0] - a[0]) * this.e;
var dy = b[1] - a[1];
if (!dx && !dy) return 0;
var bearing = Math.atan2(-dy, dx) * 180 / Math.PI + 90;
if (bearing > 180) bearing -= 360;
return bearing;
},
destination: function (p, dist, bearing) {
var a = (90 - bearing) * Math.PI / 180;
var d = dist / this.d;
return [
p[0] + d * Math.cos(a) / this.e,
p[1] + d * Math.sin(a)
];
},
lineDistance: function (points) {

@@ -55,38 +73,16 @@ var total = 0;

bearing: function (a, b) {
var dx = (b[0] - a[0]) * this.e;
var dy = b[1] - a[1];
if (!dx && !dy) return 0;
var bearing = Math.atan2(-dy, dx) * 180 / Math.PI + 90;
if (bearing > 180) bearing -= 360;
return bearing;
},
along: function (line, dist) {
var sum = 0;
bufferPoint: function (p, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
p[0] - h,
p[1] - v,
p[0] + h,
p[1] + v
];
},
if (dist <= 0) return line[0];
bufferBBox: function (bbox, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
bbox[0] - h,
bbox[1] - v,
bbox[2] + h,
bbox[3] + v
];
},
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 > dist) return interpolate(p0, p1, (dist - (sum - d)) / d);
}
insideBBox: function (p, bbox) {
return p[0] >= bbox[0] &&
p[0] <= bbox[2] &&
p[1] >= bbox[1] &&
p[1] <= bbox[3];
return line[line.length - 1];
},

@@ -167,36 +163,55 @@

along: function (line, dist) {
lineSliceAlong: function (start, stop, line) {
var sum = 0;
var slice = [];
if (dist <= 0) return line[0];
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];
if (sum > start && slice.length === 0) {
slice.push(interpolate(p0, p1, (start - (sum - d)) / d));
}
return [
p0[0] + dx * t,
p0[1] + dy * t
];
if (sum >= stop) {
slice.push(interpolate(p0, p1, (stop - (sum - d)) / d));
return slice;
}
if (sum > start) slice.push(p1);
}
return line[line.length - 1];
return slice;
},
destination: function (p, dist, bearing) {
var a = (90 - bearing) * Math.PI / 180;
var d = dist / this.d;
bufferPoint: function (p, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
p[0] + d * Math.cos(a) / this.e,
p[1] + d * Math.sin(a)
p[0] - h,
p[1] - v,
p[0] + h,
p[1] + v
];
},
bufferBBox: function (bbox, buffer) {
var v = buffer / this.d;
var h = v / this.e;
return [
bbox[0] - h,
bbox[1] - v,
bbox[2] + h,
bbox[3] + v
];
},
insideBBox: function (p, bbox) {
return p[0] >= bbox[0] &&
p[0] <= bbox[2] &&
p[1] >= bbox[1] &&
p[1] <= bbox[3];
}

@@ -208,1 +223,10 @@ };

}
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
];
}
{
"name": "cheap-ruler",
"version": "2.0.0",
"version": "2.1.0",
"description": "A collection of fast approximations to common geographic measurements.",

@@ -12,2 +12,3 @@ "main": "index.js",

"eslint-config-mourner": "^2.0.1",
"istanbul": "^0.4.3",
"tape": "^4.5.1",

@@ -20,3 +21,4 @@ "turf": "^2.0.2"

"build": "browserify index.js -s cheapRuler > cheap-ruler.js",
"prepublish": "npm run build"
"prepublish": "npm run build",
"cov": "istanbul cover tape test/test.js"
},

@@ -23,0 +25,0 @@ "eslintConfig": {

@@ -7,2 +7,25 @@ # cheap-ruler [![Build Status](https://travis-ci.org/mapbox/cheap-ruler.svg?branch=master)](https://travis-ci.org/mapbox/cheap-ruler)

For distances under a hundred miles and not on the poles,
the results are [typically within 0.1%](#precision) of corresponding Turf functions.
## Performance
Compared to corresponding Turf methods (using Node v5.10):
- `distance`: ~26x faster
- `bearing`: ~3.5x faster
- `destination`: ~6.4x faster
- `lineDistance`: ~26x faster
- `area`: ~3.6x faster
- `along`: ~21x faster
- `pointOnLine`: ~72x faster
- `lineSlice`: ~56x faster
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))`
## Usage

@@ -18,5 +41,2 @@

For a city scale (a few dozen miles) and far away from poles,
the results are typically within 0.1% of corresponding Turf functions.
**Note**: to get the full performance benefit, create the ruler object once per an area of calculation (such as a tile), and then reuse it as much as possible.

@@ -43,14 +63,39 @@

Given two points of the form `[x, y]`, returns the distance.
20–25 times faster than `turf.distance`.
Given two points of the form `[longitude, latitude]`, returns the distance.
```js
var distance = ruler.distance([30.5, 50.5], [30.51, 50.49]);
```
#### bearing(a, b)
Returns the bearing between two points in angles.
```js
var bearing = ruler.bearing([30.5, 50.5], [30.51, 50.49]);
```
#### destination(p, dist, bearing)
Returns a new point given distance and bearing from the starting point.
```js
var point = ruler.destination([30.5, 50.5], 0.1, 90);
```
#### lineDistance(line)
Given a line (an array of points), returns the total line distance.
20–25 times faster than `turf.lineDistance`.
```js
var length = ruler.lineDistance([
[-67.031, 50.458], [-67.031, 50.534],
[-66.929, 50.534], [-66.929, 50.458]
]);
```
#### area(polygon)
Given a polygon (an array of rings, where each ring is an array of points), returns the area.
3–4 times faster than `turf.area`. Note that it returns the value in the specified units
Note that it returns the value in the specified units
(square kilometers by default) rather than square meters as in `turf.area`.

@@ -60,25 +105,15 @@

var area = ruler.area([[
[-67.031, 50.458],
[-67.031, 50.534],
[-66.929, 50.534],
[-66.929, 50.458],
[-67.031, 50.458]
[-67.031, 50.458], [-67.031, 50.534], [-66.929, 50.534],
[-66.929, 50.458], [-67.031, 50.458]
]]);
```
#### bearing(a, b)
Returns the bearing between two points in angles.
3–4 times faster than `turf.bearing`.
#### along(line, dist)
Returns the point at a specified distance along the line.
20-25 times faster than `turf.along`.
#### destination(p, dist, bearing)
```js
var point = ruler.along(line, 2.5);
```
Returns a new point given distance and bearing from the starting point.
6–7 times faster than `turf.destination`.
#### pointOnLine(line, p)

@@ -88,13 +123,26 @@

and `index` is the start index of the segment with the closest point.
70–75 times faster than `turf.pointOnLine`.
```js
var point = ruler.pointOnLine(line, [-67.04, 50.5]).point;
```
#### lineSlice(start, stop, line)
Returns a part of the given line between the start and the stop points (or their closest points on the line).
50–60 times faster than `turf.lineSlice`.
```js
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)
Given a point, returns a bounding box object (`[w, s, e, n]`) created from the given point buffered by a given distance.
About _200 times faster_ than creating a bounding box with two diagonal `turf.destination` calls.

@@ -109,2 +157,6 @@ ```js

```js
var bbox = ruler.bufferBBox([30.5, 50.5, 31, 51], 0.2);
```
#### insideBBox(p, bbox)

@@ -114,2 +166,6 @@

```js
var inside = ruler.insideBBox([30.5, 50.5], [30, 50, 31, 51]);
```
## Install

@@ -119,1 +175,21 @@

- Browser build (CDN): https://npmcdn.com/cheap-ruler@1.3.0/cheap-ruler.js
## Precision
A table that shows the margin of error for `ruler.distance` compared to `turf.distance`:
| lat | 0&deg; | 10&deg; | 20&deg; | 30&deg; | 40&deg; | 50&deg; | 60&deg; | 70&deg; | 80&deg; |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1km | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% |
| 100km | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.08% | 0.09% | 0.11% |
| 1000km | 0.11% | 0.11% | 0.12% | 0.14% | 0.18% | 0.25% | 0.42% | 0.89% | 3.48% |
The same table for a much more precise Vincenty distance formula (using `node-vincenty` module):
| lat | 0&deg; | 10&deg; | 20&deg; | 30&deg; | 40&deg; | 50&deg; | 60&deg; | 70&deg; | 80&deg; |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 1km | 0.34% | 0.32% | 0.26% | 0.17% | 0.06% | 0.06% | 0.17% | 0.26% | 0.31% |
| 100km | 0.34% | 0.32% | 0.26% | 0.17% | 0.06% | 0.06% | 0.16% | 0.25% | 0.28% |
| 1000km | 0.36% | 0.34% | 0.3% | 0.23% | 0.16% | 0.11% | 0.17% | 0.55% | 3.08% |
Errors for all other methods are similar.

@@ -18,2 +18,9 @@ 'use strict';

test('cheapRuler constructor', function (t) {
t.throws(function () {
createRuler();
}, 'errors without latitude');
t.end();
});
test('distance', function (t) {

@@ -29,2 +36,24 @@ for (var i = 0; i < points.length - 1; i++) {

test('bearing', function (t) {
for (var i = 0; i < points.length - 1; i++) {
var expected = turf.bearing(turf.point(points[i]), turf.point(points[i + 1]));
var actual = ruler.bearing(points[i], points[i + 1]);
assertErr(t, expected, actual, 0.0001, 'bearing');
}
t.pass('bearing within 0.01%');
t.end();
});
test('destination', function (t) {
for (var i = 0; i < points.length; i++) {
var bearing = (i % 360) - 180;
var expected = turf.destination(turf.point(points[i]), 1.0, bearing, 'kilometers').geometry.coordinates;
var actual = ruler.destination(points[i], 1.0, bearing);
assertErr(t, expected[0], actual[0], 3e-7, 'destination longitude');
assertErr(t, expected[1], actual[1], 3e-7, 'destination latitude');
}
t.pass('destination within 3e-7');
t.end();
});
test('lineDistance', function (t) {

@@ -40,2 +69,14 @@ for (var i = 0; i < lines.length; i++) {

test('area', function (t) {
for (var i = 0; i < lines.length; i++) {
if (lines[i].length < 3) continue;
var poly = turf.polygon([lines[i].concat([lines[i][0]])]);
var expected = turf.area(poly) / 1e6;
var actual = ruler.area([lines[i]]);
assertErr(t, expected, actual, 0.0002, 'area');
}
t.pass('area within 0.02%');
t.end();
});
test('along', function (t) {

@@ -54,2 +95,20 @@ for (var i = 0; i < lines.length; i++) {

test('along with dist <= 0', function (t) {
t.same(ruler.along(lines[0], -5), lines[0][0], 'first point');
t.end();
});
test('along with dist > length', function (t) {
t.same(ruler.along(lines[0], 1000), lines[0][lines[0].length - 1], 'last point');
t.end();
});
test('pointOnLine', function (t) {
// not Turf comparison because pointOnLine is bugged https://github.com/Turfjs/turf/issues/344
var line = [[-77.031669, 38.878605], [-77.029609, 38.881946]];
var p = ruler.pointOnLine(line, [-77.034076, 38.882017]).point;
t.same(p, [-77.03051972665213, 38.88046894284234], 'pointOnLine');
t.end();
});
test('lineSlice', function (t) {

@@ -74,33 +133,28 @@ for (var i = 0; i < lines.length; i++) {

test('area', function (t) {
test('lineSliceAlong', function (t) {
for (var i = 0; i < lines.length; i++) {
if (lines[i].length < 3) continue;
var poly = turf.polygon([lines[i].concat([lines[i][0]])]);
var expected = turf.area(poly) / 1e6;
var actual = ruler.area([lines[i]]);
assertErr(t, expected, actual, 0.0002, 'area');
}
t.pass('area within 0.02%');
t.end();
});
if (i === 46) continue; // skip due to Turf bug https://github.com/Turfjs/turf/issues/351
test('bearing', function (t) {
for (var i = 0; i < points.length - 1; i++) {
var expected = turf.bearing(turf.point(points[i]), turf.point(points[i + 1]));
var actual = ruler.bearing(points[i], points[i + 1]);
assertErr(t, expected, actual, 0.0001, 'bearing');
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('bearing within 0.01%');
t.pass('lineSliceAlong length within 0.1%');
t.end();
});
test('destination', function (t) {
for (var i = 0; i < points.length; i++) {
var bearing = (i % 360) - 180;
var expected = turf.destination(turf.point(points[i]), 1.0, bearing, 'kilometers').geometry.coordinates;
var actual = ruler.destination(points[i], 1.0, bearing);
assertErr(t, expected[0], actual[0], 3e-7, 'destination longitude');
assertErr(t, expected[1], actual[1], 3e-7, 'destination latitude');
}
t.pass('destination within 3e-7');
test('lineSlice reverse', function (t) {
var line = lines[0];
var dist = ruler.lineDistance(line);
var start = ruler.along(line, dist * 0.7);
var stop = ruler.along(line, dist * 0.3);
var actual = ruler.lineDistance(ruler.lineSlice(start, stop, line));
t.equal(actual, 0.018665535420681036, 'lineSlice reversed length');
t.end();

@@ -122,10 +176,28 @@ });

test('pointOnLine', function (t) {
// not Turf comparison because pointOnLine is bugged https://github.com/Turfjs/turf/issues/344
var line = [[-77.031669, 38.878605], [-77.029609, 38.881946]];
var p = ruler.pointOnLine(line, [-77.034076, 38.882017]).point;
t.same(p, [-77.03051972665213, 38.88046894284234]);
test('bufferBBox', function (t) {
var bbox = [30, 38, 40, 39];
var bbox2 = ruler.bufferBBox(bbox, 1);
t.same(bbox2, [29.989308794440007, 37.991016879283826, 40.01069120555999, 39.008983120716174], 'bufferBBox');
t.end();
});
test('insideBBox', function (t) {
var bbox = [30, 38, 40, 39];
t.ok(ruler.insideBBox([35, 38.5], bbox), 'insideBBox inside');
t.notOk(ruler.insideBBox([45, 45], bbox), 'insideBBox outside');
t.end();
});
test('cheapRuler.fromTile', function (t) {
var ruler1 = createRuler(50.5);
var ruler2 = createRuler.fromTile(11041, 15);
var p1 = [30.5, 50.5];
var p2 = [30.51, 50.51];
assertErr(t, ruler1.distance(p1, p2), ruler2.distance(p1, p2), 2e-5, 'cheapRuler.fromTile distance');
t.end();
});
function turfPointBuffer(p, distance) {

@@ -132,0 +204,0 @@ var dist = Math.sqrt(2) * distance;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc