mgrscoordconverter.java
来自「world wind java sdk 源码」· Java 代码 · 共 1,161 行 · 第 1/3 页
JAVA
1,161 行
/*
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.globes.Globe;
import gov.nasa.worldwind.geom.Angle;
/**
* Converter used to translate MGRS coordinate strings to and from geodetic latitude and longitude.
*
* @author Patrick Murris
* @version $Id: MGRSCoordConverter.java 10332 2009-04-19 02:19:39Z patrickmurris $
* @see MGRSCoord
*/
/**
* Ported to Java from the NGA GeoTrans mgrs.c and mgrs.h code. Contains routines to convert
* from Geodetic to MGRS and the other direction.
*
* @author Garrett Headley, Patrick Murris
*/
class MGRSCoordConverter
{
public static final int MGRS_NO_ERROR = 0;
private static final int MGRS_LAT_ERROR = 0x0001;
private static final int MGRS_LON_ERROR = 0x0002;
public static final int MGRS_STRING_ERROR = 0x0004;
private static final int MGRS_PRECISION_ERROR = 0x0008;
private static final int MGRS_A_ERROR = 0x0010;
private static final int MGRS_INV_F_ERROR = 0x0020;
private static final int MGRS_EASTING_ERROR = 0x0040;
private static final int MGRS_NORTHING_ERROR = 0x0080;
private static final int MGRS_ZONE_ERROR = 0x0100;
private static final int MGRS_HEMISPHERE_ERROR = 0x0200;
private static final int MGRS_LAT_WARNING = 0x0400;
private static final int MGRS_NOZONE_WARNING = 0x0800;
private static final int MGRS_UTM_ERROR = 0x1000;
private static final int MGRS_UPS_ERROR = 0x2000;
private static final double PI = 3.14159265358979323;
private static final double PI_OVER_2 = (PI / 2.0e0);
private static final int MAX_PRECISION = 5;
private static final double MIN_UTM_LAT = (-80 * PI) / 180.0; // -80 degrees in radians
private static final double MAX_UTM_LAT = (84 * PI) / 180.0; // 84 degrees in radians
public static final double DEG_TO_RAD = 0.017453292519943295; // PI/180
private static final double RAD_TO_DEG = 57.29577951308232087; // 180/PI
private static final double MIN_EAST_NORTH = 0;
private static final double MAX_EAST_NORTH = 4000000;
private static final double TWOMIL = 2000000;
private static final double ONEHT = 100000;
private static final String CLARKE_1866 = "CC";
private static final String CLARKE_1880 = "CD";
private static final String BESSEL_1841 = "BR";
private static final String BESSEL_1841_NAMIBIA = "BN";
// Ellipsoid parameters, default to WGS 84
private double MGRS_a = 6378137.0; // Semi-major axis of ellipsoid in meters
private double MGRS_f = 1 / 298.257223563; // Flattening of ellipsoid
private double MGRS_recpf = 298.257223563;
private String MGRS_Ellipsoid_Code = "WE";
private Globe globe;
private String MGRSString = "";
private long ltr2_low_value;
private long ltr2_high_value; // this is only used for doing MGRS to xxx conversions.
private double false_northing;
private long lastLetter;
private long last_error = MGRS_NO_ERROR;
private double north, south, min_northing;
private double latitude;
private double longitude;
private static final int LETTER_A = 0; /* ARRAY INDEX FOR LETTER A */
private static final int LETTER_B = 1; /* ARRAY INDEX FOR LETTER B */
private static final int LETTER_C = 2; /* ARRAY INDEX FOR LETTER C */
private static final int LETTER_D = 3; /* ARRAY INDEX FOR LETTER D */
private static final int LETTER_E = 4; /* ARRAY INDEX FOR LETTER E */
private static final int LETTER_F = 5; /* ARRAY INDEX FOR LETTER E */
private static final int LETTER_G = 6; /* ARRAY INDEX FOR LETTER H */
private static final int LETTER_H = 7; /* ARRAY INDEX FOR LETTER H */
private static final int LETTER_I = 8; /* ARRAY INDEX FOR LETTER I */
private static final int LETTER_J = 9; /* ARRAY INDEX FOR LETTER J */
private static final int LETTER_K = 10; /* ARRAY INDEX FOR LETTER J */
private static final int LETTER_L = 11; /* ARRAY INDEX FOR LETTER L */
private static final int LETTER_M = 12; /* ARRAY INDEX FOR LETTER M */
private static final int LETTER_N = 13; /* ARRAY INDEX FOR LETTER N */
private static final int LETTER_O = 14; /* ARRAY INDEX FOR LETTER O */
private static final int LETTER_P = 15; /* ARRAY INDEX FOR LETTER P */
private static final int LETTER_Q = 16; /* ARRAY INDEX FOR LETTER Q */
private static final int LETTER_R = 17; /* ARRAY INDEX FOR LETTER R */
private static final int LETTER_S = 18; /* ARRAY INDEX FOR LETTER S */
private static final int LETTER_T = 19; /* ARRAY INDEX FOR LETTER S */
private static final int LETTER_U = 20; /* ARRAY INDEX FOR LETTER U */
private static final int LETTER_V = 21; /* ARRAY INDEX FOR LETTER V */
private static final int LETTER_W = 22; /* ARRAY INDEX FOR LETTER W */
private static final int LETTER_X = 23; /* ARRAY INDEX FOR LETTER X */
private static final int LETTER_Y = 24; /* ARRAY INDEX FOR LETTER Y */
private static final int LETTER_Z = 25; /* ARRAY INDEX FOR LETTER Z */
private static final int MGRS_LETTERS = 3; /* NUMBER OF LETTERS IN MGRS */
private static final String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// UPS Constants are in the following order:
// long letter; /* letter representing latitude band */
// long ltr2_low_value; /* 2nd letter range - high number */
// long ltr2_high_value; /* 2nd letter range - low number */
// long ltr3_high_value; /* 3rd letter range - high number (UPS) */
// double false_easting; /* False easting based on 2nd letter */
// double false_northing; /* False northing based on 3rd letter */
private static final long[][] upsConstants = {
{LETTER_A, LETTER_J, LETTER_Z, LETTER_Z, 800000, 800000},
{LETTER_B, LETTER_A, LETTER_R, LETTER_Z, 2000000, 800000},
{LETTER_Y, LETTER_J, LETTER_Z, LETTER_P, 800000, 1300000},
{LETTER_Z, LETTER_A, LETTER_J, LETTER_P, 2000000, 1300000}};
// Latitude Band Constants are in the following order:
// long letter; /* letter representing latitude band */
// double min_northing; /* minimum northing for latitude band */
// double north; /* upper latitude for latitude band */
// double south; /* lower latitude for latitude band */
private static final double[][] latitudeBandConstants = {
{LETTER_C, 1100000.0, -72.0, -80.5},
{LETTER_D, 2000000.0, -64.0, -72.0},
{LETTER_E, 2800000.0, -56.0, -64.0},
{LETTER_F, 3700000.0, -48.0, -56.0},
{LETTER_G, 4600000.0, -40.0, -48.0},
{LETTER_H, 5500000.0, -32.0, -40.0},
{LETTER_J, 6400000.0, -24.0, -32.0},
{LETTER_K, 7300000.0, -16.0, -24.0},
{LETTER_L, 8200000.0, -8.0, -16.0},
{LETTER_M, 9100000.0, 0.0, -8.0},
{LETTER_N, 0.0, 8.0, 0.0},
{LETTER_P, 800000.0, 16.0, 8.0},
{LETTER_Q, 1700000.0, 24.0, 16.0},
{LETTER_R, 2600000.0, 32.0, 24.0},
{LETTER_S, 3500000.0, 40.0, 32.0},
{LETTER_T, 4400000.0, 48.0, 40.0},
{LETTER_U, 5300000.0, 56.0, 48.0},
{LETTER_V, 6200000.0, 64.0, 56.0},
{LETTER_W, 7000000.0, 72.0, 64.0},
{LETTER_X, 7900000.0, 84.5, 72.0}};
private class MGRSComponents
{
private final int zone;
private final int latitudeBand;
private final int squareLetter1;
private final int squareLetter2;
private final double easting;
private final double northing;
private final int precision;
public MGRSComponents(int zone, int latitudeBand, int squareLetter1, int squareLetter2,
double easting, double northing, int precision)
{
this.zone = zone;
this.latitudeBand = latitudeBand;
this.squareLetter1 = squareLetter1;
this.squareLetter2 = squareLetter2;
this.easting = easting;
this.northing = northing;
this.precision = precision;
}
public String toString()
{
return "MGRS: " + zone + " " +
alphabet.charAt(latitudeBand) + " " +
alphabet.charAt(squareLetter1) + alphabet.charAt(squareLetter2) + " " +
easting + " " +
northing + " " +
"(" + precision + ")";
}
}
MGRSCoordConverter(Globe globe)
{
this.globe = globe;
if(globe != null)
{
double a = globe.getEquatorialRadius();
double f = (globe.getEquatorialRadius() - globe.getPolarRadius()) / globe.getEquatorialRadius();
setMGRSParameters(a, f, MGRS_Ellipsoid_Code);
}
}
/**
* The function setMGRSParameters receives the ellipsoid parameters and sets the corresponding state variables. If
* any errors occur, the error code(s) are returned by the function, otherwise MGRS_NO_ERROR is returned.
*
* @param mgrs_a Semi-major axis of ellipsoid in meters
* @param mgrs_f Flattening of ellipsoid
* @param ellipsoidCode 2-letter code for ellipsoid
* @return error code
*/
public long setMGRSParameters(double mgrs_a, double mgrs_f, String ellipsoidCode)
{
if (mgrs_a <= 0.0)
return MGRS_A_ERROR;
if (mgrs_f == 0.0)
return MGRS_INV_F_ERROR;
double inv_f = 1 / mgrs_f;
if (inv_f < 250 || inv_f > 350)
return MGRS_INV_F_ERROR;
MGRS_a = mgrs_a;
MGRS_f = mgrs_f;
MGRS_Ellipsoid_Code = ellipsoidCode;
return MGRS_NO_ERROR;
}
/**
* @return Flattening of ellipsoid
*/
public double getMGRS_f()
{
return MGRS_f;
}
/**
* @return Semi-major axis of ellipsoid in meters
*/
public double getMGRS_a()
{
return MGRS_a;
}
/**
* @return Latitude band letter
*/
private long getLastLetter()
{
return lastLetter;
}
/**
* @return 2-letter code for ellipsoid
*/
public String getMGRS_Ellipsoid_Code()
{
return MGRS_Ellipsoid_Code;
}
/**
* The function ConvertMGRSToGeodetic converts an MGRS coordinate string
* to Geodetic (latitude and longitude) coordinates
* according to the current ellipsoid parameters. If any errors occur,
* the error code(s) are returned by the function, otherwise UTM_NO_ERROR
* is returned.
*
* @param MGRSString MGRS coordinate string.
* @return the error code.
*/
public long convertMGRSToGeodetic (String MGRSString)
{
latitude = 0;
longitude = 0;
long error_code = checkZone(MGRSString);
if (error_code == MGRS_NO_ERROR)
{
UTMCoord UTM = convertMGRSToUTM (MGRSString);
if(UTM != null)
{
latitude = UTM.getLatitude().radians;
longitude = UTM.getLongitude().radians;
}
else
error_code = MGRS_UTM_ERROR;
}
else if (error_code == MGRS_NOZONE_WARNING)
{
// TODO: polar conversion
UPSCoord UPS = convertMGRSToUPS(MGRSString);
if(UPS != null)
{
latitude = UPS.getLatitude().radians;
longitude = UPS.getLongitude().radians;
}
else
error_code = MGRS_UPS_ERROR;
}
return (error_code);
}
public double getLatitude()
{
return latitude;
}
public double getLongitude()
{
return longitude;
}
/**
* The function Break_MGRS_String breaks down an MGRS
* coordinate string into its component parts. Updates last_error.
*
* @param MGRSString the MGRS coordinate string
* @return the corresponding <code>MGRSComponents</code> or <code>null</code>.
*/
private MGRSComponents breakMGRSString (String MGRSString)
{
int num_digits;
int num_letters;
int i = 0;
int j = 0;
long error_code = MGRS_NO_ERROR;
int zone = 0;
int[] letters = new int[3];
long easting = 0;
long northing = 0;
int precision = 0;
while (i < MGRSString.length() && MGRSString.charAt(i) == ' ')
i++; /* skip any leading blanks */
j = i;
while (i < MGRSString.length() && Character.isDigit(MGRSString.charAt(i)))
i++;
num_digits = i - j;
if (num_digits <= 2)
if (num_digits > 0)
{
/* get zone */
zone = Integer.parseInt(MGRSString.substring(j, i));
if ((zone < 1) || (zone > 60))
error_code |= MGRS_STRING_ERROR;
}
else
error_code |= MGRS_STRING_ERROR;
j = i;
while (i < MGRSString.length() && Character.isLetter(MGRSString.charAt(i)))
i++;
num_letters = i - j;
if (num_letters == 3)
{
/* get letters */
letters[0] = alphabet.indexOf(Character.toUpperCase(MGRSString.charAt(j)));
if ((letters[0] == LETTER_I) || (letters[0] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
letters[1] = alphabet.indexOf(Character.toUpperCase(MGRSString.charAt(j + 1)));
if ((letters[1] == LETTER_I) || (letters[1] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
letters[2] = alphabet.indexOf(Character.toUpperCase(MGRSString.charAt(j + 2)));
if ((letters[2] == LETTER_I) || (letters[2] == LETTER_O))
error_code |= MGRS_STRING_ERROR;
}
else
error_code |= MGRS_STRING_ERROR;
j = i;
while (i < MGRSString.length() && Character.isDigit(MGRSString.charAt(i)))
i++;
num_digits = i - j;
if ((num_digits <= 10) && (num_digits % 2 == 0))
{
/* get easting, northing and precision */
int n;
double multiplier;
/* get easting & northing */
n = num_digits / 2;
precision = n;
if (n > 0)
{
easting = Integer.parseInt(MGRSString.substring(j, j + n));
northing = Integer.parseInt(MGRSString.substring(j + n, j + n + n));
multiplier = Math.pow (10.0, 5 - n);
easting *= multiplier;
northing *= multiplier;
}
else
{
easting = 0;
northing = 0;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?