Introduce serial::CodingParams in geometry_serialization.hpp

This commit is contained in:
Yury Melnichek 2011-04-23 15:39:33 +02:00 committed by Alex Zolotarev
parent f30fafacea
commit a056e19961
3 changed files with 101 additions and 48 deletions

View file

@ -257,14 +257,14 @@ void FeatureBuilder1::Serialize(buffer_t & data) const
PushBackByteSink<buffer_t> sink(data);
if (m_bLinear || m_bArea)
serial::SaveOuterPath(m_Geometry, 0, sink);
serial::SaveOuterPath(m_Geometry, serial::CodingParams(), sink);
if (m_bArea)
{
WriteVarUint(sink, uint32_t(m_Holes.size()));
for (list<points_t>::const_iterator i = m_Holes.begin(); i != m_Holes.end(); ++i)
serial::SaveOuterPath(*i, 0, sink);
serial::SaveOuterPath(*i, serial::CodingParams(), sink);
}
// check for correct serialization
@ -296,7 +296,7 @@ void FeatureBuilder1::Deserialize(buffer_t & data)
if (m_bLinear || m_bArea)
{
serial::LoadOuterPath(src, 0, m_Geometry);
serial::LoadOuterPath(src, serial::CodingParams(), m_Geometry);
CalcRect(m_Geometry, m_LimitRect);
}
@ -306,7 +306,7 @@ void FeatureBuilder1::Deserialize(buffer_t & data)
for (uint32_t i = 0; i < count; ++i)
{
m_Holes.push_back(points_t());
serial::LoadOuterPath(src, 0, m_Holes.back());
serial::LoadOuterPath(src, serial::CodingParams(), m_Holes.back());
}
}
@ -429,7 +429,7 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base)
}
}
serial::SaveInnerPath(data.m_innerPts, base, sink);
serial::SaveInnerPath(data.m_innerPts, serial::CodingParams(base), sink);
}
else
{
@ -442,7 +442,7 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, int64_t base)
if (m_bArea)
{
if (trgCount > 0)
serial::SaveInnerTriangles(data.m_innerTrg, base, sink);
serial::SaveInnerTriangles(data.m_innerTrg, serial::CodingParams(base), sink);
else
{
// offsets was pushed from high scale index to low

View file

@ -14,6 +14,18 @@
namespace serial
{
CodingParams::CodingParams() : m_BasePoint(0, 0), m_CoordBits(30)
{
m_BasePointInt64 = m2::PointUToUint64(m_BasePoint);
}
CodingParams::CodingParams(int64_t basePointInt64, uint8_t coordBits) :
m_BasePointInt64(basePointInt64), m_CoordBits(coordBits)
{
m_BasePoint = m2::Uint64ToPointU(basePointInt64);
}
namespace pts
{
inline m2::PointU D2U(m2::PointD const & p)
@ -24,8 +36,8 @@ namespace serial
inline m2::PointD U2D(m2::PointU const & p)
{
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) );
ASSERT( MercatorBounds::minX <= pt.first && pt.first <= MercatorBounds::maxX, (pt.first) );
ASSERT( MercatorBounds::minY <= pt.second && pt.second <= MercatorBounds::maxY, (pt.second) );
return m2::PointD(pt.first, pt.second);
}
@ -34,15 +46,16 @@ namespace serial
return D2U(m2::PointD(MercatorBounds::maxX, MercatorBounds::maxY));
}
inline m2::PointU GetBasePoint(int64_t base)
inline m2::PointU GetBasePoint(CodingParams const & params)
{
return m2::Uint64ToPointU(base);
return params.GetBasePoint();
}
typedef buffer_vector<m2::PointU, 32> upoints_t;
}
void Encode(EncodeFunT fn, vector<m2::PointD> const & points, int64_t base, DeltasT & deltas)
void Encode(EncodeFunT fn, vector<m2::PointD> const & points,
CodingParams const & params, DeltasT & deltas)
{
size_t const count = points.size();
@ -55,11 +68,12 @@ namespace serial
deltas.resize(count);
geo_coding::OutDeltasT adapt(deltas);
(*fn)(make_read_adapter(upoints), pts::GetBasePoint(base), pts::GetMaxPoint(), adapt);
(*fn)(make_read_adapter(upoints), pts::GetBasePoint(params), pts::GetMaxPoint(), adapt);
}
template <class TDecodeFun, class TOutPoints>
void DecodeImpl(TDecodeFun fn, DeltasT const & deltas, int64_t base, TOutPoints & points, size_t reserveF)
void DecodeImpl(TDecodeFun fn, DeltasT const & deltas, CodingParams const & params,
TOutPoints & points, size_t reserveF)
{
size_t const count = deltas.size() * reserveF;
@ -67,7 +81,7 @@ namespace serial
upoints.resize(count);
geo_coding::OutPointsT adapt(upoints);
(*fn)(make_read_adapter(deltas), pts::GetBasePoint(base), pts::GetMaxPoint(), adapt);
(*fn)(make_read_adapter(deltas), pts::GetBasePoint(params), pts::GetMaxPoint(), adapt);
// It is may be not empty, when storing triangles.
if (points.empty())
@ -75,31 +89,34 @@ namespace serial
transform(upoints.begin(), upoints.begin() + adapt.size(), back_inserter(points), &pts::U2D);
}
void Decode(DecodeFunT fn, DeltasT const & deltas, int64_t base, OutPointsT & points, size_t reserveF)
void Decode(DecodeFunT fn, DeltasT const & deltas, CodingParams const & params,
OutPointsT & points, size_t reserveF)
{
DecodeImpl(fn, deltas, base, points, reserveF);
DecodeImpl(fn, deltas, params, points, reserveF);
}
void Decode(DecodeFunT fn, DeltasT const & deltas, int64_t base, vector<m2::PointD> & points, size_t reserveF)
void Decode(DecodeFunT fn, DeltasT const & deltas, CodingParams const & params,
vector<m2::PointD> & points, size_t reserveF)
{
DecodeImpl(fn, deltas, base, points, reserveF);
DecodeImpl(fn, deltas, params, points, reserveF);
}
void const * LoadInner(DecodeFunT fn, void const * pBeg, size_t count, int64_t base, OutPointsT & points)
void const * LoadInner(DecodeFunT fn, void const * pBeg, size_t count,
CodingParams const & params, OutPointsT & points)
{
DeltasT deltas;
deltas.reserve(count);
void const * ret = ReadVarUint64Array(static_cast<char const *>(pBeg), count,
MakeBackInsertFunctor(deltas));
Decode(fn, deltas, base, points);
Decode(fn, deltas, params, points);
return ret;
}
TrianglesChainSaver::TrianglesChainSaver(int64_t base)
TrianglesChainSaver::TrianglesChainSaver(CodingParams const & params)
{
m_base = pts::GetBasePoint(base);
m_base = pts::GetBasePoint(params);
m_max = pts::GetMaxPoint();
}
@ -243,7 +260,10 @@ namespace serial
points.push_back(points[trg[0]]);
points.push_back(points[trg[1]]);
points.push_back( DecodeDelta(deltas[i] >> 2,
PredictPointInTriangle(maxPoint, points[trg[0]], points[trg[1]], points[trg[2]])));
PredictPointInTriangle(maxPoint,
points[trg[0]],
points[trg[1]],
points[trg[2]])));
// next step
treeBits = deltas[i] & 3;

View file

@ -18,6 +18,29 @@
namespace serial
{
class CodingParams
{
public:
// TODO: Factor out?
CodingParams();
CodingParams(int64_t basePointInt64, uint8_t coordBits = 30);
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; }
uint8_t const GetCoordBits() const { return m_CoordBits; }
private:
int64_t m_BasePointInt64;
// TODO: Factor out.
m2::PointU m_BasePoint;
uint8_t m_CoordBits;
};
template <class TCont, class TSink>
inline void WriteVarUintArray(TCont const & v, TSink & sink)
{
@ -40,19 +63,23 @@ namespace serial
typedef buffer_vector<uint64_t, 32> DeltasT;
typedef buffer_vector<m2::PointD, 32> OutPointsT;
void Encode(EncodeFunT fn, vector<m2::PointD> const & points, int64_t base, DeltasT & deltas);
void Encode(EncodeFunT fn, vector<m2::PointD> const & points, CodingParams const & params,
DeltasT & deltas);
/// @name Overloads for different out container types.
//@{
void Decode(DecodeFunT fn, DeltasT const & deltas, int64_t base, OutPointsT & points, size_t reserveF = 1);
void Decode(DecodeFunT fn, DeltasT const & deltas, int64_t base, vector<m2::PointD> & points, size_t reserveF = 1);
void Decode(DecodeFunT fn, DeltasT const & deltas, CodingParams const & params,
OutPointsT & points, size_t reserveF = 1);
void Decode(DecodeFunT fn, DeltasT const & deltas, CodingParams const & params,
vector<m2::PointD> & points, size_t reserveF = 1);
//@}
template <class TSink>
void SaveInner(EncodeFunT fn, vector<m2::PointD> const & points, int64_t base, TSink & sink)
void SaveInner(EncodeFunT fn, vector<m2::PointD> const & points,
CodingParams const & params, TSink & sink)
{
DeltasT deltas;
Encode(fn, points, base, deltas);
Encode(fn, points, params, deltas);
WriteVarUintArray(deltas, sink);
}
@ -65,10 +92,11 @@ namespace serial
}
template <class TSink>
void SaveOuter(EncodeFunT fn, vector<m2::PointD> const & points, int64_t base, TSink & sink)
void SaveOuter(EncodeFunT fn, vector<m2::PointD> const & points,
CodingParams const & params, TSink & sink)
{
DeltasT deltas;
Encode(fn, points, base, deltas);
Encode(fn, points, params, deltas);
vector<char> buffer;
MemWriter<vector<char> > writer(buffer);
@ -77,10 +105,12 @@ namespace serial
WriteBufferToSink(buffer, sink);
}
void const * LoadInner(DecodeFunT fn, void const * pBeg, size_t count, int64_t base, OutPointsT & points);
void const * LoadInner(DecodeFunT fn, void const * pBeg, size_t count,
CodingParams const & params, OutPointsT & points);
template <class TSource, class TPoints>
void LoadOuter(DecodeFunT fn, TSource & src, int64_t base, TPoints & points, size_t reserveF = 1)
void LoadOuter(DecodeFunT fn, TSource & src, CodingParams const & params,
TPoints & points, size_t reserveF = 1)
{
uint32_t const count = ReadVarUint<uint32_t>(src);
vector<char> buffer(count);
@ -91,46 +121,49 @@ namespace serial
deltas.reserve(count / 2);
ReadVarUint64Array(p, p + count, MakeBackInsertFunctor(deltas));
Decode(fn, deltas, base, points, reserveF);
Decode(fn, deltas, params, points, reserveF);
}
/// @name Paths.
//@{
template <class TSink>
void SaveInnerPath(vector<m2::PointD> const & points, int64_t base, TSink & sink)
void SaveInnerPath(vector<m2::PointD> const & points, CodingParams const & params, TSink & sink)
{
SaveInner(&geo_coding::EncodePolyline, points, base, sink);
SaveInner(&geo_coding::EncodePolyline, points, params, sink);
}
template <class TSink>
void SaveOuterPath(vector<m2::PointD> const & points, int64_t base, TSink & sink)
void SaveOuterPath(vector<m2::PointD> const & points, CodingParams const & params, TSink & sink)
{
SaveOuter(&geo_coding::EncodePolyline, points, base, sink);
SaveOuter(&geo_coding::EncodePolyline, points, params, sink);
}
inline void const * LoadInnerPath(void const * pBeg, size_t count, int64_t base, OutPointsT & points)
inline void const * LoadInnerPath(void const * pBeg, size_t count, CodingParams const & params,
OutPointsT & points)
{
return LoadInner(&geo_coding::DecodePolyline, pBeg, count, base, points);
return LoadInner(&geo_coding::DecodePolyline, pBeg, count, params, points);
}
template <class TSource, class TPoints>
void LoadOuterPath(TSource & src, int64_t base, TPoints & points)
void LoadOuterPath(TSource & src, CodingParams const & params, TPoints & points)
{
LoadOuter(&geo_coding::DecodePolyline, src, base, points);
LoadOuter(&geo_coding::DecodePolyline, src, params, points);
}
//@}
/// @name Triangles.
//@{
template <class TSink>
void SaveInnerTriangles(vector<m2::PointD> const & points, int64_t base, TSink & sink)
void SaveInnerTriangles(vector<m2::PointD> const & points,
CodingParams const & params, TSink & sink)
{
SaveInner(&geo_coding::EncodeTriangleStrip, points, base, sink);
SaveInner(&geo_coding::EncodeTriangleStrip, points, params, sink);
}
inline void const * LoadInnerTriangles(void const * pBeg, size_t count, int64_t base, OutPointsT & points)
inline void const * LoadInnerTriangles(void const * pBeg, size_t count,
CodingParams const & params, OutPointsT & points)
{
return LoadInner(&geo_coding::DecodeTriangleStrip, pBeg, count, base, points);
return LoadInner(&geo_coding::DecodeTriangleStrip, pBeg, count, params, points);
}
class TrianglesChainSaver
@ -144,7 +177,7 @@ namespace serial
list<BufferT> m_buffers;
public:
TrianglesChainSaver(int64_t base);
TrianglesChainSaver(CodingParams const & params);
PointT GetBasePoint() const { return m_base; }
PointT GetMaxPoint() const { return m_max; }
@ -177,12 +210,12 @@ namespace serial
geo_coding::OutPointsT & triangles);
template <class TSource>
void LoadOuterTriangles(TSource & src, int64_t base, OutPointsT & triangles)
void LoadOuterTriangles(TSource & src, CodingParams const & params, OutPointsT & triangles)
{
int const count = ReadVarUint<uint32_t>(src);
for (int i = 0; i < count; ++i)
LoadOuter(&DecodeTriangles, src, base, triangles, 3);
LoadOuter(&DecodeTriangles, src, params, triangles, 3);
}
//@}
}