forked from organicmaps/organicmaps
Introduce serial::CodingParams in geometry_serialization.hpp
This commit is contained in:
parent
f30fafacea
commit
a056e19961
3 changed files with 101 additions and 48 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
//@}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue