[Reduce mwm size] Store first point once in header for outer linear features.

This commit is contained in:
vng 2011-09-16 23:04:38 +03:00 committed by Alex Zolotarev
parent 3e2ecdc144
commit 2872bfbffb
5 changed files with 39 additions and 11 deletions

View file

@ -481,6 +481,11 @@ void FeatureBuilder2::Serialize(buffers_holder_t & data, serial::CodingParams co
}
else
{
ASSERT_GREATER ( GetGeometry().size(), 2, () );
// Store first point once for outer linear features.
serial::SavePoint(sink, GetGeometry()[0], params);
// offsets was pushed from high scale index to low
reverse(data.m_ptsOffset.begin(), data.m_ptsOffset.end());
serial::WriteVarUintArray(data.m_ptsOffset, sink);

View file

@ -165,11 +165,18 @@ namespace feature
void WriteOuterPoints(points_t const & points, int i)
{
serial::CodingParams const cp = m_header.GetCodingParams(i);
ASSERT_GREATER ( points.size(), 2, () );
serial::CodingParams cp = m_header.GetCodingParams(i);
// Optimization: Store first point once in header for outer linear features.
cp.SetBasePoint(points[0]);
// "!!!Cry for me, river!!!"
points_t toSave(points.begin() + 1, points.end());
m_buffer.m_ptsMask |= (1 << i);
m_buffer.m_ptsOffset.push_back(m_rMain.GetFileSize(*m_rMain.m_geoFile[i]));
serial::SaveOuterPath(points, cp, *m_rMain.m_geoFile[i]);
serial::SaveOuterPath(toSave, cp, *m_rMain.m_geoFile[i]);
}
void WriteOuterTriangles(polygons_t const & polys, int i)

View file

@ -15,8 +15,7 @@ namespace serial
CodingParams::CodingParams(uint8_t coordBits, m2::PointD const & pt)
: m_CoordBits(coordBits)
{
m_BasePoint = PointD2PointU(pt.x, pt.y, coordBits);
m_BasePointUint64 = m2::PointUToUint64(m_BasePoint);
SetBasePoint(pt);
}
CodingParams::CodingParams(uint8_t coordBits, uint64_t basePointUint64)
@ -24,4 +23,10 @@ namespace serial
{
m_BasePoint = m2::Uint64ToPointU(m_BasePointUint64);
}
void CodingParams::SetBasePoint(m2::PointD const & pt)
{
m_BasePoint = PointD2PointU(pt.x, pt.y, m_CoordBits);
m_BasePointUint64 = m2::PointUToUint64(m_BasePoint);
}
}

View file

@ -24,6 +24,8 @@ namespace serial
{
return static_cast<int64_t>(m_BasePointUint64);
}
void SetBasePoint(m2::PointD const & pt);
//@}
inline uint32_t GetCoordBits() const { return m_CoordBits; }

View file

@ -127,6 +127,8 @@ void LoaderCurrent::ParseHeader2()
ArrayByteSource src(bitSource.RoundPtr());
serial::CodingParams const & cp = GetDefCodingParams();
if (h & HEADER_GEOM_LINE)
{
if (ptsCount > 0)
@ -142,13 +144,16 @@ void LoaderCurrent::ParseHeader2()
char const * start = static_cast<char const *>(src.Ptr());
src = ArrayByteSource(serial::LoadInnerPath(
src.Ptr(), ptsCount, GetDefCodingParams(), m_pF->m_Points));
src = ArrayByteSource(serial::LoadInnerPath(src.Ptr(), ptsCount, cp, m_pF->m_Points));
m_pF->m_InnerStats.m_Points = static_cast<char const *>(src.Ptr()) - start;
}
else
{
m_pF->m_Points.push_back(serial::LoadPoint(src, cp));
ReadOffsets(src, ptsMask, m_ptsOffsets);
}
}
if (h & HEADER_GEOM_AREA)
@ -160,8 +165,7 @@ void LoaderCurrent::ParseHeader2()
char const * start = static_cast<char const *>(src.Ptr());
FeatureType::points_t points;
src = ArrayByteSource(serial::LoadInnerTriangles(
src.Ptr(), trgCount, GetDefCodingParams(), points));
src = ArrayByteSource(serial::LoadInnerTriangles(src.Ptr(), trgCount, cp, points));
m_pF->m_InnerStats.m_Strips = static_cast<char const *>(src.Ptr()) - start;
@ -184,15 +188,21 @@ uint32_t LoaderCurrent::ParseGeometry(int scale)
uint32_t sz = 0;
if (Header() & HEADER_GEOM_LINE)
{
if (m_pF->m_Points.empty())
size_t const count = m_pF->m_Points.size();
if (count < 2)
{
ASSERT_EQUAL ( count, 1, () );
// outer geometry
int const ind = GetScaleIndex(scale, m_ptsOffsets);
if (ind != -1)
{
ReaderSource<FilesContainerR::ReaderT> src(m_Info.GetGeometryReader(ind));
src.Skip(m_ptsOffsets[ind]);
serial::LoadOuterPath(src, GetCodingParams(ind), m_pF->m_Points);
serial::CodingParams cp = GetCodingParams(ind);
cp.SetBasePoint(m_pF->m_Points[0]);
serial::LoadOuterPath(src, cp, m_pF->m_Points);
sz = static_cast<uint32_t>(src.Pos() - m_ptsOffsets[ind]);
}
@ -201,7 +211,6 @@ uint32_t LoaderCurrent::ParseGeometry(int scale)
{
// filter inner geometry
size_t const count = m_pF->m_Points.size();
FeatureType::points_t points;
points.reserve(count);