## com.bbn.openmap.geo
Class Geo

    java.lang.Object
      com.bbn.openmap.geo.Geo

public class Geo
extends java.lang.Object

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.4.2.15 $ on $Date: 2007/02/13 20:00:54 $
Author:
  Ken Anderson, Sachin Date, Ben Lubin, Michael Thome

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 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 this to v2.
`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)` alias for computeCorridor(path, radius, radians(10), true) *
`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)` Eqvivalent to this.cross(b).length().
`Geo` `crossNormalize(Geo b)` Eqvivalent to `this.cross(b).normalize()`.
`Geo` `crossNormalize(Geo b, Geo ret)` Eqvivalent to `this.cross(b).normalize()`.
`static Geo` `crossNormalize(Geo a, Geo b, Geo ret)` Eqvivalent to `this.cross(b).normalize()`.
`static double` `degrees(double radians)` Convert from radians to degrees.
`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(Geo v2)`
`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()`
`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)` Convert radians to kilometers.
`static double` `kmToAngle(double km)` Convert kilometers to radians.
`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)` Convert radians to nauticalMiles.
`static double` `nmToAngle(double nm)` Convert nautical miles to radians.
`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)` Convert from degrees to radians.
`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)`
`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 reprensentation (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, equals, finalize, getClass, hashCode, 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

  See Also:
    Constant Field Values

### FLATTENING_C

    public static final double FLATTENING_C

See Also:
  Constant Field Values

### METERS_PER_NM

    public static final double METERS_PER_NM

See Also:
  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)

### radians

    public static double radians(double degrees)

  Convert from degrees to radians.

### degrees

    public static double degrees(double radians)

  Convert from radians to degrees.

### km

    public static double km(double radians)

  Convert radians to kilometers. *

### kmToAngle

    public static double kmToAngle(double km)

  Convert kilometers to radians. *

### nm

    public static double nm(double radians)

  Convert radians to nauticalMiles. *

### nmToAngle

    public static double nmToAngle(double nm)

  Convert nautical miles to radians. *

### makeGeoRadians

    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.

### initializeRadians

    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:

### toString

    public java.lang.String toString()

### getLatitude

    public double getLatitude()

### getLongitude

    public double getLongitude()

### getLatitudeRadians

    public double getLatitudeRadians()

### getLongitudeRadians

    public double getLongitudeRadians()

### x

    public final double x()

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

  Returns:

### y

    public final double y()

  Reader for y in internal axis reprensentation (positive into screen).

  Returns:

### z

    public final double z()

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

  Returns:

### setLength

    public void setLength(double r)

### dot

    public double dot(Geo b)

  Dot product.

### dot

    public static double dot(Geo a,
                             Geo b)

  Dot product.

### 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.

  Returns:
    ret Do not pass in a null value.

### crossLength

    public double crossLength(Geo b)

  Eqvivalent to this.cross(b).length().

### crossNormalize

    public Geo crossNormalize(Geo b)

  Eqvivalent to `this.cross(b).normalize()`.

### crossNormalize

    public Geo crossNormalize(Geo b,
                              Geo ret)

  Eqvivalent 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)

  Eqvivalent to `this.cross(b).normalize()`.

  Returns:
    ret Do not pass in a null value.

### add

    public Geo add(Geo b)

  Returns this + b.

### add

    public Geo add(Geo b,
                   Geo ret)

### 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(Geo v2)

### 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. *

### azimuth

    public double azimuth(Geo v2)

  Azimuth in radians from this to v2.

### 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 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.

### isInside

    public boolean isInside(Geo v2,
                            double radius,
                            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,
                                   double radius,
                                   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 radius,
                                   double lat3,
                                   double lon3)

  Static version of isInside uses conventional (decimal degree) coordinates.

### inBubble

    public 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.

### 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 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));

  Returns:
    ret Do not pass in a null value.

### computeCorridor

    public static Geo[] computeCorridor(Geo[] path,
                                        double radius)

  alias for computeCorridor(path, radius, radians(10), true) *

### computeCorridor

    public 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.

  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:

### 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.

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

### offset

    public Geo offset(double distance,
                      double azimuth,
                      Geo ret)

  Returns a Geo that is distance (radians), and azimuth (radians) away from this.

  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.

### 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