/*! * \brief GetPointForTurn returns ingoingPoint or outgoingPoint for turns. * These points belongs to the route but they often are not neighbor of junctionPoint. * To calculate the resulting point the function implements the following steps: * - going from junctionPoint along feature ft according to the direction which is set in GetPointIndex(). * - until one of following conditions is fulfilled: * - the end of ft is reached; (returns the last feature point) * - more than kMaxPointsCount points are passed; (returns the kMaxPointsCount-th point) * - the length of passed parts of segment exceeds kMinDistMeters; (returns the next point after the event) * \param segment is a ingoing or outgoing feature segment. * \param ft is a ingoing or outgoing feature. * \param junctionPoint is a junction point. * \param maxPointsCount returned poit could't be more than maxPointsCount poins away from junctionPoint * \param minDistMeters returned point should be minDistMeters away from junctionPoint if ft is long and consists of short segments * \param GetPointIndex is a function for getting points by index. * It defines a direction of following along a feature. So it differs for ingoing and outgoing cases. * It has following parameters: * - start is an index of the start point of a feature segment. For example, FtSeg::m_pointStart. * - end is an index of the end point of a feature segment. For example, FtSeg::m_pointEnd. * - shift is a number of points which shall be added to end or start index. After that * the sum reflects an index of a feature segment point which will be used for a turn calculation. * The sum shall belongs to a range [min(start, end), max(start, end)]. * shift belongs to a range [0, abs(end - start)]. * \return an ingoing or outgoing point for a turn calculation. */ m2::PointD GetPointForTurn(OsrmMappingTypes::FtSeg const & segment, FeatureType const & ft, m2::PointD const & junctionPoint, size_t const maxPointsCount, double const minDistMeters, size_t (*GetPointIndex)(const size_t start, const size_t end, const size_t shift)) { double curDistanceMeters = 0.; m2::PointD point = junctionPoint; m2::PointD nextPoint; size_t const numSegPoints = abs(segment.m_pointEnd - segment.m_pointStart); ASSERT_GREATER(numSegPoints, 0, ()); ASSERT_LESS(numSegPoints, ft.GetPointsCount(), ()); size_t const usedFtPntNum = min(maxPointsCount, numSegPoints); for (size_t i = 1; i <= usedFtPntNum; ++i) { nextPoint = ft.GetPoint(GetPointIndex(segment.m_pointStart, segment.m_pointEnd, i)); curDistanceMeters += MercatorBounds::DistanceOnEarth(point, nextPoint); if (curDistanceMeters > minDistMeters) return nextPoint; point = nextPoint; } return nextPoint; }
/*! * \brief GetPointForTurn returns ingoingPoint or outgoingPoint for turns. * These points belongs to the route but they often are not neighbor of junctionPoint. * To calculate the resulting point the function implements the following steps: * - going from junctionPoint along feature ft according to the direction which is set in GetPointIndex(). * - until one of following conditions is fulfilled: * - the end of ft is reached; (returns the last feature point) * - more than kMaxPointsCount points are passed; (returns the kMaxPointsCount-th point) * - the length of passed parts of segment exceeds kMinDistMeters; (returns the next point after the event) * \param segment is a ingoing or outgoing feature segment. * \param ft is a ingoing or outgoing feature. * \param junctionPoint is a junction point. * \param GetPointIndex is a function for getting points by index. * It defines a direction of following along a feature. So it differs for ingoing and outgoing cases. * It has following parameters: * - start is an index of the start point of a feature segment. For example, FtSeg::m_pointStart. * - end is an index of the end point of a feature segment. For example, FtSeg::m_pointEnd. * - shift is a number of points which shall be added to end or start index. After that * the sum reflects an index of a point of a feature segment which will be used for turn calculation. * The sum shall belongs to a range [min(start, end), max(start, end)]. * shift belongs to a range [0, abs(end - start)]. * \return an ingoing or outgoing point for turn calculation. */ m2::PointD GetPointForTurn(OsrmMappingTypes::FtSeg const & segment, FeatureType const & ft, m2::PointD const & junctionPoint, size_t (*GetPointIndex)(const size_t start, const size_t end, const size_t shift)) { // An ingoing and outgoing point could be farther then kMaxPointsCount points from the junctionPoint size_t const kMaxPointsCount = 7; // If ft feature is long enough and consist of short segments // the point for turn generation is taken as the next point the route after kMinDistMeters. double const kMinDistMeters = 300.; double curDistanceMeters = 0.; m2::PointD point = junctionPoint; m2::PointD nextPoint; size_t const numSegPoints = abs(segment.m_pointEnd - segment.m_pointStart); ASSERT_GREATER(numSegPoints, 0, ()); ASSERT_LESS(numSegPoints, ft.GetPointsCount(), ()); size_t const usedFtPntNum = min(kMaxPointsCount, numSegPoints); for (size_t i = 1; i <= usedFtPntNum; ++i) { nextPoint = ft.GetPoint(GetPointIndex(segment.m_pointStart, segment.m_pointEnd, i)); curDistanceMeters += MercatorBounds::DistanceOnEarth(point, nextPoint); if (curDistanceMeters > kMinDistMeters) return nextPoint; point = nextPoint; } return nextPoint; }