Lat-lon formatting: support nice degree symbols
Allow Latin-1 (for PUI fnt) and UTF-8 (for Qt, osgText and everybody else) degree symbols as well as the use of *
This commit is contained in:
parent
05e3c29ee4
commit
22c2971c3c
@ -1196,12 +1196,24 @@ bool parseStringAsGeod(const std::string& s, SGGeod* result)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
namespace {
|
||||
const char* static_degreeSymbols[] = {
|
||||
"*",
|
||||
" ",
|
||||
"\xB0", // Latin-1 B0 codepoint
|
||||
"\xC2\xB0" // UTF-8 equivalent
|
||||
};
|
||||
} // of anonymous namespace
|
||||
|
||||
std::string formatLatLonValueAsString(double deg, LatLonFormat format,
|
||||
char c,
|
||||
DegreeSymbol degreeSymbol)
|
||||
{
|
||||
double min, sec;
|
||||
const int sign = deg < 0.0 ? -1 : 1;
|
||||
deg = fabs(deg);
|
||||
char buf[128];
|
||||
const char* degSym = static_degreeSymbols[static_cast<int>(degreeSymbol)];
|
||||
|
||||
switch (format) {
|
||||
case LatLonFormat::DECIMAL_DEGREES:
|
||||
@ -1217,7 +1229,7 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
min -= 60.0;
|
||||
deg += 1.0;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), "%d*%06.3f'%c", int(deg), fabs(min), c);
|
||||
snprintf(buf, sizeof(buf), "%d%s%06.3f'%c", int(deg), degSym, fabs(min), c);
|
||||
break;
|
||||
|
||||
case LatLonFormat::DEGREES_MINUTES_SECONDS:
|
||||
@ -1234,7 +1246,8 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
deg += 1.0;
|
||||
}
|
||||
}
|
||||
::snprintf(buf, sizeof(buf), "%d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
||||
::snprintf(buf, sizeof(buf), "%d%s%02d'%04.1f\"%c", int(deg), degSym,
|
||||
int(min), fabs(sec), c);
|
||||
break;
|
||||
|
||||
case LatLonFormat::SIGNED_DECIMAL_DEGREES:
|
||||
@ -1250,9 +1263,9 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
deg += 1.0;
|
||||
}
|
||||
if (sign == 1) {
|
||||
snprintf(buf, sizeof(buf), "%d*%06.3f'", int(deg), fabs(min));
|
||||
snprintf(buf, sizeof(buf), "%d%s%06.3f'", int(deg), degSym, fabs(min));
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "-%d*%06.3f'", int(deg), fabs(min));
|
||||
snprintf(buf, sizeof(buf), "-%d%s%06.3f'", int(deg), degSym, fabs(min));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1270,9 +1283,9 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
}
|
||||
}
|
||||
if (sign == 1) {
|
||||
snprintf(buf, sizeof(buf), "%d*%02d'%04.1f\"", int(deg), int(min), fabs(sec));
|
||||
snprintf(buf, sizeof(buf), "%d%s%02d'%04.1f\"", int(deg), degSym, int(min), fabs(sec));
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "-%d*%02d'%04.1f\"", int(deg), int(min), fabs(sec));
|
||||
snprintf(buf, sizeof(buf), "-%d%s%02d'%04.1f\"", int(deg), degSym, int(min), fabs(sec));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1293,9 +1306,9 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
deg += 1.0;
|
||||
}
|
||||
if (c == 'N' || c == 'S') {
|
||||
snprintf(buf, sizeof(buf), "%02d*%06.3f'%c", int(deg), fabs(min), c);
|
||||
snprintf(buf, sizeof(buf), "%02d%s%06.3f'%c", int(deg), degSym, fabs(min), c);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%03d*%06.3f'%c", int(deg), fabs(min), c);
|
||||
snprintf(buf, sizeof(buf), "%03d%s%06.3f'%c", int(deg), degSym, fabs(min), c);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1312,9 +1325,9 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
}
|
||||
}
|
||||
if (c == 'N' || c == 'S') {
|
||||
snprintf(buf, sizeof(buf), "%02d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
||||
snprintf(buf, sizeof(buf), "%02d%s%02d'%04.1f\"%c", int(deg), degSym, int(min), fabs(sec), c);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%03d*%02d'%04.1f\"%c", int(deg), int(min), fabs(sec), c);
|
||||
snprintf(buf, sizeof(buf), "%03d%s%02d'%04.1f\"%c", int(deg), degSym, int(min), fabs(sec), c);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1331,17 +1344,23 @@ std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c)
|
||||
snprintf(buf, sizeof(buf), "%03d* %02d'.%03d%c", int(deg), int(min), int(SGMisc<double>::round((min-int(min))*1000)), c);
|
||||
}
|
||||
break;
|
||||
|
||||
case LatLonFormat::DECIMAL_DEGREES_SYMBOL:
|
||||
::snprintf(buf, sizeof(buf), "%3.6f%s%c", deg, degSym, c);
|
||||
break;
|
||||
}
|
||||
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
std::string formatGeodAsString(const SGGeod& geod, LatLonFormat format)
|
||||
std::string formatGeodAsString(const SGGeod& geod, LatLonFormat format,
|
||||
DegreeSymbol degreeSymbol)
|
||||
{
|
||||
const char ns = (geod.getLatitudeDeg() > 0.0) ? 'N' : 'S';
|
||||
const char ew = (geod.getLongitudeDeg() > 0.0) ? 'E' : 'W';
|
||||
|
||||
return formatLatLonValueAsString(geod.getLatitudeDeg(), format, ns) + "," + formatLatLonValueAsString(geod.getLongitudeDeg(), format, ew);
|
||||
return formatLatLonValueAsString(geod.getLatitudeDeg(), format, ns, degreeSymbol) + ","
|
||||
+ formatLatLonValueAsString(geod.getLongitudeDeg(), format, ew, degreeSymbol);
|
||||
}
|
||||
|
||||
} // end namespace strutils
|
||||
|
@ -385,16 +385,28 @@ namespace simgear {
|
||||
ZERO_PAD_DEGREES_MINUTES,
|
||||
ZERO_PAD_DEGREES_MINUTES_SECONDS,
|
||||
TRINITY_HOUSE, ///< dd* mm'.mmm X, ddd* mm'.mmm X (Trinity House Navigation standard).
|
||||
DECIMAL_DEGREES_SYMBOL ///< 88.4*N,4.54*W
|
||||
};
|
||||
|
||||
std::string formatLatLonValueAsString(double deg, LatLonFormat format, char c);
|
||||
enum class DegreeSymbol
|
||||
{
|
||||
ASTERISK = 0,
|
||||
SPACE,
|
||||
LATIN1_DEGREE,
|
||||
UTF8_DEGREE
|
||||
};
|
||||
|
||||
std::string formatLatLonValueAsString(double deg,
|
||||
LatLonFormat format, char c,
|
||||
DegreeSymbol degreeSymbol = DegreeSymbol::ASTERISK);
|
||||
|
||||
/**
|
||||
* Format an SGGeod as a string according to the provided rule.
|
||||
* if the SGGeod is invalid (default constructed), will return an empty string
|
||||
*/
|
||||
std::string formatGeodAsString(const SGGeod& geod,
|
||||
LatLonFormat format = LatLonFormat::DECIMAL_DEGREES);
|
||||
LatLonFormat format = LatLonFormat::DECIMAL_DEGREES,
|
||||
DegreeSymbol degreeSymbol = DegreeSymbol::ASTERISK);
|
||||
} // end namespace strutils
|
||||
} // end namespace simgear
|
||||
|
||||
|
@ -647,7 +647,18 @@ void test_formatGeod()
|
||||
SG_CHECK_EQUAL(strutils::formatGeodAsString(a, strutils::LatLonFormat::SIGNED_DECIMAL_DEGREES), "55.450000,-3.460000");
|
||||
SG_CHECK_EQUAL(strutils::formatGeodAsString(a, strutils::LatLonFormat::DEGREES_MINUTES_SECONDS),
|
||||
"55*27'00.0\"N,3*27'36.0\"W");
|
||||
|
||||
|
||||
const auto s = strutils::formatGeodAsString(a,
|
||||
strutils::LatLonFormat::ZERO_PAD_DEGREES_MINUTES,
|
||||
strutils::DegreeSymbol::LATIN1_DEGREE);
|
||||
SG_CHECK_EQUAL(s, "55\xB0" "27.000'N,003\xB0" "27.600'W");
|
||||
|
||||
// Jakarta, if you care
|
||||
SGGeod b = SGGeod::fromDeg(106.8278, -6.1568);
|
||||
const auto s2 = strutils::formatGeodAsString(b,
|
||||
strutils::LatLonFormat::DECIMAL_DEGREES_SYMBOL,
|
||||
strutils::DegreeSymbol::UTF8_DEGREE);
|
||||
SG_CHECK_EQUAL(s2, "6.156800\xC2\xB0S,106.827800\xC2\xB0" "E");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
Loading…
Reference in New Issue
Block a user