diff --git a/generator/feature_sorter.cpp b/generator/feature_sorter.cpp index df2993aaa9..95ab180e63 100644 --- a/generator/feature_sorter.cpp +++ b/generator/feature_sorter.cpp @@ -30,9 +30,13 @@ namespace { m2::PointD m_midLoc, m_midAll; size_t m_locCount, m_allCount; + uint32_t m_coordBits; public: - CalculateMidPoints() : m_midAll(0, 0), m_allCount(0) {} + CalculateMidPoints() : + m_midAll(0, 0), m_allCount(0), m_coordBits(serial::CodingParams().GetCoordBits()) + { + } std::vector m_vec; @@ -45,7 +49,7 @@ namespace ft.ForEachPointRef(*this); m_midLoc = m_midLoc / m_locCount; - uint64_t const pointAsInt64 = PointToInt64(m_midLoc.x, m_midLoc.y); + uint64_t const pointAsInt64 = PointToInt64(m_midLoc.x, m_midLoc.y, m_coordBits); uint64_t const minScale = feature::MinDrawableScaleForFeature(ft.GetFeatureBase()); CHECK(minScale <= scales::GetUpperScale(), ("Dat file contain invisible feature")); @@ -147,13 +151,13 @@ namespace feature points_t m_current; - int64_t m_base; + serial::CodingParams m_codingParams; void WriteOuterPoints(points_t const & points, int i) { m_buffer.m_ptsMask |= (1 << i); m_buffer.m_ptsOffset.push_back(m_rMain.GetFileSize(*m_rMain.m_geoFile[i])); - serial::SaveOuterPath(points, m_base, *m_rMain.m_geoFile[i]); + serial::SaveOuterPath(points, m_codingParams, *m_rMain.m_geoFile[i]); } void WriteOuterTriangles(points_t const & bound, holes_t const & holes, int i) @@ -165,17 +169,19 @@ namespace feature tesselator::TrianglesInfo info; tesselator::TesselateInterior(bound, holes, info); - serial::TrianglesChainSaver saver(m_base); + serial::TrianglesChainSaver saver(m_codingParams); // points conversion tesselator::PointsInfo points; - info.GetPointsInfo(saver.GetBasePoint(), saver.GetMaxPoint(), &serial::pts::D2U, points); + m2::PointU (* D2U)(m2::PointD const &, uint32_t) = &PointD2PointU; + info.GetPointsInfo(saver.GetBasePoint(), saver.GetMaxPoint(), + bind(D2U, _1, m_codingParams.GetCoordBits()), points); // triangles processing (should be optimal) info.ProcessPortions(points, saver, true); // check triangles processing (to compare with optimal) - //serial::TrianglesChainSaver checkSaver(m_base); + //serial::TrianglesChainSaver checkSaver(m_codingParams); //info.ProcessPortions(points, checkSaver, false); //CHECK_LESS_OR_EQUAL(saver.GetBufferSize(), checkSaver.GetBufferSize(), ()); @@ -230,8 +236,11 @@ namespace feature }; public: - GeometryHolder(FeaturesCollector2 & rMain, FeatureBuilder2 & fb, int64_t base) - : m_rMain(rMain), m_rFB(fb), m_base(base), m_ptsInner(true), m_trgInner(true) + GeometryHolder(FeaturesCollector2 & rMain, + FeatureBuilder2 & fb, + serial::CodingParams const & codingParams) + : m_rMain(rMain), m_rFB(fb), m_codingParams(codingParams), + m_ptsInner(true), m_trgInner(true) { } @@ -323,7 +332,7 @@ namespace feature { (void)GetFileSize(m_datFile); - GeometryHolder holder(*this, fb, m_header.GetBase()); + GeometryHolder holder(*this, fb, m_header.GetCodingParams()); bool const isLine = fb.IsLine(); bool const isArea = fb.IsArea(); @@ -366,7 +375,7 @@ namespace feature if (fb.PreSerialize(holder.m_buffer)) { - fb.Serialize(holder.m_buffer, m_header.GetBase()); + fb.Serialize(holder.m_buffer, m_header.GetCodingParams()); WriteFeatureBase(holder.m_buffer.m_buffer, fb); } @@ -407,7 +416,7 @@ namespace feature FileReader reader(tempDatFilePath); feature::DataHeader header; - header.SetBase(midPoints.GetCenter()); + header.SetCodingParams(serial::CodingParams(30, midPoints.GetCenter())); header.SetScales(bWorld ? g_arrWorldScales : g_arrCountryScales); FeaturesCollector2 collector(datFilePath, header); diff --git a/generator/world_map_generator.hpp b/generator/world_map_generator.hpp index 27ad626acd..83363908cf 100644 --- a/generator/world_map_generator.hpp +++ b/generator/world_map_generator.hpp @@ -17,15 +17,6 @@ #include "../std/scoped_ptr.hpp" #include "../std/unordered_map.hpp" - -namespace m2 -{ - inline size_t hash_value(m2::PointD const & pt) - { - return static_cast(PointToInt64(pt.x, pt.y)); - } -} - template class WorldMapGenerator { @@ -38,7 +29,9 @@ class WorldMapGenerator size_t m_mergedCounter; size_t m_areasCounter; - typedef unordered_map FeaturesContainerT; + uint32_t m_coordBits; + + typedef unordered_map FeaturesContainerT; typedef map TypesContainerT; TypesContainerT m_features; @@ -61,7 +54,8 @@ private: { for (FeaturesContainerT::iterator base = features.begin(); base != features.end(); ++base) { - FeaturesContainerT::iterator found = features.find(base->second.LastPoint()); + FeaturesContainerT::iterator found = + features.find(PointToInt64(base->second.LastPoint(), m_coordBits)); if (found != features.end()) { CHECK(found != base, ()); @@ -80,7 +74,7 @@ private: void TryToMerge(FeatureBuilder1Merger & fbm) { FeaturesContainerT & container = m_features[fbm.KeyType()]; - FeaturesContainerT::iterator found = container.find(fbm.LastPoint()); + FeaturesContainerT::iterator found = container.find(PointToInt64(fbm.LastPoint(), m_coordBits)); if (found != container.end()) { fbm.AppendFeature(found->second); @@ -90,7 +84,8 @@ private: if (!EmitAreaFeature(fbm)) { - pair result = container.insert(make_pair(fbm.FirstPoint(), fbm)); + pair result = + container.insert(make_pair(PointToInt64(fbm.FirstPoint(), m_coordBits), fbm)); // if we found feature with the same starting point, emit it directly if (!result.second) { @@ -115,7 +110,7 @@ public: WorldMapGenerator(int maxWorldScale, bool mergeCoastlines, typename FeatureOutT::InitDataType featureOutInitData) : m_maxWorldScale(maxWorldScale), m_mergeCoastlines(mergeCoastlines), - m_mergedCounter(0), m_areasCounter(0) + m_mergedCounter(0), m_areasCounter(0), m_coordBits(30) { if (maxWorldScale >= 0) m_worldBucket.reset(new FeatureOutT(WORLD_FILE_NAME, featureOutInitData)); diff --git a/indexer/data_header.cpp b/indexer/data_header.cpp index dc5fd28e8e..000ae23f08 100644 --- a/indexer/data_header.cpp +++ b/indexer/data_header.cpp @@ -21,19 +21,14 @@ namespace feature { } - void DataHeader::SetBase(m2::PointD const & p) - { - m_base = PointToInt64(p.x, p.y); - } - m2::RectD const DataHeader::GetBounds() const { - return Int64ToRect(m_bounds); + return Int64ToRect(m_bounds, m_codingParams.GetCoordBits()); } void DataHeader::SetBounds(m2::RectD const & r) { - m_bounds = RectToInt64(r); + m_bounds = RectToInt64(r, m_codingParams.GetCoordBits()); } void DataHeader::SetScales(int * arr) @@ -58,18 +53,18 @@ namespace feature void DataHeader::Save(FileWriter & w) const { - WriteToSink(w, m_base); - WriteVarInt(w, m_bounds.first - m_base); - WriteVarInt(w, m_bounds.second - m_base); + m_codingParams.Save(w); + WriteVarInt(w, m_bounds.first - m_codingParams.GetBasePointInt64()); + WriteVarInt(w, m_bounds.second - m_codingParams.GetBasePointInt64()); w.Write(m_scales.data(), m_scales.size()); } void DataHeader::Load(FileReader const & r) { ReaderSource src(r); - m_base = ReadPrimitiveFromSource(src); - m_bounds.first = ReadVarInt(src) + m_base; - m_bounds.second = ReadVarInt(src) + m_base; + m_codingParams.Load(src); + m_bounds.first = ReadVarInt(src) + m_codingParams.GetBasePointInt64(); + m_bounds.second = ReadVarInt(src) + m_codingParams.GetBasePointInt64(); src.Read(m_scales.data(), m_scales.size()); } } diff --git a/indexer/data_header.hpp b/indexer/data_header.hpp index d985fb1b6d..b0badc5cb1 100644 --- a/indexer/data_header.hpp +++ b/indexer/data_header.hpp @@ -1,5 +1,7 @@ #pragma once +#include "geometry_serialization.hpp" + #include "../geometry/rect2d.hpp" #include "../std/array.hpp" @@ -11,11 +13,11 @@ class FileReader; class FileWriter; namespace feature -{ +{ /// All file sizes are in bytes class DataHeader { - int64_t m_base; + serial::CodingParams m_codingParams; pair m_bounds; @@ -27,8 +29,8 @@ namespace feature /// Zero all fields void Reset(); - void SetBase(m2::PointD const & p); - int64_t GetBase() const { return m_base; } + void SetCodingParams(serial::CodingParams const & params) { m_codingParams = params; } + serial::CodingParams const & GetCodingParams() const { return m_codingParams; } m2::RectD const GetBounds() const; void SetBounds(m2::RectD const & r); diff --git a/indexer/feature.cpp b/indexer/feature.cpp index 9e35d0f2f9..2b9ff42098 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -224,7 +224,7 @@ uint8_t FeatureBuilder1::GetHeader() const return header; } -void FeatureBuilder1::SerializeBase(buffer_t & data, m2::PointU const & basePoint) const +void FeatureBuilder1::SerializeBase(buffer_t & data, serial::CodingParams const & params) const { PushBackByteSink sink(data); @@ -243,7 +243,8 @@ void FeatureBuilder1::SerializeBase(buffer_t & data, m2::PointU const & basePoin } if (m_bPoint) - WriteVarUint(sink, EncodeDelta(PointD2PointU(m_Center.x, m_Center.y), basePoint)); + WriteVarUint(sink, EncodeDelta(PointD2PointU(m_Center.x, m_Center.y, params.GetCoordBits()), + params.GetBasePoint())); } void FeatureBuilder1::Serialize(buffer_t & data) const @@ -252,7 +253,7 @@ void FeatureBuilder1::Serialize(buffer_t & data) const data.clear(); - SerializeBase(data, m2::PointU(0, 0)); + SerializeBase(data, serial::CodingParams()); PushBackByteSink sink(data); @@ -289,7 +290,7 @@ namespace void FeatureBuilder1::Deserialize(buffer_t & data) { FeatureBase f; - f.Deserialize(data, 0, 0); + f.Deserialize(data, 0, serial::CodingParams()); f.InitFeatureBuilder(*this); ArrayByteSource src(f.DataPtr() + f.m_Header2Offset); @@ -379,12 +380,12 @@ namespace }; } -void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base) +void FeatureBuilder2::Serialize(buffers_holder_t & data, serial::CodingParams const & params) { data.m_buffer.clear(); // header data serialization - SerializeBase(data.m_buffer, m2::Uint64ToPointU(static_cast(base))); + SerializeBase(data.m_buffer, params); PushBackByteSink sink(data.m_buffer); @@ -429,7 +430,7 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base) } } - serial::SaveInnerPath(data.m_innerPts, serial::CodingParams(base), sink); + serial::SaveInnerPath(data.m_innerPts, params, sink); } else { @@ -442,7 +443,7 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base) if (m_bArea) { if (trgCount > 0) - serial::SaveInnerTriangles(data.m_innerTrg, serial::CodingParams(base), sink); + serial::SaveInnerTriangles(data.m_innerTrg, params, sink); else { // offsets was pushed from high scale index to low @@ -456,12 +457,12 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base) // FeatureBase implementation /////////////////////////////////////////////////////////////////////////////////////////////////// -void FeatureBase::Deserialize(buffer_t & data, uint32_t offset, int64_t base) +void FeatureBase::Deserialize(buffer_t & data, uint32_t offset, serial::CodingParams const & params) { m_Offset = offset; m_Data.swap(data); - m_base = base; + m_CodingParams = params; m_CommonOffset = m_Header2Offset = 0; m_bTypesParsed = m_bCommonParsed = false; @@ -517,7 +518,8 @@ void FeatureBase::ParseCommon() const if (h & HEADER_HAS_POINT) { CoordPointT center = PointU2PointD(DecodeDelta(ReadVarUint(source), - m2::Uint64ToPointU(m_base))); + m_CodingParams.GetBasePoint()), + m_CodingParams.GetCoordBits()); m_Center = m2::PointD(center.first, center.second); m_LimitRect.Add(m_Center); } @@ -595,7 +597,7 @@ void FeatureType::Deserialize(read_source_t & src) m_InnerStats.MakeZero(); - base_type::Deserialize(src.m_data, src.m_offset, m_header->GetBase()); + base_type::Deserialize(src.m_data, src.m_offset, m_header->GetCodingParams()); } namespace @@ -787,7 +789,7 @@ void FeatureType::ParseHeader2() const char const * start = static_cast(src.Ptr()); - src = ArrayByteSource(serial::LoadInnerPath(src.Ptr(), ptsCount, m_base, m_Points)); + src = ArrayByteSource(serial::LoadInnerPath(src.Ptr(), ptsCount, m_CodingParams, m_Points)); m_InnerStats.m_Points = static_cast(src.Ptr()) - start; } @@ -804,7 +806,7 @@ void FeatureType::ParseHeader2() const char const * start = static_cast(src.Ptr()); points_t points; - src = ArrayByteSource(serial::LoadInnerTriangles(src.Ptr(), trgCount, m_base, points)); + src = ArrayByteSource(serial::LoadInnerTriangles(src.Ptr(), trgCount, m_CodingParams, points)); m_InnerStats.m_Strips = static_cast(src.Ptr()) - start; @@ -841,7 +843,7 @@ uint32_t FeatureType::ParseGeometry(int scale) const ReaderSource src( m_cont->GetReader(feature::GetTagForIndex(GEOMETRY_FILE_TAG, ind))); src.Skip(m_ptsOffsets[ind]); - serial::LoadOuterPath(src, m_base, m_Points); + serial::LoadOuterPath(src, m_CodingParams, m_Points); sz = static_cast(src.Pos() - m_ptsOffsets[ind]); } @@ -893,7 +895,7 @@ uint32_t FeatureType::ParseTriangles(int scale) const ReaderSource src( m_cont->GetReader(feature::GetTagForIndex(TRIANGLE_FILE_TAG, ind))); src.Skip(m_trgOffsets[ind]); - serial::LoadOuterTriangles(src, m_base, m_Triangles); + serial::LoadOuterTriangles(src, m_CodingParams, m_Triangles); sz = static_cast(src.Pos() - m_trgOffsets[ind]); } diff --git a/indexer/feature.hpp b/indexer/feature.hpp index 2713f6ed17..e5c99e8ece 100644 --- a/indexer/feature.hpp +++ b/indexer/feature.hpp @@ -66,7 +66,7 @@ public: /// @name Serialization. //@{ void Serialize(buffer_t & data) const; - void SerializeBase(buffer_t & data, m2::PointU const & basePoint) const; + void SerializeBase(buffer_t & data, serial::CodingParams const & params) const; void Deserialize(buffer_t & data); //@} @@ -192,7 +192,7 @@ public: /// @name Overwrite from base_type. //@{ bool PreSerialize(buffers_holder_t const & data); - void Serialize(buffers_holder_t & data, int64_t base); + void Serialize(buffers_holder_t & data, serial::CodingParams const & params); //@} }; @@ -296,7 +296,7 @@ public: //@} protected: - void Deserialize(buffer_t & data, uint32_t offset, int64_t base); + void Deserialize(buffer_t & data, uint32_t offset, serial::CodingParams const & params); string DebugString() const; protected: @@ -318,7 +318,7 @@ protected: mutable m2::RectD m_LimitRect; - int64_t m_base; + serial::CodingParams m_CodingParams; static uint32_t const m_TypesOffset = 1; mutable uint32_t m_CommonOffset, m_Header2Offset; diff --git a/indexer/feature_impl.hpp b/indexer/feature_impl.hpp index 6f37b3ce75..b13bedab6d 100644 --- a/indexer/feature_impl.hpp +++ b/indexer/feature_impl.hpp @@ -9,14 +9,14 @@ namespace feature { namespace pts { - inline int64_t FromPoint(m2::PointD const & p) + inline int64_t FromPoint(m2::PointD const & p, uint32_t coordBits) { - return PointToInt64(p.x, p.y); + return PointToInt64(p.x, p.y, coordBits); } - inline m2::PointD ToPoint(int64_t i) + inline m2::PointD ToPoint(int64_t i, uint32_t coordBits) { - CoordPointT const pt = Int64ToPoint(i); + CoordPointT const pt = Int64ToPoint(i, coordBits); return m2::PointD(pt.first, pt.second); } } diff --git a/indexer/geometry_serialization.cpp b/indexer/geometry_serialization.cpp index 3cd5f1c233..1401921959 100644 --- a/indexer/geometry_serialization.cpp +++ b/indexer/geometry_serialization.cpp @@ -5,7 +5,11 @@ #include "../geometry/pointu_to_uint64.hpp" +#include "../coding/file_reader.hpp" +#include "../coding/file_writer.hpp" + #include "../std/algorithm.hpp" +#include "../std/bind.hpp" #include "../std/iterator.hpp" #include "../std/stack.hpp" @@ -15,35 +19,43 @@ namespace serial { -CodingParams::CodingParams() : m_BasePoint(0, 0), m_CoordBits(30) +CodingParams::CodingParams() : m_BasePointUint64(0), m_CoordBits(30) { - m_BasePointInt64 = m2::PointUToUint64(m_BasePoint); + m_BasePoint = m2::Uint64ToPointU(m_BasePointUint64); } -CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) : - m_BasePointInt64(basePointInt64), m_CoordBits(coordBits) +CodingParams::CodingParams(uint8_t coordBits, m2::PointD const & pt) : m_CoordBits(coordBits) { - m_BasePoint = m2::Uint64ToPointU(basePointInt64); + m_BasePoint = PointD2PointU(pt.x, pt.y, coordBits); + m_BasePointUint64 = m2::PointUToUint64(m_BasePoint); +} + +CodingParams::CodingParams(uint8_t coordBits, uint64_t basePointUint64) + : m_BasePointUint64(basePointUint64), m_CoordBits(coordBits) +{ + m_BasePoint = m2::Uint64ToPointU(m_BasePointUint64); } namespace pts { - inline m2::PointU D2U(m2::PointD const & p) + inline m2::PointU D2U(m2::PointD const & p, uint32_t coordBits) { - return PointD2PointU(p.x, p.y); + return PointD2PointU(p, coordBits); } - inline m2::PointD U2D(m2::PointU const & p) + inline m2::PointD U2D(m2::PointU const & p, uint32_t coordBits) { - CoordPointT const pt = PointU2PointD(p); - ASSERT( MercatorBounds::minX <= pt.first && pt.first <= MercatorBounds::maxX, (pt.first) ); - ASSERT( MercatorBounds::minY <= pt.second && pt.second <= MercatorBounds::maxY, (pt.second) ); + CoordPointT const pt = PointU2PointD(p, coordBits); + ASSERT(MercatorBounds::minX <= pt.first && pt.first <= MercatorBounds::maxX, \ + (p, pt, coordBits)); + ASSERT(MercatorBounds::minY <= pt.second && pt.second <= MercatorBounds::maxY, \ + (p, pt, coordBits)); return m2::PointD(pt.first, pt.second); } - inline m2::PointU GetMaxPoint() + inline m2::PointU GetMaxPoint(CodingParams const & params) { - return D2U(m2::PointD(MercatorBounds::maxX, MercatorBounds::maxY)); + return D2U(m2::PointD(MercatorBounds::maxX, MercatorBounds::maxY), params.GetCoordBits()); } inline m2::PointU GetBasePoint(CodingParams const & params) @@ -62,13 +74,14 @@ CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) : pts::upoints_t upoints; upoints.reserve(count); - transform(points.begin(), points.end(), back_inserter(upoints), &pts::D2U); + transform(points.begin(), points.end(), back_inserter(upoints), + bind(&pts::D2U, _1, params.GetCoordBits())); ASSERT ( deltas.empty(), () ); deltas.resize(count); geo_coding::OutDeltasT adapt(deltas); - (*fn)(make_read_adapter(upoints), pts::GetBasePoint(params), pts::GetMaxPoint(), adapt); + (*fn)(make_read_adapter(upoints), pts::GetBasePoint(params), pts::GetMaxPoint(params), adapt); } template @@ -81,12 +94,13 @@ CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) : upoints.resize(count); geo_coding::OutPointsT adapt(upoints); - (*fn)(make_read_adapter(deltas), pts::GetBasePoint(params), pts::GetMaxPoint(), adapt); + (*fn)(make_read_adapter(deltas), pts::GetBasePoint(params), pts::GetMaxPoint(params), adapt); // It is may be not empty, when storing triangles. if (points.empty()) points.reserve(count); - transform(upoints.begin(), upoints.begin() + adapt.size(), back_inserter(points), &pts::U2D); + transform(upoints.begin(), upoints.begin() + adapt.size(), back_inserter(points), + bind(&pts::U2D, _1, params.GetCoordBits())); } void Decode(DecodeFunT fn, DeltasT const & deltas, CodingParams const & params, @@ -117,7 +131,7 @@ CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) : TrianglesChainSaver::TrianglesChainSaver(CodingParams const & params) { m_base = pts::GetBasePoint(params); - m_max = pts::GetMaxPoint(); + m_max = pts::GetMaxPoint(params); } namespace diff --git a/indexer/geometry_serialization.hpp b/indexer/geometry_serialization.hpp index 12f5f7156f..d967b4a343 100644 --- a/indexer/geometry_serialization.hpp +++ b/indexer/geometry_serialization.hpp @@ -15,6 +15,8 @@ #include "../base/buffer_vector.hpp" #include "../base/stl_add.hpp" +class FileReader; +class FileWriter; namespace serial { @@ -24,18 +26,34 @@ namespace serial public: // TODO: Factor out? CodingParams(); - CodingParams(int64_t basePointInt64, uint8_t coordBits = 30); + CodingParams(uint8_t coordBits, m2::PointD const & pt); + CodingParams(uint8_t coordBits, uint64_t basePointUint64); m2::PointU GetBasePointPrediction(uint64_t offset) const; // TODO: Factor out. m2::PointU GetBasePoint() const { return m_BasePoint; } // TODO: Factor out. - int64_t GetBasePointInt64() const { return m_BasePointInt64; } + int64_t GetBasePointInt64() const { return static_cast(m_BasePointUint64); } + + uint32_t const GetCoordBits() const { return m_CoordBits; } + + template void Save(WriterT & writer) const + { + WriteVarUint(writer, GetCoordBits()); + WriteVarUint(writer, static_cast(GetBasePointInt64())); + } + + template void Load(SourceT & src) + { + uint32_t const coordBits = ReadVarUint(src); + ASSERT_LESS(coordBits, 32, ()); + uint64_t const basePointUint64 = ReadVarUint(src); + *this = CodingParams(coordBits, basePointUint64); + } - uint8_t const GetCoordBits() const { return m_CoordBits; } private: - int64_t m_BasePointInt64; + uint64_t m_BasePointUint64; // TODO: Factor out. m2::PointU m_BasePoint; uint8_t m_CoordBits; @@ -48,8 +66,6 @@ namespace serial WriteVarUint(sink, v[i]); } - namespace pts { m2::PointU D2U(m2::PointD const & p); } - /// @name Encode and Decode function types. //@{ typedef void (*EncodeFunT)( geo_coding::InPointsT const &, @@ -177,7 +193,7 @@ namespace serial list m_buffers; public: - TrianglesChainSaver(CodingParams const & params); + explicit TrianglesChainSaver(CodingParams const & params); PointT GetBasePoint() const { return m_base; } PointT GetMaxPoint() const { return m_max; } diff --git a/indexer/indexer_tests/feature_routine.cpp b/indexer/indexer_tests/feature_routine.cpp index 70fa93c5ad..519a071bbc 100644 --- a/indexer/indexer_tests/feature_routine.cpp +++ b/indexer/indexer_tests/feature_routine.cpp @@ -46,14 +46,14 @@ void FeatureBuilder2Feature(FeatureBuilder2 & fb, FeatureType & f) buffers.m_ptsOffset.push_back(0); buffers.m_trgOffset.push_back(0); buffers.m_ptsMask = 1; - fb.Serialize(buffers, 0); + fb.Serialize(buffers, serial::CodingParams()); { FilesContainerW writer(datFile); { FileWriter geom = writer.GetWriter(string(GEOMETRY_FILE_TAG) + '0'); - serial::SaveOuterPath(fb.GetGeometry(), 0, geom); + serial::SaveOuterPath(fb.GetGeometry(), serial::CodingParams(), geom); } //{ diff --git a/indexer/indexer_tests/point_to_int64_test.cpp b/indexer/indexer_tests/point_to_int64_test.cpp index 7d975fe09b..e3a48788a1 100644 --- a/indexer/indexer_tests/point_to_int64_test.cpp +++ b/indexer/indexer_tests/point_to_int64_test.cpp @@ -6,6 +6,7 @@ namespace { double const eps = MercatorBounds::GetCellID2PointAbsEpsilon(); + uint32_t const coordBits = 30; void CheckEqualPoints(CoordPointT const & p1, CoordPointT const & p2) { @@ -37,7 +38,7 @@ UNIT_TEST(PointToInt64_Smoke) for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) { CoordPointT p(arr[i].x, arr[i].y); - CheckEqualPoints(p, Int64ToPoint(PointToInt64(p))); + CheckEqualPoints(p, Int64ToPoint(PointToInt64(p, coordBits), coordBits)); } } @@ -71,12 +72,12 @@ UNIT_TEST(PointToInt64_Grid) for (int iy = -180; iy <= 180; iy += delta) { CoordPointT const pt(ix, iy); - int64_t const id = PointToInt64(pt); - CoordPointT const pt1 = Int64ToPoint(id); + int64_t const id = PointToInt64(pt, coordBits); + CoordPointT const pt1 = Int64ToPoint(id, coordBits); CheckEqualPoints(pt, pt1); - int64_t const id1 = PointToInt64(pt1); + int64_t const id1 = PointToInt64(pt1, coordBits); TEST_EQUAL(id, id1, (pt, pt1)); } } @@ -95,7 +96,7 @@ UNIT_TEST(PointToInt64_Bounds) for (size_t iY = 0; iY < ARRAY_SIZE(arrEps); ++iY) { CoordPointT const pt(arrPt[iP].x + arrEps[iX], arrPt[iP].y + arrEps[iY]); - CoordPointT const pt1 = Int64ToPoint(PointToInt64(pt)); + CoordPointT const pt1 = Int64ToPoint(PointToInt64(pt, coordBits), coordBits); TEST(fabs(pt.first - pt1.first) <= (fabs(arrEps[iX]) + eps) && fabs(pt.second - pt1.second) <= (fabs(arrEps[iY]) + eps), (pt, pt1)); diff --git a/indexer/indexer_tests/triangles_tree_coding_test.cpp b/indexer/indexer_tests/triangles_tree_coding_test.cpp index 5e41d3b62d..2d7e03015b 100644 --- a/indexer/indexer_tests/triangles_tree_coding_test.cpp +++ b/indexer/indexer_tests/triangles_tree_coding_test.cpp @@ -1,6 +1,7 @@ #include "../tesselator.hpp" #include "../geometry_serialization.hpp" #include "../mercator.hpp" +#include "../point_to_int64.hpp" #include "../../coding/reader.hpp" #include "../../coding/writer.hpp" @@ -55,10 +56,12 @@ namespace for (size_t i = 0; i < countT; ++i) info.Add(arrT[i]); - serial::TrianglesChainSaver saver(0); - + serial::CodingParams codingParams; + serial::TrianglesChainSaver saver(codingParams); tesselator::PointsInfo points; - info.GetPointsInfo(saver.GetBasePoint(), saver.GetMaxPoint(), &serial::pts::D2U, points); + m2::PointU (* D2U)(m2::PointD const &, uint32_t) = &PointD2PointU; + info.GetPointsInfo(saver.GetBasePoint(), saver.GetMaxPoint(), + bind(D2U, _1, codingParams.GetCoordBits()), points); info.ProcessPortions(points, saver); @@ -72,7 +75,7 @@ namespace ReaderSource src(reader); serial::OutPointsT triangles; - serial::LoadOuterTriangles(src, 0, triangles); + serial::LoadOuterTriangles(src, serial::CodingParams(), triangles); CompareTriangles(triangles, arrP, arrT, countT); } diff --git a/indexer/point_to_int64.hpp b/indexer/point_to_int64.hpp index 2c798c987c..eac0517c65 100644 --- a/indexer/point_to_int64.hpp +++ b/indexer/point_to_int64.hpp @@ -5,22 +5,30 @@ #include "../std/utility.hpp" -#define COORD_BITS 30 - typedef double CoordT; typedef pair CoordPointT; typedef m2::CellId<19> RectId; -m2::PointU PointD2PointU(CoordT x, CoordT y, uint32_t coordBits = COORD_BITS); -CoordPointT PointU2PointD(m2::PointU const & p, uint32_t coordBits = COORD_BITS); +m2::PointU PointD2PointU(CoordT x, CoordT y, uint32_t coordBits); +inline m2::PointU PointD2PointU(m2::PointD const & pt, uint32_t coordBits) +{ + return PointD2PointU(pt.x, pt.y, coordBits); +} -int64_t PointToInt64(CoordT x, CoordT y, uint32_t coordBits = COORD_BITS); -inline int64_t PointToInt64(CoordPointT const & pt, uint32_t coordBits = COORD_BITS) +CoordPointT PointU2PointD(m2::PointU const & p, uint32_t coordBits); + +int64_t PointToInt64(CoordT x, CoordT y, uint32_t coordBits); +inline int64_t PointToInt64(CoordPointT const & pt, uint32_t coordBits) { return PointToInt64(pt.first, pt.second, coordBits); } -CoordPointT Int64ToPoint(int64_t v, uint32_t coordBits = COORD_BITS); +inline int64_t PointToInt64(m2::PointD const & pt, uint32_t coordBits) +{ + return PointToInt64(pt.x, pt.y, coordBits); +} -pair RectToInt64(m2::RectD const & r, uint32_t coordBits = COORD_BITS); -m2::RectD Int64ToRect(pair const & p, uint32_t coordBits = COORD_BITS); +CoordPointT Int64ToPoint(int64_t v, uint32_t coordBits); + +pair RectToInt64(m2::RectD const & r, uint32_t coordBits); +m2::RectD Int64ToRect(pair const & p, uint32_t coordBits); diff --git a/indexer/tesselator.cpp b/indexer/tesselator.cpp index ff54c289de..2afa035a80 100644 --- a/indexer/tesselator.cpp +++ b/indexer/tesselator.cpp @@ -275,8 +275,10 @@ namespace tesselator m_triangles.back().Add(arr); } - void TrianglesInfo::GetPointsInfo(m2::PointU const & baseP, m2::PointU const & maxP, - m2::PointU (*convert) (m2::PointD const &), PointsInfo & info) const + void TrianglesInfo::GetPointsInfo(m2::PointU const & baseP, + m2::PointU const & maxP, + function const & convert, + PointsInfo & info) const { info.m_base = baseP; info.m_max = maxP; @@ -284,6 +286,6 @@ namespace tesselator size_t const count = m_points.size(); info.m_points.reserve(count); for (size_t i = 0; i < count; ++i) - info.m_points.push_back((*convert)(m_points[i])); + info.m_points.push_back(convert(m_points[i])); } } diff --git a/indexer/tesselator.hpp b/indexer/tesselator.hpp index c47c6828d9..061cf76369 100644 --- a/indexer/tesselator.hpp +++ b/indexer/tesselator.hpp @@ -3,6 +3,7 @@ #include "../geometry/point2d.hpp" +#include "../std/function.hpp" #include "../std/list.hpp" #include "../std/vector.hpp" #include "../std/unordered_map.hpp" @@ -132,8 +133,8 @@ namespace tesselator //@{ // Convert points from double to uint. - void GetPointsInfo( m2::PointU const & baseP, m2::PointU const & maxP, - m2::PointU (*convert) (m2::PointD const &), PointsInfo & info) const; + void GetPointsInfo(m2::PointU const & baseP, m2::PointU const & maxP, + function const & convert, PointsInfo & info) const; /// Triangles chains processing function. template