Giter VIP home page Giter VIP logo

geodesy's Introduction

Geodesy functions

Build Status Coverage Status Documentation

These libraries started life (a long time ago) as simple ‘latitude/longitude’ code fragments covering distances and bearings, intended to help people who had little experience of geodesy, and perhaps limited programming experience.

The intention was to have clear, simple illustrative code samples which could be adapted and re-used in other projects (whether those be coded in JavaScript, Java, C++, Excel VBA, or anything else...). With its untyped C-style syntax, JavaScript reads remarkably close to pseudo-code, exposing the algorithms with a minimum of syntactic distractions

While still valid for that purpose, they have grown since then into considerable libraries, based around:

  • simpler trig-based functions (distance, bearing, etc) based on a spherical earth model
  • more sophisticated trig-based functions (distance, bearing, etc) based on a more accurate ellipsoidal earth model
  • vector-based functions mostly based on a spherical earth model, with some ellipsoidal functions

Complementing these are various mapping-related functions covering:

  • UTM coordinates & MGRS grid references
  • UK Ordnance Survey (OSGB) national grid references

And also functions for historical datum conversions (such as between NAD83, OSGB36, Irl1975, etc) and modern reference frame conversions (such as ITRF2014, ETRF2000, GDA94, etc), and conversions between geodetic (latitude/longitude) coordinates and geocentric cartesian (x/y/z) coordinates.

There are also supporting libraries:

  • 3d vector manipulation functions (supporting cartesian (x/y/z) coordinates and n-vector geodesy)
  • functions for conversion between decimal degrees and (sexagesimal) degrees/minutes/seconds

The spherical-earth model provides simple formulae covering most ‘everyday’ accuracy requirements; the ellipsoidal-earth model provides more accurate formulae at the expense of complexity. The vector-based functions provide an alternative approach to the trig-based functions, with some overlapping functionality; which one to use may depend on availability of related functions or on other considerations.

These functions are as language-agnostic as possible, avoiding excessive use of JavaScript-specific language features which would not be recognised by users of other languages (and which might be difficult to translate to other languages). I use Greek letters in variables representing maths symbols conventionally presented as Greek letters: I value the great benefit in legibility over the minor inconvenience in typing.

This version 2 of the library uses JavaScript ES classes and modules to organise the interdependencies; this makes the code both more immediately readable than previously, and also more accessible to non-JavaScript readers (always bearing in mind JavaScript uses prototype-based classes rather than classical inheritance-based classes). For older browsers (or Node.js <8.0.0), v1.1.3 is ES5-based. Note that there are breaking changes in moving from version 1 to version 2.

While some aspects of the library are quite complex to understand and use, basic usage is simple – for instance:

  • to find the distance between two points using a simple spherical earth model:
import LatLon from 'geodesy/latlon-spherical.js';
const p1 = new LatLon(52.205, 0.119);
const p2 = new LatLon(48.857, 2.351);
const d = p1.distanceTo(p2); // 404.3×10³ m
  • or to find the destination point for a given distance and initial bearing on an ellipsoidal model earth:
import LatLon from 'geodesy/latlon-ellipsoidal-vincenty.js';
const p1 = new LatLon(-37.95103, 144.42487);
const dist = 54972.271;
const brng = 306.86816;
const p2 = p1.destinationPoint(dist, brng); // 37.6528°S, 143.9265°E

Full documentation is available at www.movable-type.co.uk/scripts/geodesy-library.html, and tests in the browser as well as Travis CI.

Usage

While originally intended as illustrative code fragments, these functions can be used ‘as-is’; either client-side in-browser, or with Node.js.

Usage in browser

The library can be used in the browser by taking a local copy, or loading it from jsDelivr: for example,

<!doctype html><title>geodesy example</title><meta charset="utf-8">
<script type="module">
    import LatLon from 'https://cdn.jsdelivr.net/npm/[email protected]/latlon-spherical.min.js';

    const p1 = new LatLon(50.06632, -5.71475);
    const p2 = new LatLon(58.64402, -3.07009);

    const d = p1.distanceTo(p2);
    console.assert(d.toFixed(3) == '968874.704');

    const mid = p1.midpointTo(p2);
    console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 51″ W');
</script>

Usage in Node.js

The library can be loaded from npm to be used in a Node.js app (in Node.js v13.2.0+, or Node.js v12.0.0+ using --experimental-modules, or v8.0.0–v12.15.0*) using the esm package:

$ npm install geodesy
$ node
> const { default: LatLon } = await import('geodesy/latlon-spherical.js');
> const p1 = new LatLon(50.06632, -5.71475);
> const p2 = new LatLon(58.64402, -3.07009);
> const d = p1.distanceTo(p2);
> console.assert(d.toFixed(3) == '968874.704');
> const mid = p1.midpointTo(p2);
> console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 51″ W');

To some extent, mixins can be used to add methods of a class to a different class, e.g.:

import LatLon  from 'geodesy/latlon-nvector-ellipsoidal.js';
import LatLonV from 'geodesy/latlon-ellipsoidal-vincenty.js';

for (const method of Object.getOwnPropertyNames(LatLonV.prototype)) {
    LatLon.prototype[method] = LatLonV.prototype[method];
}

const d = new LatLon(51, 0).distanceTo(new LatLon(52, 1)); // vincenty
const δ = new LatLon(51, 0).deltaTo(new LatLon(52, 1));    // n-vector

More care is of course required if there are conflicting constructors or method names.

For TypeScript users, type definitions are available from DefinitelyTyped: www.npmjs.com/package/@types/geodesy.

Other examples

Some examples of calculations possible with the libraries:

e.g. for geodesic distance on an ellipsoidal model earth using Vincenty’s algorithm:

import LatLon from 'geodesy/latlon-ellipsoidal-vincenty.js';

const p1 = new LatLon(50.06632, -5.71475);
const p2 = new LatLon(58.64402, -3.07009);

const d = p1.distanceTo(p2);
console.assert(d.toFixed(3) == '969954.166');

e.g. for UTM conversions:

import Utm from 'geodesy/utm.js';

const utm = Utm.parse('48 N 377298.745 1483034.794');
const latlon = utm.toLatLon();

console.assert(latlon.toString('dms', 2) == '13° 24′ 45.00″ N, 103° 52′ 00.00″ E');
console.assert(latlon.toUtm().toString() == '48 N 377298.745 1483034.794';

e.g. for MGRS/NATO map references:

import Mgrs, { LatLon } from 'geodesy/mgrs.js';

const mgrs = Mgrs.parse('31U DQ 48251 11932');
const latlon = mgrs.toUtm().toLatLon();
console.assert(latlon.toString('dms', 2) == '48° 51′ 29.50″ N, 002° 17′ 40.16″ E');

const p = LatLon.parse('51°28′40.37″N, 000°00′05.29″W');
const ref = p.toUtm().toMgrs();
console.assert(ref.toString() == '30U YC 08215 07233');

e.g. for OS grid references:

import OsGridRef, { LatLon } from 'geodesy/osgridref.js';

const gridref = new OsGridRef(651409.903, 313177.270);

const pWgs84 = gridref.toLatLon();
console.assert(pWgs84.toString('dms', 4) == '52° 39′ 28.7230″ N, 001° 42′ 57.7870″ E');

const pOsgb = gridref.toLatLon(LatLon.datums.OSGB36);
console.assert(pOsgb.toString('dms', 4) == '52° 39′ 27.2531″ N, 001° 43′ 04.5177″ E');

e.g. for testing if a point is enclosed within a polygon:

import LatLon from 'geodesy/latlon-nvector-spherical.js';

const polygon = [ new LatLon(48,2), new LatLon(49,2), new LatLon(49,3), new LatLon(48,3) ];

const enclosed = new LatLon(48.9,2.4).isEnclosedBy(polygon);
console.assert(enclosed == true);

e.g. greater parsing & presentation control:

import LatLon from 'geodesy/latlon-spherical.js';
Dms.separator = ' '; // full-space separator between degrees-minutes-seconds

const p1 = LatLon.parse({ lat: '50:03:59N', lng: '005:42:53W' });
const p2 = LatLon.parse('58°38′38″N, 003°04′12″W');

const mid = p1.midpointTo(p2);
console.assert(mid.toString('dms') == '54° 21′ 44″ N, 004° 31′ 50″ W');

e.g. datum conversions:

import LatLon from 'geodesy/latlon-ellipsoidal-datum.js';

const pWgs84 = new LatLon(53.3444, -6.2577);

const pIrl1975 = pWgs84.convertDatum(LatLon.datums.Irl1975);
console.assert(pIrl1975.toString() == '53.3442° N, 006.2567° W');

(The format of the import statements will vary according to deployment).

geodesy's People

Contributors

agwells avatar atgardner avatar chrisveness avatar david-r-edgar avatar jameslaneconkling avatar jamestheawesomedude avatar jnyrup avatar pbihler avatar qcz avatar s-at avatar shkoder avatar timothykang 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  avatar  avatar

geodesy's Issues

Enhance the UTM Conversion to ETRS89 and other

Hi Chris,

tank you four your excellent work. I really needed something like this.
I was hoping to use your code to convert values from ETRS89 / LAEA Europe map to LatLong using the utm.js class. (Reason: I have statistic data 100x100 meter grid about Germany and i want to map the grid above an existing open street map application)

As far as I found out the Europe grid uses zone 32 an another falseEasting and falseNorthing. So I enhanced the class with a possibility to define a different falseEasting and falseNorthing. But I still don't get wrong results. Do you have any idea why?

Here are some informations about ETRS89 / LAEA Europe
https://epsg.io/3035

Feature request: point n% of the way between two points

I can't find anywhere on the internet that describes the algorithm to do this. Your midpoint algorithm is the closest I can find:

Similar to .midpointTo, but where it is an arbitrary percentage (or distance, either one) along the path from one point to another, where .midpointTo is exactly halfway.

sourcePoint.midpointToN(destinationPoint, 0.5) == sourcePoint.midpointTo(destinationPoint);
sourcePoint.midpointToN(destinationPoint, 0.1); // 1/10th of the way there.
sourcePoint.midpointToN(destinationPoint, 0.9); // 9/10ths of the way there.
sourcePoint.midpointToN(destinationPoint, 1) == destinationPoint

.midpointToN is a bad name, obviously, since it isn't calculating the midpoint. .percantageDistanceTo?

illegal character

If you download a zip an then use a build like maven to deploy it will mess up the greek characters in the JS files.

I think it would be best not to use any type of greek characters, instead use names, such as Alpha, Omega, Beta, etc..

Output on build server -----------------------------------------------

SyntaxError: illegal character

var sinθ = this.cross(v).length();

vector3d.js (line 161, col 12)
SyntaxError: illegal character

var φ = this.lat.toRadians(), λ = this.lon.toRadians();

latlon-...idal.js (line 158, col 9)
SyntaxError: illegal character

var φ1 = this.lat.toRadians(), λ1 = this.lon.toRadians();

latlon-...enty.js (line 124, col 9

toOsGridRef() doesn't get added as a method to LatLon

the toOsGridRef() method doesn't appear to get appended to LatLon, meaning you can't convert from LatLon to OsGridRef. Consider the following code snippet:

    <script src="geodesy/vector3d.js"></script>
    <script src="geodesy/latlon-ellipsoidal.js"></script>
    <script src="geodesy/latlon-vincenty.js"></script>
    <script src="geodesy/dms.js"></script>
    <script src="geodesy/osgridref.js"></script>
    <script src="places.js"></script>
    <script>
         var latlon = new LatLon(-0.1769701, 51.5012682);
         var grid = latlon.toOsGridRef();
         console.log(grid);
    </script>

Seems to throw:

  Uncaught TypeError: latlon.toOsGridRef is not a function

OsGridRef() exists in global namespace however.

Any idea how to get round this? Is this a bug?

XYZ to LLA

Hi there. I've been trying to use your library to generate a 3d solid in lat long altitude space. So I've created an Vector3d[] array and then tried x.toLatLon(). Which of course gives me LL not LLA (oops -- should have thought of that first).

Is there something I can do to implement this? I'm thinking of looking at this and porting it. I guess my question is "have you already done this" or should I set off and attempt it?
https://www.vcalc.com/wiki/KurtHeckman/V3+-+XYZ+to+LLA

Cannot find module 'goedesy'

I think i'm missing a step somewhere, my project is not building because it cannot find the module geodesy, even though i installed it and its there in my package.json . I have tried the following import types its not working;
import { LatLonSpherical } from 'geodesy';
import LatLon from 'geodesy/latlon-spherical';

I'm using TypeScript (NestJS). and i have already installed @types/geodesy

Problem with latlon to utm conversion

Hello, thank you very much for your work !
I'm facing some problems while converting LatLon to Utm.
basically I'm running this:

	        import Utm, {LatLon} from 'https://cdn.jsdelivr.net/gh/chrisveness/[email protected]/utm.min.js';
			var utm = Utm.parse('48 N 377298.745 1483034.794');
			console.log(utm.toLatLon().toUtm().toString());

And it looks like the LatLon object created has no method toUtm. Could you please explaining what i'm doing wrong or is there something to fix ?
Thank you very much !

alongTrackDistanceTo is not a function

I'm sure it's a minor issue, but this came up when I ran npm test.

$ npm run test

> [email protected] test /Users/mac/Github/geodesy-npm-to-index
> mocha test/*.js

  301 passing (129ms)
  1 failing

  1) latlon-spherical Ed Williams along-track:
     TypeError: d.alongTrackDistanceTo is not a function
      at Context.<anonymous> (test/latlon-spherical-tests.js:59:46)

Question about the use of symbols

I understand it greatly improves the readability of the code but how the hell do I type some of these symbols without copy and pasting? especially ʹ

UTM datum ED50 conversion discrepancies

I have UTM coordinates in projection EPSG:23030, and I am noting small but significant discrepancies in the WGS84 conversion when I compare geodesy 2.1.0 with other sources.

With UTM coordinates E 572120, N 6382750, and using epsg.io on-line conversion:
https://epsg.io/transform#s_srs=23030&t_srs=4326&x=572120.0000000&y=6382750.0000000
epsg.io gives result: lon -1.7956747° lat 57.5794287°
And converting with GDAL/OGR for the same coordinates give result: (-1.79567461404655, 57.5794287230278)

Doing the conversion with geodesy code as follows:
import LatLon from 'geodesy/latlon-ellipsoidal-datum';
import Utm from 'geodesy/utm';
let [E, N] = [572120, 6382750];
let coord_UTM = new Utm(30, "N", E, N, LatLon.datums.ED50);
console.log("EPSG:23030", coord_UTM.toString());
let coord_latlon = coord_UTM.toLatLon();
console.log("EPSG:4326 [lon, lat]", [coord_latlon.lon, coord_latlon.lat])
console.assert(coord_latlon.lon.toFixed(5) == '-1.79567');
console.assert(coord_latlon.lat.toFixed(5) == '57.57943');

The geodesy code gives the following output:

EPSG:23030 30 N 572120 6382750
EPSG:4326 [lon, lat] [ -1.7939917774, 57.58011897737 ]
Assertion failed
Assertion failed

npm version behind

Can we get the new version on npm please?

EDIT: I also noticed the documentation comments of latlon-spherical.js need to be updated from LatLon to LatLonSpherical. I was getting an IDE warning for param type.

Checking for intersection of two line segements

Hi Chris,

Firstly thanks for your fantastic library and great work.

I am trying to look for a way to check if two line segments intersect on the Earth's surface (an ellipsoid model I imagine). I see there is a really neat function:

LatLon.intersection(point1, bearing1, point2, bearing2)

However this appears to find the intersection for the whole great circle that a line would create (path). Is there a way to check for intersection of just the line segments provided i.e. do the two lines segements intersect themselves? Happy to dig into it if you are able to point me in the right direction. Perhaps there is a way to check if the resulting point from intersection is on either of the two original lines? Thanks.

incorrect results

Hi Chris, these results seem to be incorrect. See the screenshots. In the second case, unlike bearing, distance could be calculated.
g1
g2

Allow customization of degree/minute/second symbols?

I see that you recently added the ability to specify what separator character is used when generating a DMS string. However, the symbols used to indicate degrees, minutes, and seconds are still hardcoded. I would like to be able to generate DMS strings that only contain basic ASCII characters, such as 51 12' 00.0". Would it be possible to apply the same approach as you did with separators, where the current characters are defined on the DMS object?

nmea to decimal degrees

hi,

Firstly thanks a lot for the excellent work. And a simple question - NMEA 0183 sentences generate these kinda sentences

$GPRMS,164745.000,A,0108.6383,N,10137.8458,E,0.00,0.00,310316,,*01
Latitude: 0108.6383
Longitude: 10137.8458

Now which of the funtions will help me turn that into decimal degrees? I have seen those that help convert from deg min sec.

Cheers,
M&M

latlon-intersection fails on identical longitudes.

The intersection function fails when given identical longitudes. Example: 51.8853,0.2545,110.8878(lat,long,bearing) and 51.8763,0.2545,54.4525 crashes, but if I change one of the longitudes to 0.2544 it works.

Modifying Number prototype

These days it's generally considered a bit of a no-no to modify the prototypes of in-built types. I've noticed this library does so for Number (adding toRadians, toDegrees, and pad).

These look like they could just as easily be changed to functions (53.toRadians() > toRadians(53)).

I can submit a pull request if there are no objections?

Does not account for leading zeroes in toMgrs

In this function in mgrs.js:

Utm.prototype.toMgrs = function() {
    if (isNaN(this.zone + this.easting + this.northing)) throw new Error('Invalid UTM coordinate ‘'+this.toString()+'’');

    // MGRS zone is same as UTM zone
    var zone = this.zone;

    // convert UTM to lat/long to get latitude to determine band
    var latlong = this.toLatLonE();
    // grid zones are 8° tall, 0°N is 10th band
    var band = Mgrs.latBands.charAt(Math.floor(latlong.lat/8+10)); // latitude band

    // columns in zone 1 are A-H, zone 2 J-R, zone 3 S-Z, then repeating every 3rd zone
    var col = Math.floor(this.easting / 100e3);
    var e100k = Mgrs.e100kLetters[(zone-1)%3].charAt(col-1); // col-1 since 1*100e3 -> A (index 0), 2*100e3 -> B (index 1), etc.

    // rows in even zones are A-V, in odd zones are F-E
    var row = Math.floor(this.northing / 100e3) % 20;
    var n100k = Mgrs.n100kLetters[(zone-1)%2].charAt(row);

    // truncate easting/northing to within 100km grid square
    var easting = this.easting % 100e3;
    var northing = this.northing % 100e3;

    // round to nm precision
    easting = Number(easting.toFixed(6));
    northing = Number(northing.toFixed(6));

    return new Mgrs(zone, band, e100k, n100k, easting, northing);
};

if the resulting 5 digit MGRS has a leading zero, it is lost in the modulus operation. For example, if this.easting is 4501231 then this.easting % 100e3 = 1231, but the correct grid is actually 01231. I recommend padding the value returned from the modulus with zeroes to 5 digits before the decimal. If you would like, I can put up a pull request with a fix.

Best,
Alex

Add Typescript Definition

Great library by the way! Looks amazing.

Do you have any objections if I send a PR to implement a Typescript definition for this library.

Essentially it's a simple index.d.ts at the root directory that has a high level overview of all the available functions of this library.

An example that has 100% typescript definitions is TurfJS.
https://github.com/Turfjs/turf/tree/master/packages

To Do

  • LatLonSpherical
  • LatLonEllipsoidal
  • LatLonVectors
  • Vector3d
  • Utm
  • Mgrs
  • OsGridRef
  • Dms

Can't resolve module for react-native Android app

We're using Geodesy in a React-Native Android app and are trying to upgrade from 1.1.3 to 2.2.0, however when trying to build and run we get the following error:

While trying to resolve module geodesy from file redux\NMEA.js, the package node_modules\geodesy\package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (\node_modules\geodesy\index). Indeed, none of these files exist:

  • node_modules\geodesy\index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json)
  • node_modules\geodesy\index\index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json)

We've got esm installed and updated to Geodesy 2.2.0 with the npm command from the readme. React-native is version 0.52.1.

Any help on this would be massively appreciated, thanks :)

Something weird going on with how MGRS/USNG to latlon to UTM is being handled

http://www.movable-type.co.uk/scripts/latlong-utm-mgrs.html

if one puts in 12S TC 52 86 the lat/long returned is 33.39823425°N, 114.22478232°W
if one puts in 12S TC 52000 86000 the lat/long returned 34.18551907°N, 113.69099623°W

These two lat/longs should be the same as they are the sw coordinate of the entered grid and adding 000 should not cause this coordinate to change since it is the same starting grid location, just a smaller box.

Further possible conversion bugs

Hi Chris,

It looks like there are still bugs in some of the NGR <-> GridRef and OSGB36 <-> WGS84 conversions. This round-trip test fails:

test('round trip conversions (NGR <-> WGS84)', function(assert) {
  var LatLonE = require('./latlon-ellipsoid.js');
  var OsGridRef = require('./osgridref.js');

  // The steps in this test are:
  //  - parse an NGR
  //  - convert to easting/northing
  //  - convert to OSGB36
  //  - convert to WGS84
  //  - convert back to OSGB36
  //  - convert back to easting/northing
  //  - convert back to NGR

  var ngr = "TQ 44359 80653";

  var grid = OsGridRef.parse(ngr);
  assert.equal(grid.easting, 544359, "grid.easting");
  assert.equal(grid.northing, 180653, "grid.northing");

  var osgb = OsGridRef.osGridToLatLon(grid);
  console.log('osgb', osgb);
  assert.equal(osgb.lat.toFixed(5), '51.50587', "osgb.lat");
  assert.equal(osgb.lon.toFixed(5), '0.08030', "osgb.lon");

  var wgs = osgb.convertDatum(LatLonE.datum.WGS84);
  console.log('wgs', wgs);
  assert.equal(wgs.lat.toFixed(5), '51.31876', "wgs.lat");
  assert.equal(wgs.lon.toFixed(5), '0.07867', "wgs.lon");

  // Problem 1: `wgs` doesn't have a convertDatum method...
  // I guess there are several types of coordinate in the geodesy library:
  var wgs2 = new LatLonE(wgs.lat, wgs.lon, LatLonE.datum.WGS84);

  // Problem 2: this conversion comes out wrong...
  // Latitude goes down instead of up as I'd expect:
  var osgb2 = wgs2.convertDatum(LatLonE.datum.OSGB36);
  console.log('osgb2', osgb2);
  assert.equal(osgb2.lat.toFixed(5), osgb.lat.toFixed(5), "osgb2.lat"); // error: expected: '51.50587', actual: '51.13099'
  assert.equal(osgb2.lon.toFixed(5), osgb.lon.toFixed(5), "osgb2.lon"); // error: expected: '0.08030', actual: '0.08029'

  // Problem 3: this conversion fails with the following error:
  // "Can only convert OSGB36 point to OsGrid"
  var grid2 = OsGridRef.latLonToOsGrid(osgb2);
  console.log('grid2', grid2);
  assert.equal(grid2.easting, grid.easting, "grid2.easting");
  assert.equal(grid2.northing, grid.northing, "grid2.northing");

  var ngr2 = grid2.toPrecision(10);
  assert.equal(ngr2, ngr, "ngr2");

  assert.end();
});

Apologies if the errors are due to me mis-using the code or the expected accuracy of the conversions involved. Happy to help with the fixes if I can.

Best regards,

Dave

Where are the docs on how to update to 2.0?

For example, my project was using import LatLon from 'geodesy/latlon-vectors'; - but this was removed in 2.0, and there's no information with what to replace it. latlon-spherical? latlon-nvector-spherical?

Problem with OsGridRef.latLonToOsGrid()

I'm testing out the osgridref library and am using the latitude/longitude conversion function with the example code that you provide. I'm getting the error:

Uncaught TypeError: Cannot read property 'datum' of undefined

The markup in question is this:

var p = new LatLonE(54.6254280, -3.1676360, LatLonE.datum.OSGB36);
var grid = OsGridRef.latLonToOsGrid(p); // grid.toString(): TG 51409 13177

The line throwing the error is the first one. I have downloaded all of the libraries so osgridref should be referencing LatLonE as a variable that requires latlon-ellipsoid.js. I can't work out what's causing the error.

Documentations mistakes or code issues ?

distance unit

Your documentation say distances are in kilometers. I tried your library but distance seems not to be kilometers. What is it ? Is it meters ?

var nantes = new LatLon(47.238222,-1.5600561);
var saintNazaire = new LatLon(47.2769351, -2.3091714);
nantes.distanceTo(nazaire); // return 56697.95954334959 - distance in kilometer is approximately 50km

function parameters

Further more your readme give latlon.destinationPoint(distance, bearing[, radius])

But your documentation give destinationPoint(brng, dist)

Which one should we trust ?

strange results

(new LatLon(0, 0)).destinationPoint(100000, 0); // return LatLon { lat: 0.8993216059187306, lon: 0 }
(new LatLon(0, 0)).destinationPoint(100000, 90); // return LatLon { lat: 5.506530518221826e-17, lon: 0.8993216059187716 }
(new LatLon(0, 0)).destinationPoint(100000, 180); // return LatLon { lat: -0.8993216059187306, lon: 0 }
(new LatLon(0, 0)).destinationPoint(100000, 270); // return LatLon { lat: -1.6519591554665477e-16, lon: -0.8993216059187716 }

why results give changes on latitude with a bearing of 90° and 270° ?

Possible conversion bug

Hi Chris,

Thanks for this library - it's been very useful.

I've come up with some erroneous behaviour and I wanted to check if it's a bug or my mistake.

The original issue came when I noticed that I was converting a National Grid Reference to a WGS84 and back again and came up with the wrong answer. Here's the data:

TQ 44359 80653 -> 51.506377,0.078658 -> TQ 44358 80653

I used a third party conversion site to get confirmation of the correct data -- it looks like the NGR -> WGS84 conversion is working fine and the WGS84 -> NGR conversion is in error:

I forked your geodesy codebase to add some tests. The behaviour I ended up with isn't consistent with the above but still deserves attention. See line 169 onwards here: https://github.com/davegurnell/geodesy/blob/master/test.js

These tests appear to reveal two bugs:

  • In test case 1, the WGS84 latitude comes out wrong. Not sure why -- this is inconsistent with the results I'm seeing elsewhere.
  • In test case 2, the conversion from OSGB36 to OsGridRef fails with the error message Can only convert OSGB36 point to OsGrid. It looks like this is because there's no datum field in the locationfollowing conversion from WGS84.

Can you provide any hint as to what's going on here? Am I using the library as intended?

It's test case 1 I'm primarily concerned about as I'm not familiar enough with the maths of coordinate conversion to help. I'm happy to provide a bug fix for test case 2 if required.

Best regards,

Dave

Vector.prototype.toLatLon defined twice

Hi,

I just realized that Vector3d.prototype.toLatLon is defined twice. Currently this leads to errors when both latlon-ellipsoid and latlon-vector are included and vector.toLatLon is called (e.g. from within LatLonV.intersection).

Is it possible to avoid this by e.g. separating toLatLon into functions specific for each LatLon type?

How to use utm and spherical scripts alltogether?

I am using geodesy scripts in an AngularJS 1.x application and need both to convert utm coordinates to latlong and get the distance between two latlong-points.

However, because I cannot use commonJS or any other javascript module framework importing both latlon-ellipsoidal.js (required by utm.js) and latlon-spherical.js for distance/bearing overwrites the LatLong-Class with an incompatible one... either utm fails to function or LatLong Spherical.

Any idea on how to get both to work at the same time?

Best regards

Jürgen

module import failing

Trying to require the module in my project fails due the define statement in latlon-spherical.js, line 444 is trying to defined [Dms] as a dependency which is looking for it as a module in node_modules. I fixed it by removing the value. Not sure it's needed there anyway, as there is a required statement for it at the top of the file.

Help! What format are these?

Hi all, just a quick newbie question. I have a database of northings and eastings of land parcels that are in a form that I cannot pin on any format. I would like to perform some conversions on them so that they can be used on Google Earth, Maps, Waze etc. For example:

23463.817 E, -54819.146 N
23449.900 E, -54808.635 N
23445.504 E, -54841.976 N
23435.597 E, -54834.499 N
23434.750 E, -54828.132 N

I'm having trouble determining what format are these because it seems the value is way out of range for many known formats. Can anyone help me figure this out?

LatLonSpherical.intersection() - rounding errors lead to φ3=NaN

Action

Add the following test case to the intersection group in latlon-spherical-tests.js:

test('φ3=NaN', () => should.equal(LatLon.intersection(new LatLon(-77.6966041375563, 18.28125000000003), 179.99999999999994, new LatLon(89, 180), 180), null));

Expected behavior

I don't know... something around the south pole or no solution at all?

Observed behavior

φ3=NaN

  1 failing

  1) latlon-spherical
       intersection
         rounding errors, φ3=NaN:
     TypeError: invalid lat ‘NaN’
      at new LatLonSpherical (latlon-spherical.js:49:31)
      at Function.intersection (latlon-spherical.js:442:16)
      at Context.test (test/latlon-spherical-tests.js:183:81)
      at process.topLevelDomainCallback (domain.js:126:23)

Workaround

(...)
const φ3 = Math.asin(Math.sin(φ1) * Math.cos(δ13) + Math.cos(φ1) * Math.sin(δ13) * Math.cos(θ13));
if (isNaN(φ3)) {
    return null;
}
(...)

Consider adding mgrs method to return corners

As the docs indicated "Grid references refer to squares rather than points (with the size of the square indicated by the precision of the reference)"

I get whey the toUtm returns the SW corner, as 'a' UTM can only be one point.. but shouldn't there be a method to get all the points for the square? Did I miss it somewhere?

eslint warnings & errors

Just ran npm run lint and came across many warnings & errors.

$ npm run lint

> [email protected] lint /Users/mac/Github/geodesy-npm-to-index
> eslint .


/Users/mac/Github/geodesy-npm-to-index/latlon-ellipsoidal.js
  196:9  warning  'h' is assigned a value but never used  no-unused-vars

/Users/mac/Github/geodesy-npm-to-index/latlon-spherical.js
  562:31  warning  'polygon' is already declared in the upper scope  no-shadow
  566:18  warning  'v' is already declared in the upper scope        no-shadow
  573:13  warning  'initBrng' is already defined                     no-redeclare

/Users/mac/Github/geodesy-npm-to-index/latlon-vectors.js
  546:14  warning  'v' is already defined  no-redeclare
  596:14  warning  'v' is already defined  no-redeclare

/Users/mac/Github/geodesy-npm-to-index/test/dms-tests.js
  44:18  warning  'v' is already defined  no-redeclare
  45:18  warning  'v' is already defined  no-redeclare
  46:18  warning  'v' is already defined  no-redeclare
  47:18  warning  'v' is already defined  no-redeclare
  48:18  warning  'v' is already defined  no-redeclare

/Users/mac/Github/geodesy-npm-to-index/utm.js
  129:15  error    Expected indentation of 8 spaces but found 14  indent
  130:24  error    Expected indentation of 8 spaces but found 23  indent
  131:32  error    Expected indentation of 8 spaces but found 31  indent
  132:50  error    Expected indentation of 8 spaces but found 49  indent
  133:63  error    Expected indentation of 8 spaces but found 62  indent
  139:14  warning  'j' is already defined                         no-redeclare
  147:14  warning  'j' is already defined                         no-redeclare
  149:14  warning  'j' is already defined                         no-redeclare
  223:16  error    Expected indentation of 8 spaces but found 15  indent
  224:25  error    Expected indentation of 8 spaces but found 24  indent
  225:34  error    Expected indentation of 8 spaces but found 33  indent
  226:48  error    Expected indentation of 8 spaces but found 47  indent
  227:62  error    Expected indentation of 8 spaces but found 61  indent
  233:14  warning  'j' is already defined                         no-redeclare
  258:14  warning  'j' is already defined                         no-redeclare
  260:14  warning  'j' is already defined                         no-redeclare

✖ 27 problems (10 errors, 17 warnings)

Also it's easier to keep your eslint configs in a separate file (.eslintrc.js) then inside your package.json.

Example of your .eslintrc.js

module.exports = {
  "env": {
      "browser": true,
      "node": true,
      "mocha": true
  },
  "extends": "eslint:recommended",
  "rules": {
      "array-bracket-spacing": [ "error", "always" ],
      "comma-dangle": [ "error", "always-multiline" ],
      "curly": [ "error", "multi-line" ],
      "indent": [ "error", 4, { "SwitchCase": 1 } ],
      "key-spacing": [ "error", { "align": "value" } ],
      "no-console": "warn",
      "no-redeclare": "warn",
      "no-shadow": "warn",
      "no-unused-vars": "warn",
      "object-curly-spacing": [ "error", "always" ],
      "quotes": [ "error", "single", "avoid-escape" ],
      "semi": [ "error", "always" ],
      "strict": [ "error", "global" ]
  }
}

Predicting future coordinate points

The latitude and longitude coordinates are passed from the XML, and a line is drawn dynamically. How to predict the line segment in the next five minutes? And a solid point is added to the line segment every five minutes.

npm.js as index.js?

First time I see npm.js as the main file, usually it's index.js.

I'd be curious to see if this would work in all the NodeJS version 4,5,6,7.

Do you have any particular reasons why you decided not to use index.js as your main file?

Bower install

Hi,

Could you add everything to allow the installation of this library thanks to bower ?

Thanks in advance

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.