Changed easting and northing arguments to int.
Signed-off-by: S. Kozyr <s.trump@gmail.com>
This commit is contained in:
parent
75b9b134eb
commit
045dd831f9
4 changed files with 66 additions and 77 deletions
|
@ -4,7 +4,6 @@
|
|||
#include "base/math.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
namespace utm_mgrs_utils
|
||||
|
@ -47,7 +46,7 @@ constexpr double P3 = (21.0 / 16.0 * _E2 - 55.0 / 32.0 * _E4);
|
|||
constexpr double P4 = (151.0 / 96.0 * _E3 - 417.0 / 128.0 * _E5);
|
||||
constexpr double P5 = (1097.0 / 512.0 * _E4);
|
||||
|
||||
constexpr double kInvalidNorthing = -1.0;
|
||||
constexpr int kInvalidEastingNorthing = -1;
|
||||
|
||||
const string ZONE_LETTERS = "CDEFGHJKLMNPQRSTUVWXX";
|
||||
|
||||
|
@ -235,23 +234,23 @@ string utm_to_mgrs_str(UTMPoint point, int precision)
|
|||
// Convert UTM parameters to lat,lon for WSG 84 ellipsoid.
|
||||
// If UTM parameters are valid lat and lon references are used to output calculated coordinates.
|
||||
// Otherwise function returns 'false'.
|
||||
std::optional<ms::LatLon> UTMtoLatLon(double easting, double northing, int zone_number, char zone_letter)
|
||||
std::optional<ms::LatLon> UTMtoLatLon(int easting, int northing, int zone_number, char zone_letter)
|
||||
{
|
||||
if (zone_number < 1 || zone_number > 60)
|
||||
return nullopt;
|
||||
|
||||
if (easting < 100000.0 || easting >= 1000000.0)
|
||||
if (easting < 100000 || easting >= 1000000)
|
||||
return nullopt;
|
||||
|
||||
if (northing < 0.0 || northing > 10000000.0)
|
||||
if (northing < 0 || northing > 10000000)
|
||||
return nullopt;
|
||||
|
||||
if (zone_letter<'C' || zone_letter>'X' || zone_letter == 'I' || zone_letter == 'O')
|
||||
return nullopt;
|
||||
|
||||
bool northern = (zone_letter >= 'N');
|
||||
double x = easting - 500000.0;
|
||||
double y = northing;
|
||||
double x = (double)easting - 500000.0;
|
||||
double y = (double)northing;
|
||||
|
||||
if (!northern)
|
||||
y -= 10000000.0;
|
||||
|
@ -299,7 +298,7 @@ std::optional<ms::LatLon> UTMtoLatLon(double easting, double northing, int zone_
|
|||
d3 / 6.0 * (1.0 + 2.0 * p_tan2 + c) +
|
||||
d5 / 120.0 * (5.0 - 2.0 * c + 28.0 * p_tan2 - 3.0 * c2 + 8.0 * E_P2 + 24.0 * p_tan4)) / p_cos;
|
||||
|
||||
longitude = mod_angle(longitude + DegToRad(zone_number_to_central_longitude(zone_number)));
|
||||
longitude = mod_angle(longitude + DegToRad((double)zone_number_to_central_longitude(zone_number)));
|
||||
|
||||
return LatLon(RadToDeg(latitude), RadToDeg(longitude));
|
||||
}
|
||||
|
@ -308,9 +307,9 @@ std::optional<ms::LatLon> UTMtoLatLon(double easting, double northing, int zone_
|
|||
/* Given the first letter from a two-letter MGRS 100k zone, and given the
|
||||
* MGRS table set for the zone number, figure out the easting value that
|
||||
* should be added to the other, secondary easting value.*/
|
||||
double square_char_to_easting(char e, int set) {
|
||||
int square_char_to_easting(char e, int set) {
|
||||
int curCol = SET_ORIGIN_COLUMN_LETTERS[set];
|
||||
double eastingValue = 100000.0;
|
||||
int eastingValue = 100000;
|
||||
bool rewindMarker = false;
|
||||
|
||||
while (curCol != e)
|
||||
|
@ -323,11 +322,11 @@ double square_char_to_easting(char e, int set) {
|
|||
if (curCol > 'Z')
|
||||
{
|
||||
if (rewindMarker)
|
||||
return kInvalidNorthing;
|
||||
return kInvalidEastingNorthing;
|
||||
curCol = 'A';
|
||||
rewindMarker = true;
|
||||
}
|
||||
eastingValue += 100000.0;
|
||||
eastingValue += 100000;
|
||||
}
|
||||
|
||||
return eastingValue;
|
||||
|
@ -341,20 +340,14 @@ double square_char_to_easting(char e, int set) {
|
|||
* cycle of letters mean a 2000000 additional northing meters. This happens
|
||||
* approx. every 18 degrees of latitude. This method does *NOT* count any
|
||||
* additional northings. You have to figure out how many 2000000 meters need
|
||||
* to be added for the zone letter of the MGRS coordinate.
|
||||
*
|
||||
* @param n
|
||||
* second letter of the MGRS 100k zone
|
||||
* @param set
|
||||
* the MGRS table set number, which is dependent on the UTM zone
|
||||
* number. */
|
||||
double square_char_to_northing(char n, int set)
|
||||
* to be added for the zone letter of the MGRS coordinate. */
|
||||
int square_char_to_northing(char n, int set)
|
||||
{
|
||||
if (n > 'V')
|
||||
return kInvalidNorthing;
|
||||
return kInvalidEastingNorthing;
|
||||
|
||||
int curRow = SET_ORIGIN_ROW_LETTERS[set];
|
||||
double northingValue = 0.0;
|
||||
int northingValue = 0;
|
||||
bool rewindMarker = false;
|
||||
|
||||
while (curRow != n)
|
||||
|
@ -367,11 +360,11 @@ double square_char_to_northing(char n, int set)
|
|||
if (curRow > 'V')
|
||||
{
|
||||
if (rewindMarker) // Making sure that this loop ends even if n has invalid value.
|
||||
return kInvalidNorthing;
|
||||
return kInvalidEastingNorthing;
|
||||
curRow = 'A';
|
||||
rewindMarker = true;
|
||||
}
|
||||
northingValue += 100000.0;
|
||||
northingValue += 100000;
|
||||
}
|
||||
|
||||
return northingValue;
|
||||
|
@ -379,80 +372,80 @@ double square_char_to_northing(char n, int set)
|
|||
|
||||
|
||||
// Get minimum northing value of a MGRS zone.
|
||||
double zone_to_min_northing(char zoneLetter)
|
||||
int zone_to_min_northing(char zoneLetter)
|
||||
{
|
||||
double northing;
|
||||
int northing;
|
||||
switch (zoneLetter)
|
||||
{
|
||||
case 'C':
|
||||
northing = 1100000.0;
|
||||
northing = 1100000;
|
||||
break;
|
||||
case 'D':
|
||||
northing = 2000000.0;
|
||||
northing = 2000000;
|
||||
break;
|
||||
case 'E':
|
||||
northing = 2800000.0;
|
||||
northing = 2800000;
|
||||
break;
|
||||
case 'F':
|
||||
northing = 3700000.0;
|
||||
northing = 3700000;
|
||||
break;
|
||||
case 'G':
|
||||
northing = 4600000.0;
|
||||
northing = 4600000;
|
||||
break;
|
||||
case 'H':
|
||||
northing = 5500000.0;
|
||||
northing = 5500000;
|
||||
break;
|
||||
case 'J':
|
||||
northing = 6400000.0;
|
||||
northing = 6400000;
|
||||
break;
|
||||
case 'K':
|
||||
northing = 7300000.0;
|
||||
northing = 7300000;
|
||||
break;
|
||||
case 'L':
|
||||
northing = 8200000.0;
|
||||
northing = 8200000;
|
||||
break;
|
||||
case 'M':
|
||||
northing = 9100000.0;
|
||||
northing = 9100000;
|
||||
break;
|
||||
case 'N':
|
||||
northing = 0.0;
|
||||
northing = 0;
|
||||
break;
|
||||
case 'P':
|
||||
northing = 800000.0;
|
||||
northing = 800000;
|
||||
break;
|
||||
case 'Q':
|
||||
northing = 1700000.0;
|
||||
northing = 1700000;
|
||||
break;
|
||||
case 'R':
|
||||
northing = 2600000.0;
|
||||
northing = 2600000;
|
||||
break;
|
||||
case 'S':
|
||||
northing = 3500000.0;
|
||||
northing = 3500000;
|
||||
break;
|
||||
case 'T':
|
||||
northing = 4400000.0;
|
||||
northing = 4400000;
|
||||
break;
|
||||
case 'U':
|
||||
northing = 5300000.0;
|
||||
northing = 5300000;
|
||||
break;
|
||||
case 'V':
|
||||
northing = 6200000.0;
|
||||
northing = 6200000;
|
||||
break;
|
||||
case 'W':
|
||||
northing = 7000000.0;
|
||||
northing = 7000000;
|
||||
break;
|
||||
case 'X':
|
||||
northing = 7900000.0;
|
||||
northing = 7900000;
|
||||
break;
|
||||
default:
|
||||
northing = kInvalidNorthing;
|
||||
northing = kInvalidEastingNorthing;
|
||||
}
|
||||
|
||||
return northing;
|
||||
}
|
||||
|
||||
// Convert MGRS parameters to UTM parameters and then use UTM to lat,lon conversion.
|
||||
std::optional<ms::LatLon> MGRStoLatLon(double easting, double northing, int zone_code, char zone_letter, char square_code[2])
|
||||
std::optional<ms::LatLon> MGRStoLatLon(int easting, int northing, int zone_code, char zone_letter, char square_code[2])
|
||||
{
|
||||
// Convert easting and northing according to zone_code and square_code
|
||||
if (zone_code < 1 || zone_code > 60)
|
||||
|
@ -469,20 +462,20 @@ std::optional<ms::LatLon> MGRStoLatLon(double easting, double northing, int zone
|
|||
if (char1 < 'A' || char2 < 'A' || char1 > 'Z' || char2 > 'Z' || char1 == 'I' || char2 == 'I' || char1 == 'O' || char2 == 'O')
|
||||
return nullopt;
|
||||
|
||||
float east100k = square_char_to_easting(char1, set);
|
||||
if (east100k == kInvalidNorthing)
|
||||
int east100k = square_char_to_easting(char1, set);
|
||||
if (east100k == kInvalidEastingNorthing)
|
||||
return nullopt;
|
||||
|
||||
float north100k = square_char_to_northing(char2, set);
|
||||
if (north100k == kInvalidNorthing)
|
||||
int north100k = square_char_to_northing(char2, set);
|
||||
if (north100k == kInvalidEastingNorthing)
|
||||
return nullopt;
|
||||
|
||||
double minNorthing = zone_to_min_northing(zone_letter);
|
||||
if (minNorthing == kInvalidNorthing)
|
||||
int minNorthing = zone_to_min_northing(zone_letter);
|
||||
if (minNorthing == kInvalidEastingNorthing)
|
||||
return nullopt;
|
||||
|
||||
while (north100k < minNorthing)
|
||||
north100k += 2000000.0;
|
||||
north100k += 2000000;
|
||||
|
||||
easting += east100k;
|
||||
northing += north100k;
|
||||
|
|
|
@ -20,9 +20,9 @@ std::optional<std::string> FormatUTM(double lat, double lon);
|
|||
std::optional<std::string> FormatMGRS(double lat, double lon, int prec);
|
||||
|
||||
// Covevrt UTM coordinates to Lat Lon. If UTM parameters are invalid function returns false
|
||||
std::optional<ms::LatLon> UTMtoLatLon(double easting, double northing, int zone_code, char zone_letter);
|
||||
std::optional<ms::LatLon> UTMtoLatLon(int easting, int northing, int zone_code, char zone_letter);
|
||||
|
||||
// Covevrt MGRS coordinates to Lat Lon. If parameters are invalid function returns false
|
||||
std::optional<ms::LatLon> MGRStoLatLon(double easting, double northing, int zone_code, char zone_letter, char square_code[2]);
|
||||
std::optional<ms::LatLon> MGRStoLatLon(int easting, int northing, int zone_code, char zone_letter, char square_code[2]);
|
||||
|
||||
} // namespace utm_mgrs_utils
|
||||
|
|
|
@ -40,8 +40,6 @@ UNIT_TEST(MatchUTMCoords)
|
|||
|
||||
UNIT_TEST(MatchUTMCoords_False)
|
||||
{
|
||||
double lat, lon;
|
||||
|
||||
TEST(!MatchUTMCoords("2 1st").has_value(), ());
|
||||
TEST(!MatchUTMCoords("15N5000004649776").has_value(), ());
|
||||
|
||||
|
@ -74,8 +72,6 @@ UNIT_TEST(MatchUTMCoords_False)
|
|||
|
||||
UNIT_TEST(MatchMGRSCoords_parsing)
|
||||
{
|
||||
double lat, lon;
|
||||
|
||||
TEST(MatchMGRSCoords("30N YF 67993 00000").has_value(), ());
|
||||
TEST(MatchMGRSCoords("30N YF 67993 00000 ").has_value(), ());
|
||||
TEST(MatchMGRSCoords("30N YF 67993 00000 ").has_value(), ());
|
||||
|
|
|
@ -21,16 +21,16 @@ string const kSpaceChars = " \t\r";
|
|||
|
||||
size_t MatchZoneCode(string const & query, int &zone_code);
|
||||
size_t MatchZoneLetter(string const & query, char &zone_letter, size_t startPos);
|
||||
size_t MatchLong(string const & query, long &value, size_t startPos);
|
||||
size_t MatchInt(string const & query, int &value, size_t startPos);
|
||||
|
||||
// Parse UTM format "(\d\d)\s?(\W)\s+(\d+)\s+(\d+)" and converts it to lat,lon.
|
||||
// Return true if parsed successfully or false otherwise.
|
||||
// See utm_mgrs_coords_match_test.cpp for sample UTM strings
|
||||
std::optional<ms::LatLon> MatchUTMCoords(string const & query)
|
||||
{
|
||||
int zone_code;
|
||||
int easting, northing;
|
||||
int zone_code;
|
||||
char zone_letter;
|
||||
long easting, northing;
|
||||
|
||||
size_t pos = MatchZoneCode(query, zone_code);
|
||||
if (pos == string::npos)
|
||||
|
@ -40,15 +40,15 @@ std::optional<ms::LatLon> MatchUTMCoords(string const & query)
|
|||
if (pos == string::npos)
|
||||
return nullopt;
|
||||
|
||||
pos = MatchLong(query, easting, pos);
|
||||
pos = MatchInt(query, easting, pos);
|
||||
if (pos == string::npos)
|
||||
return nullopt;
|
||||
|
||||
pos = MatchLong(query, northing, pos);
|
||||
pos = MatchInt(query, northing, pos);
|
||||
if (pos == string::npos)
|
||||
return nullopt;
|
||||
|
||||
return utm_mgrs_utils::UTMtoLatLon((double)easting, (double)northing, zone_code, zone_letter);
|
||||
return utm_mgrs_utils::UTMtoLatLon(easting, northing, zone_code, zone_letter);
|
||||
}
|
||||
|
||||
// Matches 2 digits zone code. Returns end position of matched chars or string::npos if no match.
|
||||
|
@ -84,19 +84,19 @@ size_t MatchZoneLetter(string const & query, char &zone_letter, size_t startPos)
|
|||
}
|
||||
|
||||
// Matches long number ignoring spaces. Returns end position of matched chars or string::npos if no match.
|
||||
size_t MatchLong(string const & query, long &value, size_t startPos)
|
||||
size_t MatchInt(string const & query, int &value, size_t startPos)
|
||||
{
|
||||
auto pos = query.find_first_not_of(kSpaceChars, startPos);
|
||||
if (query.size() == pos)
|
||||
return string::npos;
|
||||
|
||||
long n = 0;
|
||||
int n = 0;
|
||||
while(pos < query.size())
|
||||
{
|
||||
char ch = query[pos];
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
n = n*10 + (ch-'0');
|
||||
n = n * 10 + (ch - '0');
|
||||
pos ++;
|
||||
}
|
||||
else if (kSpaceChars.find(ch) != string::npos) // Found space char matching end of the number
|
||||
|
@ -119,8 +119,8 @@ std::optional<ms::LatLon> MatchMGRSCoords(std::string const & query)
|
|||
char square_code[2];
|
||||
string eastingStr;
|
||||
string northingStr;
|
||||
int64_t easting;
|
||||
int64_t northing;
|
||||
int32_t easting;
|
||||
int32_t northing;
|
||||
|
||||
strings::SimpleTokenizer it(query, " \t\r");
|
||||
if (!it)
|
||||
|
@ -194,23 +194,23 @@ std::optional<ms::LatLon> MatchMGRSCoords(std::string const & query)
|
|||
if (eastingStr.size() != northingStr.size() || eastingStr.size()>5 || northingStr.size()>5)
|
||||
return nullopt;
|
||||
|
||||
if (!strings::to_int64(eastingStr, easting))
|
||||
if (!strings::to_int32(eastingStr, easting))
|
||||
return nullopt;
|
||||
if (eastingStr.size() < 5)
|
||||
{
|
||||
int decShift = 5 - eastingStr.size();
|
||||
easting *= base::PowUint(10L, decShift);
|
||||
easting *= base::PowUint(10, decShift);
|
||||
}
|
||||
|
||||
if (!strings::to_int64(northingStr, northing))
|
||||
if (!strings::to_int32(northingStr, northing))
|
||||
return nullopt;
|
||||
if (northingStr.size() < 5)
|
||||
{
|
||||
int decShift = 5 - northingStr.size();
|
||||
northing *= base::PowUint(10L, decShift);
|
||||
northing *= base::PowUint(10, decShift);
|
||||
}
|
||||
|
||||
return utm_mgrs_utils::MGRStoLatLon((double)easting, (double)northing, zone_code, zone_letter, square_code);
|
||||
return utm_mgrs_utils::MGRStoLatLon(easting, northing, zone_code, zone_letter, square_code);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in a new issue