summaryrefslogtreecommitdiff
path: root/navit/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'navit/route.c')
-rw-r--r--navit/route.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/navit/route.c b/navit/route.c
index 858e51406..9d9ecf23d 100644
--- a/navit/route.c
+++ b/navit/route.c
@@ -939,6 +939,17 @@ struct map_selection *route_selection;
/**
* @brief Returns a single map selection
+ *
+ * The boundaries of the selection are determined as follows: First a rectangle spanning `c1` and `c2` is
+ * built (the two coordinates can be any two opposite corners of the rectangle). Then its maximum extension
+ * (height or width) is determined and multiplied with the percentage specified by `rel`. The resulting
+ * amount of padding is added to each edge. After that, the amount specified by `abs` is added to each edge.
+ *
+ * @param order Map order (deepest tile level) to select
+ * @param c1 First coordinate
+ * @param c2 Second coordinate
+ * @param rel Relative padding to add to the selection rectangle, in percent
+ * @param abs Absolute padding to add to the selection rectangle
*/
struct map_selection *
route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs) {
@@ -1047,7 +1058,8 @@ struct map_selection * route_get_selection(struct route * this_) {
int i = 0;
GList *tmp;
- c[i++] = this_->pos->c;
+ if (this_->pos)
+ c[i++] = this_->pos->c;
tmp = this_->destinations;
while (tmp) {
struct route_info *dst = tmp->data;
@@ -1062,7 +1074,7 @@ struct map_selection * route_get_selection(struct route * this_) {
*
* @param sel Start of the list to be destroyed
*/
-static void route_free_selection(struct map_selection *sel) {
+void route_free_selection(struct map_selection *sel) {
struct map_selection *next;
while (sel) {
next=sel->next;
@@ -1129,6 +1141,20 @@ void route_set_destinations(struct route *this, struct pcoord *dst, int count, i
profile(0,"end");
}
+/**
+ * @brief Retrieves destinations from the route
+ *
+ * Prior to calling this method, you may want to retrieve the number of destinations by calling
+ * {@link route_get_destination_count(struct route *)} and assigning a buffer of sufficient capacity.
+ *
+ * If the return value equals `count`, the buffer was either just large enough or too small to hold the
+ * entire list of destinations; there is no way to tell from the result which is the case.
+ *
+ * @param this The route instance
+ * @param pc Pointer to an array of projected coordinates which will receive the destination coordinates
+ * @param count Capacity of `pc`
+ * @return The number of destinations stored in `pc`, never greater than `count`
+ */
int route_get_destinations(struct route *this, struct pcoord *pc, int count) {
int ret=0;
GList *l=this->destinations;
@@ -1583,11 +1609,7 @@ int route_graph_segment_is_duplicate(struct route_graph_point *start, struct rou
* @param this The route graph to insert the segment into
* @param start The graph point which should be connected to the start of this segment
* @param end The graph point which should be connected to the end of this segment
- * @param len The length of this segment
- * @param item The item that is represented by this segment
- * @param flags Flags for this segment
- * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item
- * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known.
+ * @param data The segment data
*/
void route_graph_add_segment(struct route_graph *this, struct route_graph_point *start,
struct route_graph_point *end, struct route_graph_segment_data *data) {
@@ -2274,10 +2296,13 @@ static void route_graph_set_traffic_distortion(struct route_graph *this, struct
/**
* @brief Adds a traffic distortion item to the route graph
*
+ * If `update` is true, the end points of the traffic distortion will have their cost recalculated. Set this to true
+ * for a partial recalculation of an existing route, false when initially building the route graph.
+ *
* @param this The route graph to add to
* @param profile The vehicle profile to use for cost calculations
* @param item The item to add, must be of {@code type_traffic_distortion}
- * @param update Whether to update the point (true for LPA*, false for Dijkstra)
+ * @param update Whether to update the end points
*/
static void route_graph_add_traffic_distortion(struct route_graph *this, struct vehicleprofile *profile,
struct item *item, int update) {
@@ -2306,10 +2331,12 @@ static void route_graph_add_traffic_distortion(struct route_graph *this, struct
e_pnt=route_graph_add_point(this,&l);
s_pnt->flags |= RP_TRAFFIC_DISTORTION;
e_pnt->flags |= RP_TRAFFIC_DISTORTION;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_maxspeed, &maxspeed_attr)) {
data.flags |= AF_SPEED_LIMIT;
data.maxspeed=maxspeed_attr.u.num;
}
+ item_attr_rewind(item);
if (item_attr_get(item, attr_delay, &delay_attr))
data.len=delay_attr.u.num;
route_graph_add_segment(this, s_pnt, e_pnt, &data);
@@ -2523,37 +2550,45 @@ static void route_graph_add_street(struct route_graph *this, struct item *item,
if (item_coord_get(item, &l, 1)) {
if (!(default_flags = item_get_default_flags(item->type)))
default_flags = &default_flags_value;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_flags, &attr)) {
data.flags = attr.u.num;
segmented = (data.flags & AF_SEGMENTED);
} else
data.flags = *default_flags;
+ item_attr_rewind(item);
if ((data.flags & AF_SPEED_LIMIT) && (item_attr_get(item, attr_maxspeed, &attr)))
data.maxspeed = attr.u.num;
if (data.flags & AF_DANGEROUS_GOODS) {
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr))
data.dangerous_goods = attr.u.num;
else
data.flags &= ~AF_DANGEROUS_GOODS;
}
if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT) {
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_width, &attr))
data.size_weight.width=attr.u.num;
else
data.size_weight.width=-1;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_height, &attr))
data.size_weight.height=attr.u.num;
else
data.size_weight.height=-1;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_length, &attr))
data.size_weight.length=attr.u.num;
else
data.size_weight.length=-1;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_weight, &attr))
data.size_weight.weight=attr.u.num;
else
data.size_weight.weight=-1;
+ item_attr_rewind(item);
if (item_attr_get(item, attr_vehicle_axle_weight, &attr))
data.size_weight.axle_weight=attr.u.num;
else
@@ -2674,10 +2709,8 @@ static int route_graph_is_path_computed(struct route_graph *this_) {
* After recalculation, the route path is updated.
*
* The function uses a modified LPA* algorithm for recalculations. Most modifications were made for compatibility with
- * the algorithm used for the initial routing:
- * \li The `value` of a node represents the cost to reach the destination and thus decreases along the route
- * (eliminating the need for recalculations as the vehicle moves within the route graph)
- * \li The heuristic is always assumed to be zero (which would turn A* into Dijkstra, the basis of the main routing
+ * the old routing algorithm:
+ * \li The heuristic is always assumed to be zero (which would turn A* into Dijkstra, formerly the basis of the routing
* algorithm, and makes our keys one-dimensional)
* \li Currently, each pass evaluates all locally inconsistent points, leaving an empty heap at the end (though this
* may change in the future).
@@ -3157,17 +3190,12 @@ static void route_graph_build_idle(struct route_graph *rg, struct vehicleprofile
* add any routing information to the route graph - this has to be done via the route_graph_flood()
* function.
*
- * The function does not create a graph covering the whole map, but only covering the rectangle
- * between c1 and c2.
- *
* @param ms The mapset to build the route graph from
- * @param c The coordinates of the destination or next waypoint
- * @param c1 Corner 1 of the rectangle to use from the map
- * @param c2 Corner 2 of the rectangle to use from the map
+ * @param c An array of coordinates for the current position, waypoints (if any) and destination
+ * @param count Number of coordinates in `c`
* @param done_cb The callback which will be called when graph is complete
* @return The new route graph.
*/
-// FIXME documentation does not match argument list
static struct route_graph *route_graph_build(struct mapset *ms, struct coord *c, int count, struct callback *done_cb,
int async,
struct vehicleprofile *profile) {