Giter Club home page Giter Club logo

cheap-ruler's Introduction

Fork of cheap-ruler, using {latitude, longitude} object for all Point inputs and outputs. Tests are not covered yet, only tested distance method manually. PR for tests would be most welcome.


A collection of very fast approximations to common geodesic measurements. Useful for performance-sensitive code that measures things on a city scale.

The approximations are based on an FCC-approved formula of ellipsoidal Earth projection. For distances under 500 kilometers and not on the poles, the results are very precise — within 0.1% margin of error compared to Vincenti formulas, and usually much less for shorter distances.

Performance

Compared to corresponding Turf methods (using Node v6):

  • distance: ~31x faster
  • bearing: ~3.6x faster
  • destination: ~7.2x faster
  • lineDistance: ~31x faster
  • area: ~3.4x faster
  • along: ~31x faster
  • pointOnLine: ~78x faster
  • lineSlice: ~60x faster

Additional utility methods:

  • lineSliceAlong: ~285x faster than turf.lineSlice(turf.along(...
  • bufferPoint: ~260x faster than creating a bounding box with two diagonal turf.destination calls
  • bufferBBox: ~260x faster (likewise)
  • insideBBox: ~19x faster than turf.inside(turf.point(p), turf.bboxPolygon(bbox))

Usage

var ruler = cheapRuler(35.05, 'miles');
// ...
var distance = ruler.distance([30.51, 50.32], [30.52, 50.312]);
var lineLength = ruler.lineDistance(line.geometry.coordinates);
var bbox = ruler.bufferPoint([30.5, 50.5], 0.01);

Note: to get the full performance benefit, create a ruler object only once per a general area of calculation, and then reuse it as much as possible. Don't create a new ruler for every calculation.

Creating a ruler object

cheapRuler(latitude[, units])

Creates a ruler object that will approximate measurements around the given latitude. Units are one of: kilometers (default), miles, nauticalmiles, meters, yards, feet, inches.

cheapRuler.fromTile(y, z[, units])

Creates a ruler object from tile coordinates (y and z). Convenient in tile-reduce scripts.

var ruler = cheapRuler.fromTile(1567, 12);

Ruler methods

distance(a, b)

Given two points of the form [longitude, latitude], returns the distance.

var distance = ruler.distance([30.5, 50.5], [30.51, 50.49]);

bearing(a, b)

Returns the bearing between two points in angles.

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.

var point = ruler.destination([30.5, 50.5], 0.1, 90);

offset(p, dx, dy)

Returns a new point given easting and northing offsets from the starting point.

var point = ruler.offset([30.5, 50.5], 10, 5); // 10km east and 5km north

lineDistance(line)

Given a line (an array of points), returns the total line distance.

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. Note that it returns the value in the specified units (square kilometers by default) rather than square meters as in turf.area.

var area = ruler.area([[
    [-67.031, 50.458], [-67.031, 50.534], [-66.929, 50.534],
    [-66.929, 50.458], [-67.031, 50.458]
]]);

along(line, dist)

Returns the point at a specified distance along the line.

var point = ruler.along(line, 2.5);

pointOnLine(line, p)

Returns an object of the form {point, index, t}, where point is closest point on the line from the given point, index is the start index of the segment with the closest point, and t is a parameter from 0 to 1 that indicates where the closest point is on that segment.

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).

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.

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.

var bbox = ruler.bufferPoint([30.5, 50.5], 0.01);

bufferBBox(bbox, buffer)

Given a bounding box, returns the box buffered by a given distance.

var bbox = ruler.bufferBBox([30.5, 50.5, 31, 51], 0.2);

insideBBox(p, bbox)

Returns true if the given point is inside in the given bounding box, otherwise false.

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

Units conversion

Multipliers for converting between units are also exposed in cheapRuler.units:

// convert 50 meters to yards
50 * cheapRuler.units.yards / cheapRuler.units.meters;

If you don't specify units when creating a ruler object, you can use these constants to convert return values (using multiplication) and input arguments (using division) to any units:

// get distance between points in feet
var distanceInFeet = ruler.distance(a, b) * cheapRuler.units.feet;

// make a bbox from a point with a 200 inch buffer
var box = ruler.bufferPoint(p, 200 / cheapRuler.units.inches);

Install

Precision

A table that shows the margin of error for ruler.distance compared to node-vincenty (a state of the art distance formula):

lat 10° 20° 30° 40° 50° 60° 70° 80°
1km 0% 0% 0% 0% 0% 0% 0% 0% 0%
100km 0% 0% 0% 0% 0% 0% 0.01% 0.01% 0.04%
500km 0% 0% 0% 0.01% 0.02% 0.04% 0.08% 0.2% 0.83%
1000km 0% 0% 0.02% 0.04% 0.07% 0.15% 0.31% 0.78% 3.36%

Errors for all other methods are similar.

Related

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.