summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/projection.h6
-rw-r--r--navit/route.c165
-rw-r--r--navit/vehicle/gpsd/vehicle_gpsd.c6
3 files changed, 147 insertions, 30 deletions
diff --git a/navit/projection.h b/navit/projection.h
index 2438a235f..d67952b1f 100644
--- a/navit/projection.h
+++ b/navit/projection.h
@@ -21,7 +21,11 @@
#define NAVIT_PROJECTION_H
enum projection {
- projection_none, projection_mg, projection_garmin, projection_screen, projection_utm
+ projection_none, /*!< No projection or unknown projection */
+ projection_mg, /*!< Mercator projection */
+ projection_garmin, /*!< Garmin projection */
+ projection_screen, /*!< Screen projection */
+ projection_utm /*!< UTM projection */
};
enum map_datum {
diff --git a/navit/route.c b/navit/route.c
index 271b5fa3e..d8d29462e 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -171,11 +171,18 @@ struct route_graph_segment {
/**
* @brief A traffic distortion
*
- * This is distortion in the traffic where you can't drive as fast as usual or have to wait for some time
+ * Traffic distortions represent delays or closures on the route, which can occur for a variety of
+ * reasons such as roadworks, accidents or heavy traffic. They are also used internally by Navit to
+ * avoid using a particular segment.
+ *
+ * A traffic distortion can limit the speed on a segment, or introduce a delay. If both are given,
+ * at the same time, they are cumulative.
*/
struct route_traffic_distortion {
- int maxspeed; /**< Maximum speed possible in km/h */
- int delay; /**< Delay in tenths of seconds */
+ int maxspeed; /**< Maximum speed possible in km/h. Use {@code INT_MAX} to
+ leave the speed unchanged, or 0 to mark the segment as
+ impassable. */
+ int delay; /**< Delay in tenths of seconds (0 for no delay) */
};
/**
@@ -749,6 +756,16 @@ route_destination_reached(struct route *this)
return 2;
}
+/**
+ * @brief Returns the position from which to route to the current destination of the route.
+ *
+ * This function examines the destination list of the route. If present, it returns the destination
+ * which precedes the one indicated by the {@code current_dst} member of the route. Failing that,
+ * the current position of the route is returned.
+ *
+ * @param this The route object
+ * @return The previous destination or current position, see description
+ */
static struct route_info *
route_previous_destination(struct route *this)
{
@@ -761,12 +778,25 @@ route_previous_destination(struct route *this)
return l->data;
}
+/**
+ * @brief Updates or recreates the route graph.
+ *
+ * This function is called after the route graph has been changed or rebuilt and flooding has
+ * completed. It then updates the route path to reflect these changes.
+ *
+ * If multiple destinations are set, this function will reset and re-flood the route graph for each
+ * destination, thus recursively calling itself for each destination.
+ *
+ * @param this The route object
+ * @param new_graph FIXME Whether the route graph has been rebuilt from scratch
+ */
+/* FIXME Should we rename this function to route_graph_flood_done, in order to avoid confusion? */
static void
route_path_update_done(struct route *this, int new_graph)
{
struct route_path *oldpath=this->path2;
struct attr route_status;
- struct route_info *prev_dst;
+ struct route_info *prev_dst; /* previous destination or current position */
route_status.type=attr_route_status;
if (this->path2 && (this->path2->in_use>1)) {
this->path2->update_required=1+new_graph;
@@ -1336,11 +1366,12 @@ route_remove_waypoint(struct route *this)
}
/**
- * @brief Gets the route_graph_point with the specified coordinates
+ * @brief Gets the next route_graph_point with the specified coordinates
*
* @param this The route in which to search
* @param c Coordinates to search for
- * @param last The last route graph point returned to iterate over multiple points with the same coordinates
+ * @param last The last route graph point returned to iterate over multiple points with the same coordinates,
+ * or {@code NULL} to return the first point
* @return The point at the specified coordinates or NULL if not found
*/
static struct route_graph_point *
@@ -1361,6 +1392,13 @@ route_graph_get_point_next(struct route_graph *this, struct coord *c, struct rou
return NULL;
}
+/**
+ * @brief Gets the first route_graph_point with the specified coordinates
+ *
+ * @param this The route in which to search
+ * @param c Coordinates to search for
+ * @return The point at the specified coordinates or NULL if not found
+ */
static struct route_graph_point *
route_graph_get_point(struct route_graph *this, struct coord *c)
{
@@ -1421,7 +1459,10 @@ route_graph_point_new(struct route_graph *this, struct coord *f)
* This will insert a point into the route graph at the coordinates passed in f.
* Note that the point is not yet linked to any segments.
*
- * @param this The route to insert the point into
+ * If the route graph already contains a point at the specified coordinates, the existing point
+ * will be returned.
+ *
+ * @param this The route graph to insert the point into
* @param f The coordinates at which the point should be inserted
* @return The point inserted or NULL on failure
*/
@@ -1460,6 +1501,14 @@ route_graph_free_points(struct route_graph *this)
/**
* @brief Resets all nodes
*
+ * This iterates through all the points in the route graph, resetting them to their initial state.
+ * The {@code value} member of each point (cost to reach the destination) is reset to
+ * {@code INT_MAX}, the {@code seg} member (cheapest way to destination) is reset to {@code NULL}
+ * and the {@code el} member (pointer to element in Fibonacci heap) is also reset to {@code NULL}.
+ *
+ * References to elements of the route graph which were obtained prior to calling this function
+ * remain valid after it returns.
+ *
* @param this The route graph to reset
*/
static void
@@ -1913,14 +1962,28 @@ route_graph_destroy(struct route_graph *this)
}
/**
- * @brief Returns the estimated speed on a segment
+ * @brief Returns the estimated speed on a segment, or 0 for an impassable segment
*
- * This function returns the estimated speed to be driven on a segment, 0=not passable
+ * This function returns the estimated speed to be driven on a segment, calculated as follows:
+ * <ul>
+ * <li>Initially the route weight of the vehicle profile for the given item type is used. If the
+ * item type does not have a route weight in the vehicle profile given, it is considered impassable
+ * and 0 is returned.</li>
+ * <li>If the {@code maxspeed} attribute of the segment's item is set, either it or the previous
+ * speed estimate for the segment is used, as governed by the vehicle profile's
+ * {@code maxspeed_handling} attribute.</li>
+ * <li>If a traffic distortion is present, its {@code maxspeed} is taken into account in a similar
+ * manner. Unlike the regular {@code maxspeed}, a {@code maxspeed} resulting from a traffic
+ * distortion is always considered if it limits the speed, regardless of {@code maxspeed_handling}.
+ * </li>
+ * <li>Access restrictions for dangerous goods, size or weight are evaluated, and 0 is returned if
+ * the given vehicle profile violates one of them.</li>
+ * </ul>
*
* @param profile The routing preferences
* @param over The segment which is passed
- * @param dist A traffic distortion if applicable
- * @return The estimated speed
+ * @param dist A traffic distortion if applicable, or {@code NULL}
+ * @return The estimated speed in km/h, or 0 if the segment is impassable
*/
static int
route_seg_speed(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist)
@@ -1964,15 +2027,16 @@ route_seg_speed(struct vehicleprofile *profile, struct route_segment_data *over,
}
/**
- * @brief Returns the time needed to drive len on item
+ * @brief Returns the time needed to travel along a segment, or {@code INT_MAX} if the segment is impassable.
*
- * This function returns the time needed to drive len meters on
- * the item passed in item in tenth of seconds.
+ * This function returns the time needed to travel along the entire length of {@code over} in
+ * tenths of seconds. Restrictions for dangerous goods, weight or size are taken into account.
+ * Traffic distortions are also taken into account if a valid {@code dist} argument is given.
*
- * @param profile The routing preferences
+ * @param profile The vehicle profile (routing preferences)
* @param over The segment which is passed
- * @param dist A traffic distortion if applicable
- * @return The time needed to drive len on item in thenth of senconds
+ * @param dist A traffic distortion if applicable, or {@code NULL}
+ * @return The time needed in tenths of seconds
*/
static int
@@ -1984,6 +2048,14 @@ route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over,
return over->len*36/speed+(dist ? dist->delay : 0);
}
+/**
+ * @brief Returns the traffic distortion for a segment.
+ *
+ * @param seg The segment for which the traffic distortion is to be returned
+ * @param ret Points to a {@code struct route_traffic_distortion}, whose members will be filled
+ *
+ * @return true if a traffic distortion was found, 0 if not
+ */
static int
route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traffic_distortion *ret)
{
@@ -2020,13 +2092,22 @@ route_through_traffic_allowed(struct vehicleprofile *profile, struct route_graph
}
/**
- * @brief Returns the "costs" of driving from point from over segment over in direction dir
+ * @brief Returns the "cost" of driving from point {@code from} along segment {@code over} in direction {@code dir}
+ *
+ * Cost is relative to time, indicated in tenths of seconds.
+ *
+ * This function considers traffic distortions as well as penalties. If the segment is impassable
+ * due to traffic distortions or restrictions, {@code INT_MAX} is returned in order to prevent use
+ * of this segment for routing.
*
* @param profile The routing preferences
* @param from The point where we are starting
* @param over The segment we are using
- * @param dir The direction of segment which we are driving
- * @return The "costs" needed to drive len on item
+ * @param dir The direction of segment which we are driving. Positive values indicate we are
+ * traveling in the direction of the segment, negative values indicate we are traveling against
+ * that direction. Values of +2 or -2 cause the function to ignore traffic distortions.
+ *
+ * @return The "cost" needed to travel along the segment
*/
static int
@@ -2066,6 +2147,15 @@ route_graph_segment_match(struct route_graph_segment *s1, struct route_graph_seg
s1->end->c.x == s2->end->c.x && s1->end->c.y == s2->end->c.y);
}
+/**
+ * @brief Sets or clears a traffic distortion for a segment.
+ *
+ * This sets or clears a delay. It cannot be used to set speed.
+ *
+ * @param this The route graph
+ * @param seg The segment to which the traffic distortion applies
+ * @param delay Delay in tenths of a second
+ */
static void
route_graph_set_traffic_distortion(struct route_graph *this, struct route_graph_segment *seg, int delay)
{
@@ -2193,8 +2283,8 @@ route_process_street_graph(struct route_graph *this, struct item *item, struct v
#endif
int segmented = 0;
struct roadprofile *roadp;
- struct route_graph_point *s_pnt,*e_pnt;
- struct coord c,l;
+ struct route_graph_point *s_pnt,*e_pnt; /* Start and end point */
+ struct coord c,l; /* Current and previous point */
struct attr attr;
struct route_graph_segment_data data;
data.flags=0;
@@ -2204,7 +2294,7 @@ route_process_street_graph(struct route_graph *this, struct item *item, struct v
roadp = vehicleprofile_get_roadprofile(profile, item->type);
if (!roadp) {
- // Don't include any roads that don't have a road profile in our vehicle profile
+ /* Don't include any roads that don't have a road profile in our vehicle profile */
return;
}
@@ -2295,6 +2385,16 @@ route_process_street_graph(struct route_graph *this, struct item *item, struct v
}
}
+/**
+ * @brief Gets the next route_graph_segment belonging to the specified street
+ *
+ * @param graph The route graph in which to search
+ * @param sd The street to search for
+ * @param last The last route graph segment returned to iterate over multiple segments of the same
+ * item. If {@code NULL}, the first matching segment will be returned.
+ *
+ * @return The route graph segment, or {@code NULL} if none was found.
+ */
static struct route_graph_segment *
route_graph_get_segment(struct route_graph *graph, struct street_data *sd, struct route_graph_segment *last)
{
@@ -2327,6 +2427,15 @@ route_graph_get_segment(struct route_graph *graph, struct street_data *sd, struc
*
* This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look
* at this algorithm.
+ *
+ * References to elements of the route graph which were obtained prior to calling this function
+ * remain valid after it returns.
+ *
+ * @param this_ The route graph to flood
+ * @param dst The destination of the route
+ * @param profile The vehicle profile to use for routing. This determines which ways are passable
+ * and how their costs are calculated.
+ * @param cb The callback function to call when flooding is complete
*/
static void
route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb)
@@ -2535,11 +2644,11 @@ route_get_coord_dist(struct route *this_, int dist)
static struct route_path *
route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile)
{
- struct route_graph_segment *s=NULL,*s1=NULL,*s2=NULL;
- struct route_graph_point *start;
- struct route_info *posinfo, *dstinfo;
- int segs=0,dir;
- int val1=INT_MAX,val2=INT_MAX;
+ struct route_graph_segment *s=NULL,*s1=NULL,*s2=NULL; /* candidate segments for cheapest path */
+ struct route_graph_point *start; /* point at which the next segment starts, i.e. up to which the path is complete */
+ struct route_info *posinfo, *dstinfo; /* same as pos and dst, but NULL if not part of current segment */
+ int segs=0,dir; /* number of segments added to graph, direction of first segment */
+ int val1=INT_MAX,val2=INT_MAX; /* total cost for s1 and s2, respectively */
int val,val1_new,val2_new;
struct route_path *ret;
diff --git a/navit/vehicle/gpsd/vehicle_gpsd.c b/navit/vehicle/gpsd/vehicle_gpsd.c
index f7f5616f9..73d9e648d 100644
--- a/navit/vehicle/gpsd/vehicle_gpsd.c
+++ b/navit/vehicle/gpsd/vehicle_gpsd.c
@@ -318,7 +318,11 @@ vehicle_gpsd_io(struct vehicle_priv *priv)
if (priv->gps) {
vehicle_last = priv;
#if GPSD_API_MAJOR_VERSION >= 5
- if(gps_read(priv->gps)==-1) {
+ int read_result;
+ /* Read until EOF, in case we are lagging behind.
+ * No point in processing old GPS reports. */
+ while((read_result=gps_read(priv->gps))>0);
+ if(read_result==-1) {
dbg(lvl_error,"gps_poll failed\n");
vehicle_gpsd_close(priv);
vehicle_gpsd_open(priv);