forked from organicmaps/organicmaps
Separating preparing altitudes for saving and writing them. Using bit writer to save them.
This commit is contained in:
parent
927891f51b
commit
c8d53fa85c
3 changed files with 76 additions and 27 deletions
58
indexer/feature_altitude.cpp
Normal file
58
indexer/feature_altitude.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "indexer/feature_altitude.hpp"
|
||||
|
||||
#include "base/bits.hpp"
|
||||
|
||||
namespace feature
|
||||
{
|
||||
void Altitudes::PrepareSerializationData(TAltitude minAltitude, vector<uint32_t> & deviations) const
|
||||
{
|
||||
CHECK(!m_altitudes.empty(), ());
|
||||
|
||||
deviations.clear();
|
||||
uint32_t const firstPntDeviation =
|
||||
bits::ZigZagEncode(static_cast<int32_t>(m_altitudes[0]) -
|
||||
static_cast<int32_t>(minAltitude)) + 1 /* making it more than zero */;
|
||||
CHECK_LESS(0, firstPntDeviation, ());
|
||||
deviations.push_back(firstPntDeviation);
|
||||
for (size_t i = 1; i < m_altitudes.size(); ++i)
|
||||
{
|
||||
uint32_t const nextPntDeviation = bits::ZigZagEncode(static_cast<int32_t>(m_altitudes[i]) -
|
||||
static_cast<int32_t>(m_altitudes[i - 1])) + 1 /* making it more than zero */;
|
||||
CHECK_LESS(0, nextPntDeviation, ());
|
||||
deviations.push_back(nextPntDeviation);
|
||||
}
|
||||
}
|
||||
|
||||
bool Altitudes::FillAltitudesByDeserializedDate(TAltitude minAltitude, vector<uint32_t> const & deviations)
|
||||
{
|
||||
m_altitudes.clear();
|
||||
if (deviations.size() == 0)
|
||||
{
|
||||
ASSERT(false, ());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_altitudes.resize(deviations.size());
|
||||
TAltitude prevAltitude = minAltitude;
|
||||
for (size_t i = 0; i < deviations.size(); ++i)
|
||||
{
|
||||
if (deviations[i] == 0)
|
||||
{
|
||||
ASSERT(false, (i));
|
||||
m_altitudes.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_altitudes[i] = static_cast<TAltitude>(bits::ZigZagDecode(deviations[i] -
|
||||
1 /* Recovering value */) + prevAltitude);
|
||||
if (m_altitudes[i] < minAltitude)
|
||||
{
|
||||
ASSERT(false, (i));
|
||||
m_altitudes.clear();
|
||||
return false;
|
||||
}
|
||||
prevAltitude = m_altitudes[i];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace feature
|
|
@ -1,4 +1,6 @@
|
|||
#pragma once
|
||||
#include "coding/bit_streams.hpp"
|
||||
#include "coding/elias_coder.hpp"
|
||||
#include "coding/reader.hpp"
|
||||
#include "coding/varint.hpp"
|
||||
#include "coding/write_to_sink.hpp"
|
||||
|
@ -51,7 +53,7 @@ struct AltitudeHeader
|
|||
|
||||
size_t GetFeatureTableSize() const { return m_altitudesOffset - m_featureTableOffset; }
|
||||
|
||||
size_t GetAltitudeInfo() const { return m_endOffset - m_altitudesOffset; }
|
||||
size_t GetAltitudeInfoSize() const { return m_endOffset - m_altitudesOffset; }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
|
@ -81,40 +83,24 @@ public:
|
|||
template <class TSink>
|
||||
void Serialize(TAltitude minAltitude, TSink & sink) const
|
||||
{
|
||||
CHECK(!m_altitudes.empty(), ());
|
||||
vector<uint32_t> deviations;
|
||||
PrepareSerializationData(minAltitude, deviations);
|
||||
|
||||
WriteVarInt(sink, static_cast<int32_t>(m_altitudes[0]) - static_cast<int32_t>(minAltitude));
|
||||
for (size_t i = 1; i < m_altitudes.size(); ++i)
|
||||
{
|
||||
WriteVarInt(sink,
|
||||
static_cast<int32_t>(m_altitudes[i]) - static_cast<int32_t>(m_altitudes[i - 1]));
|
||||
}
|
||||
BitWriter<TSink> bits(sink);
|
||||
for (auto const d : deviations)
|
||||
coding::DeltaCoder::Encode(bits, d);
|
||||
}
|
||||
|
||||
template <class TSource>
|
||||
bool Deserialize(TAltitude minAltitude, size_t pointCount, TSource & src)
|
||||
{
|
||||
m_altitudes.clear();
|
||||
if (pointCount == 0)
|
||||
{
|
||||
ASSERT(false, ());
|
||||
return false;
|
||||
}
|
||||
vector<uint32_t> deviations(pointCount);
|
||||
BitReader<TSource> bits(src);
|
||||
|
||||
m_altitudes.resize(pointCount);
|
||||
TAltitude prevAltitude = minAltitude;
|
||||
for (size_t i = 0; i < pointCount; ++i)
|
||||
{
|
||||
m_altitudes[i] = static_cast<TAltitude>(ReadVarInt<int32_t>(src) + prevAltitude);
|
||||
if (m_altitudes[i] < minAltitude)
|
||||
{
|
||||
ASSERT(false, ());
|
||||
m_altitudes.clear();
|
||||
return false;
|
||||
}
|
||||
prevAltitude = m_altitudes[i];
|
||||
}
|
||||
return true;
|
||||
deviations[i] = coding::DeltaCoder::Decode(bits);
|
||||
|
||||
return FillAltitudesByDeserializedDate(minAltitude, deviations);
|
||||
}
|
||||
|
||||
/// \note |m_altitudes| is a vector of feature point altitudes. There's two possibilities:
|
||||
|
@ -122,5 +108,9 @@ public:
|
|||
/// * size of |m_pointAlt| is equal to the number of this feature's points. If so
|
||||
/// all items of |m_altitudes| have valid value.
|
||||
TAltitudes m_altitudes;
|
||||
|
||||
private:
|
||||
void PrepareSerializationData(TAltitude minAltitude, vector<uint32_t> & deviations) const;
|
||||
bool FillAltitudesByDeserializedDate(TAltitude minAltitude, vector<uint32_t> const & deviations);
|
||||
};
|
||||
} // namespace feature
|
||||
|
|
|
@ -29,6 +29,7 @@ SOURCES += \
|
|||
edits_migration.cpp \
|
||||
feature.cpp \
|
||||
feature_algo.cpp \
|
||||
feature_altitude.cpp \
|
||||
feature_covering.cpp \
|
||||
feature_data.cpp \
|
||||
feature_decl.cpp \
|
||||
|
|
Loading…
Add table
Reference in a new issue