forked from organicmaps/organicmaps
Setting valid altitude for all Junctions.
This commit is contained in:
parent
149365fe1b
commit
6840c3c18c
7 changed files with 42 additions and 34 deletions
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue