📄 utmpoint.java
字号:
/ 24.0d + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0d))); if (Lat < 0.0f) { UTMNorthing += 10000000.0f; //10000000 meter offset for // southern hemisphere } if (utmpoint == null) { utmpoint = new UTMPoint(); } utmpoint.northing = (float) Math.rint(UTMNorthing); utmpoint.easting = (float) Math.rint(UTMEasting); utmpoint.zone_number = ZoneNumber; utmpoint.zone_letter = utmpoint.getLetterDesignator(Lat); return utmpoint; } /** * Returns 'N' if the latitude is equal to or above the equator, * 'S' if it's below. * * @param lat The float value of the latitude. * * @return A char value */ protected char getLetterDesignator(double lat) { char letterDesignator = 'N'; if (lat < 0) { letterDesignator = 'S'; } return letterDesignator; } /** * Converts UTM coords to lat/long given an ellipsoid given an * instance of UTMPoint. * * @param utm_point A UTMPoint instance. * @param ellip a ellipsoid definition. * @param llpoint a LatLonPoint, if you want it to be filled in * with the results. If null, a new LatLonPoint will be * allocated. * @return A LatLonPoint class instance containing the lat/long * value, or <code>null</code> if conversion failed. If * you pass in a LatLonPoint, it will be returned as well, * if successful. */ public static LatLonPoint UTMtoLL(UTMPoint utm_point, Ellipsoid ellip, LatLonPoint llpoint) { return UTMtoLL(ellip, utm_point.northing, utm_point.easting, utm_point.zone_number, utm_point.zone_letter, llpoint); } /** * Converts UTM coords to lat/long given an ellipsoid. This is a * convenience class where the Zone can be specified as a single * string eg."61N" which is then broken down into the ZoneNumber * and ZoneLetter. * * @param ellip an ellipsoid definition. * @param UTMNorthing A float value for the northing to be * converted. * @param UTMEasting A float value for the easting to be * converted. * @param UTMZone A String value for the UTM zone eg."61N". * @param llpoint a LatLonPoint, if you want it to be filled in * with the results. If null, a new LatLonPoint will be * allocated. * @return A LatLonPoint class instance containing the lat/long * value, or <code>null</code> if conversion failed. If * you pass in a LatLonPoint, it will be returned as well, * if successful. */ public static LatLonPoint UTMtoLL(Ellipsoid ellip, float UTMNorthing, float UTMEasting, String UTMZone, LatLonPoint llpoint) { //without the zone we can't calculate the Lat and Long if (UTMZone == null || UTMZone.equals("")) { return null; } int ZoneNumber = 1; char ZoneLetter = 'N'; //northern hemisphere by default if no // character is found //Break out the Zone number and zone letter from the UTMZone //string We assume the string is a valid zone with a number //followed by a zone letter If there is no Letter we assume //that it's the Northern hemisphere int ln = UTMZone.length() - 1; if (ln > 0) { //If it's Zero then there is only one character and it // must be the Zone number ZoneLetter = UTMZone.charAt(ln); if (!Character.isLetter(ZoneLetter)) { //No letter so assume it's missing & default to 'N' ZoneLetter = 'N'; ln++; } } //convert the number but catch the exception if it's not // valid try { ZoneNumber = Integer.parseInt(UTMZone.substring(0, ln)); } catch (NumberFormatException nfe) { return null; } return UTMtoLL(ellip, UTMNorthing, UTMEasting, ZoneNumber, ZoneLetter, llpoint); } /** * Converts UTM coords to lat/long given an ellipsoid. This is a * convenience class where the exact Zone letter is not known. * Instead only the hemisphere needs to be indicated. * * @param ellip an ellipsoid definition. * @param UTMNorthing A float value for the northing to be * converted. * @param UTMEasting A float value for the easting to be * converted. * @param ZoneNumber An int value indicating the float number. * @param isnorthern A boolean which is true for the northern * hemisphere otherwise false for the southern. * @param llpoint a LatLonPoint, if you want it to be filled in * with the results. If null, a new LatLonPoint will be * allocated. * @return A LatLonPoint class instance containing the lat/long * value, or <code>null</code> if conversion failed. If * you pass in a LatLonPoint, it will be returned as well, * if successful. */ public static LatLonPoint UTMtoLL(Ellipsoid ellip, float UTMNorthing, float UTMEasting, int ZoneNumber, boolean isnorthern, LatLonPoint llpoint) { return UTMtoLL(ellip, UTMNorthing, UTMEasting, ZoneNumber, (isnorthern) ? 'N' : 'S', llpoint); } /** * Converts UTM coords to lat/long given an ellipsoid. * <p> * Equations from USGS Bulletin 1532 <br> * East Longitudes are positive, West longitudes are negative. * <br> * North latitudes are positive, South latitudes are negative. * <br> * * @param ellip an ellipsoid definition. * @param UTMNorthing A float value for the northing to be * converted. * @param UTMEasting A float value for the easting to be * converted. * @param ZoneNumber An int value specifiying the UTM zone number. * @param ZoneLetter A char value specifying the ZoneLetter within * the ZoneNumber. * @param llpoint a LatLonPoint, if you want it to be filled in * with the results. If null, a new LatLonPoint will be * allocated. * @return A LatLonPoint class instance containing the lat/long * value, or <code>null</code> if conversion failed. If * you pass in a LatLonPoint, it will be returned as well, * if successful. */ public static LatLonPoint UTMtoLL(Ellipsoid ellip, float UTMNorthing, float UTMEasting, int ZoneNumber, char ZoneLetter, LatLonPoint llpoint) { //check the ZoneNummber is valid if (ZoneNumber < 0 || ZoneNumber > 60) { return null; } double k0 = 0.9996; double a = ellip.radius; double eccSquared = ellip.eccsq; double eccPrimeSquared; double e1 = (1 - Math.sqrt(1 - eccSquared)) / (1 + Math.sqrt(1 - eccSquared)); double N1, T1, C1, R1, D, M; double LongOrigin; double mu, phi1Rad; // remove 500,000 meter offset for longitude double x = UTMEasting - 500000.0d; double y = UTMNorthing; //We must know somehow if we are in the Northern or Southern //hemisphere, this is the only time we use the letter So even //if the Zone letter isn't exactly correct it should indicate //the hemisphere correctly if (ZoneLetter == 'S') { y -= 10000000.0d;//remove 10,000,000 meter offset used // for southern hemisphere } //There are 60 zones with zone 1 being at West -180 to -174 LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin // in middle of // zone eccPrimeSquared = (eccSquared) / (1 - eccSquared); M = y / k0; mu = M / (a * (1 - eccSquared / 4 - 3 * eccSquared * eccSquared / 64 - 5 * eccSquared * eccSquared * eccSquared / 256)); phi1Rad = mu + (3 * e1 / 2 - 27 * e1 * e1 * e1 / 32) * Math.sin(2 * mu) + (21 * e1 * e1 / 16 - 55 * e1 * e1 * e1 * e1 / 32) * Math.sin(4 * mu) + (151 * e1 * e1 * e1 / 96) * Math.sin(6 * mu);// double phi1 = ProjMath.radToDeg(phi1Rad); N1 = a / Math.sqrt(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad)); T1 = Math.tan(phi1Rad) * Math.tan(phi1Rad); C1 = eccPrimeSquared * Math.cos(phi1Rad) * Math.cos(phi1Rad); R1 = a * (1 - eccSquared) / Math.pow(1 - eccSquared * Math.sin(phi1Rad) * Math.sin(phi1Rad), 1.5); D = x / (N1 * k0); double Lat = phi1Rad - (N1 * Math.tan(phi1Rad) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * eccPrimeSquared) * D * D * D * D / 24 + (61 + 90 * T1 + 298 * C1 + 45 * T1 * T1 - 252 * eccPrimeSquared - 3 * C1 * C1) * D * D * D * D * D * D / 720); Lat = ProjMath.radToDeg(Lat); double Long = (D - (1 + 2 * T1 + C1) * D * D * D / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * eccPrimeSquared + 24 * T1 * T1) * D * D * D * D * D / 120) / Math.cos(phi1Rad); Long = LongOrigin + ProjMath.radToDeg(Long); if (llpoint != null) { llpoint.setLatLon((float) Lat, (float) Long); return llpoint; } else { return new LatLonPoint((float) Lat, (float) Long); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -