|
|
1 | /* jandegr 2016 : try to merge the relevant changes from my Navit ext_graph_prep branch |
|
|
2 | * to allow P-turns and to allow for later turn cost calculation |
|
|
3 | */ |
|
|
4 | |
1 | /** |
5 | /** |
2 | * ZANavi, Zoff Android Navigation system. |
6 | * ZANavi, Zoff Android Navigation system. |
3 | * Copyright (C) 2011-2015 Zoff <zoff@zoff.cc> |
7 | * Copyright (C) 2011-2015 Zoff <zoff@zoff.cc> |
4 | * |
8 | * |
5 | * This program is free software; you can redistribute it and/or |
9 | * This program is free software; you can redistribute it and/or |
… | |
… | |
1951 | //global_route_memory_size = global_route_memory_size + sizeof(struct route_graph_point); |
1955 | //global_route_memory_size = global_route_memory_size + sizeof(struct route_graph_point); |
1952 | //dbg(0,"(A)route mem=%lu\n", global_route_memory_size); |
1956 | //dbg(0,"(A)route mem=%lu\n", global_route_memory_size); |
1953 | |
1957 | |
1954 | p->hash_next = this->hash[hashval]; |
1958 | p->hash_next = this->hash[hashval]; |
1955 | this->hash[hashval] = p; |
1959 | this->hash[hashval] = p; |
1956 | p->value = INT_MAX; |
|
|
1957 | p->c = *f; |
1960 | p->c = *f; |
1958 | |
1961 | |
1959 | return p; |
1962 | return p; |
1960 | } |
1963 | } |
1961 | |
1964 | |
… | |
… | |
2021 | static void route_graph_reset(struct route_graph *this) |
2024 | static void route_graph_reset(struct route_graph *this) |
2022 | { |
2025 | { |
2023 | __F_START__ |
2026 | __F_START__ |
2024 | |
2027 | |
2025 | struct route_graph_point *curr; |
2028 | struct route_graph_point *curr; |
|
|
2029 | struct route_graph_segment *seg; |
|
|
2030 | |
2026 | int i; |
2031 | int i; |
2027 | for (i = 0; i < HASH_SIZE; i++) |
2032 | for (i = 0; i < HASH_SIZE; i++) |
2028 | { |
2033 | { |
2029 | curr = this->hash[i]; |
2034 | curr = this->hash[i]; |
2030 | while (curr) |
2035 | while (curr) |
2031 | { |
2036 | { |
2032 | curr->value = INT_MAX; |
2037 | seg = curr->start; |
2033 | curr->seg = NULL; |
2038 | while (seg) |
2034 | curr->el = NULL; |
2039 | { |
|
|
2040 | seg->end_from_seg = NULL; |
|
|
2041 | seg->start_from_seg = NULL; |
|
|
2042 | seg->seg_end_out_cost = INT_MAX; |
|
|
2043 | seg->seg_start_out_cost = INT_MAX; |
|
|
2044 | seg = seg->start_next; |
|
|
2045 | } |
|
|
2046 | |
|
|
2047 | |
|
|
2048 | seg = curr->end; |
|
|
2049 | // overkill ? |
|
|
2050 | while (seg) |
|
|
2051 | { |
|
|
2052 | seg->end_from_seg = NULL; |
|
|
2053 | seg->start_from_seg = NULL; |
|
|
2054 | seg->seg_end_out_cost = INT_MAX; |
|
|
2055 | seg->seg_start_out_cost = INT_MAX; |
|
|
2056 | seg = seg->end_next; |
|
|
2057 | } |
|
|
2058 | |
2035 | curr = curr->hash_next; |
2059 | curr=curr->hash_next; |
2036 | } |
2060 | } |
2037 | } |
2061 | } |
2038 | |
2062 | |
2039 | __F_END__ |
2063 | __F_END__ |
2040 | } |
2064 | } |
… | |
… | |
2172 | { |
2196 | { |
2173 | printf("%s:Out of memory\n", __FUNCTION__); |
2197 | printf("%s:Out of memory\n", __FUNCTION__); |
2174 | return; |
2198 | return; |
2175 | } |
2199 | } |
2176 | |
2200 | |
|
|
2201 | s->seg_end_out_cost = INT_MAX; |
|
|
2202 | s->seg_start_out_cost = INT_MAX; |
2177 | s->start = start; |
2203 | s->start = start; |
2178 | s->start_next = start->start; |
2204 | s->start_next = start->start; |
2179 | start->start = s; |
2205 | start->start = s; |
2180 | |
2206 | |
2181 | s->end = end; |
2207 | s->end = end; |
… | |
… | |
2233 | { |
2259 | { |
2234 | printf("%s:Out of memory\n", __FUNCTION__); |
2260 | printf("%s:Out of memory\n", __FUNCTION__); |
2235 | return; |
2261 | return; |
2236 | } |
2262 | } |
2237 | |
2263 | |
|
|
2264 | s->seg_end_out_cost = INT_MAX; |
|
|
2265 | s->seg_start_out_cost = INT_MAX; |
2238 | s->start = start; |
2266 | s->start = start; |
2239 | s->start_next = start->start; |
2267 | s->start_next = start->start; |
2240 | start->start = s; |
2268 | start->start = s; |
2241 | |
2269 | |
2242 | s->end = end; |
2270 | s->end = end; |
… | |
… | |
2373 | } |
2401 | } |
2374 | sp = s; |
2402 | sp = s; |
2375 | s = s->next; |
2403 | s = s->next; |
2376 | } |
2404 | } |
2377 | |
2405 | |
2378 | if (s) |
2406 | // if (s) |
2379 | item_hash_remove(path->path_hash, item); |
2407 | // item_hash_remove(path->path_hash, item); |
2380 | |
2408 | |
2381 | return s; |
2409 | return s; |
2382 | } |
2410 | } |
2383 | |
2411 | |
2384 | /** |
2412 | /** |
… | |
… | |
2486 | */ |
2514 | */ |
2487 | 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) |
2515 | 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) |
2488 | { |
2516 | { |
2489 | //// dbg(0, "enter\n"); |
2517 | //// dbg(0, "enter\n"); |
2490 | |
2518 | |
2491 | struct route_path_segment *segment; |
2519 | struct route_path_segment *segment = NULL; |
2492 | int i, ccnt, extra = 0, ret = 0; |
2520 | int i, ccnt, extra = 0, ret = 0; |
2493 | struct coord *c, *cd, ca[2048]; |
2521 | struct coord *c, *cd, ca[2048]; |
2494 | int offset = 1; |
2522 | int offset = 1; |
2495 | int seg_size, seg_dat_size; |
2523 | int seg_size, seg_dat_size; |
2496 | int len = rgs->data.len; |
2524 | int len = rgs->data.len; |
2497 | if (rgs->data.flags & NAVIT_AF_SEGMENTED) |
2525 | if (rgs->data.flags & NAVIT_AF_SEGMENTED) |
2498 | { |
2526 | { |
2499 | offset = RSD_OFFSET(&rgs->data); |
2527 | offset = RSD_OFFSET(&rgs->data); |
2500 | } |
2528 | } |
2501 | |
2529 | |
2502 | //dbg(1, "enter (0x%x,0x%x) dir=%d pos=%p dst=%p\n", rgs->data.item.id_hi, |
2530 | |
2503 | // rgs->data.item.id_lo, dir, pos, dst); |
|
|
2504 | if (oldpath) |
2531 | if (oldpath) |
2505 | { |
2532 | { |
2506 | segment = item_hash_lookup(oldpath->path_hash, &rgs->data.item); |
2533 | segment = item_hash_lookup(oldpath->path_hash, &rgs->data.item); |
2507 | if (segment && segment->direction == dir) |
2534 | if (segment && !(dst && segment->direction != dir)) // testen als het het laatste segment betreft of dir wel gelijk is |
2508 | { |
2535 | { |
2509 | segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset); |
2536 | segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset); |
2510 | if (segment) |
2537 | if (segment) |
2511 | { |
2538 | { |
2512 | ret = 1; |
2539 | ret = 1; |
2513 | |
|
|
2514 | if (!pos) |
2540 | if (!pos) |
2515 | goto linkold; |
2541 | { |
2516 | |
2542 | segment->data->len = len; |
|
|
2543 | segment->next = NULL; |
|
|
2544 | item_hash_insert(this->path_hash, &rgs->data.item, segment); |
|
|
2545 | route_path_add_segment(this, segment); |
|
|
2546 | return ret; |
|
|
2547 | } |
2517 | } |
2548 | } |
2518 | } |
2549 | } |
2519 | } |
2550 | } |
2520 | |
2551 | |
2521 | if (pos) |
2552 | if (pos) |
… | |
… | |
2566 | //dbg(1, "dst pos=%d\n", dst->pos); |
2597 | //dbg(1, "dst pos=%d\n", dst->pos); |
2567 | if (dir > 0) |
2598 | if (dir > 0) |
2568 | { |
2599 | { |
2569 | c = dst->street->c; |
2600 | c = dst->street->c; |
2570 | ccnt = dst->pos + 1; |
2601 | ccnt = dst->pos + 1; |
2571 | len = dst->lenpos; |
2602 | len = dst->lenneg; |
2572 | } |
2603 | } |
2573 | else |
2604 | else |
2574 | { |
2605 | { |
2575 | c = dst->street->c + dst->pos + 1; |
2606 | c = dst->street->c + dst->pos + 1; |
2576 | ccnt = dst->street->count - dst->pos - 1; |
2607 | ccnt = dst->street->count - dst->pos - 1; |
2577 | len = dst->lenneg; |
2608 | len = dst->lenpos; |
2578 | } |
2609 | } |
2579 | } |
2610 | } |
2580 | else |
2611 | else |
2581 | { |
2612 | { |
2582 | ccnt = get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, &rgs->end->c); |
2613 | ccnt = get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, &rgs->end->c); |
… | |
… | |
2624 | // We identified this roundabout earlier |
2655 | // We identified this roundabout earlier |
2625 | route_check_roundabout(rgs, 13, (dir < 1), NULL); // 13 z8z8 |
2656 | route_check_roundabout(rgs, 13, (dir < 1), NULL); // 13 z8z8 |
2626 | } |
2657 | } |
2627 | |
2658 | |
2628 | memcpy(segment->data, &rgs->data, seg_dat_size); |
2659 | memcpy(segment->data, &rgs->data, seg_dat_size); |
2629 | linkold: segment->data->len = len; |
2660 | segment->data->len = len; |
2630 | segment->next = NULL; |
2661 | segment->next = NULL; |
2631 | item_hash_insert(this->path_hash, &rgs->data.item, segment); |
2662 | item_hash_insert(this->path_hash, &rgs->data.item, segment); |
2632 | |
2663 | |
2633 | route_path_add_segment(this, segment); |
2664 | route_path_add_segment(this, segment); |
2634 | |
2665 | |
… | |
… | |
2928 | * @param from The point where we are starting (can be NULL) |
2959 | * @param from The point where we are starting (can be NULL) |
2929 | * @param over The segment we are using |
2960 | * @param over The segment we are using |
2930 | * @param dir The direction of segment which we are driving |
2961 | * @param dir The direction of segment which we are driving |
2931 | * @return The "costs" needed to drive len on item |
2962 | * @return The "costs" needed to drive len on item |
2932 | */ |
2963 | */ |
2933 | static int route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir) |
2964 | static int route_value_seg(struct vehicleprofile *profile, struct route_graph_segment *from, struct route_graph_segment *over, int dir) |
2934 | { |
2965 | { |
2935 | //// dbg(0, "enter\n"); |
2966 | //// dbg(0, "enter\n"); |
2936 | |
2967 | |
2937 | int ret; |
2968 | int ret; |
2938 | struct route_traffic_distortion dist, *distp = NULL; |
2969 | struct route_traffic_distortion dist, *distp = NULL; |
… | |
… | |
2956 | if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) |
2987 | if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) |
2957 | { |
2988 | { |
2958 | return INT_MAX; |
2989 | return INT_MAX; |
2959 | } |
2990 | } |
2960 | |
2991 | |
2961 | if (from && from->seg == over) |
2992 | if (from && from == over) |
2962 | { |
2993 | { |
2963 | return INT_MAX; |
2994 | return INT_MAX; |
2964 | } |
2995 | } |
2965 | |
2996 | |
2966 | if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist)) |
2997 | if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist)) |
… | |
… | |
3009 | } |
3040 | } |
3010 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
3041 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
3011 | |
3042 | |
3012 | |
3043 | |
3013 | |
3044 | |
|
|
3045 | // sharp turn penalty ------------ |
|
|
3046 | // sharp turn penalty ------------ |
|
|
3047 | if (from) |
|
|
3048 | { |
|
|
3049 | int delta = 0; |
|
|
3050 | |
|
|
3051 | if (from->end == over->end) |
|
|
3052 | { |
|
|
3053 | // c_start_plus_1 |
|
|
3054 | //delta = from->data.angle_end - over->data.angle_end + 180; |
|
|
3055 | } |
|
|
3056 | else if (from->start == over->end) |
|
|
3057 | { |
|
|
3058 | //delta = from->data.angle_start - over->data.angle_end; |
|
|
3059 | } |
|
|
3060 | else if (from->end == over->start) |
|
|
3061 | { |
|
|
3062 | //delta = from->data.angle_end - over->data.angle_start; |
|
|
3063 | } |
|
|
3064 | else if (from->start == over->start) |
|
|
3065 | { |
|
|
3066 | //delta = from->data.angle_start - over->data.angle_start - 180; |
|
|
3067 | } |
|
|
3068 | |
|
|
3069 | if (delta < -180) |
|
|
3070 | { |
|
|
3071 | delta += 360; |
|
|
3072 | } |
|
|
3073 | |
|
|
3074 | if (delta > 180) |
|
|
3075 | { |
|
|
3076 | delta -= 360; |
|
|
3077 | } |
|
|
3078 | |
|
|
3079 | #define TURN_ANGLE_THRESHOLD 95 |
|
|
3080 | |
|
|
3081 | if (abs(delta) > TURN_ANGLE_THRESHOLD) // threshold |
|
|
3082 | { |
|
|
3083 | /* add 2 tenths of a second per degree above threshold */ |
|
|
3084 | ret = ret + abs(delta - TURN_ANGLE_THRESHOLD) + abs(delta - TURN_ANGLE_THRESHOLD); |
|
|
3085 | } |
|
|
3086 | } |
|
|
3087 | // sharp turn penalty ------------ |
|
|
3088 | // sharp turn penalty ------------ |
|
|
3089 | |
|
|
3090 | |
|
|
3091 | |
3014 | if (ret == INT_MAX) |
3092 | if (ret == INT_MAX) |
3015 | { |
3093 | { |
3016 | return ret; |
3094 | return ret; |
3017 | } |
3095 | } |
3018 | |
3096 | |
|
|
3097 | if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from)) |
|
|
3098 | { |
|
|
3099 | ret += profile->through_traffic_penalty; |
|
|
3100 | } |
|
|
3101 | |
|
|
3102 | // calc delay from traffic lights |
|
|
3103 | if ((from) && (global_traffic_light_delay > 0)) |
|
|
3104 | { |
|
|
3105 | |
|
|
3106 | // fix this later |
|
|
3107 | |
|
|
3108 | // if (from->flags & RP_TRAFFIC_LIGHT) |
|
|
3109 | // { |
|
|
3110 | // dbg(0, "traffic light delay:%d w/o:%d\n", (ret+global_traffic_light_delay), ret); |
|
|
3111 | // in 1/10 of a second !! |
|
|
3112 | // ret += global_traffic_light_delay; |
|
|
3113 | // } |
|
|
3114 | } |
|
|
3115 | |
|
|
3116 | return ret; |
|
|
3117 | } |
|
|
3118 | |
|
|
3119 | |
|
|
3120 | #if 0 |
|
|
3121 | // !!was for dijkstra reverse!! |
|
|
3122 | static int route_value_seg_r(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir) |
|
|
3123 | { |
|
|
3124 | //// dbg(0, "enter\n"); |
|
|
3125 | |
|
|
3126 | int ret; |
|
|
3127 | struct route_traffic_distortion dist, *distp = NULL; |
|
|
3128 | |
|
|
3129 | #if 0 |
|
|
3130 | dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask, profile->flags); |
|
|
3131 | #endif |
|
|
3132 | |
|
|
3133 | //dbg(0, "over data fl = %x\n", over->data.flags); |
|
|
3134 | if ((over->data.flags & (dir >= 0 ? route_get_real_oneway_mask(over->data.flags, profile->flags_forward_mask) : route_get_real_oneway_mask(over->data.flags, profile->flags_reverse_mask))) != profile->flags) |
|
|
3135 | { |
|
|
3136 | //dbg(0, "one way:001: INT_MAX\n"); |
|
|
3137 | return INT_MAX; |
|
|
3138 | } |
|
|
3139 | |
|
|
3140 | if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION)) |
|
|
3141 | { |
|
|
3142 | return INT_MAX; |
|
|
3143 | } |
|
|
3144 | |
|
|
3145 | if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) |
|
|
3146 | { |
|
|
3147 | return INT_MAX; |
|
|
3148 | } |
|
|
3149 | |
|
|
3150 | if (from && from->seg_rev == over) |
|
|
3151 | { |
|
|
3152 | return INT_MAX; |
|
|
3153 | } |
|
|
3154 | |
|
|
3155 | if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist)) |
|
|
3156 | { |
|
|
3157 | distp = &dist; |
|
|
3158 | } |
|
|
3159 | |
|
|
3160 | ret = route_time_seg(profile, &over->data, distp); |
|
|
3161 | |
|
|
3162 | |
|
|
3163 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
|
|
3164 | struct roadprofile *roadprofile = vehicleprofile_get_roadprofile(profile, (&over->data)->item.type); |
|
|
3165 | |
|
|
3166 | if (!roadprofile || !roadprofile->route_prio_weight) |
|
|
3167 | { |
|
|
3168 | } |
|
|
3169 | else |
|
|
3170 | { |
|
|
3171 | // cycle track is the same as real cycleway, its not on the road! |
|
|
3172 | if ((over->data.flags & NAVIT_AF_BICYCLE_TRACK) && ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))) |
|
|
3173 | { |
|
|
3174 | roadprofile = vehicleprofile_get_roadprofile(profile, type_cycleway); |
|
|
3175 | if ((roadprofile) && (roadprofile->route_prio_weight)) |
|
|
3176 | { |
|
|
3177 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3178 | } |
|
|
3179 | else |
|
|
3180 | { |
|
|
3181 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3182 | } |
|
|
3183 | } |
|
|
3184 | else if ((over->data.flags & NAVIT_AF_BICYCLE_LANE) && ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))) |
|
|
3185 | { |
|
|
3186 | // road with cyclelane is a bit better than normal road! |
|
|
3187 | ret = (int)( (float)ret * ((float)(roadprofile->route_prio_weight - global_cycle_lanes_prio) / 10.0f )); |
|
|
3188 | } |
|
|
3189 | else |
|
|
3190 | { |
|
|
3191 | //dbg(0, "ret =%d w=%d\n", ret, roadprofile->route_prio_weight); |
|
|
3192 | //int ret2 = ( ret * 100 * (roadprofile->route_prio_weight * 10.0 ) / 10000); |
|
|
3193 | //dbg(0, "ret2 new=%d\n", ret2); |
|
|
3194 | |
|
|
3195 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3196 | //dbg(0, "ret new=%d\n", ret); |
|
|
3197 | } |
|
|
3198 | } |
|
|
3199 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
|
|
3200 | |
|
|
3201 | |
|
|
3202 | |
|
|
3203 | if (ret == INT_MAX) |
|
|
3204 | { |
|
|
3205 | return ret; |
|
|
3206 | } |
|
|
3207 | |
3019 | if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from->seg)) |
3208 | if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from->seg_rev)) |
3020 | { |
3209 | { |
3021 | ret += profile->through_traffic_penalty; |
3210 | ret += profile->through_traffic_penalty; |
3022 | } |
3211 | } |
3023 | |
3212 | |
3024 | // calc delay from traffic lights |
3213 | // calc delay from traffic lights |
… | |
… | |
3032 | } |
3221 | } |
3033 | } |
3222 | } |
3034 | |
3223 | |
3035 | return ret; |
3224 | return ret; |
3036 | } |
3225 | } |
3037 | |
3226 | // !!was for dijkstra reverse!! |
3038 | |
|
|
3039 | |
|
|
3040 | static int route_value_seg_r(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir) |
|
|
3041 | { |
|
|
3042 | //// dbg(0, "enter\n"); |
|
|
3043 | |
|
|
3044 | int ret; |
|
|
3045 | struct route_traffic_distortion dist, *distp = NULL; |
|
|
3046 | |
|
|
3047 | #if 0 |
|
|
3048 | dbg(0,"flags 0x%x mask 0x%x flags 0x%x\n", over->flags, dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask, profile->flags); |
|
|
3049 | #endif |
3227 | # endif |
3050 | |
|
|
3051 | //dbg(0, "over data fl = %x\n", over->data.flags); |
|
|
3052 | if ((over->data.flags & (dir >= 0 ? route_get_real_oneway_mask(over->data.flags, profile->flags_forward_mask) : route_get_real_oneway_mask(over->data.flags, profile->flags_reverse_mask))) != profile->flags) |
|
|
3053 | { |
|
|
3054 | //dbg(0, "one way:001: INT_MAX\n"); |
|
|
3055 | return INT_MAX; |
|
|
3056 | } |
|
|
3057 | |
|
|
3058 | if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION)) |
|
|
3059 | { |
|
|
3060 | return INT_MAX; |
|
|
3061 | } |
|
|
3062 | |
|
|
3063 | if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) |
|
|
3064 | { |
|
|
3065 | return INT_MAX; |
|
|
3066 | } |
|
|
3067 | |
|
|
3068 | if (from && from->seg_rev == over) |
|
|
3069 | { |
|
|
3070 | return INT_MAX; |
|
|
3071 | } |
|
|
3072 | |
|
|
3073 | if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist)) |
|
|
3074 | { |
|
|
3075 | distp = &dist; |
|
|
3076 | } |
|
|
3077 | |
|
|
3078 | ret = route_time_seg(profile, &over->data, distp); |
|
|
3079 | |
|
|
3080 | |
|
|
3081 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
|
|
3082 | struct roadprofile *roadprofile = vehicleprofile_get_roadprofile(profile, (&over->data)->item.type); |
|
|
3083 | |
|
|
3084 | if (!roadprofile || !roadprofile->route_prio_weight) |
|
|
3085 | { |
|
|
3086 | } |
|
|
3087 | else |
|
|
3088 | { |
|
|
3089 | // cycle track is the same as real cycleway, its not on the road! |
|
|
3090 | if ((over->data.flags & NAVIT_AF_BICYCLE_TRACK) && ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))) |
|
|
3091 | { |
|
|
3092 | roadprofile = vehicleprofile_get_roadprofile(profile, type_cycleway); |
|
|
3093 | if ((roadprofile) && (roadprofile->route_prio_weight)) |
|
|
3094 | { |
|
|
3095 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3096 | } |
|
|
3097 | else |
|
|
3098 | { |
|
|
3099 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3100 | } |
|
|
3101 | } |
|
|
3102 | else if ((over->data.flags & NAVIT_AF_BICYCLE_LANE) && ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))) |
|
|
3103 | { |
|
|
3104 | // road with cyclelane is a bit better than normal road! |
|
|
3105 | ret = (int)( (float)ret * ((float)(roadprofile->route_prio_weight - global_cycle_lanes_prio) / 10.0f )); |
|
|
3106 | } |
|
|
3107 | else |
|
|
3108 | { |
|
|
3109 | //dbg(0, "ret =%d w=%d\n", ret, roadprofile->route_prio_weight); |
|
|
3110 | //int ret2 = ( ret * 100 * (roadprofile->route_prio_weight * 10.0 ) / 10000); |
|
|
3111 | //dbg(0, "ret2 new=%d\n", ret2); |
|
|
3112 | |
|
|
3113 | ret = (int)( (float)ret * ((float)roadprofile->route_prio_weight / 10.0f )); |
|
|
3114 | //dbg(0, "ret new=%d\n", ret); |
|
|
3115 | } |
|
|
3116 | } |
|
|
3117 | // add new "route_prio_weight" attr here ---------------------------------------------------------- |
|
|
3118 | |
|
|
3119 | |
|
|
3120 | |
|
|
3121 | if (ret == INT_MAX) |
|
|
3122 | { |
|
|
3123 | return ret; |
|
|
3124 | } |
|
|
3125 | |
|
|
3126 | if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from->seg_rev)) |
|
|
3127 | { |
|
|
3128 | ret += profile->through_traffic_penalty; |
|
|
3129 | } |
|
|
3130 | |
|
|
3131 | // calc delay from traffic lights |
|
|
3132 | if ((from) && (global_traffic_light_delay > 0)) |
|
|
3133 | { |
|
|
3134 | if (from->flags & RP_TRAFFIC_LIGHT) |
|
|
3135 | { |
|
|
3136 | // dbg(0, "traffic light delay:%d w/o:%d\n", (ret+global_traffic_light_delay), ret); |
|
|
3137 | // in 1/10 of a second !! |
|
|
3138 | ret += global_traffic_light_delay; |
|
|
3139 | } |
|
|
3140 | } |
|
|
3141 | |
|
|
3142 | return ret; |
|
|
3143 | } |
|
|
3144 | |
|
|
3145 | |
|
|
3146 | |
3228 | |
3147 | |
3229 | |
3148 | /** |
3230 | /** |
3149 | * @brief Adds a traffic light item to the route graph |
3231 | * @brief Adds a traffic light item to the route graph |
3150 | * |
3232 | * |
… | |
… | |
4041 | |
4123 | |
4042 | /** |
4124 | /** |
4043 | * @brief Calculates the routing costs for each point |
4125 | * @brief Calculates the routing costs for each point |
4044 | * |
4126 | * |
4045 | * This function is the heart of routing. It assigns each point in the route graph a |
4127 | * This function is the heart of routing. It assigns each point in the route graph a |
4046 | * cost at which one can reach the destination from this point on. Additionally it assigns |
4128 | * cost at which one can reach the destination from this point on. |
4047 | * each point a segment one should follow from this point on to reach the destination at the |
|
|
4048 | * stated costs. |
|
|
4049 | * |
4129 | * |
4050 | * elements are: seg, value |
4130 | * elements are: seg, value |
4051 | * |
4131 | * |
4052 | * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look |
4132 | * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look |
4053 | * at this algorithm. |
4133 | * at this algorithm. |
… | |
… | |
4063 | |
4143 | |
4064 | struct route_graph_point *p_min = NULL; |
4144 | struct route_graph_point *p_min = NULL; |
4065 | struct route_graph_segment *s = NULL; |
4145 | struct route_graph_segment *s = NULL; |
4066 | int min, new, old, val; |
4146 | int min, new, old, val; |
4067 | int turn_angle; |
4147 | int turn_angle; |
4068 | struct fibheap *heap; /* This heap will hold all points with "temporarily" calculated costs */ |
4148 | struct fibheap *heap; /* This heap will hold segments with "temporarily" calculated costs */ |
4069 | |
4149 | |
4070 | heap = fh_makekeyheap(); |
4150 | heap = fh_makekeyheap(); |
4071 | |
4151 | |
4072 | // start from "wanted destination" and loop until "start position" is reached |
4152 | // start from "wanted destination" and loop until "start position" is reached |
4073 | |
4153 | |
4074 | clock_t s_ = debug_measure_start(); |
4154 | clock_t s_ = debug_measure_start(); |
4075 | |
4155 | |
|
|
4156 | struct route_graph_segment *pos_segment = NULL; |
|
|
4157 | struct route_graph_segment *s_min = NULL; |
|
|
4158 | int edges_count = 0; |
|
|
4159 | int max_cost = INT_MAX; |
4076 | |
4160 | |
4077 | #ifndef NAVIT_ROUTE_DIJKSTRA_REVERSE // NAVIT_ROUTE_DIJKSTRA_REVERSE == 0 |
4161 | pos_segment = route_graph_get_segment(this, pos->street, pos_segment); |
|
|
4162 | |
|
|
4163 | |
4078 | |
4164 | |
4079 | // calc segments lengths and values ------------ |
4165 | // calc segments lengths and values ------------ |
4080 | // loop over all segments that connect to the destination street ONLY !! |
4166 | // loop over all segments that connect to the destination street ONLY !! |
4081 | // calc segments lengths and values ------------ |
4167 | // calc segments lengths and values ------------ |
4082 | // ------- |
4168 | // ------- |
4083 | dbg(0, "RR_SEG_DEBUG:001\n"); |
4169 | // dbg(0, "RR_SEG_DEBUG:001\n"); |
4084 | while ((s = route_graph_get_segment(this, dst->street, s))) |
4170 | while ((s = route_graph_get_segment(this, dst->street, s))) |
4085 | { |
4171 | { |
4086 | dbg(0, "RR_SEG_DEBUG:002:1:s=%p\n", s); |
4172 | // dbg(0, "RR_SEG_DEBUG:002:1:s=%p\n", s); |
4087 | val = route_value_seg(profile, NULL, s, -1); |
4173 | val = route_value_seg(profile, NULL, s, -1); |
4088 | dbg(0, "RR_SEG_DEBUG:002:2:val=%d\n", val); |
4174 | // dbg(0, "RR_SEG_DEBUG:002:2:val=%d\n", val); |
4089 | if (val != INT_MAX) |
4175 | if (val != INT_MAX) |
4090 | { |
4176 | { |
4091 | val = val * (100 - dst->percent) / 100; |
4177 | val = val * (100 - dst->percent) / 100; |
4092 | dbg(0, "RR_SEG_DEBUG:002:P=%p dst->percent=%d val=%d end value=%d\n", s->end, dst->percent, val, s->end->value); |
4178 | // dbg(0, "RR_SEG_DEBUG:002:P=%p dst->percent=%d val=%d end value=%d\n", s->end, dst->percent, val, s->end->value); |
4093 | s->end->seg = s; // set segment "s" to be used to drive to dest. at point "s->end" |
4179 | s->seg_end_out_cost = val; |
4094 | s->end->value = val; // set value to point "s->end" |
|
|
4095 | s->end->el = fh_insertkey(heap, s->end->value, s->end); |
4180 | s->el_end = fh_insertkey(heap, val, s); |
4096 | } |
4181 | } |
4097 | |
4182 | |
|
|
4183 | // dbg(0,"check destination segment end , val =%i, est_time = %i\n",val, 0); |
4098 | val = route_value_seg(profile, NULL, s, 1); |
4184 | val = route_value_seg(profile, NULL, s, 1); |
4099 | dbg(0, "RR_SEG_DEBUG:003:3:val=%d\n", val); |
4185 | // dbg(0, "RR_SEG_DEBUG:003:3:val=%d\n", val); |
4100 | if (val != INT_MAX) |
4186 | if (val != INT_MAX) |
4101 | { |
4187 | { |
4102 | val = val * dst->percent / 100; |
4188 | val = val * dst->percent / 100; |
4103 | dbg(0, "RR_SEG_DEBUG:003:P=%p dst->percent=%d val=%d start value=%d\n", s->start, dst->percent, val, s->start->value); |
4189 | // dbg(0, "RR_SEG_DEBUG:003:P=%p dst->percent=%d val=%d start value=%d\n", s->start, dst->percent, val, s->start->value); |
4104 | s->start->seg = s; // set segment "s" to be used to drive to dest. at point "s->start" |
4190 | s->seg_start_out_cost = val; |
4105 | s->start->value = val; // set value to point "s->start" |
4191 | s->el_start=fh_insertkey(heap, val, s); |
4106 | s->start->el = fh_insertkey(heap, s->start->value, s->start); |
|
|
4107 | } |
4192 | } |
4108 | dbg(0, "RR_SEG_DEBUG:009:9:val=%d\n", val); |
4193 | //dbg(0, "RR_SEG_DEBUG:009:9:val=%d\n", val); |
4109 | } |
4194 | } |
4110 | dbg(0, "RR_SEG_DEBUG:090\n"); |
4195 | // dbg(0, "RR_SEG_DEBUG:090\n"); |
4111 | // ------- |
4196 | // ------- |
4112 | // calc segments lengths and values ------------ |
4197 | // calc segments lengths and values ------------ |
4113 | // calc segments lengths and values ------------ |
4198 | // calc segments lengths and values ------------ |
4114 | |
4199 | |
4115 | |
4200 | |
4116 | debug_mrp("RR_TIM:g:002", debug_measure_end(s_)); |
4201 | debug_mrp("RR_TIM:g:002", debug_measure_end(s_)); |
4117 | // dbg(0, "RR_TIM:g:002 %s\n"); |
4202 | // dbg(0, "RR_TIM:g:002 %s\n"); |
4118 | |
4203 | |
4119 | |
4204 | |
4120 | |
4205 | |
4121 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4122 | route_clear_sharp_turn_list(); |
|
|
4123 | #endif |
|
|
4124 | struct coord ccc_cc; |
|
|
4125 | struct coord ccc_ss; |
|
|
4126 | struct coord ccc_ee; |
|
|
4127 | |
|
|
4128 | int val_sharp_turn = INT_MAX; |
|
|
4129 | int dir2 = 1; |
|
|
4130 | |
|
|
4131 | s_ = debug_measure_start(); |
4206 | s_ = debug_measure_start(); |
4132 | |
4207 | |
4133 | // start Dijkstra here ------------ |
4208 | // start Dijkstra here ------------ |
4134 | // start Dijkstra here ------------ |
4209 | // start Dijkstra here ------------ |
4135 | for (;;) |
4210 | for (;;) |
4136 | { |
4211 | { |
4137 | p_min = fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */ |
4212 | s_min = fh_extractmin(heap); |
4138 | // starts with the point that has the least cost to reach the destination! |
|
|
4139 | |
4213 | |
4140 | if (!p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */ |
4214 | if (!s_min) |
4141 | { |
4215 | { |
4142 | break; |
4216 | break; |
4143 | } |
4217 | } |
4144 | |
4218 | |
4145 | min = p_min->value; |
4219 | if (s_min->el_end) |
4146 | //if (debug_route) |
|
|
4147 | //{ |
4220 | { |
4148 | // printf("extract p=%p free el=%p min=%d, 0x%x, 0x%x\n", p_min, p_min->el, min, p_min->c.x, p_min->c.y); |
4221 | min = s_min->seg_end_out_cost; |
|
|
4222 | if (s_min->el_start && (s_min->seg_start_out_cost < min)) |
|
|
4223 | { |
|
|
4224 | min = s_min->seg_start_out_cost; |
|
|
4225 | p_min = s_min->start; |
|
|
4226 | s_min->el_start = NULL; |
|
|
4227 | } |
|
|
4228 | else |
|
|
4229 | { |
|
|
4230 | p_min = s_min->end; |
|
|
4231 | s_min->el_end = NULL; |
|
|
4232 | } |
4149 | //} |
4233 | } |
|
|
4234 | else |
|
|
4235 | { |
|
|
4236 | min = s_min->seg_start_out_cost; |
|
|
4237 | p_min = s_min->start; |
|
|
4238 | s_min->el_start = NULL; |
|
|
4239 | } |
4150 | |
4240 | |
4151 | p_min->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */ |
|
|
4152 | |
4241 | |
4153 | s = p_min->start; // route_graph_point "p_min": "s" = first route_graph_segment in the list of segments that start at point "p_min" |
4242 | s = p_min->start; |
4154 | |
4243 | |
4155 | while (s) |
4244 | while (s) |
4156 | { /* Iterating all the segments leading away from our point to update the points at their ends */ |
4245 | { /* Iterating all the segments leading away from our point to update the points at their ends */ |
|
|
4246 | edges_count++; |
4157 | val = route_value_seg(profile, p_min, s, -1); |
4247 | val = route_value_seg(profile, s_min, s, -1); |
4158 | if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg->data.item)) |
4248 | if (val != INT_MAX && item_is_equal(s->data.item,s_min->data.item)) |
4159 | { |
4249 | { |
4160 | |
4250 | // if (profile->turn_around_penalty2) |
4161 | if (global_avoid_sharp_turns_flag == 91) |
4251 | // { |
|
|
4252 | // val+=profile->turn_around_penalty2; |
|
|
4253 | // } |
|
|
4254 | // else |
4162 | { |
4255 | { |
4163 | // calc "sharp-turn / turnaround" value |
4256 | val=INT_MAX; |
4164 | turn_angle = route_road_to_road_angle_get_segs(s, p_min->seg, -1, &dir2, &ccc_cc, &ccc_ss, &ccc_ee, 1); |
4257 | |
4165 | if (turn_angle < global_avoid_sharp_turns_min_angle) |
4258 | } |
|
|
4259 | } |
|
|
4260 | |
|
|
4261 | if (val != INT_MAX) |
|
|
4262 | { |
|
|
4263 | new=min+val; |
|
|
4264 | if (new < s->seg_end_out_cost) |
|
|
4265 | { |
|
|
4266 | s->seg_end_out_cost = new; |
|
|
4267 | s->start_from_seg = s_min; |
|
|
4268 | |
|
|
4269 | if (!s->el_end) |
4166 | { |
4270 | { |
4167 | // dbg(0, "set turn angle penalty(1)\n"); |
|
|
4168 | val_sharp_turn = val + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4169 | #if 1 |
|
|
4170 | val = val_sharp_turn; |
|
|
4171 | #endif |
|
|
4172 | |
|
|
4173 | //if ((s->end->value + (global_avoid_sharp_turns_min_penalty * turn_angle)) < INT_MAX) |
|
|
4174 | //{ |
|
|
4175 | // s->end->value = s->end->value + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4176 | //} |
|
|
4177 | |
|
|
4178 | |
|
|
4179 | #if 0 |
|
|
4180 | // kill the prev point |
|
|
4181 | if (dir2 == 1) |
|
|
4182 | { |
|
|
4183 | p_min->seg->start->value = p_min->seg->start->value + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4184 | } |
|
|
4185 | else // -1 |
|
|
4186 | { |
|
|
4187 | p_min->seg->end->value = p_min->seg->end->value + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4188 | } |
|
|
4189 | |
|
|
4190 | // now get the seg and value of the next lowest one |
|
|
4191 | // this sets p_min->value und p_min->seg new!! |
|
|
4192 | route_find_next_lowest_segment_and_pin_it(p_min, s, (val_sharp_turn - 1), (global_avoid_sharp_turns_min_penalty * turn_angle)); |
|
|
4193 | #endif |
|
|
4194 | |
|
|
4195 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4196 | // route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, turn_angle, -1); |
|
|
4197 | route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, val, -1); |
|
|
4198 | #endif |
|
|
4199 | } |
|
|
4200 | } |
|
|
4201 | |
|
|
4202 | new = min + val; |
|
|
4203 | //if (debug_route) |
|
|
4204 | //{ |
|
|
4205 | // printf("begin %d len %d vs %d (0x%x,0x%x)\n", new, val, s->end->value, s->end->c.x, s->end->c.y); |
|
|
4206 | //} |
|
|
4207 | |
|
|
4208 | if (new < s->end->value) |
|
|
4209 | { /* We've found a less costly way to reach the end of s, update it */ |
|
|
4210 | s->end->value = new; |
|
|
4211 | s->end->seg = s; |
|
|
4212 | |
|
|
4213 | if (!s->end->el) |
|
|
4214 | { |
|
|
4215 | //if (debug_route) |
|
|
4216 | //{ |
|
|
4217 | // printf("insert_end p=%p el=%p val=%d ", s->end, s->end->el, s->end->value); |
|
|
4218 | //} |
|
|
4219 | |
|
|
4220 | s->end->el = fh_insertkey(heap, new, s->end); |
4271 | s->el_end = fh_insertkey(heap, new, s); |
4221 | |
|
|
4222 | //if (debug_route) |
|
|
4223 | //{ |
|
|
4224 | // printf("el new=%p\n", s->end->el); |
|
|
4225 | //} |
|
|
4226 | } |
4272 | } |
4227 | else |
4273 | else |
4228 | { |
4274 | { |
4229 | //if (debug_route) |
|
|
4230 | //{ |
|
|
4231 | // printf("replace_end p=%p el=%p val=%d\n", s->end, s->end->el, s->end->value); |
|
|
4232 | //} |
|
|
4233 | fh_replacekey(heap, s->end->el, new); |
4275 | fh_replacekey(heap, s->el_end, new); |
4234 | } |
4276 | } |
4235 | } |
4277 | } |
4236 | |
4278 | |
4237 | //if (debug_route) |
4279 | if (item_is_equal(pos_segment->data.item,s->data.item)) |
4238 | //{ |
4280 | { |
4239 | // printf("\n"); |
4281 | max_cost = new; |
|
|
4282 | // dbg(0,"new shortest path cost via end_out= %i\n",new); |
|
|
4283 | // dbg(0,"number of edges visited =%i\n",edges_count); |
4240 | //} |
4284 | } |
4241 | } |
4285 | } |
4242 | s = s->start_next; |
4286 | s = s->start_next; |
4243 | } |
4287 | } |
4244 | |
4288 | |
4245 | s = p_min->end; |
4289 | s = p_min->end; |
4246 | |
4290 | |
4247 | while (s) |
4291 | while (s && max_cost == INT_MAX) |
4248 | { /* Doing the same as above with the segments leading towards our point */ |
4292 | { /* Doing the same as above with the segments leading towards our point */ |
|
|
4293 | edges_count++; |
4249 | val = route_value_seg(profile, p_min, s, 1); |
4294 | val = route_value_seg(profile, s_min, s, 1); |
4250 | if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg->data.item)) |
4295 | if (val != INT_MAX && item_is_equal(s->data.item,s_min->data.item)) |
4251 | { |
4296 | { |
4252 | |
4297 | // if (profile->turn_around_penalty2) |
4253 | if (global_avoid_sharp_turns_flag == 1) // Pr.Strasse.CASE !! |
4298 | // { |
|
|
4299 | // val += profile->turn_around_penalty2; |
|
|
4300 | // } |
|
|
4301 | // else |
4254 | { |
4302 | { |
4255 | // calc "sharp-turn / turnaround" value |
4303 | val=INT_MAX; |
4256 | turn_angle = route_road_to_road_angle_get_segs(s, p_min->seg, 1, &dir2, &ccc_cc, &ccc_ss, &ccc_ee, 1); |
4304 | } |
4257 | if (turn_angle < global_avoid_sharp_turns_min_angle) |
4305 | } |
|
|
4306 | |
|
|
4307 | if (val != INT_MAX) |
|
|
4308 | { |
|
|
4309 | |
|
|
4310 | |
|
|
4311 | |
|
|
4312 | |
|
|
4313 | new = min + val; |
|
|
4314 | |
|
|
4315 | if (new < s->seg_start_out_cost) |
|
|
4316 | { |
|
|
4317 | // old = ... |
|
|
4318 | s->seg_start_out_cost = new; |
|
|
4319 | s->end_from_seg = s_min; |
|
|
4320 | |
|
|
4321 | if (!s->el_start) |
4258 | { |
4322 | { |
4259 | // dbg(0, "set turn angle penalty(2)\n"); |
|
|
4260 | // val_sharp_turn = val + (global_avoid_sharp_turns_min_penalty * turn_angle * 10); |
|
|
4261 | val_sharp_turn = val + 4000; |
|
|
4262 | #if 1 |
|
|
4263 | val = val_sharp_turn; |
|
|
4264 | #endif |
|
|
4265 | //if ((s->start->value + (global_avoid_sharp_turns_min_penalty * turn_angle)) < INT_MAX) |
|
|
4266 | //{ |
|
|
4267 | // s->start->value = s->start->value + (global_avoid_sharp_turns_min_penalty * turn_angle * 10); |
|
|
4268 | //} |
|
|
4269 | |
|
|
4270 | |
|
|
4271 | #if 0 |
|
|
4272 | // kill the prev point |
|
|
4273 | if (dir2 == 1) |
|
|
4274 | { |
|
|
4275 | p_min->seg->end->value = p_min->seg->end->value + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4276 | } |
|
|
4277 | else // -1 |
|
|
4278 | { |
|
|
4279 | p_min->seg->start->value = p_min->seg->start->value + (global_avoid_sharp_turns_min_penalty * turn_angle); |
|
|
4280 | } |
|
|
4281 | |
|
|
4282 | // now get the seg and value of the next lowest one |
|
|
4283 | // this sets p_min->value und p_min->seg new!! |
|
|
4284 | route_find_next_lowest_segment_and_pin_it(p_min, s, (val_sharp_turn - 1), (global_avoid_sharp_turns_min_penalty * turn_angle)); |
|
|
4285 | #endif |
|
|
4286 | |
|
|
4287 | struct coord_geo gg4; |
|
|
4288 | transform_to_geo(projection_mg, &(s->start->c), &gg4); |
|
|
4289 | dbg(0, "ROUTExxPOSxx:sharp_turn:N1:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4290 | transform_to_geo(projection_mg, &(s->end->c), &gg4); |
|
|
4291 | dbg(0, "ROUTExxPOSxx:sharp_turn:N2:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4292 | |
|
|
4293 | transform_to_geo(projection_mg, &(p_min->seg->start->c), &gg4); |
|
|
4294 | dbg(0, "ROUTExxPOSxx:sharp_turn:N3:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4295 | transform_to_geo(projection_mg, &(p_min->seg->end->c), &gg4); |
|
|
4296 | dbg(0, "ROUTExxPOSxx:sharp_turn:N4:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4297 | |
|
|
4298 | transform_to_geo(projection_mg, &ccc_cc, &gg4); |
|
|
4299 | dbg(0, "ROUTExxPOSxx:sharp_turn:C9:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4300 | |
|
|
4301 | dbg(0, "ROUTExxPOSxx:sharp_turn:S-start:v=%d:%d %d\n", (min + val), s->start->c.x, s->start->c.y); |
|
|
4302 | dbg(0, "ROUTExxPOSxx:sharp_turn:S-end:v=%d:%d %d\n", (min + val), s->end->c.x, s->end->c.y); |
|
|
4303 | dbg(0, "ROUTExxPOSxx:sharp_turn:A-center:v=%d:%d %d\n", (min + val), ccc_cc.x, ccc_cc.y); |
|
|
4304 | |
|
|
4305 | |
|
|
4306 | dbg(0, "ROUTExxPOSxx:sharp_turn:xxxxxxxxxxxxxxxxxxxxx\n"); |
|
|
4307 | |
|
|
4308 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4309 | route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, turn_angle, 1); |
|
|
4310 | // route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, val, 1); |
|
|
4311 | #endif |
|
|
4312 | } |
|
|
4313 | } |
|
|
4314 | |
|
|
4315 | new = min + val; |
|
|
4316 | //if (debug_route) |
|
|
4317 | //{ |
|
|
4318 | // printf("end %d len %d vs %d (0x%x,0x%x)\n", new, val, s->start->value, s->start->c.x, s->start->c.y); |
|
|
4319 | //} |
|
|
4320 | |
|
|
4321 | if (new < s->start->value) |
|
|
4322 | { |
|
|
4323 | old = s->start->value; |
|
|
4324 | s->start->value = new; |
|
|
4325 | s->start->seg = s; |
|
|
4326 | |
|
|
4327 | if (!s->start->el) |
|
|
4328 | { |
|
|
4329 | //if (debug_route) |
|
|
4330 | //{ |
|
|
4331 | // printf("insert_start p=%p el=%p val=%d ", s->start, s->start->el, s->start->value); |
|
|
4332 | //} |
|
|
4333 | s->start->el = fh_insertkey(heap, new, s->start); |
4323 | s->el_start = fh_insertkey(heap, new, s); |
4334 | //if (debug_route) |
|
|
4335 | //{ |
|
|
4336 | // printf("el new=%p\n", s->start->el); |
|
|
4337 | //} |
|
|
4338 | } |
4324 | } |
4339 | else |
4325 | else |
4340 | { |
4326 | { |
4341 | //if (debug_route) |
4327 | //if (debug_route) |
4342 | //{ |
4328 | //{ |
4343 | // printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value); |
4329 | // printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value); |
4344 | //} |
4330 | //} |
4345 | fh_replacekey(heap, s->start->el, new); |
4331 | fh_replacekey(heap, s->el_start, new); |
4346 | } |
4332 | } |
4347 | } |
4333 | } |
4348 | //if (debug_route) |
4334 | |
|
|
4335 | if (item_is_equal(pos_segment->data.item, s->data.item)) |
4349 | //{ |
4336 | { |
4350 | // printf("\n"); |
4337 | max_cost = new; |
|
|
4338 | // dbg(0,"new shortest path cost via start_out= %i\n",new); |
|
|
4339 | // dbg(0,"number of edges visited =%i\n",edges_count); |
4351 | //} |
4340 | } |
4352 | } |
4341 | } |
4353 | s = s->end_next; |
4342 | s = s->end_next; |
4354 | } |
4343 | } |
4355 | } |
4344 | } |
4356 | |
4345 | // dbg(0,"number of edges visited =%i\n",edges_count); |
4357 | |
|
|
4358 | |
|
|
4359 | |
|
|
4360 | #else // NAVIT_ROUTE_DIJKSTRA_REVERSE == 1 |
|
|
4361 | |
|
|
4362 | p_min = NULL; |
|
|
4363 | s = NULL; |
|
|
4364 | |
|
|
4365 | struct route_graph_segment *s_pos = NULL; |
|
|
4366 | |
|
|
4367 | dbg(0, "RR_SEG_DEBUG:001\n"); |
|
|
4368 | while ((s = route_graph_get_segment(this, pos->street, s))) |
|
|
4369 | { |
|
|
4370 | dbg(0, "RR_SEG_DEBUG:002:1:s=%p\n", s); |
|
|
4371 | |
|
|
4372 | s_pos = s; |
|
|
4373 | |
|
|
4374 | val = route_value_seg_r(profile, NULL, s, 1); |
|
|
4375 | dbg(0, "RR_SEG_DEBUG:002:2:val=%d\n", val); |
|
|
4376 | if (val != INT_MAX) |
|
|
4377 | { |
|
|
4378 | val = val * (100 - pos->percent) / 100; |
|
|
4379 | if (val < 1) |
|
|
4380 | { |
|
|
4381 | val = 1; |
|
|
4382 | } |
|
|
4383 | dbg(0, "RR_SEG_DEBUG:002:P=%p pos->percent=%d val=%d end value=%d\n", s->end, pos->percent, val, s->end->value); |
|
|
4384 | s->end->seg = s; // set segment "s" to be used to drive to dest. at point "s->end" |
|
|
4385 | s->end->seg_rev = s; |
|
|
4386 | s->end->value = val; // set value to point "s->end" |
|
|
4387 | s->end->el = fh_insertkey(heap, s->end->value, s->end); |
|
|
4388 | dbg(0, "RR_SEG_DEBUG:002:EL:el=%p\n", s->end->el); |
|
|
4389 | } |
|
|
4390 | |
|
|
4391 | val = route_value_seg_r(profile, NULL, s, -1); |
|
|
4392 | dbg(0, "RR_SEG_DEBUG:003:3:val=%d\n", val); |
|
|
4393 | if (val != INT_MAX) |
|
|
4394 | { |
|
|
4395 | val = val * pos->percent / 100; |
|
|
4396 | if (val < 1) |
|
|
4397 | { |
|
|
4398 | val = 1; |
|
|
4399 | } |
|
|
4400 | dbg(0, "RR_SEG_DEBUG:003:P=%p pos->percent=%d val=%d start value=%d\n", s->start, pos->percent, val, s->start->value); |
|
|
4401 | s->start->seg = s; // set segment "s" to be used to drive to dest. at point "s->start" |
|
|
4402 | s->start->seg_rev = s; |
|
|
4403 | s->start->value = val; // set value to point "s->start" |
|
|
4404 | s->start->el = fh_insertkey(heap, s->start->value, s->start); |
|
|
4405 | dbg(0, "RR_SEG_DEBUG:003:EL:el=%p\n", s->start->el); |
|
|
4406 | } |
|
|
4407 | dbg(0, "RR_SEG_DEBUG:009:9:val=%d\n", val); |
|
|
4408 | } |
|
|
4409 | dbg(0, "RR_SEG_DEBUG:090\n"); |
|
|
4410 | |
|
|
4411 | |
|
|
4412 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4413 | route_clear_sharp_turn_list(); |
|
|
4414 | #endif |
|
|
4415 | struct coord ccc_cc; |
|
|
4416 | struct coord ccc_ss; |
|
|
4417 | struct coord ccc_ee; |
|
|
4418 | |
|
|
4419 | int val_sharp_turn = INT_MAX; |
|
|
4420 | int dir2 = 1; |
|
|
4421 | |
|
|
4422 | s_ = debug_measure_start(); |
|
|
4423 | |
|
|
4424 | int start_dijkstra_loop = 1; |
|
|
4425 | |
|
|
4426 | // start (REVERSED-)Dijkstra here ------------ |
|
|
4427 | // start (REVERSED-)Dijkstra here ------------ |
|
|
4428 | dbg(0, "RR_SEG_DEBUG:R-DIJK-START\n"); |
|
|
4429 | for (;;) |
|
|
4430 | { |
|
|
4431 | |
|
|
4432 | dbg(0, "RR_SEG_DEBUG:LOOP:start\n"); |
|
|
4433 | |
|
|
4434 | p_min = fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */ |
|
|
4435 | // starts with the point that has the least cost to reach the destination! |
|
|
4436 | |
|
|
4437 | |
|
|
4438 | if (!p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */ |
|
|
4439 | { |
|
|
4440 | dbg(0, "RR_SEG_DEBUG:BREAK:p_min=%p\n", p_min); |
|
|
4441 | break; |
|
|
4442 | } |
|
|
4443 | else |
|
|
4444 | { |
|
|
4445 | dbg(0, "RR_SEG_DEBUG:LOOP:p_min=%p v=%d el=%p\n", p_min, p_min->value, p_min->el); |
|
|
4446 | } |
|
|
4447 | |
|
|
4448 | // min = p_min->value; |
|
|
4449 | if (p_min->seg_rev) |
|
|
4450 | { |
|
|
4451 | int dir_from_seg = route_find_seg_dir_at_point(p_min, p_min->seg_rev); |
|
|
4452 | |
|
|
4453 | if (dir_from_seg == 1) |
|
|
4454 | { |
|
|
4455 | min = p_min->seg_rev->end->value; |
|
|
4456 | } |
|
|
4457 | else |
|
|
4458 | { |
|
|
4459 | min = p_min->seg_rev->start->value; |
|
|
4460 | } |
|
|
4461 | } |
|
|
4462 | else |
|
|
4463 | { |
|
|
4464 | min = INT_MAX; |
|
|
4465 | dbg(0, "RR_SEG_DEBUG:p_min->seg_rev == NULL !!!\n"); |
|
|
4466 | } |
|
|
4467 | |
|
|
4468 | if (start_dijkstra_loop == 1) |
|
|
4469 | { |
|
|
4470 | start_dijkstra_loop = 0; |
|
|
4471 | min = 2; |
|
|
4472 | } |
|
|
4473 | |
|
|
4474 | dbg(0, "RR_SEG_DEBUG:new min=%d\n", min); |
|
|
4475 | |
|
|
4476 | p_min->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */ |
|
|
4477 | |
|
|
4478 | s = p_min->start; // route_graph_point "p_min": "s" = first route_graph_segment in the list of segments that start at point "p_min" |
|
|
4479 | |
|
|
4480 | while (s) |
|
|
4481 | { |
|
|
4482 | /* Iterating all the segments leading away from our point to update the points at their ends */ |
|
|
4483 | val = route_value_seg_r(profile, p_min, s, 1); |
|
|
4484 | |
|
|
4485 | dbg(0, "RR_SEG_DEBUG:LOOP-1:s=%p p_min=%p p_min->seg_rev=%p v=%d\n", s, p_min, p_min->seg_rev, val); |
|
|
4486 | |
|
|
4487 | if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg_rev->data.item)) |
|
|
4488 | { |
|
|
4489 | |
|
|
4490 | if (global_avoid_sharp_turns_flag == 1) |
|
|
4491 | { |
|
|
4492 | // calc "sharp-turn / turnaround" value |
|
|
4493 | turn_angle = route_road_to_road_angle_get_segs(s, p_min->seg_rev, -1, &dir2, &ccc_cc, &ccc_ss, &ccc_ee, 1); |
|
|
4494 | if (turn_angle < global_avoid_sharp_turns_min_angle) |
|
|
4495 | { |
|
|
4496 | // dbg(0, "set turn angle penalty(1)\n"); |
|
|
4497 | dbg(0, "RR_SEG_DEBUG:LOOP-1:turn angle=%d\n", turn_angle); |
|
|
4498 | |
|
|
4499 | val_sharp_turn = val + (global_avoid_sharp_turns_min_penalty * ((global_avoid_sharp_turns_min_angle + 10) - turn_angle)); |
|
|
4500 | #if 1 |
|
|
4501 | val = val_sharp_turn; |
|
|
4502 | #endif |
|
|
4503 | |
|
|
4504 | |
|
|
4505 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4506 | route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, turn_angle, -1); |
|
|
4507 | // route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, val, -1); |
|
|
4508 | #endif |
|
|
4509 | } |
|
|
4510 | } |
|
|
4511 | |
|
|
4512 | new = min + val; |
|
|
4513 | |
|
|
4514 | int val_cmp = s->start->value; |
|
|
4515 | if (s_pos->start == s->start) |
|
|
4516 | { |
|
|
4517 | val_cmp = INT_MAX; |
|
|
4518 | } |
|
|
4519 | |
|
|
4520 | dbg(0, "RR_SEG_DEBUG:LOOP-1:new=%d min=%d sv=%d val_cmp=%d p_min->el=%d p_min=%p\n", new, min, s->start->value, val_cmp, p_min->el, p_min); |
|
|
4521 | |
|
|
4522 | |
|
|
4523 | if (new < val_cmp) |
|
|
4524 | { |
|
|
4525 | |
|
|
4526 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x001\n"); |
|
|
4527 | /* We've found a less costly way to reach the end of s, update it */ |
|
|
4528 | s->start->value = new; |
|
|
4529 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x002\n"); |
|
|
4530 | s->start->seg = s; |
|
|
4531 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x003\n"); |
|
|
4532 | s->end->seg_rev = s; |
|
|
4533 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x004 heap=%p\n", heap); |
|
|
4534 | |
|
|
4535 | if (!s->end->el) |
|
|
4536 | { |
|
|
4537 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x005\n"); |
|
|
4538 | |
|
|
4539 | s->end->el = fh_insertkey(heap, new, s->end); |
|
|
4540 | dbg(0, "RR_SEG_DEBUG:LOOP-1:insert:s->end->el=%p s->end=%p p_min=%p\n", s->end->el, s->end, p_min); |
|
|
4541 | } |
|
|
4542 | else |
|
|
4543 | { |
|
|
4544 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x006:s->end=%p s->end->el=%p heap=%p p_min=%p new=%d\n", s->end, s->end->el, heap, p_min, new); |
|
|
4545 | |
|
|
4546 | fh_replacekey(heap, s->end->el, new); |
|
|
4547 | dbg(0, "RR_SEG_DEBUG:LOOP-1:repl:x007\n"); |
|
|
4548 | |
|
|
4549 | } |
|
|
4550 | |
|
|
4551 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x008\n"); |
|
|
4552 | |
|
|
4553 | } |
|
|
4554 | |
|
|
4555 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x009\n"); |
|
|
4556 | |
|
|
4557 | } |
|
|
4558 | |
|
|
4559 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x010\n"); |
|
|
4560 | |
|
|
4561 | s = s->start_next; |
|
|
4562 | |
|
|
4563 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x011\n"); |
|
|
4564 | |
|
|
4565 | } |
|
|
4566 | |
|
|
4567 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x012\n"); |
|
|
4568 | |
|
|
4569 | s = p_min->end; |
|
|
4570 | |
|
|
4571 | dbg(0, "RR_SEG_DEBUG:LOOP-1:x013\n"); |
|
|
4572 | |
|
|
4573 | while (s) |
|
|
4574 | { |
|
|
4575 | /* Doing the same as above with the segments leading towards our point */ |
|
|
4576 | val = route_value_seg_r(profile, p_min, s, -1); |
|
|
4577 | |
|
|
4578 | dbg(0, "RR_SEG_DEBUG:LOOP--2:s=%p p_min=%p p_min->seg_rev=%p v=%d\n", s, p_min, p_min->seg_rev, val); |
|
|
4579 | |
|
|
4580 | |
|
|
4581 | if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg_rev->data.item)) |
|
|
4582 | { |
|
|
4583 | |
|
|
4584 | if (global_avoid_sharp_turns_flag == 1) // Pr.Strasse.CASE !! |
|
|
4585 | { |
|
|
4586 | // calc "sharp-turn / turnaround" value |
|
|
4587 | turn_angle = route_road_to_road_angle_get_segs(s, p_min->seg_rev, 1, &dir2, &ccc_cc, &ccc_ss, &ccc_ee, 1); |
|
|
4588 | if (turn_angle < global_avoid_sharp_turns_min_angle) |
|
|
4589 | { |
|
|
4590 | |
|
|
4591 | dbg(0, "RR_SEG_DEBUG:LOOP--2:turn angle=%d\n", turn_angle); |
|
|
4592 | val_sharp_turn = val + (global_avoid_sharp_turns_min_penalty * ((global_avoid_sharp_turns_min_angle + 10) - turn_angle)); |
|
|
4593 | |
|
|
4594 | // val_sharp_turn = val + 4000; |
|
|
4595 | #if 1 |
|
|
4596 | val = val_sharp_turn; |
|
|
4597 | #endif |
|
|
4598 | |
|
|
4599 | #if 0 |
|
|
4600 | struct coord_geo gg4; |
|
|
4601 | transform_to_geo(projection_mg, &(s->start->c), &gg4); |
|
|
4602 | dbg(0, "ROUTExxPOSxx:sharp_turn:N1:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4603 | transform_to_geo(projection_mg, &(s->end->c), &gg4); |
|
|
4604 | dbg(0, "ROUTExxPOSxx:sharp_turn:N2:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4605 | |
|
|
4606 | transform_to_geo(projection_mg, &(p_min->seg_rev->start->c), &gg4); |
|
|
4607 | dbg(0, "ROUTExxPOSxx:sharp_turn:N3:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4608 | transform_to_geo(projection_mg, &(p_min->seg_rev->end->c), &gg4); |
|
|
4609 | dbg(0, "ROUTExxPOSxx:sharp_turn:N4:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4610 | |
|
|
4611 | transform_to_geo(projection_mg, &ccc_cc, &gg4); |
|
|
4612 | dbg(0, "ROUTExxPOSxx:sharp_turn:C9:http://maps.google.com/maps/api/staticmap?size=512x512&markers=color:blue|label:CC|%4.6f,%4.6f\n", gg4.lat, gg4.lng); |
|
|
4613 | |
|
|
4614 | dbg(0, "ROUTExxPOSxx:sharp_turn:S-start:v=%d:%d %d\n", (min + val), s->start->c.x, s->start->c.y); |
|
|
4615 | dbg(0, "ROUTExxPOSxx:sharp_turn:S-end:v=%d:%d %d\n", (min + val), s->end->c.x, s->end->c.y); |
|
|
4616 | dbg(0, "ROUTExxPOSxx:sharp_turn:A-center:v=%d:%d %d\n", (min + val), ccc_cc.x, ccc_cc.y); |
|
|
4617 | |
|
|
4618 | |
|
|
4619 | dbg(0, "ROUTExxPOSxx:sharp_turn:xxxxxxxxxxxxxxxxxxxxx\n"); |
|
|
4620 | #endif |
|
|
4621 | |
|
|
4622 | #ifdef NAVIT_ANGLE_LIST_DEBUG_PRINT_1 |
|
|
4623 | route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, turn_angle, 1); |
|
|
4624 | // route_add_to_sharp_turn_list(&ccc_cc, &ccc_ss, &ccc_ee, val, 1); |
|
|
4625 | #endif |
|
|
4626 | } |
|
|
4627 | } |
|
|
4628 | |
|
|
4629 | new = min + val; |
|
|
4630 | |
|
|
4631 | |
|
|
4632 | int val_cmp = s->end->value; |
|
|
4633 | if (s_pos->end == s->end) |
|
|
4634 | { |
|
|
4635 | val_cmp = INT_MAX; |
|
|
4636 | } |
|
|
4637 | |
|
|
4638 | dbg(0, "RR_SEG_DEBUG:LOOP--2:new=%d min=%d ev=%d val_cmp=%d p_min->el=%d p_min=%p\n", new, min, s->end->value, val_cmp, p_min->el, p_min); |
|
|
4639 | |
|
|
4640 | if (new < val_cmp) |
|
|
4641 | { |
|
|
4642 | old = s->end->value; |
|
|
4643 | s->end->value = new; |
|
|
4644 | s->end->seg = s; |
|
|
4645 | s->start->seg_rev = s; |
|
|
4646 | |
|
|
4647 | if (!s->start->el) |
|
|
4648 | { |
|
|
4649 | s->start->el = fh_insertkey(heap, new, s->start); |
|
|
4650 | dbg(0, "RR_SEG_DEBUG:LOOP--2:insert:s->start->el=%p s->start=%p p_min=%p\n", s->start->el, s->start, p_min); |
|
|
4651 | } |
|
|
4652 | else |
|
|
4653 | { |
|
|
4654 | dbg(0, "RR_SEG_DEBUG:LOOP--2:x006:s->start->el=%p heap=%p p_min=%p\n", s->start->el, heap, p_min); |
|
|
4655 | |
|
|
4656 | fh_replacekey(heap, s->start->el, new); |
|
|
4657 | dbg(0, "RR_SEG_DEBUG:LOOP--2:repl:x007\n"); |
|
|
4658 | } |
|
|
4659 | |
|
|
4660 | |
|
|
4661 | } |
|
|
4662 | |
|
|
4663 | } |
|
|
4664 | |
|
|
4665 | s = s->end_next; |
|
|
4666 | |
|
|
4667 | } |
|
|
4668 | |
|
|
4669 | |
|
|
4670 | } |
|
|
4671 | |
|
|
4672 | |
|
|
4673 | |
|
|
4674 | #endif |
|
|
4675 | |
|
|
4676 | |
|
|
4677 | |
|
|
4678 | |
|
|
4679 | |
|
|
4680 | |
|
|
4681 | |
|
|
4682 | debug_mrp("RR_TIM:g:003", debug_measure_end(s_)); |
4346 | debug_mrp("RR_TIM:g:003", debug_measure_end(s_)); |
4683 | |
4347 | |
4684 | fh_deleteheap(heap); |
4348 | fh_deleteheap(heap); |
4685 | |
4349 | |
4686 | // CB: calls -> "route_path_update_done" !! |
4350 | // CB: calls -> "route_path_update_done" !! |
… | |
… | |
4692 | __F_END__ |
4356 | __F_END__ |
4693 | } |
4357 | } |
4694 | |
4358 | |
4695 | |
4359 | |
4696 | |
4360 | |
4697 | |
4361 | #if 0 |
4698 | void route_find_next_lowest_segment_and_pin_it(struct route_graph_point *p, struct route_graph_segment *s, int min_value, int penalty) |
4362 | void route_find_next_lowest_segment_and_pin_it(struct route_graph_point *p, struct route_graph_segment *s, int min_value, int penalty) |
4699 | { |
4363 | { |
4700 | struct route_graph_segment *tmp = NULL; |
4364 | struct route_graph_segment *tmp = NULL; |
4701 | int cur_min = min_value; |
4365 | int cur_min = min_value; |
4702 | |
4366 | |
… | |
… | |
4740 | } |
4404 | } |
4741 | } |
4405 | } |
4742 | tmp = tmp->end_next; |
4406 | tmp = tmp->end_next; |
4743 | } |
4407 | } |
4744 | } |
4408 | } |
4745 | |
4409 | # endif |
4746 | |
4410 | |
4747 | |
4411 | |
4748 | /** |
4412 | /** |
4749 | * @brief Starts an "offroad" path |
4413 | * @brief Starts an "offroad" path |
4750 | * |
4414 | * |
… | |
… | |
4858 | static struct route_path * |
4522 | static struct route_path * |
4859 | route_path_new(struct route *rr, struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile) |
4523 | route_path_new(struct route *rr, struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile) |
4860 | { |
4524 | { |
4861 | __F_START__ |
4525 | __F_START__ |
4862 | |
4526 | |
4863 | struct route_graph_segment *first, *s = NULL, *s1 = NULL, *s2 = NULL; |
4527 | struct route_graph_segment *s = NULL, *s1 = NULL, *s2 = NULL; |
4864 | struct route_graph_point *start; |
4528 | struct route_graph_point *start; |
4865 | struct route_info *posinfo, *dstinfo; |
4529 | struct route_info *posinfo, *dstinfo; |
4866 | int segs = 0; |
4530 | int segs = 0; |
|
|
4531 | int dir; |
4867 | int val1 = INT_MAX, val2 = INT_MAX; |
4532 | int val1 = INT_MAX, val2 = INT_MAX; |
4868 | int val, val1_new, val2_new; |
4533 | int val, val1_new, val2_new; |
4869 | struct route_path *ret; |
4534 | struct route_path *ret; |
4870 | |
4535 | |
4871 | |
4536 | |
4872 | dbg(0, "RPNEW:ENTER\n"); |
4537 | dbg(0, "RPNEW:ENTER\n"); |
4873 | |
4538 | |
4874 | dbg(0, "RR_TIM:001\n"); |
4539 | dbg(0, "RR_TIM:001\n"); |
4875 | |
4540 | |
4876 | if (!pos->street || !dst->street) |
4541 | if (! pos->street || !dst->street) |
4877 | { |
4542 | { |
4878 | // dbg(0, "pos or dest not set\n"); |
4543 | // dbg(0, "pos or dest not set\n"); |
4879 | dbg(0, "RR_TIM:002:return\n"); |
4544 | dbg(0, "RR_TIM:002:return\n"); |
4880 | |
4545 | |
4881 | dbg(0, "RPNEW:RET001\n"); |
4546 | dbg(0, "RPNEW:RET001\n"); |
4882 | return2 NULL; |
4547 | return2 NULL; |
4883 | } |
4548 | } |
4884 | |
4549 | |
|
|
4550 | // street direction from tracking |
|
|
4551 | // dbg(0,"street_direction = %i\n",pos->street_direction); |
|
|
4552 | |
|
|
4553 | |
4885 | if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) |
4554 | if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c))) |
4886 | { |
4555 | { |
4887 | dbg(0, "RPNEW:RET002\n"); |
4556 | dbg(0, "RPNEW:RET002\n"); |
4888 | return2 route_path_new_offroad(this, pos, dst); |
4557 | return2 route_path_new_offroad(this, pos, dst); |
4889 | } |
4558 | } |
4890 | |
4559 | |
4891 | // ------ just calculate the smallest cost to reach destination ---------- |
4560 | |
4892 | // only segments connected to my current street position! |
4561 | // the integer 4000 below is a kind of turn around penalty with a hardcoded value for now |
4893 | // ------ just calculate the smallest cost to reach destination ---------- |
4562 | |
4894 | while ((s = route_graph_get_segment(this, pos->street, s))) |
4563 | while ((s = route_graph_get_segment(this, pos->street, s))) |
4895 | { |
4564 | { |
4896 | val = route_value_seg(profile, NULL, s, 1); |
4565 | val = route_value_seg(profile, NULL, s, 2); |
4897 | if (val != INT_MAX && s->end->value != INT_MAX) |
4566 | if (val != INT_MAX && s->seg_start_out_cost != INT_MAX) |
|
|
4567 | { |
|
|
4568 | val = val * (pos->percent) / 100; // cost om naar het andere uiteinde te rijden !! |
|
|
4569 | val1_new = s->seg_start_out_cost - val; |
|
|
4570 | |
|
|
4571 | if (pos->street_direction == -1) |
4898 | { |
4572 | { |
4899 | val = val * (100 - pos->percent) / 100; |
4573 | val1_new = val1_new + 4000; |
4900 | val1_new = s->end->value + val; |
4574 | } |
|
|
4575 | |
4901 | if (val1_new < val1) |
4576 | if (val1_new < val1) |
4902 | { |
4577 | { |
4903 | val1 = val1_new; |
4578 | val1 = val1_new; |
4904 | s1 = s; |
4579 | s1 = s; |
4905 | } |
4580 | } |
4906 | } |
4581 | } |
4907 | val = route_value_seg(profile, NULL, s, -1); |
4582 | val = route_value_seg(profile, NULL, s, -2); |
4908 | if (val != INT_MAX && s->start->value != INT_MAX) |
4583 | if (val != INT_MAX && s->seg_end_out_cost != INT_MAX) |
4909 | { |
4584 | { |
4910 | val = val * pos->percent / 100; |
4585 | val = val * (100 - pos->percent) / 100; |
4911 | val2_new = s->start->value + val; |
4586 | val2_new = s->seg_end_out_cost - val; |
|
|
4587 | |
|
|
4588 | if (pos->street_direction == 1) |
|
|
4589 | { |
|
|
4590 | val2_new = val2_new + 4000; |
|
|
4591 | } |
|
|
4592 | |
4912 | if (val2_new < val2) |
4593 | if (val2_new < val2) |
4913 | { |
4594 | { |
4914 | val2 = val2_new; |
4595 | val2 = val2_new; |
4915 | s2 = s; |
4596 | s2 = s; |
4916 | } |
4597 | } |
4917 | } |
4598 | } |
4918 | } |
4599 | } |
4919 | // ------ just calculate the smallest cost to reach destination ---------- |
4600 | // ------ just calculate the smallest cost to reach destination ---------- |
4920 | // ------ just calculate the smallest cost to reach destination ---------- |
4601 | // ------ just calculate the smallest cost to reach destination ---------- |
4921 | |
4602 | |
4922 | dbg(0, "RR_TIM:002\n"); |
|
|
4923 | |
4603 | |
|
|
4604 | // val1 en s1 = goedkoopst voorwaarts |
|
|
4605 | // val2 en s2 = goedkoppst achterwaards |
4924 | |
4606 | |
4925 | if (val1 == INT_MAX && val2 == INT_MAX) |
4607 | if (val1 == INT_MAX && val2 == INT_MAX) |
4926 | { |
4608 | { |
4927 | //dbg(0, "no route found, pos blocked\n"); |
4609 | //dbg(0, "no route found, pos blocked\n"); |
4928 | dbg(0, "RR_TIM:003:return\n"); |
4610 | dbg(0, "RR_TIM:003:return\n"); |
… | |
… | |
4931 | return2 NULL; |
4613 | return2 NULL; |
4932 | } |
4614 | } |
4933 | |
4615 | |
4934 | if (val1 == val2) |
4616 | if (val1 == val2) |
4935 | { |
4617 | { |
4936 | val1 = s1->end->value; |
4618 | val1 = s1->seg_end_out_cost; |
4937 | val2 = s2->start->value; |
4619 | val2 = s2->seg_start_out_cost; |
4938 | } |
4620 | } |
4939 | |
|
|
4940 | if (val1 < val2) |
4621 | if (val1 < val2) |
4941 | { |
4622 | { |
4942 | start = s1->start; // start point |
4623 | start = s1->start; |
4943 | s = s1; // start segment |
4624 | s = s1; |
|
|
4625 | dir = 1; |
4944 | } |
4626 | } |
4945 | else |
4627 | else |
4946 | { |
4628 | { |
4947 | start = s2->end; // start point |
4629 | start = s2->end; |
4948 | s = s2; // start segment |
4630 | s = s2; |
|
|
4631 | dir = -1; |
4949 | } |
4632 | } |
4950 | |
4633 | |
|
|
4634 | // if (pos->street_direction && dir != pos->street_direction && profile->turn_around_penalty) |
|
|
4635 | // { |
|
|
4636 | // if (!route_graph_segment_match(this->avoid_seg,s)) |
|
|
4637 | // { |
|
|
4638 | // dbg(0,"avoid current segment\n"); |
|
|
4639 | // if (this->avoid_seg) |
|
|
4640 | // route_graph_set_traffic_distortion(this, this->avoid_seg, 0); |
|
|
4641 | // this->avoid_seg=s; |
|
|
4642 | // route_graph_set_traffic_distortion(this, this->avoid_seg, profile->turn_around_penalty); |
|
|
4643 | // route_graph_reset(this); |
|
|
4644 | // route_graph_flood_frugal(this, dst, pos, profile, NULL); |
|
|
4645 | // return route_path_new(NULL, this, oldpath, pos, dst, profile); |
|
|
4646 | // } |
|
|
4647 | // } |
4951 | ret=g_new0(struct route_path, 1); |
4648 | ret=g_new0(struct route_path, 1); |
4952 | ret->in_use = 1; |
4649 | ret->in_use = 1; |
4953 | ret->updated = 1; |
4650 | ret->updated = 1; |
4954 | |
|
|
4955 | if (pos->lenextra) |
4651 | if (pos->lenextra) |
4956 | { |
4652 | { |
4957 | //dbg(0,"l extra1=%d\n", pos->lenextra); |
|
|
4958 | if (rr->pos != pos) |
|
|
4959 | { |
|
|
4960 | dbg(0, "RPNEW:PP:not pos\n"); |
|
|
4961 | // route_path_add_line_as_waypoint(ret, &pos->c, &pos->lp, pos->lenextra); // mark as waypoint!! |
|
|
4962 | route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra); // ORIG |
4653 | route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra); |
4963 | } |
|
|
4964 | else |
|
|
4965 | { |
|
|
4966 | dbg(0, "RPNEW:PP:IS pos\n"); |
|
|
4967 | route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra); // ORIG |
|
|
4968 | } |
|
|
4969 | } |
4654 | } |
4970 | |
4655 | |
4971 | ret->path_hash = item_hash_new(); |
4656 | ret->path_hash = item_hash_new(); |
4972 | dstinfo = NULL; |
4657 | dstinfo = NULL; |
4973 | posinfo = pos; |
4658 | posinfo = pos; |
4974 | first = s; // first segment = start segment |
|
|
4975 | |
|
|
4976 | |
|
|
4977 | dbg(0, "RR_TIM:004\n"); |
4659 | dbg(0, "RR_TIM:004\n"); |
4978 | |
4660 | |
4979 | clock_t s_; |
4661 | clock_t s_; |
4980 | s_ = debug_measure_start(); |
4662 | s_ = debug_measure_start(); |
4981 | |
4663 | |
… | |
… | |
4983 | // ------- build the real route here ------------------------ |
4665 | // ------- build the real route here ------------------------ |
4984 | // ------- build the real route here ------------------------ |
4666 | // ------- build the real route here ------------------------ |
4985 | while (s && !dstinfo) |
4667 | while (s && !dstinfo) |
4986 | { /* following start->seg, which indicates the least costly way to reach our destination */ |
4668 | { /* following start->seg, which indicates the least costly way to reach our destination */ |
4987 | segs++; |
4669 | segs++; |
4988 | #if 0 |
|
|
4989 | printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y); |
|
|
4990 | #endif |
|
|
4991 | if (s->start == start) |
4670 | if (s->start == start) |
4992 | { |
4671 | { |
4993 | if (item_is_equal(s->data.item, dst->street->item) && (s->end->seg == s || !posinfo)) |
4672 | if (item_is_equal(s->data.item, dst->street->item) && (s->end_from_seg == s || !posinfo)) |
4994 | { |
4673 | { |
4995 | dstinfo = dst; |
4674 | dstinfo = dst; |
4996 | } |
4675 | } |
4997 | |
|
|
4998 | if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo, dstinfo)) |
4676 | if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo, dstinfo)) |
4999 | { |
4677 | { |
5000 | ret->updated = 0; |
4678 | ret->updated = 0; |
5001 | } |
4679 | } |
5002 | |
4680 | |
5003 | start = s->end; // new start point |
4681 | start = s->end; // new start point |
|
|
4682 | s = s->end_from_seg; |
5004 | } |
4683 | } |
5005 | else |
4684 | else |
5006 | { |
4685 | { |
5007 | if (item_is_equal(s->data.item, dst->street->item) && (s->start->seg == s || !posinfo)) |
4686 | if (item_is_equal(s->data.item, dst->street->item) && (s->start_from_seg == s || !posinfo)) |
5008 | { |
4687 | { |
5009 | dstinfo = dst; |
4688 | dstinfo = dst; |
5010 | } |
4689 | } |
5011 | if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo, dstinfo)) |
4690 | if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo, dstinfo)) |
5012 | { |
4691 | { |
5013 | ret->updated = 0; |
4692 | ret->updated = 0; |
5014 | } |
4693 | } |
5015 | start = s->start; // new start point |
4694 | start = s->start; // new start point |
|
|
4695 | s = s->start_from_seg; |
5016 | } |
4696 | } |
5017 | |
4697 | |
5018 | posinfo = NULL; |
4698 | posinfo = NULL; |
5019 | s = start->seg; // segment to use in direction of destination |
|
|
5020 | |
|
|
5021 | } |
4699 | } |
5022 | // ------- build the real route here ------------------------ |
4700 | // ------- build the real route here ------------------------ |
5023 | // ------- build the real route here ------------------------ |
4701 | // ------- build the real route here ------------------------ |
5024 | |
4702 | |
5025 | debug_mrp("RR_TIM:005", debug_measure_end(s_)); |
4703 | debug_mrp("RR_TIM:005", debug_measure_end(s_)); |
5026 | |
4704 | |
5027 | #if 0 |
4705 | #if 0 |
5028 | if (dst->lenextra) |
4706 | if (dst->lenextra) |
5029 | { |
4707 | { |
5030 | //dbg(0,"l extra2=%d\n", dst->lenextra); |
4708 | // |
5031 | route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra); |
4709 | route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra); |
5032 | } |
4710 | } |
5033 | #endif |
4711 | #endif |
5034 | |
4712 | |
5035 | if (dst->lenextra) |
4713 | if (dst->lenextra) |
… | |
… | |
5050 | } |
4728 | } |
5051 | |
4729 | |
5052 | |
4730 | |
5053 | //dbg(1, "%d segments\n", segs); |
4731 | //dbg(1, "%d segments\n", segs); |
5054 | |
4732 | |
5055 | dbg(0, "RR_TIM:099:segs=%d\n", segs); |
4733 | // dbg(0, "RR_TIM:099:segs=%d\n", segs); |
5056 | |
4734 | |
5057 | dbg(0, "RPNEW:LEAVE\n"); |
4735 | dbg(0, "RPNEW:LEAVE\n"); |
5058 | |
4736 | |
5059 | return2 ret; |
4737 | return2 ret; |
5060 | |
4738 | |
… | |
… | |
6315 | return 0; |
5993 | return 0; |
6316 | } |
5994 | } |
6317 | |
5995 | |
6318 | if (mr->item.type == type_rg_point) |
5996 | if (mr->item.type == type_rg_point) |
6319 | { |
5997 | { |
|
|
5998 | attr->type = attr_label; // ZZZx |
|
|
5999 | if (mr->str) |
|
|
6000 | { |
|
|
6001 | g_free(mr->str); |
|
|
6002 | } // ZZZx |
|
|
6003 | |
|
|
6004 | int lowest_cost = INT_MAX; |
|
|
6005 | if (p->start && p->start->seg_start_out_cost < lowest_cost) |
|
|
6006 | { |
|
|
6007 | lowest_cost = p->start->seg_start_out_cost; |
|
|
6008 | } |
|
|
6009 | |
|
|
6010 | if (p->end && p->end->seg_end_out_cost < lowest_cost) |
|
|
6011 | { |
|
|
6012 | lowest_cost = p->end->seg_end_out_cost; |
|
|
6013 | } |
|
|
6014 | |
|
|
6015 | if (lowest_cost < INT_MAX) |
|
|
6016 | { |
|
|
6017 | mr->str = g_strdup_printf("%d", lowest_cost); |
|
|
6018 | } |
|
|
6019 | else |
|
|
6020 | { |
|
|
6021 | mr->str = g_strdup("-"); |
|
|
6022 | } |
|
|
6023 | attr->u.str = mr->str; // ZZZx |
|
|
6024 | } |
|
|
6025 | else if (mr->item.type == type_rg_segment) |
|
|
6026 | { |
6320 | attr->type = attr_label; |
6027 | attr->type = attr_label; |
6321 | if (mr->str) |
6028 | if (mr->str) |
6322 | { |
6029 | { |
6323 | g_free(mr->str); |
6030 | g_free(mr->str); |
6324 | } |
6031 | } |
6325 | |
6032 | |
6326 | if (p->value != INT_MAX) |
6033 | #if 0 |
6327 | { |
|
|
6328 | mr->str = g_strdup_printf("%d", p->value); |
|
|
6329 | } |
|
|
6330 | else |
|
|
6331 | { |
|
|
6332 | mr->str = g_strdup("-"); |
|
|
6333 | } |
|
|
6334 | attr->u.str = mr->str; |
|
|
6335 | } |
|
|
6336 | else if (mr->item.type == type_rg_segment) |
|
|
6337 | { |
|
|
6338 | attr->type = attr_label; |
|
|
6339 | if (mr->str) |
|
|
6340 | { |
|
|
6341 | g_free(mr->str); |
|
|
6342 | } |
|
|
6343 | |
|
|
6344 | // z5z5 |
6034 | // z5z5 |
6345 | if (seg) |
6035 | if (seg) |
6346 | { |
6036 | { |
|
|
6037 | |
|
|
6038 | // FIXME |
6347 | mr->str = g_strdup_printf("%dl, %dt, %ds sv=%d ev=%d", seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL), route_seg_speed(route->vehicleprofile, &seg->data, NULL), seg->start->value, seg->end->value); |
6039 | // mr->str = g_strdup_printf("%dl, %dt, %ds sv=%d ev=%d", seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL), route_seg_speed(route->vehicleprofile, &seg->data, NULL), seg->start->value, seg->end->value); |
|
|
6040 | mr->str = g_strdup_printf("%dl, %dt, %ds", seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL), route_seg_speed(route->vehicleprofile, &seg->data, NULL)); |
6348 | } |
6041 | } |
6349 | else |
6042 | else |
6350 | { |
6043 | { |
6351 | mr->str = g_strdup("??"); |
6044 | mr->str = g_strdup("??"); |
6352 | } |
6045 | } |
|
|
6046 | #endif |
|
|
6047 | |
|
|
6048 | mr->str = g_strdup("fix me - fix me"); |
|
|
6049 | |
6353 | attr->u.str = mr->str; |
6050 | attr->u.str = mr->str; |
6354 | } |
6051 | } |
6355 | |
6052 | |
6356 | return 1; |
6053 | return 1; |
6357 | |
6054 | |
… | |
… | |
6487 | if (mr->last_coord >= 2) |
6184 | if (mr->last_coord >= 2) |
6488 | break; |
6185 | break; |
6489 | |
6186 | |
6490 | dir = 0; |
6187 | dir = 0; |
6491 | |
6188 | |
|
|
6189 | // FIXME !! |
|
|
6190 | |
6492 | if (seg->end->seg == seg) |
6191 | // if (seg->end->seg == seg) |
6493 | dir = 1; |
6192 | // dir = 1; |
6494 | |
6193 | |
6495 | if (mr->last_coord) |
6194 | if (mr->last_coord) |
6496 | dir = 1 - dir; |
6195 | dir = 1 - dir; |
6497 | |
6196 | |
6498 | if (dir) |
6197 | // if (dir) |
6499 | { |
6198 | // { |
6500 | if (pro != projection_mg) |
6199 | // if (pro != projection_mg) |
6501 | transform_from_to(&seg->end->c, pro, &c[i], projection_mg); |
6200 | // transform_from_to(&seg->end->c, pro, &c[i], projection_mg); |
6502 | else |
6201 | // else |
6503 | c[i] = seg->end->c; |
6202 | // c[i] = seg->end->c; |
6504 | } |
6203 | // } |
6505 | else |
6204 | // else |
6506 | { |
6205 | { |
6507 | if (pro != projection_mg) |
6206 | if (pro != projection_mg) |
6508 | transform_from_to(&seg->start->c, pro, &c[i], projection_mg); |
6207 | transform_from_to(&seg->start->c, pro, &c[i], projection_mg); |
6509 | else |
6208 | else |
6510 | c[i] = seg->start->c; |
6209 | c[i] = seg->start->c; |