📄 utmpoint.java
字号:
/** * 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 lon = (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); lon = LongOrigin + ProjMath.radToDeg(lon); if (llpoint != null) { llpoint.setLatLon((float) lat, (float) lon); return llpoint; } else { return new LatLonPoint((float) lat, (float) lon); } } /** * Find zone number based on the given latitude and longitude in *degrees*. * * @param lat * @param lon * @return */ public static int getZoneNumber(double lat, double lon) { int zoneNumber = (int) ((lon + 180) / 6) + 1; //Make sure the longitude 180.00 is in Zone 60 if (lon == 180) { zoneNumber = 60; } // Special zone for Norway if (lat >= 56.0f && lat < 64.0f && lon >= 3.0f && lon < 12.0f) { zoneNumber = 32; } // Special zones for Svalbard if (lat >= 72.0f && lat < 84.0f) { if (lon >= 0.0f && lon < 9.0f) zoneNumber = 31; else if (lon >= 9.0f && lon < 21.0f) zoneNumber = 33; else if (lon >= 21.0f && lon < 33.0f) zoneNumber = 35; else if (lon >= 33.0f && lon < 42.0f) zoneNumber = 37; } return zoneNumber; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -