Diff of /trunk/src/map.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 155 by harbaum, Tue Mar 31 10:19:50 2009 UTC revision 156 by harbaum, Wed Apr 1 12:47:35 2009 UTC
# Line 2045  void map_delete_selected(appdata_t *appd Line 2045  void map_delete_selected(appdata_t *appd
2045    
2046  /* ----------------------- track related stuff ----------------------- */  /* ----------------------- track related stuff ----------------------- */
2047    
2048    static gboolean track_pos2lpos(bounds_t *bounds, pos_t *pos, lpos_t *lpos) {
2049      pos2lpos(bounds, pos, lpos);
2050    
2051      /* check if point is within bounds */
2052      return ((lpos->x >= bounds->min.x) && (lpos->x <= bounds->max.x) &&
2053              (lpos->y >= bounds->min.y) && (lpos->y <= bounds->max.y));
2054    }
2055    
2056  void map_track_draw_seg(map_t *map, track_seg_t *seg) {  void map_track_draw_seg(map_t *map, track_seg_t *seg) {
2057      bounds_t *bounds = map->appdata->osm->bounds;
2058    
2059    /* a track_seg needs at least 2 points to be drawn */    /* a track_seg needs at least 2 points to be drawn */
2060    guint pnum = track_seg_points(seg);    guint pnum = track_seg_points(seg);
2061    printf("seg of length %d\n", pnum);    printf("seg of length %d\n", pnum);
2062    
2063    if(pnum == 1) {    if(!pnum)
2064      g_assert(!seg->item);      return;
2065    
2066      seg->item = canvas_circle_new(map->canvas, CANVAS_GROUP_TRACK,    /* nothing should have been drawn by now ... */
2067            seg->track_point->lpos.x, seg->track_point->lpos.y,    g_assert(!seg->item_chain);
2068            map->style->track.width/2.0, 0, map->style->track.color, NO_COLOR);  
2069    }    track_item_chain_t **itemP = &seg->item_chain;
2070      track_point_t *track_point = seg->track_point;
2071      while(track_point) {
2072        lpos_t lpos;
2073    
2074        /* skip all points not on screen */
2075        track_point_t *last = NULL;
2076        while(track_point && !track_pos2lpos(bounds, &track_point->pos, &lpos)) {
2077          last = track_point;
2078          track_point = track_point->next;
2079        }
2080    
2081        int visible = 0;
2082    
2083        /* count nodes that _are_ on screen */
2084        track_point_t *tmp = track_point;
2085        while(tmp && track_pos2lpos(bounds, &tmp->pos, &lpos)) {
2086          tmp = tmp->next;
2087          visible++;
2088        }
2089    
2090        /* actually start drawing with the last position that was offscreen */
2091        /* so the track nicely enters the viewing area */
2092        if(last) {
2093          track_point = last;
2094          visible++;
2095        }
2096    
2097        /* also use last one that's offscreen to nicely leave the visible area */
2098        if(tmp && tmp->next)
2099          visible++;
2100    
   if(pnum > 1) {  
   
2101      /* allocate space for nodes */      /* allocate space for nodes */
2102      canvas_points_t *points = canvas_points_new(pnum);      canvas_points_t *points = canvas_points_new(visible);
2103    
2104      int point = 0;      printf("visible are %d\n", visible);
2105      track_point_t *track_point = seg->track_point;      int point;
2106      while(track_point) {      for(point=0;point<visible;point++) {
2107        points->coords[point++] = track_point->lpos.x;        track_pos2lpos(bounds, &track_point->pos, &lpos);
2108        points->coords[point++] = track_point->lpos.y;  
2109          points->coords[2*point+0] = lpos.x;
2110          points->coords[2*point+1] = lpos.y;
2111        track_point = track_point->next;        track_point = track_point->next;
2112      }      }
   
     /* there may be a circle (one point line) */  
     if(seg->item)  
       canvas_item_destroy(seg->item);  
2113    
2114      seg->item = canvas_polyline_new(map->canvas, CANVAS_GROUP_TRACK,      *itemP = g_new0(track_item_chain_t, 1);
2115            points, map->style->track.width, map->style->track.color);      (*itemP)->item = canvas_polyline_new(map->canvas, CANVAS_GROUP_TRACK,
2116                     points, map->style->track.width, map->style->track.color);
2117        itemP = &(*itemP)->next;
2118    
2119      canvas_points_free(points);      canvas_points_free(points);
2120    }    }
2121  }  }
2122    
2123    /* update the last visible fragment of this segment since a */
2124    /* gps position may have been added */
2125  void map_track_update_seg(map_t *map, track_seg_t *seg) {  void map_track_update_seg(map_t *map, track_seg_t *seg) {
2126      bounds_t *bounds = map->appdata->osm->bounds;
2127    
2128      printf("-- APPENDING TO TRACK --\n");
2129    
2130    /* a track_seg needs at least 2 points to be drawn */    /* a track_seg needs at least 2 points to be drawn */
2131    guint pnum = track_seg_points(seg);    guint pnum = track_seg_points(seg);
2132    printf("seg of length %d\n", pnum);    printf("seg of length %d\n", pnum);
2133    
2134    if(pnum > 1) {    /* there are two cases: either the second last point was on screen */
2135      /* or it wasn't. We'll have to start a new screen item if the latter */
2136      /* is the case */
2137    
2138      /* search last point */
2139      track_point_t *begin = seg->track_point, *second_last = seg->track_point;
2140      lpos_t lpos;
2141      while(second_last && second_last->next && second_last->next->next) {
2142        if(!track_pos2lpos(bounds, &second_last->pos, &lpos))
2143          begin = second_last;
2144    
2145        second_last = second_last->next;
2146      }
2147      track_point_t *last = second_last->next;
2148    
2149      /* since we are updating an existing track, it sure has at least two */
2150      /* points, second_last must be valid and its "next" (last) also */
2151      g_assert(second_last);
2152      g_assert(last);
2153    
2154      /* check if the last and second_last points are visible */
2155      gboolean last_is_visible =
2156        track_pos2lpos(bounds, &last->pos, &lpos);
2157      gboolean second_last_is_visible =
2158        track_pos2lpos(bounds, &second_last->pos, &lpos);
2159    
2160      /* if both are invisible, then nothing has changed on screen */
2161      if(!last_is_visible && !second_last_is_visible) {
2162        printf("second_last and last entry are invisible -> doing nothing\n");
2163        return;
2164      }
2165    
2166      /* search last element in item chain */
2167      track_item_chain_t *item = seg->item_chain;
2168      while(item && item->next)
2169        item = item->next;
2170    
2171      if(second_last_is_visible) {
2172        /* there must be something already on the screen and there must */
2173        /* be visible nodes in the chain */
2174        g_assert(item);
2175        g_assert(begin);
2176    
2177        printf("second_last is visible -> append\n");
2178    
2179        /* count points to be placed */
2180        int npoints = 0;
2181        track_point_t *tmp = begin;
2182        while(tmp) {
2183          tmp = tmp->next;
2184          npoints++;
2185        }
2186    
2187        printf("updating last segment to %d points\n", npoints);
2188    
2189        canvas_points_t *points = canvas_points_new(npoints);
2190    
2191        gint point = 0;
2192        while(begin) {
2193          track_pos2lpos(bounds, &begin->pos, &lpos);
2194          canvas_point_set_pos(points, point++, &lpos);
2195          begin = begin->next;
2196        }
2197    
2198      /* allocate space for nodes */      canvas_item_set_points(item->item, points);
2199      canvas_points_t *points = canvas_points_new(pnum);      canvas_points_free(points);
2200    
2201      int point = 0;    } else {
2202      track_point_t *track_point = seg->track_point;      printf("second last is invisible -> start new screen segment\n");
2203      while(track_point) {  
2204        canvas_point_set_pos(points, point++, &track_point->lpos);      /* the search for the "begin" ends with the second_last item */
2205        track_point = track_point->next;      /* verify the last one also */
2206        if(begin->next && !track_pos2lpos(bounds, &begin->next->pos, &lpos))
2207          begin = begin->next;
2208    
2209        item->next = g_new0(track_item_chain_t, 1);
2210        item = item->next;
2211    
2212        /* count points to be placed */
2213        int npoints = 0;
2214        track_point_t *tmp = begin;
2215        while(tmp) {
2216          tmp = tmp->next;
2217          npoints++;
2218        }
2219    
2220        printf("attaching new segment with %d points\n", npoints);
2221    
2222        canvas_points_t *points = canvas_points_new(npoints);
2223    
2224        gint point = 0;
2225        while(begin) {
2226          track_pos2lpos(bounds, &begin->pos, &lpos);
2227          canvas_point_set_pos(points, point++, &lpos);
2228          begin = begin->next;
2229      }      }
2230    
2231      g_assert(seg->item);      item->item = canvas_polyline_new(map->canvas, CANVAS_GROUP_TRACK,
2232      canvas_item_set_points(seg->item, points);                   points, map->style->track.width, map->style->track.color);
2233    
2234      canvas_points_free(points);      canvas_points_free(points);
2235    }    }
2236    
2237  }  }
2238    
2239  void map_track_draw(map_t *map, track_t *track) {  void map_track_draw(map_t *map, track_t *track) {
# Line 2125  void map_track_remove(appdata_t *appdata Line 2256  void map_track_remove(appdata_t *appdata
2256    /* remove all segments */    /* remove all segments */
2257    track_seg_t *seg = track->track_seg;    track_seg_t *seg = track->track_seg;
2258    while(seg) {    while(seg) {
2259      if(seg->item) {      track_item_chain_t *item = seg->item_chain;
2260        canvas_item_destroy(seg->item);      while(item) {
2261        seg->item = NULL;        track_item_chain_t *next = item->next;
2262          canvas_item_destroy(item->item);
2263          item = next;
2264      }      }
2265    
2266        seg->item_chain = NULL;
2267      seg = seg->next;      seg = seg->next;
2268    }    }
2269  }  }
2270    
2271  void map_track_pos(appdata_t *appdata, lpos_t *lpos) {  void map_track_pos(appdata_t *appdata, pos_t *pos) {
2272    if(appdata->track.gps_item) {    if(appdata->track.gps_item) {
2273      canvas_item_destroy(appdata->track.gps_item);      canvas_item_destroy(appdata->track.gps_item);
2274      appdata->track.gps_item = NULL;      appdata->track.gps_item = NULL;
2275    }    }
2276    
2277    if(lpos)    if(pos) {
2278        lpos_t lpos;
2279        pos2lpos(appdata->osm->bounds, pos, &lpos);
2280    
2281      appdata->track.gps_item =      appdata->track.gps_item =
2282        canvas_circle_new(appdata->map->canvas, CANVAS_GROUP_GPS,        canvas_circle_new(appdata->map->canvas, CANVAS_GROUP_GPS,
2283          lpos->x, lpos->y, appdata->map->style->track.width/2.0, 0,          lpos.x, lpos.y, appdata->map->style->track.width/2.0, 0,
2284                          appdata->map->style->track.gps_color, NO_COLOR);                          appdata->map->style->track.gps_color, NO_COLOR);
2285      }
2286  }  }
2287    
2288  /* ------------------- map background ------------------ */  /* ------------------- map background ------------------ */

Legend:
Removed from v.155  
changed lines
  Added in v.156