geographiclibgo

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2022 License: MIT Imports: 1 Imported by: 0

README

geographiclib-go

Author: Nathan McIntosh

About

A golang port of geographiclib.

Aims

  • Mimic the rust port, the python port, and the java port as closely as possible
  • Test as extensively as possible. Match all the rust, python, and java tests

Outline:

Short Explanation of Library

This library can calculate the following:

  • Given a latitude/longitude point, an angle from due North, and a distance, calculate the latitude/longitude of the new point. This is calculated with any function starting with DirectCalc...()
  • Given two latitude/longitude points, calculate the distance between them, and the angles formed from due North to the line connecting the two points. This is calculated with any function starting with InverseCalc...()
  • Given a set of points or edges that form a polygon, calculate the area of said polygon. This is done by calling NewPolygonArea(), adding the points, and finally calling the Compute() method to get both the area and the perimeter of the polygon.
  • Given a set of points or edges that form a polyline (a set of connected lines), calculate the perimeter of the line. This is done by calling NewPolygonArea() with is_polyline set to true, adding the points, and finally calling the Compute() method to get the length of the lines.

Long Explanation of Library

This section is copied from the python documentation

Introduction

Consider an ellipsoid of revolution with equatorial radius $a$, polar semi-axis $b$, and flattening $f = (a − b)/a$ . Points on the surface of the ellipsoid are characterized by their latitude $\phi$ and longitude $\lambda$. (Note that latitude here means the geographical latitude, the angle between the normal to the ellipsoid and the equatorial plane).

The shortest path between two points on the ellipsoid at $(\phi_1, \lambda_1)$ and $(\phi_2, \lambda_2)$ is called the geodesic. Its length is $s_{12}$ and the geodesic from point 1 to point 2 has forward azimuths $\alpha_1$ and $\alpha_2$ at the two end points. In this figure, we have $\lambda_{12} = \lambda_2 − \lambda_1$.

Geodesic A geodesic can be extended indefinitely by requiring that any sufficiently small segment is a shortest path; geodesics are also the straightest curves on the surface.

Solution of Geodesic Problems

Traditionally two geodesic problems are considered:

  • the direct problem — given $\phi_1$, $\lambda_1$, $\alpha_1$, $s_{12}$, determine $\phi_2$, $\lambda_2$, and $\alpha_2$; this is solved by the various functions starting with DirectCalc...

  • the inverse problem — given $\phi_1$, $\lambda_1$, $\phi_2$, $\lambda_2$, determine $s_{12}$, $\alpha_1$, and $\alpha_2$; this is solved by the various functions starting with InverseCalc...

Aditional Properties

The routines also calculate several other quantities of interest

  • $S_{12}$ is the area between the geodesic from point 1 to point 2 and the equator; i.e., it is the area, measured counter-clockwise, of the quadrilateral with corners $(\phi_1,\lambda_1), (0,\lambda_1), (0,\lambda_2)$, and $(\phi_2,\lambda_2)$. It is given in $\text{meters}^2$.

  • $m_{12}$, the reduced length of the geodesic is defined such that if the initial azimuth is perturbed by $\delta\alpha_1$ (radians) then the second point is displaced by $m_{12}\ \delta\alpha_1$ in the direction perpendicular to the geodesic. $m_{12}$ is given in meters. On a curved surface the reduced length obeys a symmetry relation, $m_{12} + m_{21} = 0$. On a flat surface, we have $m_{12} = s_{12}$.

  • $M_{12}$ and $M_{21}$ are geodesic scales. If two geodesics are parallel at point 1 and separated by a small distance $\delta t$, then they are separated by a distance $M_{12} \delta t$ at point 2. $M_{21}$ is defined similarly (with the geodesics being parallel to one another at point 2). $M_{12}$ and $M_{21}$ are dimensionless quantities. On a flat surface, we have $M_{12} = M_{21} = 1$.

  • $\sigma_{12}$ is the arc length on the auxiliary sphere. This is a construct for converting the problem to one in spherical trigonometry. The spherical arc length from one equator crossing to the next is always $180 \degree$.

If points 1, 2, and 3 lie on a single geodesic, then the following addition rules hold:

  • $s_{13} = s_{12} + s_{23}$
  • $\sigma_{13} = \sigma_{12} + \sigma_{23}$
  • $S_{13} = S_{12} + S_{23}$
  • $m_{13} = m_{12}M_{23} + m_{23}M_{21}$
  • $M_{13} = M_{12}M_{23} − (1 − M_{12}M_{21}) m_{23}/m_{12}$
  • $M_{31} = M_{32}M_{21} − (1 − M_{23}M_{32}) m_{12}/m_{23}$
Multiple Shortest Geodesics

The shortest distance found by solving the inverse problem is (obviously) uniquely defined. However, in a few special cases there are multiple azimuths which yield the same shortest distance. Here is a catalog of those cases:

  • $\phi_1 = −\phi_2$ (with neither point at a pole). If $\alpha_1 = \alpha_2$, the geodesic is unique. Otherwise there are two geodesics and the second one is obtained by setting

    • $[\alpha1,\alpha2] \leftarrow [\alpha2,\alpha1]$
    • $[M_{12},M_{21}] \leftarrow [M_{21},M_{12}]$
    • $S12 \leftarrow −S12$

    (This occurs when the longitude difference is near $\pm 180 \degree$ for oblate ellipsoids.)

  • $\lambda_2 = \lambda_1 \pm 180 \degree$ (with neither point at a pole). If $\alpha_1 = 0 \degree$ or $\pm 180 \degree$, the geodesic is unique. Otherwise there are two geodesics and the second one is obtained by setting

    • $[\alpha1,\alpha2] \leftarrow [−\alpha1,−\alpha2]$
    • $S12 \leftarrow −S12$

    (This occurs when $\phi_2$ is near $−\phi_1$ for prolate ellipsoids.)

  • Points 1 and 2 at opposite poles. There are infinitely many geodesics which can be generated by setting $[\alpha1,\alpha2] \leftarrow [\alpha1,\alpha2] + [\delta,−\delta]$, for arbitrary $\delta$. (For spheres, this prescription applies when points 1 and 2 are antipodal.)

  • $s_{12} = 0$ (coincident points). There are infinitely many geodesics which can be generated by setting $[\alpha1,\alpha2] \leftarrow [\alpha1,\alpha2] + [\delta,\delta]$, for arbitrary $\delta$.

Area of a Polygon

The area of a geodesic polygon can be determined by summing $S_{12}$ for successive edges of the polygon ($S_{12}$ is negated so that clockwise traversal of a polygon gives a positive area). However, if the polygon encircles a pole, the sum must be adjusted by $\pm A/2$, where $A$ is the area of the full ellipsoid, with the sign chosen to place the result in $(-A/2, A/2]$.

The library Interface

This section is mostly copied from the python documentation, and altered where necessary.

The Units

All angles (latitude, longitude, azimuth, arc length) are measured in degrees with latitudes increasing northwards, longitudes increasing eastwards, and azimuths measured clockwise from north. For a point at a pole, the azimuth is defined by keeping the longitude fixed, writing $\phi = \pm (90 \degree − \varepsilon)$, and taking the limit $\varepsilon → 0+$

Geodesic Dictionary

The results returned by DirectCalc...() and InverseCalc...() are structs that may contain some or all of the following:

  • LatDeg = $φ_1$, latitude of a point (degrees)
  • LonDeg = $λ_1$, longitude of a point (degrees)
  • AziDeg = $α_1$, azimuth of line at point (degrees)
  • DistanceM = $s_{12}$, distance from 1 to 2 (meters)
  • ArcLengthDeg = $σ_{12}$, arc length on auxiliary sphere from 1 to 2 (degrees)
  • ReducedLengthM = $m_{12}$, reduced length of geodesic (meters)
  • M12 = $M_{12}$, geodesic scale at 2 relative to 1 (dimensionless)
  • M21 = $M_{21}$, geodesic scale at 1 relative to 2 (dimensionless)
  • S12M2 = $S_{12}$, area between geodesic and equator (meters2)
Outmaks and caps

There are a number of functions provided by the API. Each returns a struct with the fields calculated. A method that returns a struct with fewer fields than another means fewer calculations were made. For faster computation, call methods that return only the fields you need.

You can also specify your own subset of fields by using the DirectCalcWithCapabilities() or InverseCalcWithCapabilities() and passing in a capabilities (sometimes called caps) field. capabilities are obtained by or’ing together the following values

  • EMPTY, no capabilities, no output
  • LATITUDE, compute latitude, lat2
  • LONGITUDE, compute longitude, lon2
  • AZIMUTH, compute azimuths, azi1 and azi2
  • DISTANCE, compute distance, s12
  • STANDARD, all of the above
  • DISTANCE_IN, allow s12 to be used as input in the direct problem
  • REDUCEDLENGTH, compute reduced length, m12
  • GEODESICSCALE, compute geodesic scales, M12 and M21
  • AREA, compute area, S12
  • ALL, all of the above;
  • LONG_UNROLL, unroll longitudes

DISTANCE_IN is a capability provided to the GeodesicLine constructor. It allows the position on the line to specified in terms of distance. (Without this, the position can only be specified in terms of the arc length.) This only makes sense in the caps parameter.

LONG_UNROLL controls the treatment of longitude. If it is not set then the lon1 and lon2 fields are both reduced to the range $[−180\degree, 180\degree]$. If it is set, then lon1 is as given in the function call and (lon2 − lon1) determines how many times and in what sense the geodesic has encircled the ellipsoid. This only makes sense in the outmask parameter.

Restrictions on Parameters
  • Latitudes must lie in $[−90\degree, 90\degree]$. Latitudes outside this range are replaced by NaNs.
  • The distance $s_{12}$ is unrestricted. This allows geodesics to wrap around the ellipsoid. Such geodesics are no longer shortest paths. However they retain the property that they are the straightest curves on the surface.
  • Similarly, the spherical arc length $a_{12}$ is unrestricted.
  • Longitudes and azimuths are unrestricted; internally these are exactly reduced to the range $[−180\degree, 180\degree]$; but see also the LONG_UNROLL bit.
  • The equatorial radius a and the polar semi-axis b must both be positive and finite (this implies that $−\infty < f < 1)$.
  • The flattening $f$ should satisfy $f \in [−1/50,1/50]$ in order to retain full accuracy. This condition holds for most applications in geodesy.

Reasonably accurate results can be obtained for $−0.2 \le f \le 0.2$. Here is a table of the approximate maximum error (expressed as a distance) for an ellipsoid with the same equatorial radius as the WGS84 ellipsoid and different values of the flattening.

$\text{abs}(f)$ $\text{error}$
0.003 15 nm
0.01 25 nm
0.02 30 nm
0.05 10 μm
0.1 1.5 mm
0.2 300 mm

Here 1 nm = 1 nanometer = $10^{−9}$ m (not 1 nautical mile!)

Examples

package geographiclibgo_test

import (
	"fmt"

	geodesic "github.com/natemcintosh/geographiclib-go"
)

func Example() {
	// Create a struct representing the Earth
	earth := geodesic.Wgs84()

	// If I start in the middle of Times Square in New York City, and head due West for
	// 1000km, where will I end up?
	NY_lat := 40.757954
	NY_lon := -73.985548
	ended_up_at := earth.DirectCalcLatLon(NY_lat, NY_lon, -90, 1000e3)
	fmt.Println("Ended up at", ended_up_at)

	// Looking on a map, we have ended up in Lafayette Township, a little ways outside
	// Indianapolis

	// Now let's do the inverse calculation. What is the distance from New York City to
	// Chicago?
	CHI_lat := 41.882609
	CHI_lon := -87.621978
	NYC_to_CHI_dist := earth.InverseCalcDistance(NY_lat, NY_lon, CHI_lat, CHI_lon)
	fmt.Printf("Distance from NYC to CHI is %0.1f m\n", NYC_to_CHI_dist)

	// Wyoming is a fairly rectangular state. Taking its four corners as its boundaries,
	// what is its area?
	WY_corners_lat_lon := [][2]float64{
		{40.997958, -111.046710},
		{45.001311, -111.055200},
		{44.997380, -104.057699},
		{41.001432, -104.053249},
	}
	polygon := geodesic.NewPolygonArea(earth, false)
	for _, corner := range WY_corners_lat_lon {
		polygon.AddPoint(corner[0], corner[1])
	}
	polygon_result := polygon.Compute(true, false)
	fmt.Printf("Wyoming area is approximatley %0.0f m^2\n", polygon_result.Area)

	// What is the approximate perimeter of Wyoming?
	fmt.Printf("Wyoming perimeter is approximately %0.0f m\n", polygon_result.Perimeter)

	// But we don't only have to do calculations on Earth. Let's try some on Mars!
	mars_equatorial_radius_m := 3396.2e3
	mars_flattening_factor := 5.0304e-3
	mars := geodesic.NewGeodesic(mars_equatorial_radius_m, mars_flattening_factor)

	// What is the distance from Olympus Mons (18.65, -133.8) to the Curiosity Rover's
	// landing site (-4.47, 137.42)?
	mars_distance := mars.InverseCalcDistance(18.65, -133.8, -4.47, 137.42)
	fmt.Printf("Olympus Mons to Curiosity landing site is %0.0f m", mars_distance)

	// Output:
	// Ended up at {40.15431701948773 -85.75720579845405}
	// Distance from NYC to CHI is 1147311.9 m
	// Wyoming area is approximatley 253282066939 m^2
	// Wyoming perimeter is approximately 2028472 m
	// Olympus Mons to Curiosity landing site is 5348380 m
}

Progress

  • Go translation
    • Geomath
    • Geomath tests
    • Geodesic Capability constants
    • Geodisic Direct
    • Geodisic Direct tests
    • Geodisic line
    • Geodisic line tests
    • Geodisic Inverse
    • Geodisic Inverse tests
    • Polygon Area
    • Polygon Area tests
  • Consider switching from having units in names to using github.com/golang/geo/ which uses types for units. It would perhaps involve more allocations; need to do some testing.

Documentation

Overview

Package offers two main functionalities: solving the "direct" and the "inverse" problems.

Direct:

Place a second point, given the first point, an azimuth, and a distance.

Arguments

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

Returns

There are a variety of outputs associated with this calculation. We save computation by only calculating the outputs you need. You can get any and all of the following

  • lat2 latitude of point 2 [degrees].
  • lon2 longitude of point 2 [degrees].
  • azi2 (forward) azimuth at point 2 [degrees].
  • m12 reduced length of geodesic (meters).
  • M12 geodesic scale of point 2 relative to point 1 [dimensionless].
  • M21 geodesic scale of point 1 relative to point 2 [dimensionless].
  • S12 area under the geodesic [meters^2]
  • a12 arc length of between point 1 and point 2 [degrees].

Call the appropriate function to get the output you need. The following functions are available for solving the Direct problem. Each describes what it returns

- DirectCalcLatLon -> calculate latitude and longitude

- DirectCalcLatLonAzi -> calculate latitude, longitude, and azimuth

- DirectCalcLatLonAziReducedLength -> calculate latitude, longitude, azimuth, and reduced length of the geodesic

- DirectCalcLatLonAziGeodesicScales -> calculate latitude, longitude, azimuth, and the geodesic scales

- DirectCalcLatLonAziReducedLengthGeodesicScales -> calculate latitude, longitude, azimuth, reduced length, and the geodesic scales

- DirectCalcAll -> calculates all of the above plus Area under the geodesic and the arc length between point 1 and point 2

===================================================================================== ===================================================================================== ===================================================================================== Indirect:

Measure the distance (and other values) between two points.

# Arguments - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

Returns

There are a variety of outputs associated with this calculation. We save computation by only calculating the outputs you need. You can get any and all of the following

- s12 distance between point 1 and point 2 (meters). - azi1 azimuth at point 1 [degrees]. - azi2 (forward) azimuth at point 2 [degrees]. - m12 reduced length of geodesic (meters). - M12 geodesic scale of point 2 relative to point 1 [dimensionless]. - M21 geodesic scale of point 1 relative to point 2 [dimensionless]. - S12 area under the geodesic [meters^2] - a12 arc length of between point 1 and point 2 [degrees].

Call the appropriate function to get the output you need. The following functions are available for solving the Direct problem. Each describes what it returns

`lat1` and `lat2` should be in the range [&minus;90&deg;, 90&deg;].
The values of `azi1` and `azi2` returned are in the range
[&minus;180&deg;, 180&deg;].

If either point is at a pole, the azimuth is defined by keeping the longitude fixed, writing `lat` = &plusmn;(90&deg; &minus; &epsilon;), and taking the limit &epsilon; &rarr; 0+.

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.

Example
package main

import (
	"fmt"

	geodesic "github.com/natemcintosh/geographiclib-go"
)

func main() {
	// Create a struct representing the Earth
	earth := geodesic.Wgs84()

	// If I start in the middle of Times Square in New York City, and head due West for
	// 1000km, where will I end up?
	NY_lat := 40.757954
	NY_lon := -73.985548
	ended_up_at := earth.DirectCalcLatLon(NY_lat, NY_lon, -90, 1000e3)
	fmt.Println("Ended up at", ended_up_at)

	// Looking on a map, we have ended up in Lafayette Township, a little ways outside
	// Indianapolis

	// Now let's do the inverse calculation. What is the distance from New York City to
	// Chicago?
	CHI_lat := 41.882609
	CHI_lon := -87.621978
	NYC_to_CHI_dist := earth.InverseCalcDistance(NY_lat, NY_lon, CHI_lat, CHI_lon)
	fmt.Printf("Distance from NYC to CHI is %0.1f m\n", NYC_to_CHI_dist)

	// Wyoming is a fairly rectangular state. Taking its four corners as its boundaries,
	// what is its area?
	WY_corners_lat_lon := [][2]float64{
		{40.997958, -111.046710},
		{45.001311, -111.055200},
		{44.997380, -104.057699},
		{41.001432, -104.053249},
	}
	polygon := geodesic.NewPolygonArea(earth, false)
	for _, corner := range WY_corners_lat_lon {
		polygon.AddPoint(corner[0], corner[1])
	}
	polygon_result := polygon.Compute(true, false)
	fmt.Printf("Wyoming area is approximatley %0.0f m^2\n", polygon_result.Area)

	// What is the approximate perimeter of Wyoming?
	fmt.Printf("Wyoming perimeter is approximately %0.0f m\n", polygon_result.Perimeter)

	// But we don't only have to do calculations on Earth. Let's try some on Mars!
	mars_equatorial_radius_m := 3396.2e3
	mars_flattening_factor := 5.0304e-3
	mars := geodesic.NewGeodesic(mars_equatorial_radius_m, mars_flattening_factor)

	// What is the distance from Olympus Mons (18.65, -133.8) to the Curiosity Rover's
	// landing site (-4.47, 137.42)?
	mars_distance := mars.InverseCalcDistance(18.65, -133.8, -4.47, 137.42)
	fmt.Printf("Olympus Mons to Curiosity landing site is %0.0f m", mars_distance)

}
Output:
Ended up at {40.15431701948773 -85.75720579845405}
Distance from NYC to CHI is 1147311.9 m
Wyoming area is approximatley 253282066939 m^2
Wyoming perimeter is approximately 2028472 m
Olympus Mons to Curiosity landing site is 5348380 m

Index

Examples

Constants

View Source
const (

	// Includes LONG_UNROLL
	OUT_MASK      uint64 = 0xFF80
	EMPTY         uint64 = 0
	LATITUDE      uint64 = 1<<7 | _CAP_NONE
	LONGITUDE     uint64 = 1<<8 | _CAP_C3
	AZIMUTH       uint64 = 1<<9 | _CAP_NONE
	DISTANCE      uint64 = 1<<10 | _CAP_C1
	STANDARD      uint64 = LATITUDE | LONGITUDE | AZIMUTH | DISTANCE
	DISTANCE_IN   uint64 = 1<<11 | _CAP_C1 | _CAP_C1p
	REDUCEDLENGTH uint64 = 1<<12 | _CAP_C1 | _CAP_C2
	GEODESICSCALE uint64 = 1<<13 | _CAP_C1 | _CAP_C2
	AREA          uint64 = 1<<14 | _CAP_C4
	LONG_UNROLL   uint64 = 1 << 15

	// Does not include LONG_UNROLL
	ALL uint64 = _OUT_ALL | _CAP_ALL
)
View Source
const DEG2RAD float64 = math.Pi / 180.0
View Source
const RAD2DEG float64 = 180.0 / math.Pi
View Source
const WGS84_A float64 = 6378137.0
View Source
const WGS84_F float64 = 1.0 / ((298257223563.0) / 1000000000.0)

Evaluating this as 1000000000.0 / (298257223563f_64) reduces the round-off error by about 10%. However, expressing the flattening as 1/298.257223563 is well ingrained.

Variables

This section is empty.

Functions

This section is empty.

Types

type Accumulator

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

Accumulator allows a running sum of float64s

func NewAccumulatorFromS

func NewAccumulatorFromS(s float64) Accumulator

func NewAccumulatorFromST

func NewAccumulatorFromST(s, t float64) Accumulator

func (*Accumulator) Add

func (p *Accumulator) Add(y float64)

Add a value to the sum

func (*Accumulator) Negate

func (p *Accumulator) Negate()

Negate negates the sum

func (*Accumulator) Remainder

func (p *Accumulator) Remainder(y float64)

Remainder on division by y

func (*Accumulator) SetS

func (p *Accumulator) SetS(s float64)

SetS sets s to the argument, and t to 0

func (*Accumulator) SetST

func (p *Accumulator) SetST(s, t float64)

SetST sets both s and t

func (*Accumulator) Sum

func (p *Accumulator) Sum(y float64) float64

Sum returns sum + y

type AllDirectResults

type AllDirectResults struct {
	LatDeg         float64 // Latitude [degrees]
	LonDeg         float64 // Longitude [degrees]
	AziDeg         float64 // Azimuth [degrees]
	ReducedLengthM float64 // Reduced length of the geodesic [meters]
	M12            float64 // Geodesic scale of point 2 relative to point 1 [dimensionless]
	M21            float64 // Geodesic scale of point 1 relative to point 2 [dimensionless]
	S12M2          float64 // Area under the geodesic [meters^2]
	A12Deg         float64 // Arc length between point 1 and point 2 [degrees]
}

AllDirectResults contains all information that can be computed from the direct method latitude, longitude, azimuth, reduced length, geodesic scales, area under the geodesic, and arc length between point 1 and point 2

type AllInverseResults

type AllInverseResults struct {
	DistanceM      float64 // distance between point 1 and point 2 [meters]
	Azimuth1Deg    float64 // azimuth at point 1 [degrees]
	Azimuth2Deg    float64 // (forward) azimuth at point 2 [degrees]
	ArcLengthDeg   float64 // arc length between point 1 and point 2 [degrees]
	ReducedLengthM float64 // reduced length of geodesic [meters]
	M12            float64 // geodesic scale of point 2 relative to point 1 [dimensionless]
	M21            float64 // geodesic scale of point 1 relative to point 2 [dimensionless]
	S12M2          float64 // area under the geodesic [meters^2]
}

type AzimuthsArcLength

type AzimuthsArcLength struct {
	Azimuth1Deg  float64 // azimuth at point 1 [degrees]
	Azimuth2Deg  float64 // (forward) azimuth at point 2 [degrees]
	ArcLengthDeg float64 // arc length between point 1 and point 2 [degrees]
}

type DistanceArcLength

type DistanceArcLength struct {
	DistanceM    float64 // distance between point 1 and point 2 [meters]
	ArcLengthDeg float64 // arc length between point 1 and point 2 [degrees]
}

type DistanceAzimuths

type DistanceAzimuths struct {
	DistanceM   float64 // distance between point 1 and point 2 [meters]
	Azimuth1Deg float64 // azimuth at point 1 [degrees]
	Azimuth2Deg float64 // (forward) azimuth at point 2 [degrees]
}

type DistanceAzimuthsArcLength

type DistanceAzimuthsArcLength struct {
	DistanceM    float64 // distance between point 1 and point 2 [meters]
	Azimuth1Deg  float64 // azimuth at point 1 [degrees]
	Azimuth2Deg  float64 // (forward) azimuth at point 2 [degrees]
	ArcLengthDeg float64 // arc length between point 1 and point 2 [degrees]
}

type DistanceAzimuthsArcLengthReducedLength

type DistanceAzimuthsArcLengthReducedLength struct {
	DistanceM      float64 // distance between point 1 and point 2 [meters]
	Azimuth1Deg    float64 // azimuth at point 1 [degrees]
	Azimuth2Deg    float64 // (forward) azimuth at point 2 [degrees]
	ArcLengthDeg   float64 // arc length between point 1 and point 2 [degrees]
	ReducedLengthM float64 // reduced length of geodesic [meters]
}

type DistanceAzimuthsArcLengthReducedLengthScales

type DistanceAzimuthsArcLengthReducedLengthScales struct {
	DistanceM      float64 // distance between point 1 and point 2 [meters]
	Azimuth1Deg    float64 // azimuth at point 1 [degrees]
	Azimuth2Deg    float64 // (forward) azimuth at point 2 [degrees]
	ArcLengthDeg   float64 // arc length between point 1 and point 2 [degrees]
	ReducedLengthM float64 // reduced length of geodesic [meters]
	M12            float64 // geodesic scale of point 2 relative to point 1 [dimensionless]
	M21            float64 // geodesic scale of point 1 relative to point 2 [dimensionless]
}

type Geodesic

type Geodesic struct {
	GEODESIC_ORDER int64
	// contains filtered or unexported fields
}

func NewGeodesic

func NewGeodesic(a, f float64) Geodesic

func Wgs84

func Wgs84() Geodesic

func (*Geodesic) DirectCalcAll

func (g *Geodesic) DirectCalcAll(lat1_deg, lon1_deg, azi1_deg, s12_m float64) AllDirectResults

DirectCalcAll calculates everything possible for the direct method. Takes inputs

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcLatLon

func (g *Geodesic) DirectCalcLatLon(lat1_deg, lon1_deg, azi1_deg, s12_m float64) LatLon

DirectCalcLatLon gets the lat and lon of the second point, based on input

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcLatLonAzi

func (g *Geodesic) DirectCalcLatLonAzi(lat1_deg, lon1_deg, azi1_deg, s12_m float64) LatLonAzi

DirectCalcLatLonAzi gets the lat, lon, and azimuth of the second point, based on input

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcLatLonAziGeodesicScales

func (g *Geodesic) DirectCalcLatLonAziGeodesicScales(lat1_deg, lon1_deg, azi1_deg, s12_m float64) LatLonAziGeodesicScales

DirectCalcLatLonAziGeodesicScales gets the lat, lon, azimuth, and geodesic scales, based on input

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcLatLonAziReducedLength

func (g *Geodesic) DirectCalcLatLonAziReducedLength(lat1_deg, lon1_deg, azi1_deg, s12_m float64) LatLonAziReducedLength

DirectCalcLatLonAziReducedLength gets the lat, lon, azimuth, and reduced length of geodesic of the second point, based on input

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcLatLonAziReducedLengthGeodesicScales

func (g *Geodesic) DirectCalcLatLonAziReducedLengthGeodesicScales(
	lat1_deg, lon1_deg, azi1_deg, s12_m float64,
) LatLonAziReducedLengthGeodesicScales

DirectCalcLatLonAziReducedLengthGeodesicScales gets the lat, lon, azimuth, reduced length, and geodesic scales based on input

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • s12_m - Distance from 1st to 2nd point [meters] Value may be negative

func (*Geodesic) DirectCalcWithCapabilities

func (g *Geodesic) DirectCalcWithCapabilities(
	lat1_deg, lon1_deg, azi1_deg, s12_m float64,
	capabilities uint64,
) AllDirectResults

DirectCalcWithCapabilities allows the user to specify which capabilites they wish to use. This function is useful if you want some other subset of capabilities than those offered by the other DirectCalc...() methods. Takes inputs

  • lat1_deg - Latitude of 1st point [degrees] [-90.,90.]
  • lon1_deg - Longitude of 1st point [degrees] [-180., 180.]
  • azi1_deg - Azimuth at 1st point [degrees] [-180., 180.]
  • capabilities - One or more of the capabilities constant as defined in the file geodesiccapability.go. Usually, they are OR'd together, e.g. LATITUDE | LONGITUDE

func (*Geodesic) DirectLineWithCapabilities

func (g *Geodesic) DirectLineWithCapabilities(
	lat1_deg, lon1_deg, azi1_deg, s12_m float64,
	capabilities uint64,
) GeodesicLine

DirectLineWithCapabilities defines a GeodesicLine struct in terms of the the direct geodesic problem specified in terms of spherical arc length. This function sets point 3 of the GeodesicLine to correspond to point 2 of the direct geodesic problem

func (*Geodesic) EqualtorialRadius

func (g *Geodesic) EqualtorialRadius() float64

func (*Geodesic) Flattening

func (g *Geodesic) Flattening() float64

func (*Geodesic) InverseCalcAll

func (g *Geodesic) InverseCalcAll(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
) AllInverseResults

InverseCalcAll returns everything described in the `AllInverseResults` results type. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcAzimuthsArcLength

func (g *Geodesic) InverseCalcAzimuthsArcLength(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
) AzimuthsArcLength

InverseCalcAzimuthsArcLength returns the azimuth at point 1, the azimuth at point 2, and the arc length between the points. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistance

func (g *Geodesic) InverseCalcDistance(lat1_deg, lon1_deg, lat2_deg, lon2_deg float64) float64

InverseCalcDistance returns the distance from point 1 to point 2 in meters. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistanceArcLength

func (g *Geodesic) InverseCalcDistanceArcLength(lat1_deg, lon1_deg, lat2_deg, lon2_deg float64) DistanceArcLength

InverseCalcDistanceArcLength returns the distance from one point to the next, and the arc length between the points. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistanceAzimuths

func (g *Geodesic) InverseCalcDistanceAzimuths(lat1_deg, lon1_deg, lat2_deg, lon2_deg float64) DistanceAzimuths

InverseCalcDistanceAzimuths returns the distance from one point to the next, and the azimuths. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistanceAzimuthsArcLength

func (g *Geodesic) InverseCalcDistanceAzimuthsArcLength(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
) DistanceAzimuthsArcLength

InverseCalcDistanceAzimuthsArcLength returns the distance from one point to the next, the azimuth at point 1, the azimuth at point 2, and the arc length between the points. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistanceAzimuthsArcLengthReducedLength

func (g *Geodesic) InverseCalcDistanceAzimuthsArcLengthReducedLength(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
) DistanceAzimuthsArcLengthReducedLength

InverseCalcDistanceAzimuthsArcLengthReducedLength returns the distance from one point to the next, the azimuth at point 1, the azimuth at point 2, the arc length between the points, and the reduceed length of the geodesic. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcDistanceAzimuthsArcLengthReducedLengthScales

func (g *Geodesic) InverseCalcDistanceAzimuthsArcLengthReducedLengthScales(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
) DistanceAzimuthsArcLengthReducedLengthScales

InverseCalcDistanceAzimuthsArcLengthReducedLengthScales returns everything described by the `DistanceAzimuthsArcLengthReducedLengthScales` type. Takes inputs - lat1_deg latitude of point 1 [degrees]. - lon1_deg longitude of point 1 [degrees]. - lat2_deg latitude of point 2 [degrees]. - lon2_deg longitude of point 2 [degrees].

func (*Geodesic) InverseCalcWithCapabilities

func (g *Geodesic) InverseCalcWithCapabilities(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
	capabilities uint64,
) AllInverseResults

InverseCalcWithCapabilities allows the user to specify which capabilites they wish to use. This function is useful if you want some other subset of capabilities than those offered by the other InverseCalc...() methods. Takes inputs

  • lat1_deg latitude of point 1 [degrees].
  • lon1_deg longitude of point 1 [degrees].
  • lat2_deg latitude of point 2 [degrees].
  • lon2_deg longitude of point 2 [degrees].
  • capabilities - One or more of the capabilities constant as defined in the file geodesiccapability.go. Usually, they are OR'd together, e.g. LATITUDE | LONGITUDE

func (*Geodesic) InverseLineWithCapabilities

func (g *Geodesic) InverseLineWithCapabilities(
	lat1_deg, lon1_deg, lat2_deg, lon2_deg float64,
	capabilities uint64,
) GeodesicLine

InverseLineWithCapabilities: define a GeodesicLine struct in terms of the inverse geodesic problem. This function sets point 3 of the GeodesicLine to correspond to point 2 of the inverse geodesic problem.

func (*Geodesic) LineWithCapabilities

func (g *Geodesic) LineWithCapabilities(
	lat1_deg, lon1_deg, azi1_deg float64,
	capabilities uint64,
) GeodesicLine

Line returns a GeodesicLine. This allows points along a geodesic starting at lat1_deg, lon1_deg with azimuth azi1_deg to be found.

type GeodesicLine

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

func NewGeodesicLine

func NewGeodesicLine(
	geod Geodesic,
	lat1, lon1, azi1 float64,
) GeodesicLine

NewGeodesicLine creates a GeodesicLine, with `caps` of STANDARD | DISTANCE_IN

func NewGeodesicLineWithCapability

func NewGeodesicLineWithCapability(
	geod Geodesic,
	lat1, lon1, azi1 float64,
	caps uint64,
) GeodesicLine

NewGeodesicLineWithCapability is the same as NewGeodesicLine but the user specifies a `caps` field.

func (GeodesicLine) PositionStandard

func (g GeodesicLine) PositionStandard(s12_m float64) PositionResultStandard

PositionStandard finds the position on the line given s12_m [meters]. It uses the STANDARD capabilities, and returns a PositionResultStandard struct

func (GeodesicLine) PositionWithCapabilities

func (g GeodesicLine) PositionWithCapabilities(s12_m float64, capabilities uint64) PositionResult

PositionWithCapabilities finds the position on the line given s12_m [meters]. It uses whatever capabilities are handed in. Any results not asked for with the capabilities will be math.NaN()

type LatLon

type LatLon struct {
	LatDeg, LonDeg float64
}

LatLon represents latitude and longitude of a point. All units in degrees

type LatLonAzi

type LatLonAzi struct {
	LatDeg, LonDeg, AziDeg float64
}

LatLonAzi represents latitude, longitude, and azimuth of a point. All units in degrees

type LatLonAziGeodesicScales

type LatLonAziGeodesicScales struct {
	LatDeg float64 // Latitude [degrees]
	LonDeg float64 // Longitude [degrees]
	AziDeg float64 // Azimuth [degrees]
	M12    float64 // Geodesic scale of point 2 relative to point 1 [dimensionless]
	M21    float64 // Geodesic scale of point 1 relative to point 2 [dimensionless]
}

LatLonAziGeodesicScales: All units in degrees. Scales are dimensionless

type LatLonAziReducedLength

type LatLonAziReducedLength struct {
	LatDeg         float64 // Latitude [degrees]
	LonDeg         float64 // Longitude [degrees]
	AziDeg         float64 // Azimuth [degrees]
	ReducedLengthM float64 // Reduced length of the geodesic [meters]
}

LatLonAziReducedLength: All units in degrees and meters

type LatLonAziReducedLengthGeodesicScales

type LatLonAziReducedLengthGeodesicScales struct {
	LatDeg         float64 // Latitude [degrees]
	LonDeg         float64 // Longitude [degrees]
	AziDeg         float64 // Azimuth [degrees]
	ReducedLengthM float64 // Reduced length of the geodesic [meters]
	M12            float64 // Geodesic scale of point 2 relative to point 1 [dimensionless]
	M21            float64 // Geodesic scale of point 1 relative to point 2 [dimensionless]
}

LatLonAziReducedLengthGeodesicScales: All units in degrees and meters. Scales are dimensionless

type PolygonArea

type PolygonArea struct {
	Earth    Geodesic
	Polyline bool
	Area0_M2 float64

	Num      int
	Lat1_Deg float64

	Lon1_Deg float64
	// contains filtered or unexported fields
}

func NewPolygonArea

func NewPolygonArea(g Geodesic, is_polyline bool) PolygonArea

NewPolygonArea creates a new struct for calculating area and perimeter of a polygon, or for calculating the perimeter of a polyline (a set of connected lines). Takes inputs:

  • g Geodesic on which you wish to calculate
  • is_polyline if true, then assume all points added will only form a polyline. No area will be calculated

func (*PolygonArea) AddEdge

func (p *PolygonArea) AddEdge(azi_deg, s_m float64)

AddEdge adds the next edge to the polygon. This specifies the new vertex in terms of the edge from the current vertex. INPUTS: - azi_deg: the azimuth at the current point in degrees - s_m: the length of the edge in meters

func (*PolygonArea) AddPoint

func (p *PolygonArea) AddPoint(lat_deg, lon_deg float64)

AddPoint adds the next vertex to the polygon. This adds an edge from the current vertex to the new vertex

func (*PolygonArea) Clear

func (p *PolygonArea) Clear()

Clear resets to an empty polygon

func (*PolygonArea) Compute

func (p *PolygonArea) Compute(reverse, sign bool) PolygonResult

Compute the properties of the polygon

INPUTS:

- reverse: if true then clockwise (instead of counter-clockwise) traversal counts as a positive area

- sign: if true 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

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.

If the object is a polygon (and not a polyline), the perimeter includes the length of a final edge connecting the current point to the initial point. If the object is a polyline, then area is nan.

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

func (*PolygonArea) TestEdge

func (p *PolygonArea) TestEdge(
	azi_deg float64,
	s_m float64,
	reverse bool,
	sign bool,
) PolygonResult

TestEdge returns the results assuming a tentative final test point is added via an azimuth and distance; however, the data for the test point is not saved. This lets you report a running result for the perimeter and area as the user moves the mouse cursor. Ordinary floating point arithmetic is used to accumulate the data for the test point; thus the area and perimeter returned are less accurate than if AddPoint and Compute are used.

INPUTS:

- azi_deg: azimuth at the current point [degrees]

- s_m: distance from the current point to the final test point [meters]

- reverse: if true then clockwise (instead of counter-clockwise) traversal counts as a positive area

- sign: if true 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

func (*PolygonArea) TestPoint

func (p *PolygonArea) TestPoint(
	lat_deg float64,
	lon_deg float64,
	reverse bool,
	sign bool,
) PolygonResult

TestPoint return the results assuming a tentative final test point is added; however, the data for the test point is not saved. This lets you report a running result for the perimeter and area as the user moves the mouse cursor. Ordinary floating point arithmetic is used to accumulate the data for the test point; thus the area and perimeter returned are less accurate than if AddPoint and Compute are used.

INPUTS:

- lat_deg: the latitude of the test point [degrees]. Should be in the range [-90, 90]

- lon_deg: the longitude of the test point [degrees]

- reverse: if true then clockwise (instead of counter-clockwise) traversal counts as a positive area

- sign: if true 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

type PolygonResult

type PolygonResult struct {
	Num       int     // the number of vertices in the polygon
	Perimeter float64 // the perimeter fo the polygon or the length of the polyline [meters]
	Area      float64 // the area of the polygon [meters^2]
}

type PositionResult

type PositionResult struct {
	Lat1Deg        float64 // Latitude of point 1 [degrees]
	Lon1Deg        float64 // Longitude of point 1 [degrees]
	Azi1Deg        float64 // Azimuth of point 1 [degrees]
	Lat2Deg        float64 // Latitude of point 2 [degrees]
	Lon2Deg        float64 // Longitude of point 2 [degrees]
	Azi2Deg        float64 // Azimuth of point 2 [degrees]
	DistanceM      float64 // Distance from point 1 to point 2 [meters]
	ArcLengthDeg   float64 // Arc length between point 1 and point 2 [degrees]
	ReducedLengthM float64 // Reduced length of the geodesic [meters]
	M12            float64 // Geodesic scale of point 2 relative to point 1 [dimensionless]
	M21            float64 // Geodesic scale of point 1 relative to point 2 [dimensionless]
	S12M2          float64 // Area under the geodesic [meters^2]
}

type PositionResultStandard

type PositionResultStandard struct {
	Lat1Deg   float64 // Latitude of point 1 [degrees]
	Lon1Deg   float64 // Longitude of point 1 [degrees]
	Azi1Deg   float64 // Azimuth of point 1 [degrees]
	Lat2Deg   float64 // Latitude of point 2 [degrees]
	Lon2Deg   float64 // Longitude of point 2 [degrees]
	Azi2Deg   float64 // Azimuth of point 2 [degrees]
	DistanceM float64 // Distance from point 1 to point 2 [meters]
}

Jump to

Keyboard shortcuts

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