## com.bbn.openmap.geo Class Geo

```java.lang.Object com.bbn.openmap.geo.Geo
```
All Implemented Interfaces:
java.io.Serializable

`public class Geoextends java.lang.Objectimplements java.io.Serializable`

A class that represents a point on the Earth as a three dimensional unit length vector, rather than latitude and longitude. For the theory and an efficient implementation using partial evaluation see: http://openmap.bbn.com/~kanderso/lisp/performing-lisp/essence.ps This implementation matches the theory carefully, but does not use partial evaluation.

For the area calculation see: http://math.rice.edu/~pcmi/sphere/

Version:
\$Revision: 1.30 \$ on \$Date: 2007/02/13 20:02:14 \$
Author:
Ken Anderson, Sachin Date, Ben Lubin, Michael Thome
Serialized Form

Field Summary
`static double` `flattening`
Constants for the shape of the earth.
`static double` `FLATTENING_C`

`static double` `METERS_PER_NM`

`static Geo` `north`
North pole.

Constructor Summary
`Geo()`

```Geo(double lat, double lon)```
Construct a Geo from its latitude and longitude.
```Geo(double lat, double lon, boolean isDegrees)```
Construct a Geo from its latitude and longitude.
```Geo(double x, double y, double z)```
Construct a Geo from its parts.
`Geo(Geo geo)`
Construct a Geo from another Geo.

Method Summary
` Geo` `add(Geo b)`
Returns this + b.
` Geo` ```add(Geo b, Geo ret)```

`static double` ```angle(Geo p0, Geo p1, Geo p2)```
Given 3 points on a sphere, p0, p1, p2, return the angle between them in radians.
` Geo` `antipode()`
Returns the point opposite this point on the earth.
` Geo` `antipode(Geo ret)`
Returns the point opposite this point on the earth.
` Geo[]` ```approximateArc(Geo p0, Geo p1, double err)```

`static Geo[]` ```approximateArc(Geo pc, Geo p0, Geo p1, double err)```
compute a polygonal approximation of an arc centered at pc, beginning at p0 and ending at p1, going clockwise and including the two end points.
`static double` `area(java.util.Enumeration<Geo> vs)`
Computes the area of a polygon on the surface of a unit sphere given an enumeration of its point.
` double` `azimuth(Geo v2)`
Azimuth in radians from v2 to this.
`static Geo[]` `closeGa(Geo[] ga)`
return a Geo array where the first and last elements are the same, thus closing the path, by adding a point if needed.
`static float[]` `closeLLa(float[] lla)`
return a float array of alternating lat lon pairs where the first and last pair are the same, thus closing the path, by adding a point if needed.
`static Geo[]` ```computeCorridor(Geo[] path, double radius)```
`static Geo[]` ```computeCorridor(Geo[] path, double radius, double err, boolean capp)```
Wrap a fixed-distance corridor around an (open) path, as specified by an array of Geo.
` Geo` `cross(Geo b)`
Vector cross product.
` Geo` ```cross(Geo b, Geo ret)```
Vector cross product.
` double` `crossLength(Geo b)`
Equivalent to this.cross(b).length().
` Geo` `crossNormalize(Geo b)`
Equivalent to `this.cross(b).normalize()`.
` Geo` ```crossNormalize(Geo b, Geo ret)```
Equivalent to `this.cross(b).normalize()`.
`static Geo` ```crossNormalize(Geo a, Geo b, Geo ret)```
Equivalent to `this.cross(b).normalize()`.
`static double` `degrees(double radians)`
`static double` ```distance(double lat1, double lon1, double lat2, double lon2)```
Angular distance, in radians between the two lat lon points.
` double` `distance(Geo v2)`
Angular distance, in radians between this and v2.
`static double` ```distance(Geo v1, Geo v2)```
Angular distance, in radians between v1 and v2.
`static double` ```distanceKM(double lat1, double lon1, double lat2, double lon2)```
Distance in kilometers.
` double` `distanceKM(Geo v2)`
Distance in kilometers.
`static double` ```distanceKM(Geo v1, Geo v2)```
Distance in kilometers.
`static double` ```distanceNM(double lat1, double lon1, double lat2, double lon2)```
Distance in nautical miles.
` double` `distanceNM(Geo v2)`
Distance in nautical miles.
`static double` ```distanceNM(Geo v1, Geo v2)```
Distance in nautical miles.
` double` `dot(Geo b)`
Dot product.
`static double` ```dot(Geo a, Geo b)```
Dot product.
` boolean` `equals(java.lang.Object obj)`

`static float[]` `GaToLLa(Geo[] ga)`
Convert a Geo array into a floating point lat lon array (alternating lat and lon values)
`static double[]` ```GaToLLa(Geo[] ga, double[] lla)```
Convert a Geo array into a floating point lat lon array (alternating lat and lon values).
`static float[]` ```GaToLLa(Geo[] ga, float[] lla)```
Convert a Geo array into a floating point lat lon array (alternating lat and lon values).
` Geo` ```geoAt(double distance, double azimuth)```
Deprecated. use #offset(double, double)
`static double` `geocentricLatitude(double geographicLatitude)`
Convert from geographic to geocentric latitude (radians)
`static double` `geographicLatitude(double geocentricLatitude)`
Convert from geocentric to geographic latitude (radians)
` double` `getLatitude()`

` double` `getLatitudeRadians()`

` double` `getLongitude()`

` double` `getLongitudeRadians()`

` int` `hashCode()`

` boolean` ```inBubble(Geo v2, double forwardRadius, double backRadius, Geo p)```
Is Geo p inside the time bubble along the great circle segment from this to v2 looking forward forwardRadius and backward backwardRadius.
` void` ```initialize(double lat, double lon)```
Initialize this Geo with to represent coordinates.
` void` ```initialize(double x, double y, double z)```
Initialize this Geo with new parameters.
` void` `initialize(Geo g)`
Initialize this Geo to match another.
` void` ```initializeRadians(double lat, double lon)```
Initialize this Geo with to represent coordinates.
` Geo` ```interpolate(Geo g2, double x)```

` Geo` ```interpolate(Geo g2, double x, Geo ret)```

` Geo` ```intersect(Geo q, Geo r)```
Find the intersection of the great circle between this and q and the great circle normal to r.
` Geo` ```intersect(Geo q, Geo r, Geo ret)```
Find the intersection of the great circle between this and q and the great circle normal to r.
`static boolean` ```isInside(double lat1, double lon1, double lat2, double lon2, double radius, double lat3, double lon3)```
Static version of isInside uses conventional (decimal degree) coordinates.
` boolean` ```isInside(Geo v2, double radius, Geo p)```
Is the point, p, within radius radians of the great circle segment between this and v2?
`static boolean` ```isInside(Geo v1, Geo v2, double radius, Geo p1, Geo p2)```
do the segments v1-v2 and p1-p2 come within radius (radians) of each other?
`static double` `km(double radians)`
`static double` `kmToAngle(double km)`
` double` `length()`
Euclidian length.
`static Geo[]` `LLaToGa(double[] lla)`
Convert a double array of alternating lat and lon pairs into a Geo array.
`static Geo[]` ```LLaToGa(double[] lla, boolean isDegrees)```
Convert a double array of alternating lat and lon pairs into a Geo array.
`static Geo[]` `LLaToGa(float[] lla)`
Convert a float array of alternating lat and lon pairs into a Geo array.
`static Geo[]` ```LLaToGa(float[] lla, boolean isDegrees)```
Convert a float array of alternating lat and lon pairs into a Geo array.
`static Geo` ```makeGeo(double x, double y, double z)```

`static Geo` `makeGeo(Geo p)`

`static Geo` ```makeGeoDegrees(double latd, double lond)```

`static Geo` ```makeGeoRadians(double latr, double lonr)```

` Geo` `midPoint(Geo g2)`
Find the midpoint Geo between this one and another on a Great Circle line between the two.
` Geo` ```midPoint(Geo g2, Geo ret)```
Find the midpoint Geo between this one and another on a Great Circle line between the two.
`static double` `nm(double radians)`
`static double` `nmToAngle(double nm)`
` Geo` `normalize()`
Returns a unit length vector parallel to this.
` Geo` `normalize(Geo ret)`
Returns a unit length vector parallel to this.
`static double` `npdAtLat(double latdeg)`
Compute nautical miles per degree at a specified latitude (in degrees).
` Geo` ```offset(double distance, double azimuth)```
Returns a Geo that is distance (radians), and azimuth (radians) away from this.
` Geo` ```offset(double distance, double azimuth, Geo ret)```
Returns a Geo that is distance (radians), and azimuth (radians) away from this.
`static Geo` ```offset(Geo origin, double distance, double azimuth)```

`static Geo` ```offset(Geo origin, double distance, double azimuth, Geo ret)```

`static Geo[]` `posToGa(java.lang.String coords)`
convert a String containing space-separated pairs of comma-separated decimal lat-lon pairs into a Geo array.
`static Geo[]` `posToGa(java.lang.String[] coords)`
Convert an array of strings with comma-separated decimal lat,lon pairs into a Geo array
`static double` `radians(double degrees)`
`static Geo[]` `removeDups(Geo[] ga)`
Return a Geo array with the duplicates removed.
` Geo` `scale(double s)`
Multiply this by s.
` Geo` ```scale(double s, Geo ret)```
Multiply this by s.
` void` `setLength(double r)`

` double` `strictAzimuth(Geo v2)`
Azimuth in radians from v2 to this.
` Geo` `subtract(Geo b)`
Returns this - b.
` Geo` ```subtract(Geo b, Geo ret)```
Returns this - b.
` java.lang.String` `toString()`

` double` `x()`
Reader for x, in internal axis representation (positive to the right side of screen).
` double` `y()`
Reader for y in internal axis representation (positive into screen).
` double` `z()`
Reader for z in internal axis representation (positive going to top of screen).

Methods inherited from class java.lang.Object
`clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

Field Detail

### flattening

`public static final double flattening`
Constants for the shape of the earth. see http://www.gfy.ku.dk/%7Eiag/HB2000/part4/groten.htm

Constant Field Values

### FLATTENING_C

`public static final double FLATTENING_C`
Constant Field Values

### METERS_PER_NM

`public static final double METERS_PER_NM`
Constant Field Values

### north

`public static final Geo north`
North pole.

Constructor Detail

### Geo

`public Geo()`

### Geo

```public Geo(double lat,
double lon)```
Construct a Geo from its latitude and longitude.

Parameters:
`lat` - latitude in decimal degrees.
`lon` - longitude in decimal degrees.

### Geo

```public Geo(double lat,
double lon,
boolean isDegrees)```
Construct a Geo from its latitude and longitude.

Parameters:
`lat` - latitude.
`lon` - longitude.
`isDegrees` - should be true if the lat/lon are specified in decimal degrees, false if they are radians.

### Geo

```public Geo(double x,
double y,
double z)```
Construct a Geo from its parts.

### Geo

`public Geo(Geo geo)`
Construct a Geo from another Geo.

Method Detail

### npdAtLat

`public static final double npdAtLat(double latdeg)`
Compute nautical miles per degree at a specified latitude (in degrees). Calculation from NIMA: http://pollux.nss.nima.mil/calc/degree.html

### geocentricLatitude

`public static double geocentricLatitude(double geographicLatitude)`
Convert from geographic to geocentric latitude (radians)

### geographicLatitude

`public static double geographicLatitude(double geocentricLatitude)`
Convert from geocentric to geographic latitude (radians)

`public static double radians(double degrees)`

### degrees

`public static double degrees(double radians)`

### km

`public static double km(double radians)`

### kmToAngle

`public static double kmToAngle(double km)`

### nm

`public static double nm(double radians)`

### nmToAngle

`public static double nmToAngle(double nm)`
Convert nautical miles to radians. *

```public static final Geo makeGeoRadians(double latr,
double lonr)```

### makeGeoDegrees

```public static final Geo makeGeoDegrees(double latd,
double lond)```

### makeGeo

```public static final Geo makeGeo(double x,
double y,
double z)```

### makeGeo

`public static final Geo makeGeo(Geo p)`

### initialize

`public void initialize(Geo g)`
Initialize this Geo to match another.

Parameters:
`g` -

### initialize

```public void initialize(double x,
double y,
double z)```
Initialize this Geo with new parameters.

Parameters:
`x` -
`y` -
`z` -

### initialize

```public void initialize(double lat,
double lon)```
Initialize this Geo with to represent coordinates.

Parameters:
`lat` - latitude in decimal degrees.
`lon` - longitude in decimal degrees.

```public void initializeRadians(double lat,
double lon)```
Initialize this Geo with to represent coordinates.

Parameters:
`lat` - latitude in radians.
`lon` - longitude in radians.

### midPoint

`public Geo midPoint(Geo g2)`
Find the midpoint Geo between this one and another on a Great Circle line between the two. The result is undefined of the two points are antipodes.

Parameters:
`g2` -
Returns:
midpoint Geo.

### midPoint

```public Geo midPoint(Geo g2,
Geo ret)```
Find the midpoint Geo between this one and another on a Great Circle line between the two. The result is undefined of the two points are antipodes.

Parameters:
`g2` -
`ret` - a Geo value to set returned values in. Do not pass in a null value.
Returns:
midpoint Geo.

### interpolate

```public Geo interpolate(Geo g2,
double x)```

### interpolate

```public Geo interpolate(Geo g2,
double x,
Geo ret)```
Parameters:
`g2` -
`x` -
`ret` - Do not pass in a null value.
Returns:
ret, or new Geo set at distance between g2 and this one.

### toString

`public java.lang.String toString()`
Overrides:
`toString` in class `java.lang.Object`

### getLatitude

`public double getLatitude()`

### getLongitude

`public double getLongitude()`

`public double getLatitudeRadians()`

`public double getLongitudeRadians()`

### x

`public final double x()`
Reader for x, in internal axis representation (positive to the right side of screen).

Returns:
x

### y

`public final double y()`
Reader for y in internal axis representation (positive into screen).

Returns:
y

### z

`public final double z()`
Reader for z in internal axis representation (positive going to top of screen).

Returns:
z

### setLength

`public void setLength(double r)`

### dot

`public double dot(Geo b)`
Dot product. Gives you the cos of the angle between this point and b.

### dot

```public static double dot(Geo a,
Geo b)```
Dot product. Gives you the cos of the angle between the two points.

### length

`public double length()`
Euclidian length.

### scale

`public Geo scale(double s)`
Multiply this by s. *

### scale

```public Geo scale(double s,
Geo ret)```
Multiply this by s.

Returns:
ret that was passed in, filled in with scaled values. Do not pass in a null value.

### normalize

`public Geo normalize()`
Returns a unit length vector parallel to this.

### normalize

`public Geo normalize(Geo ret)`
Returns a unit length vector parallel to this.

Returns:
ret with normalized values. Do not pass in a null value.

### cross

`public Geo cross(Geo b)`
Vector cross product.

### cross

```public Geo cross(Geo b,
Geo ret)```
Vector cross product. Gives you the point 90 degrees from the great circle line between this point and b. The side of the line depends on the right hand rule.

Returns:
ret Do not pass in a null value.

### crossLength

`public double crossLength(Geo b)`
Equivalent to this.cross(b).length().

### crossNormalize

`public Geo crossNormalize(Geo b)`
Equivalent to `this.cross(b).normalize()`.

### crossNormalize

```public Geo crossNormalize(Geo b,
Geo ret)```
Equivalent to `this.cross(b).normalize()`.

Returns:
ret Do not pass in a null value.

### crossNormalize

```public static Geo crossNormalize(Geo a,
Geo b,
Geo ret)```
Equivalent to `this.cross(b).normalize()`.

Returns:
ret Do not pass in a null value.

`public Geo add(Geo b)`
Returns this + b.

```public Geo add(Geo b,
Geo ret)```
Returns:
ret Do not pass in a null value.

### subtract

`public Geo subtract(Geo b)`
Returns this - b.

### subtract

```public Geo subtract(Geo b,
Geo ret)```
Returns this - b. *

Returns:
ret Do not pass in a null value.

### equals

`public boolean equals(java.lang.Object obj)`
Overrides:
`equals` in class `java.lang.Object`

### distance

`public double distance(Geo v2)`
Angular distance, in radians between this and v2.

### distance

```public static double distance(Geo v1,
Geo v2)```
Angular distance, in radians between v1 and v2.

### distance

```public static double distance(double lat1,
double lon1,
double lat2,
double lon2)```
Angular distance, in radians between the two lat lon points.

### distanceKM

`public double distanceKM(Geo v2)`
Distance in kilometers. *

### distanceKM

```public static double distanceKM(Geo v1,
Geo v2)```
Distance in kilometers. *

### distanceKM

```public static double distanceKM(double lat1,
double lon1,
double lat2,
double lon2)```
Distance in kilometers. *

### distanceNM

`public double distanceNM(Geo v2)`
Distance in nautical miles. *

### distanceNM

```public static double distanceNM(Geo v1,
Geo v2)```
Distance in nautical miles. *

### distanceNM

```public static double distanceNM(double lat1,
double lon1,
double lat2,
double lon2)```
Distance in nautical miles. *

### strictAzimuth

`public double strictAzimuth(Geo v2)`
Azimuth in radians from v2 to this.

Parameters:
`v2` - other Geo
Returns:
radian angle between this and v2. Will also return NaN for identical points, or other Math conventions for resulting math results.

### azimuth

`public double azimuth(Geo v2)`
Azimuth in radians from v2 to this.

Parameters:
`v2` - other Geo
Returns:
radian angle between v2 and this, and zero instead of NaN if the two geos are identical.

### angle

```public static double angle(Geo p0,
Geo p1,
Geo p2)```
Given 3 points on a sphere, p0, p1, p2, return the angle between them in radians.

### area

`public static double area(java.util.Enumeration<Geo> vs)`
Computes the area of a polygon on the surface of a unit sphere given an enumeration of its point. For a non unit sphere, multiply this by the radius of sphere squared. Make sure the first point doesn't equal the last.

### isInside

```public boolean isInside(Geo v2,
Geo p)```
Is the point, p, within radius radians of the great circle segment between this and v2?

### isInside

```public static boolean isInside(Geo v1,
Geo v2,
Geo p1,
Geo p2)```
do the segments v1-v2 and p1-p2 come within radius (radians) of each other?

### isInside

```public static boolean isInside(double lat1,
double lon1,
double lat2,
double lon2,
double lat3,
double lon3)```
Static version of isInside uses conventional (decimal degree) coordinates.

### inBubble

```public boolean inBubble(Geo v2,
Geo p)```
Is Geo p inside the time bubble along the great circle segment from this to v2 looking forward forwardRadius and backward backwardRadius.

### antipode

`public Geo antipode()`
Returns the point opposite this point on the earth.

### antipode

`public Geo antipode(Geo ret)`
Returns the point opposite this point on the earth. *

Returns:
ret Do not pass in a null value.

### intersect

```public Geo intersect(Geo q,
Geo r)```
Find the intersection of the great circle between this and q and the great circle normal to r.

That is, find the point, y, lying between this and q such that

```
y = [x*this + (1-x)*q]*c
where c = 1/y.dot(y) is a factor for normalizing y.
y.dot(r) = 0
substituting:
[x*this + (1-x)*q]*c.dot(r) = 0 or
[x*this + (1-x)*q].dot(r) = 0
x*this.dot(r) + (1-x)*q.dot(r) = 0
x*a + (1-x)*b = 0
x = -b/(a - b)

```
We assume that this and q are less than 180 degrees appart. When this and q are 180 degrees appart, the point -y is also a valid intersection.

Alternatively the intersection point, y, satisfies y.dot(r) = 0 y.dot(this.crossNormalize(q)) = 0 which is satisfied by y = r.crossNormalize(this.crossNormalize(q));

### intersect

```public Geo intersect(Geo q,
Geo r,
Geo ret)```
Find the intersection of the great circle between this and q and the great circle normal to r.

That is, find the point, y, lying between this and q such that

```
y = [x*this + (1-x)*q]*c
where c = 1/y.dot(y) is a factor for normalizing y.
y.dot(r) = 0
substituting:
[x*this + (1-x)*q]*c.dot(r) = 0 or
[x*this + (1-x)*q].dot(r) = 0
x*this.dot(r) + (1-x)*q.dot(r) = 0
x*a + (1-x)*b = 0
x = -b/(a - b)

```
We assume that this and q are less than 180 degrees apart. When this and q are 180 degrees apart, the point -y is also a valid intersection.

Alternatively the intersection point, y, satisfies y.dot(r) = 0 y.dot(this.crossNormalize(q)) = 0 which is satisfied by y = r.crossNormalize(this.crossNormalize(q));

Returns:
ret Do not pass in a null value.

### computeCorridor

```public static Geo[] computeCorridor(Geo[] path,

### computeCorridor

```public static Geo[] computeCorridor(Geo[] path,
double err,
boolean capp)```
Wrap a fixed-distance corridor around an (open) path, as specified by an array of Geo.

Parameters:
`path` - Open path, must not have repeated points or consecutive antipodes.
`radius` - Distance from path to widen corridor, in angular radians.
`err` - maximum angle of rounded edges, in radians. If 0, will directly cut outside bends.
`capp` - iff true, will round end caps
Returns:
a closed polygon representing the specified corridor around the path.

### approximateArc

```public static final Geo[] approximateArc(Geo pc,
Geo p0,
Geo p1,
double err)```
compute a polygonal approximation of an arc centered at pc, beginning at p0 and ending at p1, going clockwise and including the two end points.

Parameters:
`pc` - center point
`p0` - starting point
`p1` - ending point
`err` - The maximum angle between approximates allowed, in radians. Smaller values will look better but will result in more returned points.
Returns:
Geo array of arc points

### approximateArc

```public final Geo[] approximateArc(Geo p0,
Geo p1,
double err)```

### geoAt

```public Geo geoAt(double distance,
double azimuth)```
Deprecated. use #offset(double, double)

### offset

```public Geo offset(double distance,
double azimuth)```
Returns a Geo that is distance (radians), and azimuth (radians) away from this. this is undefined at the north pole, at which point "azimuth" is undefined.

Parameters:
`distance` - distance of this to the target point in radians.
`azimuth` - Direction of target point from this, in radians, clockwise from north.
Returns:
Geo at distance

### offset

```public Geo offset(double distance,
double azimuth,
Geo ret)```
Returns a Geo that is distance (radians), and azimuth (radians) away from this. This is undefined at the north pole, at which point "azimuth" is undefined.

Parameters:
`distance` - distance of this to the target point in radians.
`azimuth` - Direction of target point from this, in radians, clockwise from north.
Returns:
ret Do not pass in a null value.

### hashCode

`public int hashCode()`
Overrides:
`hashCode` in class `java.lang.Object`

### offset

```public static Geo offset(Geo origin,
double distance,
double azimuth)```

### offset

```public static Geo offset(Geo origin,
double distance,
double azimuth,
Geo ret)```
Parameters:
`origin` -
`distance` -
`azimuth` -
`ret` -
Returns:
ret Do not pass in a null value.

### posToGa

`public static Geo[] posToGa(java.lang.String coords)`
convert a String containing space-separated pairs of comma-separated decimal lat-lon pairs into a Geo array.

### posToGa

`public static Geo[] posToGa(java.lang.String[] coords)`
Convert an array of strings with comma-separated decimal lat,lon pairs into a Geo array

### GaToLLa

```public static double[] GaToLLa(Geo[] ga,
double[] lla)```
Convert a Geo array into a floating point lat lon array (alternating lat and lon values).

Returns:
the ll array provided, or a new array of lla is null.

### GaToLLa

```public static float[] GaToLLa(Geo[] ga,
float[] lla)```
Convert a Geo array into a floating point lat lon array (alternating lat and lon values).

Returns:
the ll array provided, or a new array of lla is null.

### GaToLLa

`public static float[] GaToLLa(Geo[] ga)`
Convert a Geo array into a floating point lat lon array (alternating lat and lon values)

### removeDups

`public static Geo[] removeDups(Geo[] ga)`
Return a Geo array with the duplicates removed. May arbitrarily mutate the input array.

### LLaToGa

`public static Geo[] LLaToGa(float[] lla)`
Convert a float array of alternating lat and lon pairs into a Geo array.

### LLaToGa

```public static Geo[] LLaToGa(float[] lla,
boolean isDegrees)```
Convert a float array of alternating lat and lon pairs into a Geo array.

### LLaToGa

`public static Geo[] LLaToGa(double[] lla)`
Convert a double array of alternating lat and lon pairs into a Geo array.

### LLaToGa

```public static Geo[] LLaToGa(double[] lla,
boolean isDegrees)```
Convert a double array of alternating lat and lon pairs into a Geo array.

### closeLLa

`public static float[] closeLLa(float[] lla)`
return a float array of alternating lat lon pairs where the first and last pair are the same, thus closing the path, by adding a point if needed. Does not mutate the input.

### closeGa

`public static Geo[] closeGa(Geo[] ga)`
return a Geo array where the first and last elements are the same, thus closing the path, by adding a point if needed. Does not mutate the input.

Copyright (C) BBNT Solutions LLC; See http://openmap.bbn.com/ for details