Setting valid altitude for all Junctions.

This commit is contained in:
Vladimir Byko-Ianko 2016-07-26 18:50:47 +03:00
parent 149365fe1b
commit 6840c3c18c
7 changed files with 42 additions and 34 deletions

View file

@ -79,12 +79,14 @@ public:
}
TFeatureAltitudes const & GetFeatureAltitudes() const { return m_featureAltitudes; }
succinct::bit_vector_builder & GetAltitudeAvailabilityBuilder()
{
return m_altitudeAvailabilityBuilder;
}
TAltitude GetMinAltitude() const { return m_minAltitude; }
void operator()(FeatureType const & f, uint32_t const & id)
{
if (id != m_altitudeAvailabilityBuilder.size())

View file

@ -53,12 +53,13 @@ AltitudeLoader::AltitudeLoader(MwmValue const & mwmValue)
}
bool AltitudeLoader::HasAltitudes() const { return m_header.m_minAltitude != kInvalidAltitude; }
TAltitudes const & AltitudeLoader::GetAltitudes(uint32_t featureId, size_t pointCount)
{
if (!HasAltitudes())
{
// The version of mwm is less than version::Format::v8 or there's no altitude section in mwm.
return m_dummy;
return m_cache.insert(make_pair(featureId, TAltitudes(pointCount, kDefautlAltitudeMeters))).first->second;
}
auto const it = m_cache.find(featureId);
@ -68,7 +69,7 @@ TAltitudes const & AltitudeLoader::GetAltitudes(uint32_t featureId, size_t point
if (!m_altitudeAvailability[featureId])
{
LOG(LINFO, ("Feature featureId =", featureId, "does not contain any altitude information."));
return m_cache.insert(make_pair(featureId, m_dummy)).first->second;
return m_cache.insert(make_pair(featureId, TAltitudes(pointCount, m_header.m_minAltitude))).first->second;
}
uint64_t const r = m_altitudeAvailability.rank(featureId);
@ -81,17 +82,26 @@ TAltitudes const & AltitudeLoader::GetAltitudes(uint32_t featureId, size_t point
try
{
Altitudes a;
Altitudes altitudes;
ReaderSource<FilesContainerR::TReader> src(*m_reader);
src.Skip(altitudeInfoOffsetInSection);
a.Deserialize(m_header.m_minAltitude, pointCount, src);
altitudes.Deserialize(m_header.m_minAltitude, pointCount, src);
return m_cache.insert(make_pair(featureId, a.GetAltitudes())).first->second;
TAltitudes pntAlt = altitudes.GetAltitudes();
bool const isResultValid = none_of(pntAlt.begin(), pntAlt.end(),
[](TAltitude a) { return a == kInvalidAltitude; });
if (!isResultValid)
{
ASSERT(false, (pntAlt));
return m_cache.insert(make_pair(featureId, TAltitudes(pointCount, m_header.m_minAltitude))).first->second;
}
return m_cache.insert(make_pair(featureId, move(pntAlt))).first->second;
}
catch (Reader::OpenException const & e)
{
LOG(LERROR, ("Error while getting altitude data", e.Msg()));
return m_cache.insert(make_pair(featureId, m_dummy)).first->second;
return m_cache.insert(make_pair(featureId, TAltitudes(pointCount, m_header.m_minAltitude))).first->second;
}
}
} // namespace feature

View file

@ -16,10 +16,13 @@ class AltitudeLoader
public:
explicit AltitudeLoader(MwmValue const & mwmValue);
/// \returns altitude of feature with |featureId|. All items of the returned vertor are valid
/// or the returned vertor is empty.
TAltitudes const & GetAltitudes(uint32_t featureId, size_t pointCount);
bool HasAltitudes() const;
private:
bool HasAltitudes() const;
unique_ptr<CopiedMemoryRegion> m_altitudeAvailabilityRegion;
unique_ptr<CopiedMemoryRegion> m_featureTableRegion;
@ -28,7 +31,6 @@ private:
unique_ptr<FilesContainerR::TReader> m_reader;
map<uint32_t, TAltitudes> m_cache;
TAltitudes const m_dummy;
AltitudeHeader m_header;
};
} // namespace feature

View file

@ -15,6 +15,7 @@ using TAltitude = int16_t;
using TAltitudes = vector<feature::TAltitude>;
TAltitude constexpr kInvalidAltitude = numeric_limits<TAltitude>::min();
feature::TAltitude constexpr kDefautlAltitudeMeters = 0;
struct AltitudeHeader
{
@ -50,10 +51,11 @@ struct AltitudeHeader
size_t GetFeatureTableSize() const { return m_altitudesOffset - m_featureTableOffset; }
size_t GetAltitudeInfo() const { return m_endOffset - m_altitudesOffset; }
void Reset()
{
m_version = 0;
m_minAltitude = kInvalidAltitude;
m_minAltitude = kDefautlAltitudeMeters;
m_featureTableOffset = 0;
m_altitudesOffset = 0;
m_endOffset = 0;
@ -117,10 +119,8 @@ public:
private:
/// \note |m_altitudes| is a vector of feature point altitudes. There's two possibilities:
/// * |m_altitudes| is empty. It means there is no altitude information for this feature.
/// * size of |m_pointAlt| is equal to the number of this feature's points.
/// In this case the i'th element of |m_pointAlt| corresponds to the altitude of the
/// i'th point of the feature and is set to kInvalidAltitude when there is no information about
/// the point.
/// * 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;
};
} // namespace feature

View file

@ -275,25 +275,23 @@ void FeaturesRoadGraph::ExtractRoadInfo(FeatureID const & featureId, FeatureType
size_t const pointsCount = ft.GetPointsCount();
feature::TAltitudes altitudes;
if (value.HasAltitudeLoader())
if (value.m_altitudeLoader)
{
altitudes = value.m_altitudeLoader->GetAltitudes(featureId.m_index, ft.GetPointsCount());
if (altitudes.size() != pointsCount)
{
ASSERT(false, ("altitudes.size() is different from ft.GetPointsCount()"));
altitudes.clear();
}
}
else
{
ASSERT(false, ());
altitudes = feature::TAltitudes(ft.GetPointsCount(), feature::kDefautlAltitudeMeters);
}
ri.m_junctions.clear();
CHECK_EQUAL(altitudes.size(), pointsCount,
("altitudeLoader->GetAltitudes(", featureId.m_index, "...) returns wrong alititudes:",
altitudes));
ri.m_junctions.resize(pointsCount);
for (size_t i = 0; i < pointsCount; ++i)
{
if (altitudes.empty())
ri.m_junctions[i] = Junction(ft.GetPoint(i), feature::kInvalidAltitude);
else
ri.m_junctions[i] = Junction(ft.GetPoint(i), altitudes[i]);
}
ri.m_junctions[i] = Junction(ft.GetPoint(i), altitudes[i]);
}
IRoadGraph::RoadInfo const & FeaturesRoadGraph::GetCachedRoadInfo(FeatureID const & featureId) const

View file

@ -86,8 +86,6 @@ private:
bool IsAlive() const { return m_mwmHandle.IsAlive(); }
bool HasAltitudeLoader() const { return m_altitudeLoader && m_altitudeLoader->HasAltitudes(); }
MwmSet::MwmHandle m_mwmHandle;
unique_ptr<feature::AltitudeLoader> m_altitudeLoader;
};

View file

@ -19,13 +19,11 @@ double constexpr KMPH2MPS = 1000.0 / (60 * 60);
inline double TimeBetweenSec(Junction const & j1, Junction const & j2, double speedMPS)
{
ASSERT(speedMPS > 0.0, ());
double const distanceM = MercatorBounds::DistanceOnEarth(j1.GetPoint(), j2.GetPoint());
feature::TAltitude const j1Altitude = j1.GetAltitude();
feature::TAltitude const j2Altitude = j2.GetAltitude();
if (j1Altitude == feature::kInvalidAltitude || j2Altitude == feature::kInvalidAltitude)
return distanceM / speedMPS;
ASSERT_NOT_EQUAL(j1.GetAltitude(), feature::kInvalidAltitude, ());
ASSERT_NOT_EQUAL(j2.GetAltitude(), feature::kInvalidAltitude, ());
feature::TAltitude const altidudeDiffM = j2Altitude - j1Altitude;
double const distanceM = MercatorBounds::DistanceOnEarth(j1.GetPoint(), j2.GetPoint());
feature::TAltitude const altidudeDiffM = j2.GetAltitude() - j1.GetAltitude();
return sqrt(distanceM * distanceM + altidudeDiffM * altidudeDiffM) / speedMPS;
}