Beispiel #1
0
ftypes::HighwayClass GetOutgoingHighwayClass(NodeID outgoingNode,
                                             RoutingMapping const & routingMapping,
                                             Index const & index)
{
  OsrmMappingTypes::FtSeg const seg =
      GetSegment(outgoingNode, routingMapping, GetFirstSegmentPointIndex);
  if (!seg.IsValid())
    return ftypes::HighwayClass::Error;

  Index::FeaturesLoaderGuard loader(index, routingMapping.GetMwmId());
  FeatureType ft;
  loader.GetFeatureByIndex(seg.m_fid, ft);
  return ftypes::GetHighwayClass(ft);
}
Beispiel #2
0
void FindGraphNodeOffsets(uint32_t const nodeId, m2::PointD const & point,
                          Index const * pIndex, TRoutingMappingPtr & mapping,
                          FeatureGraphNode & graphNode)
{
    graphNode.segmentPoint = point;

    helpers::Point2PhantomNode::Candidate best;

    auto range = mapping->m_segMapping.GetSegmentsRange(nodeId);
    for (size_t i = range.first; i < range.second; ++i)
    {
        OsrmMappingTypes::FtSeg s;
        mapping->m_segMapping.GetSegmentByIndex(i, s);
        if (!s.IsValid())
            continue;

        FeatureType ft;
        Index::FeaturesLoaderGuard loader(*pIndex, mapping->GetMwmId());
        loader.GetFeatureByIndex(s.m_fid, ft);

        helpers::Point2PhantomNode::Candidate mappedSeg;
        helpers::Point2PhantomNode::FindNearestSegment(ft, point, mappedSeg);

        OsrmMappingTypes::FtSeg seg;
        seg.m_fid = mappedSeg.m_fid;
        seg.m_pointStart = mappedSeg.m_segIdx;
        seg.m_pointEnd = mappedSeg.m_segIdx + 1;
        if (!s.IsIntersect(seg))
            continue;

        if (mappedSeg.m_dist < best.m_dist)
            best = mappedSeg;
    }

    CHECK_NOT_EQUAL(best.m_fid, kInvalidFid, ());

    graphNode.segment.m_fid = best.m_fid;
    graphNode.segment.m_pointStart = best.m_segIdx;
    graphNode.segment.m_pointEnd = best.m_segIdx + 1;
}
Beispiel #3
0
void Point2PhantomNode::CalculateWeight(OsrmMappingTypes::FtSeg const & seg,
                                        m2::PointD const & segPt, NodeID const & nodeId,
                                        bool calcFromRight, int & weight, int & offset) const
{
  // nodeId can be INVALID_NODE_ID when reverse node is absent. This node has no weight.
  if (nodeId == INVALID_NODE_ID)
  {
    offset = 0;
    weight = 0;
    return;
  }

  Index::FeaturesLoaderGuard loader(m_index, m_routingMapping.GetMwmId());

  // Offset is measured in milliseconds. We don't know about speed restrictions on the road.
  // So we find it by a whole edge weight.
  // Distance from the node border to the projection point is in meters.
  double distanceM = 0.;
  // Whole node distance in meters.
  double fullDistanceM = 0.;
  // Minimal OSRM edge weight in milliseconds.
  EdgeWeight minWeight = 0;

  auto const range = m_routingMapping.m_segMapping.GetSegmentsRange(nodeId);
  OsrmMappingTypes::FtSeg segment;

  size_t const startIndex = calcFromRight ? range.second - 1 : range.first;
  size_t const endIndex = calcFromRight ? range.first - 1 : range.second;
  int const indexIncrement = calcFromRight ? -1 : 1;

  bool foundSeg = false;
  m2::PointD lastPoint;
  for (size_t segmentIndex = startIndex; segmentIndex != endIndex; segmentIndex += indexIncrement)
  {
    m_routingMapping.m_segMapping.GetSegmentByIndex(segmentIndex, segment);
    if (!segment.IsValid())
      continue;

    FeatureType ft;
    loader.GetFeatureByIndex(segment.m_fid, ft);
    ft.ParseGeometry(FeatureType::BEST_GEOMETRY);

    // Find whole edge weight by node outgoing point.
    if (segmentIndex == range.second - 1)
      minWeight = GetMinNodeWeight(nodeId, ft.GetPoint(segment.m_pointEnd));

    // Calculate distances.
    double distance = CalculateDistance(ft, segment.m_pointStart, segment.m_pointEnd);
    fullDistanceM += distance;
    if (foundSeg)
      continue;

    if (segment.m_fid == seg.m_fid && OsrmMappingTypes::IsInside(segment, seg))
    {
      auto const splittedSegment = OsrmMappingTypes::SplitSegment(segment, seg, !calcFromRight);
      distanceM += CalculateDistance(ft, splittedSegment.m_pointStart, splittedSegment.m_pointEnd);
      // node.m_seg always forward ordered (m_pointStart < m_pointEnd)
      distanceM -= MercatorBounds::DistanceOnEarth(
          ft.GetPoint(calcFromRight ? seg.m_pointStart : seg.m_pointEnd), segPt);

      foundSeg = true;
    }
    else
    {
      distanceM += distance;
    }
  }

  ASSERT_GREATER(fullDistanceM, 0, ("No valid segments on the edge."));
  double const ratio = (fullDistanceM == 0) ? 0 : distanceM / fullDistanceM;
  ASSERT_LESS_OR_EQUAL(ratio, 1., ());

  // OSRM calculates edge weight form start to user point how offset + weight.
  // But it doesn't place info about start and end edge result weight into result structure.
  // So we store whole edge weight into offset and calculates this weights at a postprocessing step.
  offset = minWeight;
  weight = max(static_cast<int>(minWeight * ratio), 0) - minWeight;
}