geodesy

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 20, 2021 License: MIT Imports: 1 Imported by: 0

README

geodesy

GoDoc

geodesy is a Go package providing operations for performaing accurate measurements of Earth. Includes a Go port of the geodesic routines from GeographicLib along with general-purpose spherical algorithms.

Features

  • Precise distance calculations (5-15 nanometer)
  • Calculate the area and perimeter of a polygon
  • Get the length of a polyline
  • Direct and Inverse solutions
  • Optional spherical formulas for efficency, such as Haversine.

Installing

To start using geodesy, install Go and run go get:

$ go get -u github.com/tidwall/geodesy

This will retrieve the library.

Using

All operations are performed on an Ellipsoid object.

To create a custom ellipsoid:

  • geodesy.NewEllipsoid: For highly accurate geodesic routines.
  • geodesy.NewSpherical: For faster spherical routines such as Haversine.
// The first argument is the radius and the second is the flattening.
myEllipsoid := geodesy.NewEllipsoid(6378137.0, 1.0/298.257223563)

Or, you can simply use the built-in geodesy.WGS84 non-spherical ellipsoid, which conforms to the WGS84 standard.

// The argument is the radius.
mySphere := geodesy.NewSpherical(6378137.0)

Or, you can use the geodesy.Globe spherical ellipsoid, which represents Earth as a terrestrial globe.

Examples

Calculate distance between two points.

var dist float64
geodesy.WGS84.Inverse(33.4911, -112.4223, 32.1189, -113.1123, &dist, nil, nil)
fmt.Printf("%f meters\n", dist)
// output: 
// 165330.214571 meters

Calculate initial azimuth from point A to point B.

var azi float64
geodesy.WGS84.Inverse(33.4911, -112.4223, 32.1189, -113.1123, nil, &azi, nil)
fmt.Printf("%f degrees\n", azi)
// output:
// -156.803310 degrees

Calculate final azimuth from point A to point B.

var azi float64
geodesy.WGS84.Inverse(33.4911, -112.4223, 32.1189, -113.1123, nil, nil, &azi)
fmt.Printf("%f degrees\n", azi)
// output:
// -157.177169 degrees

Calculate distance and azimuths at the same time.

var dist, azi1, azi2 float64
geodesy.WGS84.Inverse(33.4911, -112.4223, 32.1189, -113.1123, &dist, &azi1, &azi2)
fmt.Printf("%f meters, %f degrees, %f degrees\n", dist,azi1,azi2)
// output:
// 165330.214571 meters, -156.803310 degrees, -157.177169 degrees

Calculate destination using an initial point, azimuth, and distance.

var lat, lon float64
geodesy.WGS84.Direct(33.4911, -112.4223, -156.803310, 165330.214571, &lat, &lon, nil)
fmt.Printf("%f, %f\n", lat, lon)
// output: 
// 32.118900, -113.112300

Calculate the area and perimeter of a polygon.

// Arizona
poly := WGS84.PolygonInit(false)
poly.AddPoint(36.99377, -109.050292)
poly.AddPoint(36.96744, -114.049072)
poly.AddPoint(36.26199, -114.016113)
poly.AddPoint(36.08462, -114.279785)
poly.AddPoint(36.11125, -114.730224)
poly.AddPoint(34.86790, -114.631347)
poly.AddPoint(34.47939, -114.367675)
poly.AddPoint(34.29806, -114.104003)
poly.AddPoint(33.89777, -114.532470)
poly.AddPoint(33.58716, -114.543457)
poly.AddPoint(33.35806, -114.708251)
poly.AddPoint(33.09154, -114.708251)
poly.AddPoint(32.87036, -114.444580)
poly.AddPoint(32.74108, -114.719238)
poly.AddPoint(32.50049, -114.818115)
poly.AddPoint(31.33487, -111.093749)
poly.AddPoint(31.35363, -109.050292)
poly.AddPoint(36.99377, -109.050292)
var area, perimeter float64
poly.Compute(false, false, &area, &perimeter)
fmt.Printf("%f area (km²), %f perimeter (meters)\n", area/1000000, perimeter)
// output:
// 294838.722804 area (km²), 2254910.021767 perimeter (meters)

Documentation

Overview

API for the geodesic routines in Go

This an implementation in Go of the geodesic algorithms described in

Copyright (c) Charles Karney (2012-2021) <charles@karney.com> and licensed under the MIT/X11 License. For more information, see https://geographiclib.sourceforge.io/

Ported to Go by Joshua Baker <joshbaker77@gmail.com> and licensed under the MIT License.

Index

Constants

This section is empty.

Variables

View Source
var Globe = NewSpherical(6378137)

Globe is a pre-initialized spherical representing Earth as a terrestrial globe.

View Source
var WGS84 = NewEllipsoid(6378137, float64(1.)/298.257223563)

WGS84 conforming ellispoid https://en.wikipedia.org/wiki/World_Geodetic_System

Functions

This section is empty.

Types

type Ellipsoid

type Ellipsoid struct {
	// contains filtered or unexported fields
}

Ellipsoid is an object for performing geodesic operations.

func NewEllipsoid

func NewEllipsoid(radius, flattening float64) *Ellipsoid

NewEllipsoid initializes a new geodesic ellipsoid object.

Param radius is the equatorial radius (meters). Param flattening is the flattening factor of the ellipsoid.

The WGS84 pacakge-level variable is a pre-initialized ellipsoid representing Earth.

func NewSpherical

func NewSpherical(radius float64) *Ellipsoid

NewSpherical initializes a new geodesic ellipsoid object that uses simplified operations on a sphere.

The Inverse and Direct operations will often be more computationally efficient than NewEllipsoid because it uses simplier great-circle calculations such as the Haversine formula.

Param radius is the equatorial radius (meters).

The Globe package-level variable is a pre-initialized spherical representing Earth as a terrestrial globe.

func (*Ellipsoid) Direct

func (e *Ellipsoid) Direct(
	lat1, lon1, azi1, s12 float64,
	lat2, lon2, azi2 *float64,
)

Direct solves the direct geodesic problem.

Param g is a pointer to the geod_geodesic object specifying the ellipsoid. Param lat1 is the latitude of point 1 (degrees). Param lon1 is the longitude of point 1 (degrees). Param azi1 is the azimuth at point 1 (degrees). Param s12 is the distance from point 1 to point 2 (meters). negative is ok. Out param plat2 is a pointer to the latitude of point 2 (degrees). Out param plon2 is a pointer to the longitude of point 2 (degrees). Out param pazi2 is a pointer to the (forward) azimuth at point 2 (degrees).

lat1 should be in the range [-90,+90]. The values of lon2 and azi2 returned are in the range [-180,+180]. Any of the "return" arguments, plat2, etc., may be replaced with nil, if you do not need some quantities computed.

func (*Ellipsoid) Flattening

func (e *Ellipsoid) Flattening() float64

Flattening of the Ellipsoid

func (*Ellipsoid) Inverse

func (e *Ellipsoid) Inverse(
	lat1, lon1, lat2, lon2 float64,
	s12, azi1, azi2 *float64,
)

Inverse solve the inverse geodesic problem.

Param lat1 is latitude of point 1 (degrees). Param lon1 is longitude of point 1 (degrees). Param lat2 is latitude of point 2 (degrees). Param lon2 is longitude of point 2 (degrees). Out param ps12 is a pointer to the distance from point 1 to point 2 (meters). Out param pazi1 is a pointer to the azimuth at point 1 (degrees). Out param pazi2 is a pointer to the (forward) azimuth at point 2 (degrees).

lat1 and lat2 should be in the range [-90,+90]. The values of azi1 and azi2 returned are in the range [-180,+180]. Any of the "return" arguments, ps12, etc., may be replaced with nil, if you do not need some quantities computed.

The solution to the inverse problem is found using Newton's method. If this fails to converge (this is very unlikely in geodetic applications but does occur for very eccentric ellipsoids), then the bisection method is used to refine the solution.

func (*Ellipsoid) PolygonInit

func (e *Ellipsoid) PolygonInit(polyline bool) Polygon

PolygonInit initializes a polygon. Param polyline for polyline instead of a polygon.

If polyline is not set, then the sequence of vertices and edges added by Polygon.AddPoint() and Polygon.AddEdge() define a polygon and the perimeter and area are returned by Polygon.Compute(). If polyline is set, then the vertices and edges define a polyline and only the perimeter is returned by Polygon.Compute().

The area and perimeter are accumulated at two times the standard floating point precision to guard against the loss of accuracy with many-sided polygons. At any point you can ask for the perimeter and area so far.

func (*Ellipsoid) Radius

func (e *Ellipsoid) Radius() float64

Radius of the Ellipsoid

func (*Ellipsoid) Spherical

func (e *Ellipsoid) Spherical() bool

Spherical returns true if the ellipsoid was initialized using NewSpherical.

type Polygon

type Polygon struct {
	// contains filtered or unexported fields
}

Polygon struct for accumulating information about a geodesic polygon. Used for computing the perimeter and area of a polygon. This must be initialized from Ellipsoid.PolygonInit before use.

func (*Polygon) AddEdge

func (p *Polygon) AddEdge(azi, s float64)

AddEdge adds an edge to the polygon or polyline.

Param azi is the azimuth at current point (degrees). Param s is the distance from current point to next point (meters).

func (*Polygon) AddPoint

func (p *Polygon) AddPoint(lat, lon float64)

AddPoint adds a point to the polygon or polyline.

Param lat is the latitude of the point (degrees). Param lon is the longitude of the point (degrees).

func (*Polygon) Clear

func (p *Polygon) Clear()

Clear the polygon, allowing a new polygon to be started.

func (*Polygon) Compute

func (p *Polygon) Compute(clockwise, sign bool, area, perimeter *float64) int

Compute the results for a polygon

Param reverse, if set then clockwise (instead of

counter-clockwise) traversal counts as a positive area.

Param sign, if set then return a signed result for the area if

the polygon is traversed in the "wrong" direction instead of returning
the area for the rest of the earth.

Out param pA is a pointer to the area of the polygon (meters-squared); Out param pP is a pointer to the perimeter of the polygon or length of the

polyline (meters).

Returns the number of points.

The area and perimeter are accumulated at two times the standard floating point precision to guard against the loss of accuracy with many-sided polygons. Arbitrarily complex polygons are allowed. In the case of self-intersecting polygons the area is accumulated "algebraically", e.g., the areas of the 2 loops in a figure-8 polygon will partially cancel. There's no need to "close" the polygon by repeating the first vertex. Set pA or pP to nil, if you do not want the corresponding quantity returned.

More points can be added to the polygon after this call.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL