/*
Copyright (C) 2001, 2008 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/
package gov.nasa.worldwind.geom.coords;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.globes.Globe;
import gov.nasa.worldwind.util.Logging;
/**
* This class holds a set of Transverse Mercator coordinates along with the
* corresponding latitude and longitude.
*
* @author Patrick Murris
* @version $Id: TMCoord.java 5188 2008-04-27 02:05:53Z patrickmurris $
* @see TMCoordConverter
*/
public class TMCoord
{
private final Angle latitude;
private final Angle longitude;
private final Angle originLatitude;
private final Angle centralMeridian;
private final double falseEasting;
private final double falseNorthing;
private final double scale;
private final double easting;
private final double northing;
/**
* Create a set of Transverse Mercator coordinates from a pair of latitude and longitude,
* for the given <code>Globe</code> and projection parameters.
*
* @param latitude the latitude <code>Angle</code>.
* @param longitude the longitude <code>Angle</code>.
* @param globe the <code>Globe</code> - can be null (will use WGS84).
* @param originLatitude the origin latitude <code>Angle</code>.
* @param centralMeridian the central meridian longitude <code>Angle</code>.
* @param falseEasting easting value at the center of the projection in meters.
* @param falseNorthing northing value at the center of the projection in meters.
* @param scale scaling factor.
* @return the corresponding <code>TMCoord</code>.
* @throws IllegalArgumentException if <code>latitude</code> or <code>longitude</code> is null,
* or the conversion to TM coordinates fails. If the globe is null conversion will default
* to using WGS84.
*/
public static TMCoord fromLatLon(Angle latitude, Angle longitude, Globe globe,
Angle originLatitude, Angle centralMeridian,
double falseEasting, double falseNorthing,
double scale)
{
if (latitude == null || longitude == null)
{
String message = Logging.getMessage("nullValue.LatitudeOrLongitudeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (originLatitude == null || centralMeridian == null)
{
String message = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
final TMCoordConverter converter = new TMCoordConverter();
double a, f;
if (globe != null)
{
a = globe.getEquatorialRadius();
f = (globe.getEquatorialRadius() - globe.getPolarRadius()) / globe.getEquatorialRadius();
}
else
{
a = converter.getA();
f = converter.getF();
}
long err = converter.setTransverseMercatorParameters(a, f, originLatitude.radians, centralMeridian.radians,
falseEasting, falseNorthing, scale);
if (err == TMCoordConverter.TRANMERC_NO_ERROR)
err = converter.convertGeodeticToTransverseMercator(latitude.radians, longitude.radians);
if (err != TMCoordConverter.TRANMERC_NO_ERROR && err != TMCoordConverter.TRANMERC_LON_WARNING)
{
String message = Logging.getMessage("Coord.TMConversionError");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return new TMCoord(latitude, longitude, converter.getEasting(), converter.getNorthing(),
originLatitude, centralMeridian, falseEasting, falseNorthing, scale);
}
/**
* Create a set of Transverse Mercator coordinates for the given <code>Globe</code>,
* easting, northing and projection parameters.
*
* @param easting the easting distance value in meters.
* @param northing the northing distance value in meters.
* @param globe the <code>Globe</code> - can be null (will use WGS84).
* @param originLatitude the origin latitude <code>Angle</code>.
* @param centralMeridian the central meridian longitude <code>Angle</code>.
* @param falseEasting easting value at the center of the projection in meters.
* @param falseNorthing northing value at the center of the projection in meters.
* @param scale scaling factor.
* @return the corresponding <code>TMCoord</code>.
* @throws IllegalArgumentException if <code>originLatitude</code> or <code>centralMeridian</code>
* is null, or the conversion to geodetic coordinates fails. If the globe is null conversion will default
* to using WGS84.
*/
public static TMCoord fromTM(double easting, double northing, Globe globe,
Angle originLatitude, Angle centralMeridian,
double falseEasting, double falseNorthing,
double scale)
{
if (originLatitude == null || centralMeridian == null)
{
String message = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
final TMCoordConverter converter = new TMCoordConverter();
double a, f;
if (globe != null)
{
a = globe.getEquatorialRadius();
f = (globe.getEquatorialRadius() - globe.getPolarRadius()) / globe.getEquatorialRadius();
}
else
{
a = converter.getA();
f = converter.getF();
}
long err = converter.setTransverseMercatorParameters(a, f, originLatitude.radians, centralMeridian.radians,
falseEasting, falseNorthing, scale);
if (err == TMCoordConverter.TRANMERC_NO_ERROR)
err = converter.convertTransverseMercatorToGeodetic(easting, northing);
if (err != TMCoordConverter.TRANMERC_NO_ERROR && err != TMCoordConverter.TRANMERC_LON_WARNING)
{
String message = Logging.getMessage("Coord.TMConversionError");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
return new TMCoord(Angle.fromRadians(converter.getLatitude()), Angle.fromRadians(converter.getLongitude()),
easting, northing, originLatitude, centralMeridian, falseEasting, falseNorthing, scale);
}
/**
* Create an arbitrary set of Transverse Mercator coordinates with the given values.
*
* @param latitude the latitude <code>Angle</code>.
* @param longitude the longitude <code>Angle</code>.
* @param easting the easting distance value in meters.
* @param northing the northing distance value in meters.
* @param originLatitude the origin latitude <code>Angle</code>.
* @param centralMeridian the central meridian longitude <code>Angle</code>.
* @param falseEasting easting value at the center of the projection in meters.
* @param falseNorthing northing value at the center of the projection in meters.
* @param scale scaling factor.
* @throws IllegalArgumentException if <code>latitude</code>, <code>longitude</code>, <code>originLatitude</code>
* or <code>centralMeridian</code> is null.
*/
public TMCoord(Angle latitude, Angle longitude, double easting, double northing,
Angle originLatitude, Angle centralMeridian,
double falseEasting, double falseNorthing,
double scale)
{
if (latitude == null || longitude == null)
{
String message = Logging.getMessage("nullValue.LatitudeOrLongitudeIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (originLatitude == null || centralMeridian == null)
{
String message = Logging.getMessage("nullValue.AngleIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
this.latitude = latitude;
this.longitude = longitude;
this.easting = easting;
this.northing = northing;
this.originLatitude = originLatitude;
this.centralMeridian = centralMeridian;
this.falseEasting = falseEasting;
this.falseNorthing = falseNorthing;
this.scale = scale;
}
public Angle getLatitude()
{
return this.latitude;
}
public Angle getLongitude()
{
return this.longitude;
}
public Angle getOriginLatitude()
{
return this.originLatitude;
}
public Angle getCentralMeridian()
{
return this.centralMeridian;
}
public double getFalseEasting()
{
return this.falseEasting;
}
public double getFalseNorthing()
{
return this.falseNorthing;
}
public double getScale()
{
return this.scale;
}
public double getEasting()
{
return this.easting;
}
public double getNorthing()
{
return this.northing;
}
}