mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 04:53:36 +00:00
[feature] Added RouteRelation and linked it with FeatureType.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
committed by
Konstantin Pastbin
parent
315bba2a22
commit
b85c11ea5a
@@ -244,6 +244,7 @@ std::unique_ptr<FeatureType> FeatureType::CreateFromMapObject(osm::MapObject con
|
||||
ft->m_parsed.m_types = true;
|
||||
ft->m_header = CalculateHeader(emo.GetTypes().Size(), headerGeomType, ft->m_params);
|
||||
ft->m_parsed.m_header2 = true;
|
||||
ft->m_parsed.m_relations = true;
|
||||
|
||||
ft->m_id = emo.GetID();
|
||||
return ft;
|
||||
@@ -305,7 +306,17 @@ void FeatureType::ParseCommon()
|
||||
|
||||
if (GetGeomType() == GeomType::Point)
|
||||
{
|
||||
m_center = serial::LoadPoint(source, m_loadInfo->GetDefGeometryCodingParams());
|
||||
uint64_t decoded = ReadVarUint<uint64_t>(source);
|
||||
|
||||
if (m_loadInfo->m_version >= DatSectionHeader::Version::V1)
|
||||
{
|
||||
m_hasRelations = (decoded & 0x1) == 1;
|
||||
decoded >>= 1;
|
||||
}
|
||||
|
||||
auto const & cp = m_loadInfo->GetDefGeometryCodingParams();
|
||||
m_center = PointUToPointD(coding::DecodePointDeltaFromUint(decoded, cp.GetBasePoint()), cp.GetCoordBits());
|
||||
|
||||
m_limitRect.Add(m_center);
|
||||
}
|
||||
|
||||
@@ -329,13 +340,7 @@ int8_t FeatureType::GetLayer()
|
||||
return m_params.layer;
|
||||
}
|
||||
|
||||
// TODO: there is a room to store more information in Header2 (geometry header),
|
||||
// but it needs a mwm version change.
|
||||
// 1st bit - inner / outer flag
|
||||
// 4 more bits - inner points/triangles count or outer geom offsets mask
|
||||
// (but actually its enough to store number of the first existing geom level only - 2 bits)
|
||||
// 3-5 more bits are spare
|
||||
// One of them could be used for a closed line flag to avoid storing identical first + last points.
|
||||
// TODO: One of the free bits could be used for a closed line flag to avoid storing identical first + last points.
|
||||
void FeatureType::ParseHeader2()
|
||||
{
|
||||
if (m_parsed.m_header2)
|
||||
@@ -347,7 +352,10 @@ void FeatureType::ParseHeader2()
|
||||
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
if (headerGeomType != HeaderGeomType::Line && headerGeomType != HeaderGeomType::Area)
|
||||
{
|
||||
m_offsets.m_relations = m_offsets.m_header2;
|
||||
return;
|
||||
}
|
||||
|
||||
BitSource bitSource(m_data.data() + m_offsets.m_header2);
|
||||
uint8_t elemsCount = bitSource.Read(4);
|
||||
@@ -362,13 +370,15 @@ void FeatureType::ParseHeader2()
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQUAL(m_loadInfo->m_version, DatSectionHeader::Version::V1, ());
|
||||
ASSERT(m_loadInfo->m_version >= DatSectionHeader::Version::V1, ());
|
||||
bool const isOuter = (bitSource.Read(1) == 1);
|
||||
if (isOuter)
|
||||
{
|
||||
geomScalesMask = elemsCount;
|
||||
elemsCount = 0;
|
||||
}
|
||||
|
||||
m_hasRelations = (bitSource.Read(1) == 1);
|
||||
}
|
||||
|
||||
ArrayByteSource src(bitSource.RoundPtr());
|
||||
@@ -426,6 +436,23 @@ void FeatureType::ParseHeader2()
|
||||
}
|
||||
}
|
||||
|
||||
m_offsets.m_relations = CalcOffset(src, m_data.data());
|
||||
}
|
||||
|
||||
void FeatureType::ParseRelations()
|
||||
{
|
||||
if (m_parsed.m_relations)
|
||||
return;
|
||||
|
||||
ParseHeader2();
|
||||
|
||||
ArrayByteSource src(m_data.data() + m_offsets.m_relations);
|
||||
|
||||
if (m_hasRelations)
|
||||
ReadVarUInt32SortedShortArray(src, m_relationIDs);
|
||||
|
||||
m_parsed.m_relations = true;
|
||||
|
||||
// Size of the whole header incl. inner geometry / triangles.
|
||||
m_innerStats.m_size = CalcOffset(src, m_data.data());
|
||||
}
|
||||
@@ -442,7 +469,7 @@ void FeatureType::ResetGeometry()
|
||||
if (GetGeomType() != GeomType::Point)
|
||||
m_limitRect = m2::RectD();
|
||||
|
||||
m_parsed.m_header2 = m_parsed.m_points = m_parsed.m_triangles = false;
|
||||
m_parsed.m_relations = m_parsed.m_header2 = m_parsed.m_points = m_parsed.m_triangles = false;
|
||||
m_offsets.m_pts.clear();
|
||||
m_offsets.m_trg.clear();
|
||||
m_ptsSimpMask = 0;
|
||||
@@ -501,9 +528,9 @@ void FeatureType::ParseGeometry(int scale)
|
||||
|
||||
FeatureType::GeomStat FeatureType::GetOuterGeometryStats()
|
||||
{
|
||||
CHECK(m_loadInfo && m_parsed.m_header2 && !m_parsed.m_points, ("Call geometry stats first and once!"));
|
||||
CHECK(m_loadInfo && m_parsed.m_relations && !m_parsed.m_points, ());
|
||||
size_t const scalesCount = m_loadInfo->GetScalesCount();
|
||||
ASSERT_LESS_OR_EQUAL(scalesCount, DataHeader::kMaxScalesCount, ("MWM has too many geometry scales!"));
|
||||
ASSERT_LESS_OR_EQUAL(scalesCount, DataHeader::kMaxScalesCount, ());
|
||||
FeatureType::GeomStat res;
|
||||
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
@@ -576,10 +603,9 @@ void FeatureType::ParseTriangles(int scale)
|
||||
|
||||
FeatureType::GeomStat FeatureType::GetOuterTrianglesStats()
|
||||
{
|
||||
CHECK(m_loadInfo && m_parsed.m_header2 && !m_parsed.m_triangles, ("Call geometry stats first and once!"));
|
||||
CHECK(m_loadInfo && m_parsed.m_relations && !m_parsed.m_triangles, ());
|
||||
int const scalesCount = m_loadInfo->GetScalesCount();
|
||||
ASSERT_LESS_OR_EQUAL(scalesCount, static_cast<int>(DataHeader::kMaxScalesCount),
|
||||
("MWM has too many geometry scales!"));
|
||||
ASSERT_LESS_OR_EQUAL(scalesCount, static_cast<int>(DataHeader::kMaxScalesCount), ());
|
||||
FeatureType::GeomStat res;
|
||||
|
||||
auto const headerGeomType = static_cast<HeaderGeomType>(Header(m_data) & HEADER_MASK_GEOMTYPE);
|
||||
@@ -868,3 +894,16 @@ bool FeatureType::HasMetadata(feature::Metadata::EType type)
|
||||
|
||||
return base::FindIf(m_metaIds, [&type](auto const & v) { return v.first == type; }) != m_metaIds.end();
|
||||
}
|
||||
|
||||
FeatureType::RelationIDsV const & FeatureType::GetRelations()
|
||||
{
|
||||
ParseRelations();
|
||||
return m_relationIDs;
|
||||
}
|
||||
|
||||
/// @pre id is from m_relationIDs.
|
||||
feature::RouteRelationBase FeatureType::ReadRelation(uint32_t id)
|
||||
{
|
||||
ParseRelations();
|
||||
return m_loadInfo->ReadRelation(id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user