Git Product home page Git Product logo

geolib's Introduction

Geolib

Library to provide basic geospatial operations like distance calculation, conversion of decimal coordinates to sexagesimal and vice versa, etc. This library is currently 2D, meaning that altitude/elevation is not yet supported by any of its functions!

CircleCI styled with prettier

Changelog

A detailed changelog can be found in CHANGELOG.md

Install

npm install geolib
yarn add geolib

Usage

There is a UMD build and an ES Module build. You can either use the UMD build in Node like any other library:

const geolib = require('geolib');

or in the browser by using a simple script element:

<script src="lib/geolib.js"></script>

If you load it in the browser, you can access all the functions via window.geolib.

If you're working with a bundler (like Webpack or Parcel) or have an environment that supports ES Modules natively, you can either import certain functions from the package directly:

import { getDistance } from 'geolib';

or load the whole library:

import * as geolib from 'geolib';

or you can import single functions directly to potentially make use of treeshaking (recommended):

import getDistance from 'geolib/es/getDistance';

General

This library is written in TypeScript. You don't have to know TypeScript to use Geolib but the type definitions give you valuable information about the general usage, input parameters etc.

Supported values and formats

All methods that are working with coordinates accept either an object with a lat/latitude and a lon/lng/longitude property, or a GeoJSON coordinates array, like: [lon, lat]. All values can be either in decimal (53.471) or sexagesimal (53° 21' 16") format.

Distance values are always floats and represent the distance in meters.

Functions

getDistance(start, end, accuracy = 1)

Calculates the distance between two geo coordinates.

This function takes up to 3 arguments. First 2 arguments must be valid GeolibInputCoordinates (e.g. {latitude: 52.518611, longitude: 13.408056}). Coordinates can be in sexagesimal or decimal format. The third argument is accuracy (in meters). By default the accuracy is 1 meter. If you need a more accurate result, you can set it to a lower value, e.g. to 0.01 for centimeter accuracy. You can set it higher to have the result rounded to the next value that is divisible by your chosen accuracy (e.g. 25428 with an accuracy of 100 becomes 25400).

getDistance(
    { latitude: 51.5103, longitude: 7.49347 },
    { latitude: "51° 31' N", longitude: "7° 28' E" }
);
// Working with W3C Geolocation API
navigator.geolocation.getCurrentPosition(
    (position) => {
        console.log(
            'You are ',
            geolib.getDistance(position.coords, {
                latitude: 51.525,
                longitude: 7.4575,
            }),
            'meters away from 51.525, 7.4575'
        );
    },
    () => {
        alert('Position could not be determined.');
    }
);

Returns the distance in meters as a numeric value.

getPreciseDistance(start, end, accuracy = 1)

Calculates the distance between two geo coordinates. This method is more accurate then getDistance, especially for long distances but it is also slower. It is using the Vincenty inverse formula for ellipsoids.

It takes the same (up to 3) arguments as getDistance.

geolib.getPreciseDistance(
    { latitude: 51.5103, longitude: 7.49347 },
    { latitude: "51° 31' N", longitude: "7° 28' E" }
);

getCenter(coords)

Calculates the geographical center of all points in a collection of geo coordinates. Takes an array of coordinates and calculates the center of it.

geolib.getCenter([
    { latitude: 52.516272, longitude: 13.377722 },
    { latitude: 51.515, longitude: 7.453619 },
    { latitude: 51.503333, longitude: -0.119722 },
]);

Returns an object:

{
    "latitude": centerLat,
    "longitude": centerLon
}

getCenterOfBounds(coords)

Calculates the center of the bounds of geo coordinates.

Takes an array of coordinates, calculate the border of those, and gives back the center of that rectangle.

On polygons like political borders (eg. states), this may gives a closer result to human expectation, than getCenter, because that function can be disturbed by uneven distribution of point in different sides.

Imagine the US state Oklahoma: getCenter on that gives a southern point, because the southern border contains a lot more nodes, than the others.

geolib.getCenterOfBounds([
    { latitude: 51.513357512, longitude: 7.45574331 },
    { latitude: 51.515400598, longitude: 7.45518541 },
    { latitude: 51.516241842, longitude: 7.456494328 },
    { latitude: 51.516722545, longitude: 7.459863183 },
    { latitude: 51.517443592, longitude: 7.463232037 },
]);

Returns an object:

{
    "latitude": centerLat,
    "longitude": centerLng
}

getBounds(points)

Calculates the bounds of geo coordinates.

geolib.getBounds([
    { latitude: 52.516272, longitude: 13.377722 },
    { latitude: 51.515, longitude: 7.453619 },
    { latitude: 51.503333, longitude: -0.119722 },
]);

It returns minimum and maximum latitude and minimum and maximum longitude as an object:

{
    "minLat": minimumLatitude,
    "maxLat": maximumLatitude,
    "minLng": minimumLongitude,
    "maxLng": maximumLongitude,
}

isPointInPolygon(point, polygon)

Checks whether a point is inside of a polygon or not.

geolib.isPointInPolygon({ latitude: 51.5125, longitude: 7.485 }, [
    { latitude: 51.5, longitude: 7.4 },
    { latitude: 51.555, longitude: 7.4 },
    { latitude: 51.555, longitude: 7.625 },
    { latitude: 51.5125, longitude: 7.625 },
]);

Returns true or false

isPointWithinRadius(point, centerPoint, radius)

Checks whether a point is inside of a circle or not.

// checks if 51.525/7.4575 is within a radius of 5 km from 51.5175/7.4678
geolib.isPointWithinRadius(
    { latitude: 51.525, longitude: 7.4575 },
    { latitude: 51.5175, longitude: 7.4678 },
    5000
);

Returns true or false

getRhumbLineBearing(origin, destination)

Gets rhumb line bearing of two points. Find out about the difference between rhumb line and great circle bearing on Wikipedia. Rhumb line should be fine in most cases:

http://en.wikipedia.org/wiki/Rhumb_line#General_and_mathematical_description

Function is heavily based on Doug Vanderweide's great PHP version (licensed under GPL 3.0) http://www.dougv.com/2009/07/13/calculating-the-bearing-and-compass-rose-direction-between-two-latitude-longitude-coordinates-in-php/

geolib.getRhumbLineBearing(
    { latitude: 52.518611, longitude: 13.408056 },
    { latitude: 51.519475, longitude: 7.46694444 }
);

Returns calculated bearing as number.

getGreatCircleBearing(origin, destination)

Gets great circle bearing of two points. This is more accurate than rhumb line bearing but also slower.

geolib.getGreatCircleBearing(
    { latitude: 52.518611, longitude: 13.408056 },
    { latitude: 51.519475, longitude: 7.46694444 }
);

Returns calculated bearing as number.

getCompassDirection(origin, destination, bearingFunction = getRhumbLineBearing)

Gets the compass direction from an origin coordinate to a destination coordinate. Optionally a function to determine the bearing can be passed as third parameter. Default is getRhumbLineBearing.

geolib.getCompassDirection(
    { latitude: 52.518611, longitude: 13.408056 },
    { latitude: 51.519475, longitude: 7.46694444 }
);

Returns the direction (e.g. NNE, SW, E, …) as string.

orderByDistance(point, arrayOfPoints)

Sorts an array of coords by distance to a reference coordinate.

geolib.orderByDistance({ latitude: 51.515, longitude: 7.453619 }, [
    { latitude: 52.516272, longitude: 13.377722 },
    { latitude: 51.518, longitude: 7.45425 },
    { latitude: 51.503333, longitude: -0.119722 },
]);

Returns an array of points ordered by their distance to the reference point.

findNearest(point, arrayOfPoints)

Finds the single one nearest point to a reference coordinate. It's actually just a convenience method that uses orderByDistance under the hood and returns the first result.

geolib.findNearest({ latitude: 52.456221, longitude: 12.63128 }, [
    { latitude: 52.516272, longitude: 13.377722 },
    { latitude: 51.515, longitude: 7.453619 },
    { latitude: 51.503333, longitude: -0.119722 },
    { latitude: 55.751667, longitude: 37.617778 },
    { latitude: 48.8583, longitude: 2.2945 },
    { latitude: 59.3275, longitude: 18.0675 },
    { latitude: 59.916911, longitude: 10.727567 },
]);

Returns the point nearest to the reference point.

getPathLength(points, distanceFunction = getDistance)

Calculates the length of a collection of coordinates. Expects an array of points as first argument and optionally a function to determine the distance as second argument. Default is getDistance.

geolib.getPathLength([
    { latitude: 52.516272, longitude: 13.377722 },
    { latitude: 51.515, longitude: 7.453619 },
    { latitude: 51.503333, longitude: -0.119722 },
]);

Returns the length of the path in meters as number.

getDistanceFromLine(point, lineStart, lineEnd, accuracy = 1)

Gets the minimum distance from a point to a line of two points.

geolib.getDistanceFromLine(
    { latitude: 51.516, longitude: 7.456 },
    { latitude: 51.512, longitude: 7.456 },
    { latitude: 51.516, longitude: 7.459 }
);

Returns the shortest distance to the given line as number.

Note: if all points are too close together the function might return NaN. In this case it usually helps to slightly increase the accuracy (e.g. 0.01).

getBoundsOfDistance(point, distance)

Computes the bounding coordinates of all points on the surface of the earth less than or equal to the specified great circle distance.

geolib.getBoundsOfDistance(
    { latitude: 34.090166, longitude: -118.276736555556 },
    1000
);

Returns an array with the southwestern and northeastern coordinates.

isPointInLine(point, lineStart, lineEnd)

Calculates if given point lies in a line formed by start and end.

geolib.isPointInLine(
    { latitude: 0, longitude: 10 },
    { latitude: 0, longitude: 0 },
    { latitude: 0, longitude: 15 }
);

sexagesimalToDecimal(value)

Converts a sexagesimal coordinate into decimal format

geolib.sexagesimalToDecimal(`51° 29' 46" N`);

Returns the new value as decimal number.

decimalToSexagesimal(value)

Converts a decimal coordinate to sexagesimal format

geolib.decimalToSexagesimal(51.49611111); // -> 51° 29' 46`

Returns the new value as sexagesimal string.

geolib.getLatitude(point, raw = false)

geolib.getLongitude(point, raw = false)

Returns the latitude/longitude for a given point and converts it to decimal. If the second argument is set to true it does not convert the value to decimal.

geolib.getLatitude({ lat: 51.49611, lng: 7.38896 }); // -> 51.49611
geolib.getLongitude({ lat: 51.49611, lng: 7.38896 }); // -> 7.38896

Returns the value as decimal or in its original format if the second argument was set to true.

toDecimal(point)

Checks if a coordinate is already in decimal format and, if not, converts it to. Works with single values (e.g. 51° 32' 17") and complete coordinates (e.g. {lat: 1, lon: 1}) as long as it in a supported format.

geolib.toDecimal(`51° 29' 46" N`); // -> 51.59611111
geolib.toDecimal(51.59611111); // -> 51.59611111

Returns a decimal value for the given input value.

computeDestinationPoint(point, distance, bearing, radius = earthRadius)

Computes the destination point given an initial point, a distance (in meters) and a bearing (in degrees). If no radius is given it defaults to the mean earth radius of 6,371,000 meters.

Attention: this formula is not 100% accurate (but very close though).

geolib.computeDestinationPoint(
    { latitude: 52.518611, longitude: 13.408056 },
    15000,
    180
);
geolib.computeDestinationPoint(
    [13.408056, 52.518611]
    15000,
    180
);

Returns the destination in the same format as the input coordinates. So if you pass a GeoJSON point, you will get a GeoJSON point.

getAreaOfPolygon(points)

Calculates the surface area of a polygon.

geolib.getAreaOfPolygon([
    [7.453635617650258, 51.49320556213869],
    [7.454583481047989, 51.49328893754685],
    [7.454778172179346, 51.49240881084831],
    [7.453832678225655, 51.49231619246726],
    [7.453635617650258, 51.49320556213869],
]);

Returns the result as number in square meters.

getCoordinateKeys(point)

Gets the property names of that are used in the point in a normalized form:

geolib.getCoordinateKeys({ lat: 1, lon: 1 });
// -> { latitude: 'lat', longitude: 'lon' }

Returns an object with a latitude and a longitude property. Their values are the property names for latitude and longitude that are used in the passed point. Should probably only be used internally.

getCoordinateKey(point, keysToLookup)

Is used by getCoordinateKeys under the hood and returns the property name out of a list of possible names.

geolib.getCoordinateKey({ latitude: 1, longitude: 2 }, ['lat', 'latitude']);
// -> latitude

Returns the name of the property as string or undefined if no there was no match.

isValidCoordinate(point)

Checks if a given point has at least a latitude and a longitude and is in a supported format.

// true:
geolib.isValidCoordinate({ latitude: 1, longitude: 2 });

// false, longitude is missing:
geolib.isValidCoordinate({ latitude: 1 });

// true, GeoJSON format:
geolib.isValidCoordinate([2, 1]);

Returns true or false.

getSpeed(startPointWithTime, endPointWithTime)

Calculates the speed between two points within a given time span.

geolib.getSpeed(
    { latitude: 51.567294, longitude: 7.38896, time: 1360231200880 },
    { latitude: 52.54944, longitude: 13.468509, time: 1360245600880 }
);

Return the speed in meters per second as number.

convertSpeed(value, unit)

Converts the result from getSpeed into a more human friendly format. Currently available units are mph and kmh.

Units

unit can be one of:

  • kmh (kilometers per hour)
  • mph (miles per hour)
geolib.convertSpeed(29.8678, 'kmh');

Returns the converted value as number.

convertDistance(value, unit)

Converts a given distance (in meters) into another unit.

Units

unit can be one of:

  • m (meter)
  • km (kilometers)
  • cm (centimeters)
  • mm (millimeters)
  • mi (miles)
  • sm (seamiles)
  • ft (feet)
  • in (inches)
  • yd (yards)
geolib.convertDistance(14200, 'km'); // 14.2
geolib.convertDistance(500, 'km'); // 0.5

Returns the converted distance as number.

convertArea(value, unit)

Converts the result from getAreaForPolygon into a different unit.

Units

unit can be one of:

  • m2, sqm (square meters)
  • km2, sqkm (square kilometers)
  • ha (hectares)
  • a (ares)
  • ft2, sqft (square feet)
  • yd2, sqyd (square yards)
  • in2, sqin (square inches)
geolib.convertArea(298678, 'km2'));

Returns the converted area as number.

wktToPolygon(wkt)

Converts the Well-known text (a.k.a WKT) to polygon that Geolib understands. https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry#Geometric_Objects

geolib.wktToPolygon('POLYGON ((30 10.54321, 40 40, 20 40, 10 20, 30 10))');
// [
//     { latitude: 10.54321, longitude: 30 },
//     { latitude: 40, longitude: 40 },
//     { latitude: 40, longitude: 20 },
//     { latitude: 20, longitude: 10 },
//     { latitude: 10, longitude: 30 },}
// ]

Returns the array of coordinates.

Breaking Changes in 3.0.0 and migration from 2.x.x

In version 3.0.0 I'm trying to get a little bit back to the roots. Geolib was once started because I needed a handful of methods to perform very specific geo related tasks like getting the distance or the direction between two points. Since it was one of the very first libraries on npm back then to do these kind of things in a very simple way it became very popular (with more than 300k downloads per month as of April 2019!) and as a consequence got a lot of contributions over the years. Many of which I just merged as long as they had accompanying tests, without looking at consistency, conventions, complexity, coding style or even the overall quality of the functions that I sometimes didn't even fully understand.

I have now cleaned up the codebase completely, rebuilt the entire library "from scratch", unified all the function arguments, removed a few functions where I wasn't sure if they should be in here (feel free to add them back of you're using them!) or if they were even used (did a few searches on GitHub for the function names, turned out there are zero results).

Elevation support was dropped, as well as a few functions that unnecessarily made the library really large in size (e.g. isPointInsideRobust alone was over 700[!] lines of code and was basically taken from a different library).

I removed Grunt from the build process, added "modern" tools like ESLint and Prettier. I switched from Travis CI to Circle CI and I am in the process of further automating the release process of new versions using semantic-release and conventional-commits. I also switched from pure JavaScript to TypeScript because I think it does have some benefits.

  • All functions are pure functions now. No input data is mutated anymore. You give the same input, you get the same output. No side effects or whatsoever.
  • I changed the default getDistance function from being the slow, accurate one to being the fast, slightly inaccurate one. The old getDistance function is now named getPreciseDistance while the old getDistanceSimple function is now the default getDistance function. You can, however, pass getPreciseDistance as argument to any function that uses distance calculation internally.
  • Artificial limitation to 8 decimal places in decimal coordinates was removed
  • getBoundsOfDistance() now returns the exact coordinates due to the removal of the artificial 8 decimal place limitation
  • getCompassDirection() does no longer return an object with an exact and a rough direction but only the exact direction as string
  • third argument to getCompassDirection() is no longer a string ("circle", "line") but a function to determine the bearing (you can pass getRhumbLineBearing or getGreatCircleBearing). The function receives the origin and the destination as first and second argument. If no 3rd argument was given, getRhumbLineBearing(origin, dest) is used by default.
  • There is now a new helper function roughCompassDirection(exact) if you really only need a very rough (and potentially inaccurate or inappropriate) direction. Better don't use it.
  • orderByDistance() does no longer modify its input so does not add a distance and key property to the returned coordinates.
  • The result of getSpeed() is now always returned as meters per second. It can be converted using the new convenience function convertSpeed(mps, targetUnit)
  • Relevant value (usually point or distance) is now consistently the first argument for each function (it wasn't before, how confusing is that?)
  • findNearest() does no longer take offset and limit arguments. It's only a convenience method to get the single one nearest point from a set of coordinates. If you need more than one, have a look at the implementation and implement your own logic using orderByDistance
  • Whereever distances are involved, they are returned as meters or meters per second. No more inconsistent defaults like kilometers or kilometers per hour.
  • The method how sexagesimal is formatted differs a little bit. It may now potentially return ugly float point units like 52° 46' 21.0004" in rare cases but it is also more accurate than it was before.
  • Dropped support for Meteor (feel free to add it back if you like)

✅ Functions with the same name

  • computeDestinationPoint
  • getBounds
  • getBoundsOfDistance
  • getCenter
  • getCenterOfBounds
  • getCompassDirection
  • getDistanceFromLine
  • getPathLength
  • getRhumbLineBearing
  • getSpeed
  • isDecimal
  • isPointInLine
  • isPointNearLine
  • isSexagesimal
  • orderByDistance

❗ Renamed functions

  • getKeys renamed to getCoordinateKeys
  • validate renamed to isValidCoordinate
  • getLat renamed to getLatitude
  • getLon renamed to getLongitude
  • latitude -> renamed to getLatitude
  • longitude -> renamed to getLongitude
  • convertUnit -> remamed to convertDistance, because name was too ambiguous
  • useDecimal renamed to toDecimal
  • decimal2sexagesimal renamed to decimalToSexagesimal
  • sexagesimal2decimal renamed to sexagesimalToDecimal
  • getDistance renamed to getPreciseDistance
  • getDistanceSimple renamed to getDistance
  • isPointInside renamed to isPointInPolygon
  • isPointInCircle renamed to isPointWithinRadius
  • getBearing renamed to getGreatCircleBearing to be more explicit

🗑 Removed functions

  • getElev -> removed
  • elevation -> removed
  • coords -> removed (might be re-added as getCoordinate or getNormalizedCoordinate)
  • ll -> removed (because wtf?)
  • preparePolygonForIsPointInsideOptimized -> removed due to missing documentation and missing tests
  • isPointInsideWithPreparedPolygon -> removed due to missing documentation
  • isInside alias -> removed (too ambiguous) - use isPointInPolygon or isPointWithinRadius
  • withinRadius -> removed, use isPointWithinRadius
  • getDirection alias -> removed (unnecessary clutter) - use getCompassDirection

🆕 Added functions

  • getAreaOfPolygon to calculate the area of a polygon
  • getCoordinateKey to get a property name (e.g. lat or lng of an object based on an array of possible names)

geolib's People

Contributors

airportyh avatar andarist avatar anuragagarwal561994 avatar captainanderman avatar chucre avatar climbsrocks avatar ddarren avatar dependabot[bot] avatar emanueleliardo avatar feasul avatar gilmoreorless avatar jfrux avatar jhsu avatar linusu avatar manuelbieh avatar mateusppereira avatar maximepeabody avatar mightyiam avatar miklosme avatar missinglink avatar mmai avatar outatime avatar paulcapron avatar rdbenoit avatar regality avatar semantic-release-bot avatar stevelacey avatar sylvainlap avatar timvahlbrock avatar tylereich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

geolib's Issues

Sub-meter accuracy in getDistance?

Is there a way to achieve sub-meter accuracy? I'm pretty sure the raw distance has more resolution than meters before rounding. Thanks!

Document undocumented functions

Hi,

I was looking for a js geo library that could also calc bearing and direction. At first your (great!) lib didn't seem to do that until I took a closer look at the example page. Seems it can indeed do so as I also found in the src file (getRhumbLineBearing, getBearing, getDirection, etc).

I would recommend documenting this so even more people will be finding a great solution in your lib!

isPointInside

var geolib = require('geolib');

var polygon = [
{latitude: -46, longitude: 1},
{latitude: -46, longitude: 2},
{latitude: -47, longitude: 2},
{latitude: -47, longitude: 1}
];
console.log(geolib.isPointInside({ latitude:-46, longitude:1}, polygon)) // --> false
console.log(geolib.isPointInside({ latitude:-46, longitude:2}, polygon)) // --> false
console.log(geolib.isPointInside({ latitude:-47, longitude:2}, polygon)) // --> false
console.log(geolib.isPointInside({ latitude:-47, longitude:1}, polygon)) // --> true

why get different result?

qunit tests fail

From a fresh checkout, npm install; npm test gives the following error:

Running "qunit" task

Running "qunit:files" (qunit) task
Verifying property qunit.files exists in config...OK

Testing geolib.test.html

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:980:11)
    at Process.ChildProcess._handle.onexit (child_process.js:771:34)
npm ERR! weird error 8
npm ERR! not ok code 0

Calculated distance, then show and order

Why isn't the following working:

<input type="number" id="distance" value="10">
<input type="text" id="userLatitude" value="52.880709">
<input type="text" id="userLongitude" value="5.4560155">
<button id="search">go</button>
$(document).on('click', '#search', function(){

    var userLatitude    = $('#userLatitude').val();
    var userLongitude   = $('#userLongitude').val();
    var user = { latitude: userLatitude, longitude: userLongitude };

    var distance = parseInt($('#distance').val()) * 100;

    console.log(distance);
 $('.user').hide();
    $('.user').each(function(index, value) { 
        var talent = $(this).data('talent');

        var lat = $(this).data('latitude');
        var lng = $(this).data('longitude');

        var current = { latitude: lat, longitude: lng };

        var calculated = geolib.isPointInCircle(
            current, 
            user,
            distance
        );  

        if(calculated){
            $(this).show();
        }

        console.log(calculated);

    });

    return false;

});

How to order this all by Distance? So the closest one shows first.

TypeError: Cannot read property 'hasOwnProperty' of null

When using with AngularJS
shows a NullPointerException at 116 geolib.js

                // TODO: check if point is an object
                if(typeof point != 'object' ) {

changed to " if(typeof point != 'object' || point == null) {" and it works just fine

geolib object is empty within Meteor server code?

cc'ing @dandv

This could be a big misunderstanding on my part - I am still pretty new to Meteor. I am running Meteor 1.2 and have added geolib to my project via meteor add. I can successfully access a global geolib object in my client code, but I was hoping to use it on my server with some large sets of location data - is that possible? I've tried using it in multiple ways - inside the Meteor.startup hook, inside of Meteor.methods, and geolib always shows up as an empty object {}.

Let me know if I should try anything in particular or import it in any special way, or if it simply isn't possible!

orderByDistance

Hello, I'm having a list of items. It are div's with a data-lat="1234" and data-lng="1234". How can I make use of orderByDistance, that it'll order all items by distance?

request: travel a distance

Say I wanted to get, roughly, a 30km by 30km square around a given lat/long, how would I do this?

Something like geolib.travel(lat, long, 30, 'km', degrees) where degrees is a number between 0 and 359.9999, and indicates the direction of travel..

Calculate distance beetween point and line

It would be great if we had something like that:
distanceToLine(point, lineStart, lineEnd) //returns distance in meters to nearest point of the line.

BTW thx for your GeoLib!!!

isPointInside clarification

The readme file states for the isPointInside method that the polygon coords must be in correct order!

Can you please clarify what the 'correct' order is and how can I check if my coords are in the correct order.

Using the Coordinates object from the geolocation API causes an error

It would be nice if it was possible to use the Coordinates object returned by the geolocation API.

But since the getKey function has this requirement:

return point.hasOwnProperty(val) ? (function() { key = val; return false; }()) : true;

And the Coordinates latitude & longitude is in the prototype, I get:

Cannot read property 'latitude' of undefined 

When trying to calculate a distance.

Currently I'm just using:

{
   'latitude':position.coords.latitude,
   'longitude':position.coords.longitude
};

But it would just be nicer if I could use the object as it were. Anyways - great library. Thanks

Python equivalent to this lib?

This lib is superb. Hands down it's super indepth but digestable, easily!

👍

Is there a python equivalent to something this powerful?

Thanks for your works!

So many times it returns.. throw new Error('Unknown format.');

/**
                * Checks if a value is in decimal format or, if neccessary, converts to decimal
                *
                * @param        mixed       Value to be checked/converted
                * @return       float       Coordinate in decimal format
                */
        useDecimal: function(value) {

            value = value.toString().replace(/\s*/, '');

            // looks silly but works as expected
            // checks if value is in decimal format
            if (!isNaN(parseFloat(value)) && parseFloat(value) == value) {
                return parseFloat(value);
                // checks if it's sexagesimal format (HHH° MM' SS" (NESW))
            } else if (geolib.isSexagesimal(value) === true) {
                return parseFloat(geolib.sexagesimal2decimal(value));
            } else {
                throw new Error('Unknown format.');
            }

        },

orderByDistance -return the sorted array

Why does the function orderByDistance return a new array with a different shape to the original?

Convention says this method should return an array with the same contents as the source but sorted by distance.

npm install failing with version 2.0.7

Seems like something happened with the latest commit because I can install previous versions but 2.0.7 fails. Did it not get updated properly in the repository?

about keyword 'this'

var geolib = require('geolib');

geolib.getDistance(
{latitude: 51.5103, longitude: 7.49347},
{latitude: "51° 31' N", longitude: "7° 28' E"}
);

// when
var warper = geolib.getDistance
warper(
{latitude: 51.5103, longitude: 7.49347},
{latitude: "51° 31' N", longitude: "7° 28' E"}
);

// throw

// TypeError: Cannot read property 'coords' of undefined
// at geolib.extend.getDistance (\geolib\node_modules\geolib\dist\geolib.js:229:16)
// at Object. (
\geolib\test.js:10:1)
// at Module._compile (module.js:460:26)
// at Object.Module._extensions..js (module.js:478:10)
// at Module.load (module.js:355:32)
// at Function.Module._load (module.js:310:12)
// at Function.Module.runMain (module.js:501:10)
// at startup (node.js:129:16)
// at node.js:814:3

Polygon overlap

Are there any plans to add a function that checks if two polygons overlap?

getCenter() does not support object as param

Hi,

first of all, you did a great job with this lib.
Thank you!

To get to the problem:
Either your doc describes the function incorrect or your implementation lacks of this functionality.
You say in your docs that it is possible to give the function an object as param. In the docs it is:

var spots = {
    "Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
    "Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
    "London Eye": {latitude: 51.503333, longitude: -0.119722},
    "Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
    "Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
    "Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
    "Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
}
geolib.getCenter(spots);

When I execute exactly this code I get returned "false".
A look in your geolib.js shows that you even don't support objects:

getCenter: function(coords) {

            if (!coords.length) {
                return false;
            }

            var X = 0.0;
            var Y = 0.0;
...

Documentation Mistake

The docs say that getPathLength() returns distance in KM but the result is in Meters for me. Is that a mistake in the docs?

Add to Bower?

Hey, loving your library, would you mind adding it to Bower?

http://twitter.github.com/bower/

All you need to do is run this command in your project root:

bower register geolib git://github.com/manuelbieh/Geolib

Then it should be possible to install with:

bower install geolib

Bower should use your package.json to find the right file to download, but if you want to get more specific you could add this component.json file to the root of your project:

{
  "name": "geolib",
  "version": "x",
  "main": "./geolib.js"
}

Cheers.

hasOwnProperty in getKeys causing undefined values

On line 110 of geolib.js the lookup of the latitude, longitude and elevation fields on the point object is currently the following:

return point.hasOwnProperty(val) ? (function() { key = val; return false; }()) : true;

The issue I'm seeing is for some object that are created by frameworks (loopback for instance), the fields are set on the prototype and not the object itself. hasOwnProperty does not check the prototype values, and as such I'm seeing undefined exceptions being thrown when the json debugging output looks fine.

I have done a local test and changed the line to the following:

return val in point ? (function() { key = val; return false; }()) : true;

The in keyword returns the proper fields and everything works as expected.

Return bearing/angle/heading in getDistance method

When the distance is returned in getDistance method, is it possible to also return the bearing between the two points?

I would like to say that Point 1 is 500 meters northwest of Point 2, with "northwest" being the information I want. The library could simply return the angle as an integer between 0 and 360, inclusive, and I could write my own script to correlate the angle as a string direction.

Method to calculate bearing between points

I implemented a method to calculate bearing between points which could be useful. Should we add this?

// From http://www.movable-type.co.uk/scripts/latlong.html
var bearingFromPoints = function (pointA, pointB) {
var lat1 = pointA.latitude;
var lon1 = pointA.longitude;
var lat2 = pointB.latitude;
var lon2 = pointB.longitude;

// var dLat = (lat2-lat1).toRad();  // unused
var dLon = (lon2-lon1).toRad();

var y = Math.sin(dLon) * Math.cos(lat2);
var x = Math.cos(lat1)*Math.sin(lat2) - Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
var brng = Math.atan2(y, x).toDeg();
return brng;

};

computeDestinationPoint is not in npm

Hi

thank you for this great library.

However, when I install geolib via npm the function computeDestinationPoint is not implemented. The same when I try to install it from github.
I have version 2.0.18 installed, any idea why this function is not there?

Andries

isPointInside fails on polygon that transits the anti-meridian

isPointInside does not appear to work correctly when the polygon straddles the anti-meridian.
I maintain a system with lots of polygons that do straddle the antimeridian (I'm in Australia :-) so it's important to me.

see the test code below that illustrates the problem when it's run:

var geolib = require('geolib');

// -------------
// Test 1 This succeeds
// -------------
var polygon = [
    {latitude: -46, longitude: 1},
    {latitude: -46, longitude: 2},
    {latitude: -47, longitude: 2},
    {latitude: -47, longitude: 1}
];
console.log('Test 1: Polygon:',polygon);
console.log('should be true', geolib.isPointInside({ latitude:-46.5, longitude:1.5}, polygon))
console.log('should be false', geolib.isPointInside({ latitude:-47.9, longitude:1.2}, polygon))
console.log('should be true', geolib.isPointInside({ latitude:-46.8, longitude:1.1}, polygon))
console.log('------------');

// -------------
// Test 2 This succeeds
// -------------
var polygon = [
    {latitude: 10, longitude: -10},
    {latitude: 10, longitude: 10},
    {latitude: 20, longitude: 10},
    {latitude: 20, longitude: -10}
];
console.log('Test 2: Polygon:',polygon);
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:-5}, polygon))
console.log('should be false', geolib.isPointInside({ latitude:15, longitude:-15}, polygon))
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:-5}, polygon))

// ----------
// Test 3 : AntiMeridian 1: This fails
// ----------
var polygon = [
    {latitude: 10, longitude: 175},
    {latitude: 10, longitude: -175},
    {latitude: 20, longitude: -175},
    {latitude: 20, longitude: 175}
];
console.log('Test 3: Antimeridian 1: Polygon:',polygon);
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:177}, polygon))
console.log('should be false', geolib.isPointInside({ latitude:15, longitude:-170}, polygon))
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:-176}, polygon))
console.log('------------');

// ----------
// Test 4: Antimeridian 2: This fails
// ----------
var polygon = [
    {latitude: 10, longitude: -175},
    {latitude: 10, longitude: 175},
    {latitude: 20, longitude: 175},
    {latitude: 20, longitude: -175}
];
console.log('Test 4: Antimeridian 2: Polygon:',polygon);
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:177}, polygon))
console.log('should be false', geolib.isPointInside({ latitude:15, longitude:-170}, polygon))
console.log('should be true', geolib.isPointInside({ latitude:15, longitude:-176}, polygon))
console.log('------------');

ReferenceError: geolib is not defined

I'm getting this error when I require geolib:

ReferenceError: geolib is not defined
    at Object.<anonymous> (./node_modules/geolib/geolib.js:818:1)

Moving everything starting at line 810 so it's inside the anonymous function fixes it for me.

prime meridian is broken

geolib.getDistance(
    {latitude: 0, longitude:179.9}, 
    {latitude:0, longitude:1}
);

yeilds 19915057.

geolib.getDistance(
    {latitude: 0, longitude:180}, 
    {latitude:0, longitude:0});

yeilds NaN

geolib.getDistance(
    {latitude: 0, longitude:-1}, 
    {latitude:0, longitude:1});

yeilds 222639

Documentation - lng lat order

From the README.md:

Works with:

  • latitude: latitude, lat, 0 (GeoJSON array)
  • longitude: longitude, lng, lon, 1 (GeoJSON array)

When these functions are called with an array longitude returns the first element and latitude returns the second element.

Missing licence(-note)

I stumbled this library, but unfortunately I do not see any licence-information.
Are you just lacking one because of priority-issues of other tasks or is this intented, so this library is proprietary?

orderByDistance in forEach loop?

I'm doing this now:

$http.get('/locations').success(function(locations) {

    var log = [];
    angular.forEach(locations, function(item, index) {

        var isPointInCircle = geolib.isPointInCircle(
                {latitude: $localStorage.latitude, longitude: $localStorage.longitude},
                {latitude: item.address.latitude, longitude: item.address.longitude},
                (100*1000)
            );

        if(!isPointInCircle)
        {
            locations.splice(index, 1);
        }
    }, log);

    // orderByDistance HOW?

    $scope.locations = locations;
}

But I want the results ordered by Distance.. how?

getCenter fn examples not working

I am using geolib in a project. The getCenter() fn was not working, I followed the source code and was unable to determine why. I then tried running the basic examples from the README in the Chrome console and these returned the same errors I was receiving.

 var spots = {
    "Brandenburg Gate, Berlin": {latitude: 52.516272, longitude: 13.377722},
    "Dortmund U-Tower": {latitude: 51.515, longitude: 7.453619},
    "London Eye": {latitude: 51.503333, longitude: -0.119722},
    "Kremlin, Moscow": {latitude: 55.751667, longitude: 37.617778},
    "Eiffel Tower, Paris": {latitude: 48.8583, longitude: 2.2945},
    "Riksdag building, Stockholm": {latitude: 59.3275, longitude: 18.0675},
    "Royal Palace, Oslo": {latitude: 59.916911, longitude: 10.727567}
}

geolib.getCenter(spots);

returns "false"

geolib.getCenter([
    {latitude: 52.516272, longitude: 13.377722}, 
    {latitude: 51.515, longitude: 7.453619}, 
    {latitude: 51.503333, longitude: -0.119722}
])

throws error Uncaught TypeError: Cannot read property 'latitude' of undefined

isPointInCircle not correct

Hi, I manually tried calculating the circle between two points with: http://www.movable-type.co.uk/scripts/latlong.html
Distance: 19.43 km
But when I'm trying this code:

var user =  geolib.useDecimal({
                    lat: document.getElementById('userLatitude').value,
                    lng: document.getElementById('userLongitude').value
                });

    var distance = parseInt($('#rangeslider').val()) * 1000;
    var current = geolib.useDecimal({
            lat: $(this).data('latitude'),
            lng: $(this).data('longitude')
        });

        var calculated = geolib.isPointInCircle(
            current, 
            user,
            distance
        );  

When input distance is 5 (so 5000), it already tells me the points are in the circle.

Why do polygon coords need to be in correct order?

Hello.

First, this lib is just awesome and i wanna thank you for creating and sharing it!

Now my question, why do coords of the polygon in isPointInside do need to be in the correct order? The reason why i ask is because if i make some points on a piece of paper, there is only one way i can connect the points without a line crossing an other line.

Do they have to be in correct order because the way you wrote the function or do i oversee something and it is technically not possible? I completly understand that it might be much more work and you don`t want or have no time to do it, i am just curious.

Thanks!

convertUnit should ideally do two way conversion

Hi there, feature request here! :)

It would be ideal if convertUnit() would convert other units into meters, instead of just meters into other units.

Reason being, I have an API interface that outputs distances in various desired units, and it should be able to take in distances in other units as well, with my primary logic working in meters.

Thanks for the module!

geolib.useDecimal is broken

If given a string ending with '0', geolib.useDecimal will throw an error due to the wacky checking, since the trailing 0 gets lost on the conversion to a Float and the string comparison does not match.

Example:

require("geolib").useDecimal("1.23450");

getCenter should convert coords if passed as array

getDistance begins with:

var s = this.coords(start);
var e = this.coords(end);

so if the coordinates are passed as [lng, lat] pairs, they will be converted.

Why not doing the same for getCenter? It should also begin with:

coords = coords.map(this.coords);

P.S. The [lng, lat] form is much more common among those who use GeoJson.

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.