summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormvglasow <michael@vonglasow.com>2019-01-11 20:04:39 +0100
committerGitHub <noreply@github.com>2019-01-11 20:04:39 +0100
commitfabeea80a7f137ddb6e96e48bc543717aa7d5aec (patch)
tree08543e5adf9361d250857261697501d4d386ec9e
parent09345bbf2f236aeb33a1a9406b81ec035a01cd8b (diff)
parent5cf646c8f521db88bb68f5f7ca20c35c3474606b (diff)
downloadnavit-fabeea80a7f137ddb6e96e48bc543717aa7d5aec.tar.gz
Merge branch 'trunk' into coverity_bypass
-rw-r--r--.circleci/config.yml42
-rw-r--r--README.md4
-rw-r--r--navit/graphics.c58
-rw-r--r--navit/maptool/boundaries.c3
-rw-r--r--navit/maptool/osm.c3
-rw-r--r--navit/traffic.c211
-rw-r--r--navit/transform.c9
-rwxr-xr-xscripts/build_android_arm.sh61
-rw-r--r--scripts/build_linux.sh7
9 files changed, 289 insertions, 109 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1cbfd6809..c9b2bd214 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -82,46 +82,12 @@ jobs:
command: |
sudo apt-get update
sudo apt-get install -y cmake gettext libsaxonb-java librsvg2-bin pkg-config libprotobuf-c-dev protobuf-c-compiler
- cmake ./ -Dsvg2png_scaling:STRING=-1,24,32,48,64,96,128,192,256 -Dsvg2png_scaling_nav:STRING=-1,24,32,48,64,96,128,192,256 -Dsvg2png_scaling_flag:STRING=-1,24,32,64,96 -DUSE_PLUGINS=n -DBUILD_MAPTOOL=n -DXSL_PROCESSING=y -DXSLTS=android -DANDROID=y -DSAMPLE_MAP=n
- run:
- name: Process icons
- command: |
- cd navit/icons
- make
- mkdir ../android/res/drawable-nodpi
- rename 'y/A-Z/a-z/' *.png
- cp *.png ../android/res/drawable-nodpi
- cd ../../
- - run:
- name: Process translations
- command: |
- cd po
- make
- mkdir ../navit/android/res/raw
- rename 'y/A-Z/a-z/' *.mo
- cp *.mo ../navit/android/res/raw
- cd ../
- - run:
- name: Process xml's
- command: |
- make navit_config_xml
- cd navit
- mkdir -p ./android/assets
- cp -R config ./android/assets/
- cd ../
- - run:
- name: Chmod permissions
- command: chmod +x ./gradlew
- - run:
- name: Download Dependencies
- command: ./gradlew -v
-# command: ./gradlew androidDependencies
- - run:
- name: Install ndk
- command: sdkmanager ndk-bundle
+ name: Install Android SDK components
+ command: sdkmanager ndk-bundle "cmake;3.6.4111459"
- run:
- name: Build
- command: ./gradlew assembleDebug
+ name: Build for Android (ARM)
+ command: bash scripts/build_android_arm.sh
- run:
name: Run Lint Test
command: |
diff --git a/README.md b/README.md
index f71a5a351..4e7f8d577 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,7 @@ Navit reads the current vehicle position:
Routing algorithm
=================
-Navit uses LPA* (see https://en.wikipedia.org/wiki/Lifelong_Planning_A*), a derivative of the Dijkstra algorithm, for
+Navit uses LPA* (see [Lifelong_Planning_A*](https://en.wikipedia.org/wiki/Lifelong_Planning_A*)), a derivative of the Dijkstra algorithm, for
routing. Routing starts at the destination by assigning a value to each point directly connected to the destination
point. The value represents the estimated time needed to reach the destination from that point.
@@ -91,4 +91,4 @@ destination.
LPA* is slightly more complex, as it allows partial re-evaluation of the route graph as segment costs change. This is
used by the (still experimental) traffic module, which can process traffic reports and tries to find a way around
-traffic problems. Refer to the Wikipedia page for a full description. \ No newline at end of file
+traffic problems. Refer to the Wikipedia page for a full description.
diff --git a/navit/graphics.c b/navit/graphics.c
index 50913eeea..1bb7dbd3c 100644
--- a/navit/graphics.c
+++ b/navit/graphics.c
@@ -135,7 +135,8 @@ struct displaylist_icon_cache {
};
-static void circle_to_points(const struct point *center, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir);
+static void circle_to_points(const struct point *center, int diameter, int scale, int start, int len, struct point *res,
+ int *pos, int dir);
static void graphics_process_selection(struct graphics *gra, struct displaylist *dl);
static void graphics_gc_init(struct graphics *this_);
@@ -251,7 +252,8 @@ void graphics_set_rect(struct graphics *gra, struct point_rect *pr) {
struct graphics * graphics_new(struct attr *parent, struct attr **attrs) {
struct graphics *this_;
struct attr *type_attr, cbl_attr;
- struct graphics_priv * (*graphicstype_new)(struct navit *nav, struct graphics_methods *meth, struct attr **attrs, struct callback_list *cbl);
+ struct graphics_priv * (*graphicstype_new)(struct navit *nav, struct graphics_methods *meth, struct attr **attrs,
+ struct callback_list *cbl);
if (! (type_attr=attr_search(attrs, NULL, attr_type))) {
dbg(lvl_error,"Graphics plugin type is not set.");
@@ -629,7 +631,8 @@ struct graphics_image * graphics_image_new_scaled(struct graphics *gra, char *pa
return graphics_image_new_scaled_rotated(gra, path, w, h, 0);
}
-static void image_new_helper(struct graphics *gra, struct graphics_image *this_, char *path, char *name, int width, int height, int rotate, int zip) {
+static void image_new_helper(struct graphics *gra, struct graphics_image *this_, char *path, char *name, int width,
+ int height, int rotate, int zip) {
int i=0;
int stdsizes[]= {8,12,16,22,24,32,36,48,64,72,96,128,192,256};
const int numstdsizes=sizeof(stdsizes)/sizeof(int);
@@ -725,7 +728,8 @@ static void image_new_helper(struct graphics *gra, struct graphics_image *this_,
struct graphics_image_buffer buffer= {"buffer:",graphics_image_type_unknown};
buffer.start=start;
buffer.len=len;
- this_->priv=gra->meth.image_new(gra->priv, &this_->meth, (char *)&buffer, &this_->width, &this_->height, &this_->hot, rotate);
+ this_->priv=gra->meth.image_new(gra->priv, &this_->meth, (char *)&buffer, &this_->width, &this_->height, &this_->hot,
+ rotate);
g_free(start);
}
} else {
@@ -929,7 +933,8 @@ void graphics_draw_rectangle(struct graphics *this_, struct graphics_gc *gc, str
this_->meth.draw_rectangle(this_->priv, gc->priv, p, w, h);
}
-void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc *gc, struct point *plu, int w, int h, int r, int fill) {
+void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc *gc, struct point *plu, int w, int h,
+ int r, int fill) {
struct point *p=g_alloca(sizeof(struct point)*(r*4+32));
struct point pi0= {plu->x+r,plu->y+r};
struct point pi1= {plu->x+w-r,plu->y+r};
@@ -956,7 +961,8 @@ void graphics_draw_rectangle_rounded(struct graphics *this_, struct graphics_gc
* @returns <>
* @author Martin Schaller (04/2008)
*/
-void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct graphics_gc *gc2, struct graphics_font *font, char *text, struct point *p, int dx, int dy) {
+void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct graphics_gc *gc2,
+ struct graphics_font *font, char *text, struct point *p, int dx, int dy) {
this_->meth.draw_text(this_->priv, gc1->priv, gc2 ? gc2->priv : NULL, font->priv, text, p, dx, dy);
}
@@ -967,7 +973,8 @@ void graphics_draw_text(struct graphics *this_, struct graphics_gc *gc1, struct
* @returns <>
* @author Martin Schaller (04/2008)
*/
-void graphics_get_text_bbox(struct graphics *this_, struct graphics_font *font, char *text, int dx, int dy, struct point *ret, int estimate) {
+void graphics_get_text_bbox(struct graphics *this_, struct graphics_font *font, char *text, int dx, int dy,
+ struct point *ret, int estimate) {
this_->meth.get_text_bbox(this_->priv, font->priv, text, dx, dy, ret, estimate);
}
@@ -1143,7 +1150,8 @@ static void xdisplay_free(struct displaylist *dl) {
* @returns <>
* @author Martin Schaller (04/2008)
*/
-static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label, int label_count) {
+static void display_add(struct hash_entry *entry, struct item *item, int count, struct coord *c, char **label,
+ int label_count) {
struct displayitem *di;
int len,i;
char *p;
@@ -1187,7 +1195,8 @@ static void display_add(struct hash_entry *entry, struct item *item, int count,
* @returns <>
* @author Martin Schaller (04/2008)
*/
-static void label_line(struct graphics *gra, struct graphics_gc *fg, struct graphics_gc *bg, struct graphics_font *font, struct point *p, int count, char *label) {
+static void label_line(struct graphics *gra, struct graphics_gc *fg, struct graphics_gc *bg, struct graphics_font *font,
+ struct point *p, int count, char *label) {
int i,x,y,tl,tlm,th,thm,tlsq,l;
float lsq;
double dx,dy;
@@ -1366,7 +1375,8 @@ struct circle {
* @param[out] pos Index of the last point filled inside array @p res
* @param dir Direction of the circle (valid values are 1 (counter-clockwise) or -1 (clockwise), other values may lead to unknown result)
*/
-static void circle_to_points(const struct point *center, int diameter, int scale, int start, int len, struct point *res, int *pos, int dir) {
+static void circle_to_points(const struct point *center, int diameter, int scale, int start, int len, struct point *res,
+ int *pos, int dir) {
struct circle *c;
int count=64;
int end=start+len;
@@ -1561,7 +1571,8 @@ static int draw_middle(struct draw_polyline_context *ctx, struct point *p) {
draw_point(&ctx->prev_shape, p, &poso, 1);
if (delta >= 256)
return 0;
- if (intersection(&pos, ctx->shape.dx, ctx->shape.dy, &poso, ctx->prev_shape.dx, ctx->prev_shape.dy, &ctx->res[ctx->ppos])) {
+ if (intersection(&pos, ctx->shape.dx, ctx->shape.dy, &poso, ctx->prev_shape.dx, ctx->prev_shape.dy,
+ &ctx->res[ctx->ppos])) {
ctx->ppos++;
draw_point(&ctx->prev_shape, p, &ctx->res[ctx->npos--], 0);
draw_point(&ctx->shape, p, &ctx->res[ctx->npos--], 0);
@@ -1573,7 +1584,8 @@ static int draw_middle(struct draw_polyline_context *ctx, struct point *p) {
draw_point(&ctx->prev_shape, p, &nego, 0);
if (delta <= -256)
return 0;
- if (intersection(&neg, ctx->shape.dx, ctx->shape.dy, &nego, ctx->prev_shape.dx, ctx->prev_shape.dy, &ctx->res[ctx->npos])) {
+ if (intersection(&neg, ctx->shape.dx, ctx->shape.dy, &nego, ctx->prev_shape.dx, ctx->prev_shape.dy,
+ &ctx->res[ctx->npos])) {
ctx->npos--;
draw_point(&ctx->prev_shape, p, &ctx->res[ctx->ppos++], 1);
draw_point(&ctx->shape, p, &ctx->res[ctx->ppos++], 1);
@@ -1600,7 +1612,9 @@ static void draw_init_ctx(struct draw_polyline_context *ctx, int maxpoints) {
}
-static void graphics_draw_polyline_as_polygon(struct graphics_priv *gra_priv, struct graphics_gc_priv *gc_priv, struct point *pnt, int count, int *width, void (*draw)(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count)) {
+static void graphics_draw_polyline_as_polygon(struct graphics_priv *gra_priv, struct graphics_gc_priv *gc_priv,
+ struct point *pnt, int count, int *width, void (*draw)(struct graphics_priv *gr, struct graphics_gc_priv *gc,
+ struct point *p, int count)) {
int maxpoints=200;
struct draw_polyline_context ctx;
int i=0;
@@ -1657,7 +1671,8 @@ static int relative_pos(struct wpoint *p, struct point_rect *r) {
return relative_pos;
}
-static void clip_line_endoint_to_rect_edge(struct wpoint *p, int rel_pos, int dx, int dy, int dw, struct point_rect *clip_rect) {
+static void clip_line_endoint_to_rect_edge(struct wpoint *p, int rel_pos, int dx, int dy, int dw,
+ struct point_rect *clip_rect) {
// We must cast to float to avoid integer
// overflow (i.e. undefined behaviour) at high
// zoom levels.
@@ -1725,7 +1740,8 @@ static int clip_line(struct wpoint *p1, struct wpoint *p2, struct point_rect *cl
* @param[in] width An array of width matching the line starting from the corresponding @p pa (if all equal, all lines will have the same width)
* @param poly A boolean indicating whether the polyline should be closed to form a polygon (only the contour of this polygon will be drawn)
*/
-void graphics_draw_polyline_clipped(struct graphics *gra, struct graphics_gc *gc, struct point *pa, int count, int *width, int poly) {
+void graphics_draw_polyline_clipped(struct graphics *gra, struct graphics_gc *gc, struct point *pa, int count,
+ int *width, int poly) {
struct point *points_to_draw=g_alloca(sizeof(struct point)*(count+1));
int *w=g_alloca(sizeof(int)*(count+1));
struct wpoint segment_start,segment_end;
@@ -2489,7 +2505,8 @@ static void do_draw(struct displaylist *displaylist, int cancel, int flags) {
* @returns <>
* @author Martin Schaller (04/2008)
*/
-void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans, struct layout *l, int flags) {
+void graphics_displaylist_draw(struct graphics *gra, struct displaylist *displaylist, struct transformation *trans,
+ struct layout *l, int flags) {
int order=transform_get_order(trans);
if(displaylist->dc.trans && displaylist->dc.trans!=trans)
transform_destroy(displaylist->dc.trans);
@@ -2520,7 +2537,8 @@ void graphics_displaylist_draw(struct graphics *gra, struct displaylist *display
gra->meth.draw_mode(gra->priv, draw_mode_end);
}
-static void graphics_load_mapset(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset, struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags) {
+static void graphics_load_mapset(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset,
+ struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags) {
int order=transform_get_order(trans);
dbg(lvl_debug,"enter");
@@ -2559,7 +2577,8 @@ static void graphics_load_mapset(struct graphics *gra, struct displaylist *displ
* @returns <>
* @author Martin Schaller (04/2008)
*/
-void graphics_draw(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset, struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags) {
+void graphics_draw(struct graphics *gra, struct displaylist *displaylist, struct mapset *mapset,
+ struct transformation *trans, struct layout *l, int async, struct callback *cb, int flags) {
graphics_load_mapset(gra, displaylist, mapset, trans, l, async, cb, flags);
}
@@ -2808,7 +2827,8 @@ static int within_dist_polygon(struct point *p, struct point *poly_pnt, int coun
* @returns <>
* @author Martin Schaller (04/2008)
*/
-int graphics_displayitem_within_dist(struct displaylist *displaylist, struct displayitem *di, struct point *p, int dist) {
+int graphics_displayitem_within_dist(struct displaylist *displaylist, struct displayitem *di, struct point *p,
+ int dist) {
struct point *pa=g_alloca(sizeof(struct point)*displaylist->dc.maxlen);
int count;
diff --git a/navit/maptool/boundaries.c b/navit/maptool/boundaries.c
index e7dc90123..2f64d092c 100644
--- a/navit/maptool/boundaries.c
+++ b/navit/maptool/boundaries.c
@@ -131,7 +131,8 @@ static GList *process_boundaries_setup(FILE *boundaries, struct relations *relat
relations_add_relation_member_entry(relations, relations_func, boundary, (gpointer)role, rel_member_way, osm_id);
}
if(member_type==rel_member_relation) {
- if (!g_strcmp0(rolestr,"outer") || !g_strcmp0(rolestr,"exclave") || !g_strcmp0(rolestr,"inner") || !g_strcmp0(rolestr,"enclave"))
+ if (!g_strcmp0(rolestr,"outer") || !g_strcmp0(rolestr,"exclave") || !g_strcmp0(rolestr,"inner")
+ || !g_strcmp0(rolestr,"enclave"))
has_subrelations++;
}
}
diff --git a/navit/maptool/osm.c b/navit/maptool/osm.c
index e36234775..f640c8674 100644
--- a/navit/maptool/osm.c
+++ b/navit/maptool/osm.c
@@ -1619,7 +1619,8 @@ void osm_end_relation(struct maptool_osm *osm) {
} else
type=type_none;
- if ((!g_strcmp0(relation_type, "multipolygon") || !g_strcmp0(relation_type, "boundary")) && (boundary || type!=type_none)) {
+ if ((!g_strcmp0(relation_type, "multipolygon") || !g_strcmp0(relation_type, "boundary"))
+ && (boundary || type!=type_none)) {
item_bin_write(tmp_item_bin, osm->boundaries);
}
diff --git a/navit/traffic.c b/navit/traffic.c
index 4fafa104d..a5862a625 100644
--- a/navit/traffic.c
+++ b/navit/traffic.c
@@ -62,10 +62,13 @@
#define MESSAGE_UPDATE_SEGMENTS 1 << 1
/** The penalty applied to an off-road link */
-#define PENALTY_OFFROAD 4
+#define PENALTY_OFFROAD 8
+
+/** The penalty applied to segments with non-matching attributes */
+#define PENALTY_SEGMENT_MATCH 4
/** The maximum penalty applied to points with non-matching attributes */
-#define PENALTY_POINT_MATCH 16
+#define PENALTY_POINT_MATCH 24
/** Flag to indicate expired messages should be purged */
#define PROCESS_MESSAGES_PURGE_EXPIRED 1 << 0
@@ -275,7 +278,7 @@ static struct traffic * traffic_new(struct attr *parent, struct attr **attrs);
static int traffic_process_messages_int(struct traffic * this_, int flags);
static void traffic_message_dump_to_stderr(struct traffic_message * this_);
static struct seg_data * traffic_message_parse_events(struct traffic_message * this_);
-static struct route_graph_point * traffic_route_flood_graph(struct route_graph * rg,
+static struct route_graph_point * traffic_route_flood_graph(struct route_graph * rg, struct seg_data * data,
struct coord * c_start, struct coord * c_dst, struct route_graph_point * start_existing);
static struct item_methods methods_traffic_item = {
@@ -1319,9 +1322,19 @@ static int traffic_point_match_attributes(struct traffic_point * this_, struct i
* the quality of the match.
*
* Segments which are part of the route are treated in a different manner, as the direction in which the segment is
- * traversed (not the direction of the segment itself) is taken into account: When evaluating the start point of the
- * route, only the first point (whose `seg` member points to the segment) will match; the opposite is true when the end
- * point of the route is evaluated. This ensures the matched segment ends up being part of the route.
+ * traversed (not the direction of the segment itself) is taken into account, which is needed to govern whether the
+ * matched segment ends up being part of the route or not.
+ *
+ * In some cases, `this_` refers to a point which is actually a segment (such as a bridge or tunnel), which we want to
+ * include in the route. In other cases, `this_` refers to an intersection with another road, and the junction name is
+ * the name of the other road; these segments need to be excluded from the route.
+ *
+ * This is controlled by the `match_start` argument: if true, we are evaluating the start point of a route, else we are
+ * evaluating its end point. To include the matched segment in the route, only the first point (whose `seg` member
+ * points to the segment) will match for the start point, the opposite is true for the end point. To exclude the
+ * matched segment, this logic is reversed.
+ *
+ * A heuristic is in place to distinguish whether or not we want the matched segment included.
*
* If no points can be attained (because no attributes which must match are supplied), the score is 0 for any point.
*
@@ -1335,13 +1348,22 @@ static int traffic_point_match_attributes(struct traffic_point * this_, struct i
static int traffic_point_match_segment_attributes(struct traffic_point * this_, struct route_graph_point *p,
struct route_graph_point * start, int match_start) {
+ /*
+ * Whether we want a match for the route segment starting at p (leading away from it) or the route segment ending
+ * at p (leading towards it).
+ */
+ int want_start_match = match_start;
+
/* Iterator for route graph points */
struct route_graph_point *p_iter = start;
/* The predecessor pf `p`in the route graph */
struct route_graph_point *p_prev = NULL;
- /* Whether we have a match for the start of a route segment, the end of a route segment or an off-route segment */
+ /*
+ * Whether this_ matches the route segment starting at p (leading away from it), the route segment ending at p
+ * (leading towards it), or an off-route segment connected to p, respectively
+ */
int has_start_match = 0, has_end_match = 0, has_offroute_match = 0;
/* The route segment being examined */
@@ -1356,9 +1378,17 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_,
/* The attribute being examined */
struct attr attr;
- if (!this_->junction_name)
+ /* Name and systematic name for route segments starting and ending at p */
+ char *start_name = NULL, *start_ref = NULL, *end_name = NULL, *end_ref = NULL;
+
+ /* Whether or not the route follows the road (if both are true or both are false, the case is not clear) */
+ int route_follows_road = 0, route_leaves_road = 0;
+
+ if (!this_->junction_name) {
/* nothing to compare, score is 0 */
+ dbg(lvl_debug, "p=%p: no junction name, score 0", p);
return 0;
+ }
/* find predecessor of p, if any */
while (p_iter && (p_iter != p)) {
@@ -1375,74 +1405,147 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_,
if (!p_prev && (p != start)) {
/* not a point on the route */
+ dbg(lvl_debug, "p=%p: not on the route, score 0", p);
return 0;
}
/* check if we have a match for the start of a route segment */
if (p->seg) {
mr = map_rect_new(p->seg->data.item.map, NULL);
- if ((item = map_rect_get_item_byid(mr, p->seg->data.item.id_hi, p->seg->data.item.id_lo))
- && item_attr_get(item, attr_street_name, &attr)
+ if ((item = map_rect_get_item_byid(mr, p->seg->data.item.id_hi, p->seg->data.item.id_lo))) {
+ if (item_attr_get(item, attr_street_name, &attr)) {
+ start_name = g_strdup(attr.u.str);
// TODO crude comparison in need of refinement
- && !strcmp(this_->junction_name, attr.u.str))
- has_start_match = 1;
+ if (!strcmp(this_->junction_name, attr.u.str))
+ has_start_match = 1;
+ }
+ if (item_attr_get(item, attr_street_name_systematic, &attr))
+ start_ref = g_strdup(attr.u.str);
+ }
map_rect_destroy(mr);
}
/* check if we have a match for the end of a route segment */
if (p_prev && p_prev->seg) {
mr = map_rect_new(p_prev->seg->data.item.map, NULL);
- if ((item = map_rect_get_item_byid(mr, p_prev->seg->data.item.id_hi, p_prev->seg->data.item.id_lo))
- && item_attr_get(item, attr_street_name, &attr)
+ if ((item = map_rect_get_item_byid(mr, p_prev->seg->data.item.id_hi, p_prev->seg->data.item.id_lo))) {
+ if (item_attr_get(item, attr_street_name, &attr)) {
+ end_name = g_strdup(attr.u.str);
// TODO crude comparison in need of refinement
- && !strcmp(this_->junction_name, attr.u.str))
- has_end_match = 1;
+ if (!strcmp(this_->junction_name, attr.u.str))
+ has_end_match = 1;
+ }
+ if (item_attr_get(item, attr_street_name_systematic, &attr))
+ end_ref = g_strdup(attr.u.str);
+ }
map_rect_destroy(mr);
}
- /* we cannot have multiple matches in different categories */
+ /*
+ * If we have both a start match and an end match, the point is in the middle of a stretch of road which matches
+ * the junction name. Regardless of whether we want that stretch included in the route or not, a middle point
+ * cannot be an end point.
+ */
if (has_start_match && has_end_match) {
+ dbg(lvl_debug, "p=%p: both start and end match, score 0", p);
+ g_free(start_name);
+ g_free(start_ref);
+ g_free(end_name);
+ g_free(end_ref);
return 0;
}
+ if (start_name && end_name)
+ // TODO crude comparison in need of refinement
+ route_follows_road |= !strcmp(start_name, end_name);
+
+ if (start_ref && end_ref)
+ // TODO crude comparison in need of refinement
+ route_follows_road |= !strcmp(start_ref, end_ref);
+
/* check if we have a match for an off-route segment */
- for (s = p->start; s && !has_offroute_match; s = s->start_next) {
+ /* TODO consolidate these two loops, which differ only in their loop statement while the body is identical */
+ for (s = p->start; s && !(has_offroute_match && route_leaves_road); s = s->start_next) {
if ((p->seg == s) || (p_prev && (p_prev->seg == s)))
/* segments is on the route, skip */
continue;
mr = map_rect_new(s->data.item.map, NULL);
- if ((item = map_rect_get_item_byid(mr, s->data.item.id_hi, s->data.item.id_lo))
- && item_attr_get(item, attr_street_name, &attr)
+ if ((item = map_rect_get_item_byid(mr, s->data.item.id_hi, s->data.item.id_lo))) {
+ if (item_attr_get(item, attr_street_name, &attr)) {
// TODO crude comparison in need of refinement
- && !strcmp(this_->junction_name, attr.u.str))
- has_offroute_match = 1;
+ if (!strcmp(this_->junction_name, attr.u.str))
+ has_offroute_match = 1;
+ if (start_name)
+ route_leaves_road |= !strcmp(start_name, attr.u.str);
+ if (end_name)
+ route_leaves_road |= !strcmp(end_name, attr.u.str);
+ }
+ if (!route_leaves_road && item_attr_get(item, attr_street_name_systematic, &attr)) {
+ // TODO crude comparison in need of refinement
+ if (start_ref)
+ route_leaves_road |= !strcmp(start_ref, attr.u.str);
+ if (end_ref)
+ route_leaves_road |= !strcmp(end_ref, attr.u.str);
+ }
+ }
map_rect_destroy(mr);
}
- for (s = p->end; s && !has_offroute_match; s = s->end_next) {
+ for (s = p->end; s && !(has_offroute_match && route_leaves_road); s = s->end_next) {
if ((p->seg == s) || (p_prev && (p_prev->seg == s)))
/* segments is on the route, skip */
continue;
mr = map_rect_new(s->data.item.map, NULL);
- if ((item = map_rect_get_item_byid(mr, s->data.item.id_hi, s->data.item.id_lo))
- && item_attr_get(item, attr_street_name, &attr)
+ if ((item = map_rect_get_item_byid(mr, s->data.item.id_hi, s->data.item.id_lo))) {
+ if (item_attr_get(item, attr_street_name, &attr)) {
+ // TODO crude comparison in need of refinement
+ if (!strcmp(this_->junction_name, attr.u.str))
+ has_offroute_match = 1;
+ if (start_name)
+ route_leaves_road |= !strcmp(start_name, attr.u.str);
+ if (end_name)
+ route_leaves_road |= !strcmp(end_name, attr.u.str);
+ }
+ if (!route_leaves_road && item_attr_get(item, attr_street_name_systematic, &attr)) {
// TODO crude comparison in need of refinement
- && !strcmp(this_->junction_name, attr.u.str))
- has_offroute_match = 1;
+ if (start_ref)
+ route_leaves_road |= !strcmp(start_ref, attr.u.str);
+ if (end_ref)
+ route_leaves_road |= !strcmp(end_ref, attr.u.str);
+ }
+ }
map_rect_destroy(mr);
}
+ dbg(lvl_debug,
+ "p=%p: %s %s → %s %s\nhas_offroute_match=%d, has_start_match=%d, has_end_match=%d, route_follows_road=%d, route_leaves_road=%d",
+ p, end_ref, end_name, start_ref, start_name,
+ has_offroute_match, has_start_match, has_end_match, route_follows_road, route_leaves_road);
+
+ g_free(start_name);
+ g_free(start_ref);
+ g_free(end_name);
+ g_free(end_ref);
+
+ if (route_leaves_road && !route_follows_road)
+ want_start_match = !match_start;
+ /* TODO decide how to handle ambiguous situations (both true or both false), currently we include the segment */
+
if (has_offroute_match) {
if (has_start_match || has_end_match) {
/* we cannot have multiple matches in different categories */
+ /* TODO maybe we can: e.g. one segment of the crossing road got added to the route, the other did not */
+ dbg(lvl_debug, "p=%p: both off-route and start/end match, score 0", p);
return 0;
}
} else {
- if ((match_start && !has_start_match) || (!match_start && !has_end_match)) {
+ if ((want_start_match && !has_start_match) || (!want_start_match && !has_end_match)) {
/* no match in requested category */
+ dbg(lvl_debug, "p=%p: no match in requested category, score 0", p);
return 0;
}
}
+ dbg(lvl_debug, "p=%p: score 100 (full score)", p);
return 100;
}
@@ -1451,17 +1554,18 @@ static int traffic_point_match_segment_attributes(struct traffic_point * this_,
*
* The cost is calculated based on the length of the segment and a penalty which depends on the score.
* A segment with the maximum score of 100 is not penalized, i.e. its cost is equal to its length. A
- * segment with a zero score is penalized with a factor of `PENALTY_OFFROAD`. For scores in between, a
- * penalty factor between 1 and `PENALTY_OFFROAD` is applied.
+ * segment with a zero score is penalized with a factor of `PENALTY_SEGMENT_MATCH`. For scores in between, a
+ * penalty factor between 1 and `PENALTY_SEGMENT_MATCH` is applied.
*
* If the segment is impassable in the given direction, the cost is always `INT_MAX`.
*
* @param over The segment
+ * @param data Data for the segments added to the map
* @param dir The direction (positive numbers indicate positive direction)
*
* @return The cost of the segment
*/
-static int traffic_route_get_seg_cost(struct route_graph_segment *over, int dir) {
+static int traffic_route_get_seg_cost(struct route_graph_segment *over, struct seg_data * data, int dir) {
if (over->data.flags & (dir >= 0 ? AF_ONEWAYREV : AF_ONEWAY))
return INT_MAX;
if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION))
@@ -1470,8 +1574,11 @@ static int traffic_route_get_seg_cost(struct route_graph_segment *over, int dir)
return INT_MAX;
if ((over->data.item.type < route_item_first) || (over->data.item.type > route_item_last))
return INT_MAX;
+ /* at least a partial match is required for access flags */
+ if (!(over->data.flags & data->flags & AF_ALL))
+ return INT_MAX;
- return over->data.len * (100 - over->data.score) * (PENALTY_OFFROAD - 1) / 100 + over->data.len;
+ return over->data.len * (100 - over->data.score) * (PENALTY_SEGMENT_MATCH - 1) / 100 + over->data.len;
}
/**
@@ -1886,13 +1993,14 @@ static int traffic_location_equals(struct traffic_location * l, struct traffic_l
* longer needed.
*
* @param rg The route graph
+ * @param data Data for the segments added to the map
* @param c_start Start coordinates
* @param c_dst Destination coordinates
* @param start_existing Start point of an existing route (whose points will not be used)
*
* @return The point in the route graph at which the path begins, or `NULL` if no path was found.
*/
-static struct route_graph_point * traffic_route_flood_graph(struct route_graph * rg,
+static struct route_graph_point * traffic_route_flood_graph(struct route_graph * rg, struct seg_data * data,
struct coord * c_start, struct coord * c_dst, struct route_graph_point * start_existing) {
struct route_graph_point * ret;
@@ -1973,7 +2081,7 @@ static struct route_graph_point * traffic_route_flood_graph(struct route_graph *
p->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */
s = p->start;
while (s) { /* Iterating all the segments leading away from our point to update the points at their ends */
- val = traffic_route_get_seg_cost(s, -1);
+ val = traffic_route_get_seg_cost(s, data, -1);
dbg(lvl_debug, " negative segment, val=%d", val);
@@ -1998,7 +2106,7 @@ static struct route_graph_point * traffic_route_flood_graph(struct route_graph *
}
s = p->end;
while (s) { /* Doing the same as above with the segments leading towards our point */
- val = traffic_route_get_seg_cost(s, 1);
+ val = traffic_route_get_seg_cost(s, data, 1);
dbg(lvl_debug, " positive segment, val=%d", val);
@@ -2612,11 +2720,11 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m
dbg(lvl_debug, "*****checkpoint ADD-4.1");
if (point_pairs == 1) {
if (dir > 0)
- p_start = traffic_route_flood_graph(rg,
+ p_start = traffic_route_flood_graph(rg, data,
pcoords[0] ? pcoords[0] : pcoords[1],
pcoords[2] ? pcoords[2] : pcoords[1], NULL);
else
- p_start = traffic_route_flood_graph(rg,
+ p_start = traffic_route_flood_graph(rg, data,
pcoords[2] ? pcoords[2] : pcoords[1],
pcoords[0] ? pcoords[0] : pcoords[1], NULL);
dbg(lvl_debug, "*****checkpoint ADD-4.1.1");
@@ -2635,9 +2743,9 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m
/* TODO handle cases in which the route goes through the "third" point
* (this should not happen; if it does, we need to detect and fix it) */
if (dir > 0)
- p_start = traffic_route_flood_graph(rg, pcoords[0], pcoords[1], NULL);
+ p_start = traffic_route_flood_graph(rg, data, pcoords[0], pcoords[1], NULL);
else
- p_start = traffic_route_flood_graph(rg, pcoords[2], pcoords[1], NULL);
+ p_start = traffic_route_flood_graph(rg, data, pcoords[2], pcoords[1], NULL);
if ((this_->location->fuzziness == location_fuzziness_low_res)
|| this_->location->at || this_->location->not_via) {
/* extend start to next junction */
@@ -2648,17 +2756,17 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m
if (dir > 0) {
if (!p_start) {
/* fallback if calculating the first piece of the route failed */
- p_start = traffic_route_flood_graph(rg, pcoords[1], pcoords[2], NULL);
+ p_start = traffic_route_flood_graph(rg, data, pcoords[1], pcoords[2], NULL);
start_new = traffic_route_prepend(rg, p_start);
} else
- traffic_route_flood_graph(rg, pcoords[1], pcoords[2], p_start);
+ traffic_route_flood_graph(rg, data, pcoords[1], pcoords[2], p_start);
} else {
if (!p_start) {
/* fallback if calculating the first piece of the route failed */
- p_start = traffic_route_flood_graph(rg, pcoords[1], pcoords[0], NULL);
+ p_start = traffic_route_flood_graph(rg, data, pcoords[1], pcoords[0], NULL);
start_new = traffic_route_prepend(rg, p_start);
} else
- traffic_route_flood_graph(rg, pcoords[1], pcoords[0], p_start);
+ traffic_route_flood_graph(rg, data, pcoords[1], pcoords[0], p_start);
}
dbg(lvl_debug, "*****checkpoint ADD-4.1.2");
}
@@ -2710,7 +2818,11 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m
p_to = NULL;
dbg(lvl_debug, "*****checkpoint ADD-4.2.3");
+ struct coord_geo wgs;
while (p_iter) {
+ transform_to_geo(projection_mg, &(p_iter->c), &wgs);
+ dbg(lvl_debug, "*****checkpoint ADD-4.2.3, p_iter=%p (value=%d)\nhttps://www.openstreetmap.org?mlat=%f&mlon=%f/#map=13",
+ p_iter, p_iter->value, wgs.lat, wgs.lng);
if (route_graph_point_is_endpoint_candidate(p_iter, s_prev)) {
score = traffic_location_get_point_match(this_->location, p_iter,
this_->location->at ? 1 : (dir > 0) ? 2 : 0,
@@ -2756,7 +2868,6 @@ static int traffic_message_add_segments(struct traffic_message * this_, struct m
minval = INT_MAX;
p_from = NULL;
- struct coord_geo wgs;
transform_to_geo(projection_mg, &(p_start->c), &wgs);
dbg(lvl_debug, "*****checkpoint ADD-4.2.6, p_start=%p\nhttps://www.openstreetmap.org?mlat=%f&mlon=%f/#map=13",
p_start, wgs.lat, wgs.lng);
@@ -3382,8 +3493,12 @@ static struct seg_data * traffic_message_parse_events(struct traffic_message * t
}
/* if no vehicle type is specified in supplementary information, assume all */
- if (!has_flags)
- flags = AF_ALL;
+ if (!has_flags) {
+ if (this_->location->road_type == type_line_unspecified)
+ flags = AF_ALL;
+ else
+ flags = AF_MOTORIZED_FAST | AF_MOPED;
+ }
if (!ret)
ret = seg_data_new();
@@ -3545,7 +3660,7 @@ static void traffic_dump_messages_to_xml(struct traffic * this_) {
if (message->location->ramps)
fprintf(f, " ramps=\"%s\"", location_ramps_to_string(message->location->ramps));
if (message->location->road_type != type_line_unspecified)
- fprintf(f, " road_type=\"%s\"", item_to_name(message->location->road_type));
+ fprintf(f, " road_class=\"%s\"", item_to_name(message->location->road_type));
if (message->location->road_ref)
fprintf(f, " road_ref=\"%s\"", message->location->road_ref);
if (message->location->road_name)
@@ -4179,7 +4294,7 @@ static void traffic_xml_end(xml_context *dummy, const char *tag_name, void *data
location_dir_new(traffic_xml_get_attr("directionality", el->names, el->values)),
location_fuzziness_new(traffic_xml_get_attr("fuzziness", el->names, el->values)),
location_ramps_new(traffic_xml_get_attr("ramps", el->names, el->values)),
- item_type_from_road_type(traffic_xml_get_attr("road_type", el->names, el->values),
+ item_type_from_road_type(traffic_xml_get_attr("road_class", el->names, el->values),
/* TODO revisit default for road_is_urban */
boolean_new(traffic_xml_get_attr("road_is_urban", el->names, el->values), 0)),
traffic_xml_get_attr("road_name", el->names, el->values),
diff --git a/navit/transform.c b/navit/transform.c
index 85a9c41da..4c0cb68b1 100644
--- a/navit/transform.c
+++ b/navit/transform.c
@@ -993,6 +993,15 @@ int transform_int_scale(int y) {
}
#endif
+/**
+ * @brief Calculates the distance between two points.
+ *
+ * @param pro The projection used for `c1` and `c2`.
+ * @param c1 The first point.
+ * @param c2 The second point.
+ *
+ * @return The distance in meters.
+ */
double transform_distance(enum projection pro, struct coord *c1, struct coord *c2) {
if (pro == projection_mg) {
#ifndef AVOID_FLOAT
diff --git a/scripts/build_android_arm.sh b/scripts/build_android_arm.sh
new file mode 100755
index 000000000..74cf8e28d
--- /dev/null
+++ b/scripts/build_android_arm.sh
@@ -0,0 +1,61 @@
+#!/bin/bash
+# Build Navit for Android on ARM.
+#
+# This script is to be run from the root of the Navit source tree. It is used by CircleCI as well as for local builds,
+# in order to keep build environments as uniform as possible and CI test results meaningful.
+#
+# When running this script locally, ensure all build dependencies are in place:
+# - Packages required: cmake gettext libsaxonb-java librsvg2-bin pkg-config libprotobuf-c-dev protobuf-c-compiler
+# - Android SDK installed
+# - Environment variable $ANDROID_HOME points to Android SDK install location
+# - Android NDK and CMake components installed via
+# sdkmanager ndk-bundle "cmake;3.6.4111459"
+# (later CMake versions from the SDK repository may also work)
+#
+# If any of the build steps fails, this script aborts with an error immediately.
+
+echo Set up environment
+set - e
+export PATH=$PATH:$ANDROID_HOME/tools
+export JVM_OPTS="-Xmx3200m"
+export GRADLE_OPTS='-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
+
+echo Run CMake
+cmake ./ -Dvehicle/gpsd_dbus:BOOL=FALSE -Dsvg2png_scaling:STRING=-1,24,32,48,64,96,128,192,256 -Dsvg2png_scaling_nav:STRING=-1,24,32,48,64,96,128,192,256 -Dsvg2png_scaling_flag:STRING=-1,24,32,64,96 -DUSE_PLUGINS=n -DBUILD_MAPTOOL=n -DXSL_PROCESSING=y -DXSLTS=android -DANDROID=y -DSAMPLE_MAP=n || exit 1
+
+echo Process icons
+cd navit/icons
+make || exit 32
+mkdir ../android/res/drawable-nodpi
+rename 'y/A-Z/a-z/' ./*.png
+cp ./*.png ../android/res/drawable-nodpi
+cd ../../
+
+echo Process translations
+cd po
+make || exit 64
+mkdir ../navit/android/res/raw
+rename 'y/A-Z/a-z/' ./*.mo
+cp ./*.mo ../navit/android/res/raw
+cd ../
+
+echo Process xml config files
+make navit_config_xml || exit 96
+cd navit
+mkdir -p ./android/assets
+cp -R config ./android/assets/
+cd ../
+
+echo Chmod permissions
+chmod a+x ./gradlew
+
+echo Download dependencies
+./gradlew -v
+
+echo Build
+./gradlew assembleDebug || exit 128
+
+echo Build finished.
+echo APK should be in "navit/android/build/outputs/apk" and can be installed with
+echo ./gradlew installDebug
+
diff --git a/scripts/build_linux.sh b/scripts/build_linux.sh
index ba04c1efc..5d807ec45 100644
--- a/scripts/build_linux.sh
+++ b/scripts/build_linux.sh
@@ -10,6 +10,7 @@ cmake_opts="-Dgraphics/qt_qpainter:BOOL=FALSE -Dgui/qml:BOOL=FALSE -DSVG2PNG:BOO
pushd $BUILD_PATH
# Build everything
+ echo "Building..."
cmake ${cmake_opts} ../
make -j $(nproc --all)
make package
@@ -19,14 +20,18 @@ if [[ "${CIRCLE_PROJECT_USERNAME}" == "navit-gps" && "${CIRCLE_BRANCH}" == "trun
# Temporarily disabled because Coverity is down.
# TODO on the long run, CI should not fail just because the Coverity test did not run,
# especially if the test results are not taken into account.
+ #echo "Pushing an update to coverity as we are building the official trunk code."
+ #echo "Downloading coverity..."
#curl \
# -X POST --data "token=${COVERITY_TOKEN}&project=${CIRCLE_PROJECT_USERNAME}" \
# -o /tmp/cov-analysis-linux64-${COVERITY_VERSION}.tar.gz -s \
# https://scan.coverity.com/download/linux64
+ #echo "Unpacking coverity..."
#tar xfz /tmp/cov-analysis-linux64-${COVERITY_VERSION}.tar.gz --no-same-owner -C /usr/local/share/
#export PATH=/usr/local/share/cov-analysis-linux64-${COVERITY_VERSION}/bin:$PATH
+ #echo "Re-running build with coverity..."
#cov-build --dir cov-int make -j $(nproc --all)
#tar czvf navit.tgz cov-int
@@ -38,11 +43,13 @@ if [[ "${CIRCLE_PROJECT_USERNAME}" == "navit-gps" && "${CIRCLE_BRANCH}" == "trun
# https://scan.coverity.com/builds?project=$CIRCLE_PROJECT_USERNAME
# Then update the translation template on launchpad
+ echo "Updating the translation template on launchpad..."
sed -i '/INTEGER/d' po/navit.pot
cp po/navit.pot $CIRCLE_ARTIFACTS/
curl "https://translations.launchpad.net/navit/${CIRCLE_BRANCH}/+translations-upload" -H "$lp_cookie" -H "Referer: https://translations.launchpad.net/navit/${CIRCLE_BRANCH}/+translations-upload" -F file=@po/navit.pot | grep title
fi
if [[ "$CIRCLE_ARTIFACTS" != "" ]]; then
+ echo "Copying icons to artifacts..."
cp -r navit/icons $CIRCLE_ARTIFACTS
fi