Pass digits after comma in LatLon -> DMS conversion.

This commit is contained in:
vng 2014-03-21 12:43:30 +03:00 committed by Alex Zolotarev
parent c8c785cf07
commit 618a7a153d
4 changed files with 55 additions and 54 deletions

View file

@ -813,7 +813,7 @@ extern "C"
JNIEXPORT jobject JNICALL
Java_com_mapswithme_maps_Framework_nativeLatLon2DMS(JNIEnv * env, jclass clazz, jdouble lat, jdouble lon)
{
return jni::ToJavaString(env, MeasurementUtils::FormatLatLonAsDMS(lat, lon, false));
return jni::ToJavaString(env, MeasurementUtils::FormatLatLonAsDMS(lat, lon, 3));
}
JNIEXPORT jobject JNICALL

View file

@ -40,25 +40,25 @@ UNIT_TEST(Measurement_Smoke)
UNIT_TEST(LatLonToDMS_Origin)
{
TEST_EQUAL(FormatLatLonAsDMS(0, 0, true), "00°0000″ 00°0000″", ());
TEST_EQUAL(FormatLatLonAsDMS(0, 0, false), "00°0000″ 00°0000″", ());
TEST_EQUAL(FormatLatLonAsDMS(0, 0), "00°0000″ 00°0000″", ());
TEST_EQUAL(FormatLatLonAsDMS(0, 0, 3), "00°0000″ 00°0000″", ());
}
UNIT_TEST(LatLonToDMS_Rounding)
{
// Here and after data is from Wiki: http://bit.ly/datafotformatingtest
// Boston
TEST_EQUAL(FormatLatLonAsDMS(42.358056, -71.063611, true), "42°2129″N 71°0349″W", ());
TEST_EQUAL(FormatLatLonAsDMS(42.358056, -71.063611), "42°2129″N 71°0349″W", ());
// Minsk
TEST_EQUAL(FormatLatLonAsDMS(53.916667, 27.55, true), "53°5500″N 27°3300″E", ());
TEST_EQUAL(FormatLatLonAsDMS(53.916667, 27.55), "53°5500″N 27°3300″E", ());
// Rio
TEST_EQUAL(FormatLatLonAsDMS(-22.908333, -43.196389, true), "22°5430″S 43°1147″W", ());
TEST_EQUAL(FormatLatLonAsDMS(-22.908333, -43.196389), "22°5430″S 43°1147″W", ());
}
UNIT_TEST(LatLonToDMS_NoRounding)
{
// Paris
TEST_EQUAL(FormatLatLonAsDMS(48.8567, 2.3508, false), "48°5124.12″N 02°2102.88″E", ());
TEST_EQUAL(FormatLatLonAsDMS(48.8567, 2.3508, 2), "48°5124.12″N 02°2102.88″E", ());
// Vatican
TEST_EQUAL(FormatLatLonAsDMS(41.904, 12.453, false), "41°5414.4″N 12°2710.8″E", ());
TEST_EQUAL(FormatLatLonAsDMS(41.904, 12.453, 2), "41°5414.4″N 12°2710.8″E", ());
}

View file

@ -1,9 +1,10 @@
#include "measurement_utils.hpp"
#include "../platform/settings.hpp"
#include "../base/string_utils.hpp"
#include "../std/cmath.hpp"
#include "../base/string_utils.hpp"
#include "../base/math.hpp"
#include "../std/iomanip.hpp"
#include "../std/sstream.hpp"
@ -14,8 +15,7 @@ namespace MeasurementUtils
string ToStringPrecision(double d, int pr)
{
stringstream ss;
ss.precision(pr);
ss << std::fixed << d;
ss << setprecision(pr) << fixed << d;
return ss.str();
}
@ -57,54 +57,53 @@ bool FormatDistance(double m, string & res)
}
/// @todo change ostreamstring to something faster
string FormatLatLonAsDMSImpl(string const & posPost, string const & negPost,
double value,bool roundSec)
string FormatLatLonAsDMSImpl(double value, char positive, char negative, int dac)
{
double i = 0.0;
double d = 0.0;
string postfix;
ostringstream sstream;
sstream << setfill('0');
using namespace my;
// Degreess
d = modf(fabs(value), &i);
sstream << setw(2) << i << "°";
// Minutes
d = modf(d * 60, &i);
sstream << setw(2) << i << "";
// Seconds
if (roundSec)
{
d = modf(round(d * 60), &i);
sstream << setw(2) << i;
}
else
{
d = modf(d * 60, &i);
sstream << setw(2) << setprecision(2) << i;
if (d > 1e-5)
{
ostringstream tstream;
tstream << setprecision(4) << d;
string dStr = tstream.str().substr(1, 5);
sstream << dStr;
}
}
sstream << "";
ostringstream sstream;
sstream << setfill('0');
if (value > 0)
postfix = posPost;
else if (value < 0)
postfix = negPost;
sstream << postfix;
// Degrees
double i;
double d = modf(fabs(value), &i);
sstream << setw(2) << i << "°";
return sstream.str();
// Minutes
d = modf(d * 60.0, &i);
sstream << setw(2) << i << "";
// Seconds
d = d * 60.0;
if (dac == 0)
d = rounds(d);
d = modf(d, &i);
sstream << setw(2) << i;
if (dac > 0)
sstream << strings::to_string_dac(d, dac).substr(1);
sstream << "";
// This condition is too heavy for production purposes (but more correct).
//if (my::rounds(value * 3600.0 * pow(10, dac)) != 0)
if (!AlmostEqual(value, 0.0))
{
char postfix = positive;
if (value < 0.0)
postfix = negative;
sstream << postfix;
}
return sstream.str();
}
string FormatLatLonAsDMS(double lat, double lon, bool roundSecToInt)
string FormatLatLonAsDMS(double lat, double lon, int dac)
{
return FormatLatLonAsDMSImpl("N", "S", lat, roundSecToInt) + " " + FormatLatLonAsDMSImpl("E", "W", lon, roundSecToInt);
return (FormatLatLonAsDMSImpl(lat, 'N', 'S', dac) + " " +
FormatLatLonAsDMSImpl(lon, 'E', 'W', dac));
}
} // namespace MeasurementUtils

View file

@ -20,6 +20,8 @@ inline double YardToMiles(double yd) { return yd * 1760; }
/// @return should be direction arrow drawed? false if distance is to small (< 1.0)
bool FormatDistance(double m, string & res);
string FormatLatLonAsDMS(double lat, double lon, bool roundSecToInt);
/// @param[in] dac Digits after comma in seconds.
/// Use dac == 3 for our common conversions.
string FormatLatLonAsDMS(double lat, double lon, int dac = 0);
}