diff --git a/generator/extract_addr/extract_addr.cpp b/generator/extract_addr/extract_addr.cpp index 7cedc615d1..190ac12c5e 100644 --- a/generator/extract_addr/extract_addr.cpp +++ b/generator/extract_addr/extract_addr.cpp @@ -1,4 +1,5 @@ #include "generator/feature_builder.hpp" +#include "generator/regions/to_string_policy.hpp" #include "indexer/classificator.hpp" #include "indexer/classificator_loader.hpp" @@ -79,7 +80,8 @@ void PrintFeature(FeatureBuilder const & fb, uint64_t) ToJSONObject(*feature, "geometry", geometry); ToJSONObject(*feature, "properties", properties); - std::cout << json_dumps(feature.release(), JSON_COMPACT) << std::endl; + std::cout << json_dumps(feature.release(), + JSON_REAL_PRECISION(generator::regions::JsonPolicy::kDefaultPrecision) | JSON_COMPACT) << std::endl; } int main(int argc, char * argv[]) diff --git a/generator/geo_objects/geo_objects.cpp b/generator/geo_objects/geo_objects.cpp index 277e229982..d7405c42f4 100644 --- a/generator/geo_objects/geo_objects.cpp +++ b/generator/geo_objects/geo_objects.cpp @@ -8,6 +8,7 @@ #include "generator/locality_sorter.hpp" #include "generator/regions/region_base.hpp" #include "generator/regions/region_info_getter.hpp" +#include "generator/regions/to_string_policy.hpp" #include "indexer/classificator.hpp" #include "indexer/ftypes_matcher.hpp" @@ -93,7 +94,8 @@ std::unique_ptr MakeGeoObjectValueWithAddress(FeatureBuilder const & fb, KeyValue const & keyValue) { auto const jsonWithAddress = AddAddress(fb, keyValue); - auto const cstr = json_dumps(jsonWithAddress.get(), JSON_COMPACT); + auto const cstr = json_dumps(jsonWithAddress.get(), + JSON_REAL_PRECISION(regions::JsonPolicy::kDefaultPrecision) | JSON_COMPACT); return std::unique_ptr(cstr); } @@ -110,7 +112,8 @@ MakeGeoObjectValueWithoutAddress(FeatureBuilder const & fb, JsonValue const & js auto properties = json_object_get(jsonWithAddress.get(), "properties"); ToJSONObject(*properties, "name", fb.GetName()); UpdateCoordinates(fb.GetKeyPoint(), jsonWithAddress); - auto const cstr = json_dumps(jsonWithAddress.get(), JSON_COMPACT); + auto const cstr = json_dumps(jsonWithAddress.get(), + JSON_REAL_PRECISION(generator::regions::JsonPolicy::kDefaultPrecision) | JSON_COMPACT); return std::unique_ptr(cstr); } diff --git a/generator/regions/regions.cpp b/generator/regions/regions.cpp index 37481d2fd4..9513240d39 100644 --- a/generator/regions/regions.cpp +++ b/generator/regions/regions.cpp @@ -93,6 +93,8 @@ private: size_t countryObjectCount = 0; auto jsonPolicy = std::make_unique(m_verbose); + jsonPolicy->SetRealPrecision(JsonPolicy::kDefaultPrecision); + for (auto const & tree : outers) { if (m_verbose) diff --git a/generator/regions/to_string_policy.cpp b/generator/regions/to_string_policy.cpp index 1524721535..290171919c 100644 --- a/generator/regions/to_string_policy.cpp +++ b/generator/regions/to_string_policy.cpp @@ -2,6 +2,8 @@ #include "geometry/mercator.hpp" +#include "base/assert.hpp" + #include #include @@ -13,6 +15,14 @@ namespace generator { namespace regions { + +JsonPolicy & JsonPolicy::SetRealPrecision(int32_t precision) +{ + CHECK_LESS(precision, 32, ()); + m_precision = precision; + return *this; +} + std::string JsonPolicy::ToString(NodePath const & path) const { auto const & main = path.back()->GetData(); @@ -69,7 +79,11 @@ std::string JsonPolicy::ToString(NodePath const & path) const ToJSONObject(*feature, "geometry", geometry); ToJSONObject(*feature, "properties", properties); - auto const cstr = json_dumps(feature.get(), JSON_COMPACT); + uint32_t jsonFlags = JSON_COMPACT; + if (m_precision >= 0) + jsonFlags |= JSON_REAL_PRECISION(m_precision); + + auto const cstr = json_dumps(feature.get(), jsonFlags); std::unique_ptr buffer(cstr); return buffer.get(); } diff --git a/generator/regions/to_string_policy.hpp b/generator/regions/to_string_policy.hpp index b7452f10e8..41da04879d 100644 --- a/generator/regions/to_string_policy.hpp +++ b/generator/regions/to_string_policy.hpp @@ -20,11 +20,20 @@ class JsonPolicy : public ToStringPolicyInterface { public: JsonPolicy(bool extendedOutput = false) : m_extendedOutput(extendedOutput) {} - + JsonPolicy & SetRealPrecision(int32_t precision); std::string ToString(NodePath const & path) const override; +public: + // Longitude and latitude has maximum 3 digits before comma. So we have minimum 6 digits after comma. + // Nautical mile is good approximation for one angle minute, so we can rely, that + // final precision is 60 (minutes in degree) * 1852 (meters in one mile) / 1000000 = 0.111 = 111 millimeters. + // Also, if you are quizzed by nautical mile, just forget, precision was defined in https://jira.mail.ru/browse/MAPSB2B-41 + static uint32_t constexpr kDefaultPrecision = 9; + private: bool m_extendedOutput; + int32_t m_precision = kDefaultPrecision; + }; } // namespace regions } // namespace generator diff --git a/generator/streets/streets_builder.cpp b/generator/streets/streets_builder.cpp index fd5c1fa775..fd98803568 100644 --- a/generator/streets/streets_builder.cpp +++ b/generator/streets/streets_builder.cpp @@ -1,5 +1,5 @@ +#include "generator/regions/to_string_policy.hpp" #include "generator/streets/streets_builder.hpp" - #include "generator/streets/street_regions_tracing.hpp" #include "indexer/classificator.hpp" @@ -188,7 +188,8 @@ std::unique_ptr StreetsBuilder::MakeStreetValue( auto const & pinArray = std::vector{pinLatLon.m_lon, pinLatLon.m_lat}; ToJSONObject(*streetObject, "pin", std::move(pinArray)); - auto const value = json_dumps(streetObject.get(), JSON_COMPACT); + auto const value = json_dumps(streetObject.get(), + JSON_REAL_PRECISION(regions::JsonPolicy::kDefaultPrecision) | JSON_COMPACT); return std::unique_ptr{value}; }