Logo Search packages:      
Sourcecode: navit version File versions

static int route_path_add_item_from_graph ( struct route_path this,
struct route_path oldpath,
struct route_graph_segment rgs,
int  dir,
struct route_info pos,
struct route_info dst 
) [static]

Inserts a new item into the path.

This function does almost the same as "route_path_add_item()", but identifies the item to add by a segment from the route graph. Another difference is that it "copies" the segment from the route graph, i.e. if the item is segmented, only the segment passed in rgs will be added to the route path, not all segments of the item.

The function can be sped up by passing an old path already containing this segment in oldpath - the segment will then be extracted from this old path. Please note that in this case the direction parameter has no effect.

Parameters:
this The path to add the item to
oldpath Old path containing the segment to be added. Speeds up the function, but can be NULL.
rgs Segment of the route graph that should be "copied" to the route path
dir Order in which to add the coordinates. See route_path_add_item()
pos Information about start point if this is the first segment
dst Information about end point if this is the last segment

Definition at line 1277 of file route.c.

References route_path_segment::c, route_graph_point::c, street_data::c, street_data::count, route_path_segment::data, route_graph_segment::data, route_path_segment::direction, route_graph_segment::end, route_segment_data::flags, get_item_seg_coords(), route_segment_data::item, route_segment_data::len, route_info::lenneg, route_info::lenpos, route_info::lp, route_path_segment::ncoords, route_path_segment::next, route_path::path_hash, route_info::pos, route_check_roundabout(), route_extract_segment_from_path(), route_path_add_segment(), route_segment_data_size(), route_graph_segment::start, route_info::street, coord::x, and coord::y.

Referenced by route_path_new().

{
      struct route_path_segment *segment;
      int i, ccnt, extra=0, ret=0;
      struct coord *c,*cd,ca[2048];
      int offset=1;
      int seg_size,seg_dat_size;
      int len=rgs->data.len;
      if (rgs->data.flags & AF_SEGMENTED) 
            offset=RSD_OFFSET(&rgs->data);

      dbg(1,"enter (0x%x,0x%x) dir=%d pos=%p dst=%p\n", rgs->data.item.id_hi, rgs->data.item.id_lo, dir, pos, dst);
      if (oldpath) {
            segment=item_hash_lookup(oldpath->path_hash, &rgs->data.item);
            if (segment && segment->direction == dir) {
                  segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset);
                  if (segment) {
                        ret=1;
                        if (!pos)
                              goto linkold;
                  }
            }
      }

      if (pos) {
            if (dst) {
                  extra=2;
                  if (dst->lenneg >= pos->lenneg) {
                        dir=1;
                        ccnt=dst->pos-pos->pos;
                        c=pos->street->c+pos->pos+1;
                        len=dst->lenneg-pos->lenneg;
                  } else {
                        dir=-1;
                        ccnt=pos->pos-dst->pos;
                        c=pos->street->c+dst->pos+1;
                        len=pos->lenneg-dst->lenneg;
                  }
            } else {
                  extra=1;
                  dbg(1,"pos dir=%d\n", dir);
                  dbg(1,"pos pos=%d\n", pos->pos);
                  dbg(1,"pos count=%d\n", pos->street->count);
                  if (dir > 0) {
                        c=pos->street->c+pos->pos+1;
                        ccnt=pos->street->count-pos->pos-1;
                        len=pos->lenpos;
                  } else {
                        c=pos->street->c;
                        ccnt=pos->pos+1;
                        len=pos->lenneg;
                  }
            }
      } else      if (dst) {
            extra=1;
            dbg(1,"dst dir=%d\n", dir);
            dbg(1,"dst pos=%d\n", dst->pos);
            if (dir > 0) {
                  c=dst->street->c;
                  ccnt=dst->pos+1;
                  len=dst->lenpos;
            } else {
                  c=dst->street->c+dst->pos+1;
                  ccnt=dst->street->count-dst->pos-1;
                  len=dst->lenneg;
            }
      } else {
            ccnt=get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, &rgs->end->c);
            c=ca;
      }
      seg_size=sizeof(*segment) + sizeof(struct coord) * (ccnt + extra);
      seg_dat_size=route_segment_data_size(rgs->data.flags);
      segment=g_malloc0(seg_size + seg_dat_size);
      segment->data=(struct route_segment_data *)((char *)segment+seg_size);
      segment->direction=dir;
      cd=segment->c;
      if (pos && (c[0].x != pos->lp.x || c[0].y != pos->lp.y))
            *cd++=pos->lp;
      if (dir < 0)
            c+=ccnt-1;
      for (i = 0 ; i < ccnt ; i++) {
            *cd++=*c;
            c+=dir;     
      }
      segment->ncoords+=ccnt;
      if (dst && (cd[-1].x != dst->lp.x || cd[-1].y != dst->lp.y)) 
            *cd++=dst->lp;
      segment->ncoords=cd-segment->c;
      if (segment->ncoords <= 1) {
            g_free(segment);
            return 1;
      }

      /* We check if the route graph segment is part of a roundabout here, because this
       * only matters for route graph segments which form parts of the route path */
      if (!(rgs->data.flags & AF_ROUNDABOUT)) { // We identified this roundabout earlier
            route_check_roundabout(rgs, 13, (dir < 1), NULL);
      }

      memcpy(segment->data, &rgs->data, seg_dat_size);
linkold:
      segment->data->len=len;
      segment->next=NULL;
      item_hash_insert(this->path_hash,  &rgs->data.item, segment);

      route_path_add_segment(this, segment);

      return ret;
}


Generated by  Doxygen 1.6.0   Back to index