Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Zolotarev <alex@maps.me>2016-03-15 20:39:41 +0300
committerSergey Yershov <yershov@corp.mail.ru>2016-03-23 16:57:05 +0300
commitba208ffb6cc5e9ab60310e22b4487c58635b39e8 (patch)
tree3cca4a06ae72af58748670b16152e5e084b89840 /platform/measurement_utils.cpp
parent226b50494a06297c205fb979a83a9fcfbfab8f61 (diff)
MeasurementUtils::OSMDistanceToMeters validation.
Diffstat (limited to 'platform/measurement_utils.cpp')
-rw-r--r--platform/measurement_utils.cpp98
1 files changed, 97 insertions, 1 deletions
diff --git a/platform/measurement_utils.cpp b/platform/measurement_utils.cpp
index b29d17f03d..5ba0a7cf5d 100644
--- a/platform/measurement_utils.cpp
+++ b/platform/measurement_utils.cpp
@@ -3,9 +3,12 @@
#include "geometry/mercator.hpp"
-#include "base/string_utils.hpp"
+#include "base/macros.hpp"
#include "base/math.hpp"
+#include "base/stl_add.hpp"
+#include "base/string_utils.hpp"
+#include "std/cstring.hpp"
#include "std/iomanip.hpp"
#include "std/sstream.hpp"
@@ -189,4 +192,97 @@ string FormatSpeed(double metersPerSecond)
return res;
}
+bool OSMDistanceToMeters(string const & osmRawValue, double & outMeters)
+{
+ char * stop;
+ char const * s = osmRawValue.c_str();
+ outMeters = strtod(s, &stop);
+
+ // Not a number, was not parsed at all.
+ if (s == stop)
+ return false;
+
+ if (!isfinite(outMeters))
+ return false;
+
+ switch (*stop)
+ {
+ // Default units - meters.
+ case 0: return true;
+
+ // Feet and probably inches.
+ case '\'':
+ {
+ outMeters = FeetToMeters(outMeters);
+ s = stop + 1;
+ double const inches = strtod(s, &stop);
+ if (s != stop && *stop == '"' && isfinite(inches))
+ outMeters += InchesToMeters(inches);
+ return true;
+ }
+ break;
+
+ // Inches.
+ case '\"': outMeters = InchesToMeters(outMeters); return true;
+
+ // It's probably a range. Use maximum value (if possible) for a range.
+ case '-':
+ {
+ s = stop + 1;
+ double const newValue = strtod(s, &stop);
+ if (s != stop && isfinite(newValue))
+ outMeters = newValue;
+ }
+ break;
+
+ // It's probably a list. Use maximum value (if possible) for a list.
+ case ';':
+ do
+ {
+ s = stop + 1;
+ double const newValue = strtod(s, &stop);
+ if (s == stop)
+ break;
+ if (isfinite(newValue))
+ outMeters = newValue;
+ } while (*stop && *stop == ';');
+ break;
+ }
+
+ while (*stop && isspace(*stop))
+ ++stop;
+
+ // Default units - meters.
+ if (*stop == 0)
+ return true;
+
+ if (strstr(stop, "nmi") == stop)
+ outMeters = NauticalMilesToMeters(outMeters);
+ else if (strstr(stop, "mi") == stop)
+ outMeters = MilesToMeters(outMeters);
+ else if (strstr(stop, "ft") == stop)
+ outMeters = FeetToMeters(outMeters);
+ else if (strstr(stop, "feet") == stop)
+ outMeters = FeetToMeters(outMeters);
+ else if (strstr(stop, "km") == stop)
+ outMeters = outMeters * 1000;
+
+ // Count all other cases as meters.
+ return true;
+}
+
+string OSMDistanceToMetersString(string const & osmRawValue,
+ bool supportZeroAndNegativeValues,
+ int digitsAfterComma)
+{
+ double meters;
+ if (OSMDistanceToMeters(osmRawValue, meters))
+ {
+ if (!supportZeroAndNegativeValues && meters <= 0)
+ return {};
+ return strings::to_string_dac(meters, digitsAfterComma);
+ }
+ return {};
+}
+
} // namespace MeasurementUtils