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:
-rw-r--r--generator/feature_sorter.cpp33
-rw-r--r--generator/world_map_generator.hpp23
-rw-r--r--indexer/data_header.cpp21
-rw-r--r--indexer/data_header.hpp10
-rw-r--r--indexer/feature.cpp34
-rw-r--r--indexer/feature.hpp8
-rw-r--r--indexer/feature_impl.hpp8
-rw-r--r--indexer/geometry_serialization.cpp50
-rw-r--r--indexer/geometry_serialization.hpp30
-rw-r--r--indexer/indexer_tests/feature_routine.cpp4
-rw-r--r--indexer/indexer_tests/point_to_int64_test.cpp11
-rw-r--r--indexer/indexer_tests/triangles_tree_coding_test.cpp11
-rw-r--r--indexer/point_to_int64.hpp26
-rw-r--r--indexer/tesselator.cpp8
-rw-r--r--indexer/tesselator.hpp5
15 files changed, 165 insertions, 117 deletions
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<TCellAndOffset> 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<size_t>(PointToInt64(pt.x, pt.y));
- }
-}
-
template <class FeatureOutT>
class WorldMapGenerator
{
@@ -38,7 +29,9 @@ class WorldMapGenerator
size_t m_mergedCounter;
size_t m_areasCounter;
- typedef unordered_map<m2::PointD, FeatureBuilder1Merger> FeaturesContainerT;
+ uint32_t m_coordBits;
+
+ typedef unordered_map<uint64_t, FeatureBuilder1Merger> FeaturesContainerT;
typedef map<uint32_t, FeaturesContainerT> 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<FeaturesContainerT::iterator, bool> result = container.insert(make_pair(fbm.FirstPoint(), fbm));
+ pair<FeaturesContainerT::iterator, bool> 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<FileReader> src(r);
- m_base = ReadPrimitiveFromSource<int64_t>(src);
- m_bounds.first = ReadVarInt<int64_t>(src) + m_base;
- m_bounds.second = ReadVarInt<int64_t>(src) + m_base;
+ m_codingParams.Load(src);
+ m_bounds.first = ReadVarInt<int64_t>(src) + m_codingParams.GetBasePointInt64();
+ m_bounds.second = ReadVarInt<int64_t>(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<int64_t, int64_t> 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<buffer_t> 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<buffer_t> 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<uint64_t>(base)));
+ SerializeBase(data.m_buffer, params);
PushBackByteSink<buffer_t> 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<uint64_t>(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<char const *>(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<char const *>(src.Ptr()) - start;
}
@@ -804,7 +806,7 @@ void FeatureType::ParseHeader2() const
char const * start = static_cast<char const *>(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<char const *>(src.Ptr()) - start;
@@ -841,7 +843,7 @@ uint32_t FeatureType::ParseGeometry(int scale) const
ReaderSource<FileReader> 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<uint32_t>(src.Pos() - m_ptsOffsets[ind]);
}
@@ -893,7 +895,7 @@ uint32_t FeatureType::ParseTriangles(int scale) const
ReaderSource<FileReader> 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<uint32_t>(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_BasePoint = m2::Uint64ToPointU(m_BasePointUint64);
+}
+
+CodingParams::CodingParams(uint8_t coordBits, m2::PointD const & pt) : m_CoordBits(coordBits)
{
- m_BasePointInt64 = m2::PointUToUint64(m_BasePoint);
+ m_BasePoint = PointD2PointU(pt.x, pt.y, coordBits);
+ m_BasePointUint64 = m2::PointUToUint64(m_BasePoint);
}
-CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) :
- m_BasePointInt64(basePointInt64), m_CoordBits(coordBits)
+CodingParams::CodingParams(uint8_t coordBits, uint64_t basePointUint64)
+ : m_BasePointUint64(basePointUint64), m_CoordBits(coordBits)
{
- m_BasePoint = m2::Uint64ToPointU(basePointInt64);
+ 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 <class TDecodeFun, class TOutPoints>
@@ -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<int64_t>(m_BasePointUint64); }
+
+ uint32_t const GetCoordBits() const { return m_CoordBits; }
+
+ template <typename WriterT> void Save(WriterT & writer) const
+ {
+ WriteVarUint(writer, GetCoordBits());
+ WriteVarUint(writer, static_cast<uint64_t>(GetBasePointInt64()));
+ }
+
+ template <typename SourceT> void Load(SourceT & src)
+ {
+ uint32_t const coordBits = ReadVarUint<uint32_t>(src);
+ ASSERT_LESS(coordBits, 32, ());
+ uint64_t const basePointUint64 = ReadVarUint<uint64_t>(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<BufferT> 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<MemReader> 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<CoordT, CoordT> 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);
+}
+
+CoordPointT PointU2PointD(m2::PointU const & p, uint32_t 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)
+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);
+}
+
+CoordPointT Int64ToPoint(int64_t v, uint32_t coordBits);
-pair<int64_t, int64_t> RectToInt64(m2::RectD const & r, uint32_t coordBits = COORD_BITS);
-m2::RectD Int64ToRect(pair<int64_t, int64_t> const & p, uint32_t coordBits = COORD_BITS);
+pair<int64_t, int64_t> RectToInt64(m2::RectD const & r, uint32_t coordBits);
+m2::RectD Int64ToRect(pair<int64_t, int64_t> 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<m2::PointU (m2::PointD)> 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<m2::PointU (m2::PointD)> const & convert, PointsInfo & info) const;
/// Triangles chains processing function.
template <class EmitterT>