[search] Parse coordinates like: N xxx° xx.xxx E xxx° xx.xxx

This commit is contained in:
vng 2014-08-28 02:02:01 +03:00 committed by Alex Zolotarev
parent a66dfc3fcb
commit 10c59ef568
4 changed files with 48 additions and 26 deletions

View file

@ -11,6 +11,9 @@
#include "../std/sstream.hpp"
using namespace Settings;
using namespace strings;
namespace MeasurementUtils
{
@ -45,9 +48,8 @@ bool FormatDistanceImpl(double m, string & res,
bool FormatDistance(double m, string & res)
{
using namespace Settings;
Units u = Metric;
Settings::Get("Units", u);
(void)Get("Units", u);
/// @todo Put string units resources.
switch (u)
@ -84,7 +86,7 @@ string FormatLatLonAsDMSImpl(double value, char positive, char negative, int dac
sstream << setw(2) << i;
if (dac > 0)
sstream << strings::to_string_dac(d, dac).substr(1);
sstream << to_string_dac(d, dac).substr(1);
sstream << "";
@ -128,13 +130,13 @@ string FormatMercatorAsDMS(m2::PointD const & mercator, int dac)
// @TODO take into account decimal points or commas as separators in different locales
string FormatLatLon(double lat, double lon, int dac)
{
return strings::to_string_dac(lat, dac) + " " + strings::to_string_dac(lon, dac);
return to_string_dac(lat, dac) + " " + to_string_dac(lon, dac);
}
void FormatLatLon(double lat, double lon, string & latText, string & lonText, int dac)
{
latText = strings::to_string_dac(lat, dac);
lonText = strings::to_string_dac(lon, dac);
latText = to_string_dac(lat, dac);
lonText = to_string_dac(lon, dac);
}
string FormatMercator(m2::PointD const & mercator, int dac)
@ -144,33 +146,32 @@ string FormatMercator(m2::PointD const & mercator, int dac)
void FormatMercator(m2::PointD const & mercator, string & lat, string & lon, int dac)
{
lat = strings::to_string_dac(MercatorBounds::YToLat(mercator.y), dac);
lon = strings::to_string_dac(MercatorBounds::XToLon(mercator.x), dac);
lat = to_string_dac(MercatorBounds::YToLat(mercator.y), dac);
lon = to_string_dac(MercatorBounds::XToLon(mercator.x), dac);
}
string FormatAltitude(double altitudeInMeters)
{
using namespace Settings;
Units u = Metric;
(void)Settings::Get("Units", u);
(void)Get("Units", u);
ostringstream ss;
ss << fixed << setprecision(0);
ostringstream sstream;
sstream << std::fixed << setprecision(0);
/// @todo Put string units resources.
switch (u)
{
case Yard: sstream << MetersToYards(altitudeInMeters) << "yd"; break;
case Foot: sstream << MetersToFeet(altitudeInMeters) << "ft"; break;
default: sstream << altitudeInMeters << "m"; break;
case Yard: ss << MetersToYards(altitudeInMeters) << "yd"; break;
case Foot: ss << MetersToFeet(altitudeInMeters) << "ft"; break;
default: ss << altitudeInMeters << "m"; break;
}
return sstream.str();
return ss.str();
}
string FormatSpeed(double metersPerSecond)
{
using namespace Settings;
Units u = Metric;
(void)Settings::Get("Units", u);
(void)Get("Units", u);
double perHour;
string res;

View file

@ -28,12 +28,13 @@ string FormatAltitude(double altitudeInMeters);
string FormatSpeed(double metersPerSecond);
/// @param[in] dac Digits after comma in seconds.
/// Use dac == 3 for our common conversions.
/// Use dac == 3 for our common conversions to DMS.
string FormatLatLonAsDMS(double lat, double lon, int dac = 3);
void FormatLatLonAsDMS(double lat, double lon, string & latText, string & lonText, int dac = 3);
string FormatMercatorAsDMS(m2::PointD const & mercator, int dac = 3);
void FormatMercatorAsDMS(m2::PointD const & mercator, string & lat, string & lon, int dac = 3);
/// Simple decimal degrees formating
/// Default dac == 6 for the simple decimal formatting.
string FormatLatLon(double lat, double lon, int dac = 6);
void FormatLatLon(double lat, double lon, string & latText, string & lonText, int dac = 6);
string FormatMercator(m2::PointD const & mercator, int dac = 6);

View file

@ -146,6 +146,7 @@ bool MatchLatLonDegree(string const & query, double & lat, double & lon)
// Positions of N, S, E, W symbols
char const * arrPos[] = { 0, 0, 0, 0 };
bool arrDegreeSymbol[] = { false, false };
char const * s = query.c_str();
while (true)
@ -179,17 +180,21 @@ bool MatchLatLonDegree(string const & query, double & lat, double & lon)
SkipSpaces(s);
int i = GetDMSIndex(s);
bool degreeSymbol = true;
if (i == -1)
{
if (v[base].second && v[base + 1].second && !v[base + 2].second)
// try to assign next possible value mark
if (arrDegreeSymbol[base / 3])
{
// assume seconds if degrees and minutes are present
i = 2;
if (!v[base + 1].second)
i = 1;
else
i = 2;
}
else
{
// assume degrees by default
i = 0;
degreeSymbol = false;
}
}
@ -205,11 +210,17 @@ bool MatchLatLonDegree(string const & query, double & lat, double & lon)
return false;
}
}
arrDegreeSymbol[base / 3] = degreeSymbol;
}
else // minutes or seconds
else // minutes or seconds
{
if (x < 0.0 || v[base + i].second || !v[base].second)
if (x < 0.0 || x > 60.0 || // minutes or seconds should be in [0, 60] range
v[base + i].second || // value already exists
!v[base].second || // no degrees found for value
(i == 2 && !v[base + 1].second)) // no minutes for seconds
{
return false;
}
}
v[base + i].first = x;

View file

@ -141,4 +141,13 @@ UNIT_TEST(LatLon_Degree_Match)
TEST(MatchLatLonDegree("47.33471°N 8.53112°E", lat, lon), ());
TEST_ALMOST_EQUAL(lat, 47.33471, ());
TEST_ALMOST_EQUAL(lon, 8.53112, ());
TEST(MatchLatLonDegree("N 51* 33.217 E 11* 10.113", lat, lon), ());
TEST_ALMOST_EQUAL(lat, 51.55361666666667, ());
TEST_ALMOST_EQUAL(lon, 11.16855, ());
TEST(!MatchLatLonDegree("N 51* 33.217 E 11* 60.113", lat, lon), ());
TEST(!MatchLatLonDegree("N 51* -33.217 E 11* 10.113", lat, lon), ());
TEST(!MatchLatLonDegree("N 33.217\' E 11* 10.113", lat, lon), ());
TEST(!MatchLatLonDegree("N 51* 33.217 E 11* 10.113\"", lat, lon), ());
}