/[zanavi_public1]/navit/navit/route.c
ZANavi

Diff of /navit/navit/route.c

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

Revision 28 Revision 30
210 unsigned ncoords; /**< How many coordinates does this segment have? */ 210 unsigned ncoords; /**< How many coordinates does this segment have? */
211 struct coord c[0]; /**< Pointer to the ncoords coordinates of this segment */ 211 struct coord c[0]; /**< Pointer to the ncoords coordinates of this segment */
212/* WARNING: There will be coordinates following here, so do not create new fields after c! */ 212/* WARNING: There will be coordinates following here, so do not create new fields after c! */
213}; 213};
214 214
215
216/** 215/**
217 * @brief A complete route path 216 * @brief A complete route path
218 * 217 *
219 * This structure describes a whole routing path 218 * This structure describes a whole routing path
220 */ 219 */
281 { 280 {
282 GList *list; 281 GList *list;
283 } u; 282 } u;
284}; 283};
285 284
286static struct route_info * route_find_nearest_street( 285static struct route_info * route_find_nearest_street(struct vehicleprofile *vehicleprofile, struct mapset *ms, struct pcoord *c);
287 struct vehicleprofile *vehicleprofile, struct mapset *ms, 286static struct route_graph_point *route_graph_get_point(struct route_graph *this, struct coord *c);
288 struct pcoord *c);
289static struct route_graph_point *route_graph_get_point(
290 struct route_graph *this, struct coord *c);
291static void route_graph_update(struct route *this, struct callback *cb, 287static void route_graph_update(struct route *this, struct callback *cb, int async);
292 int async);
293static void route_graph_build_done(struct route_graph *rg, int cancel); 288static void route_graph_build_done(struct route_graph *rg, int cancel);
294static struct route_path *route_path_new(struct route_graph *this, 289static struct route_path *route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile);
295 struct route_path *oldpath, struct route_info *pos, 290static void route_process_street_graph(struct route_graph *this, struct item *item, struct vehicleprofile *profile);
296 struct route_info *dst, struct vehicleprofile *profile);
297static void route_process_street_graph(struct route_graph *this,
298 struct item *item, struct vehicleprofile *profile);
299//static void route_graph_destroy(struct route_graph *this); 291//static void route_graph_destroy(struct route_graph *this);
300void route_path_update(struct route *this, int cancel, int async); 292void route_path_update(struct route *this, int cancel, int async);
301static int route_time_seg(struct vehicleprofile *profile, 293static int route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist);
302 struct route_segment_data *over, struct route_traffic_distortion *dist); 294static void route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb);
303static void route_graph_flood(struct route_graph *this, struct route_info *dst,
304 struct vehicleprofile *profile, struct callback *cb);
305static void route_graph_reset(struct route_graph *this); 295static void route_graph_reset(struct route_graph *this);
306 296
307/** 297/**
308 * @brief Returns the projection used for this route 298 * @brief Returns the projection used for this route
309 * 299 *
313static enum projection route_projection(struct route *route) 303static enum projection route_projection(struct route *route)
314{ 304{
315 struct street_data *street; 305 struct street_data *street;
316 struct route_info *dst = route_get_dst(route); 306 struct route_info *dst = route_get_dst(route);
317 if (!route->pos && !dst) 307 if (!route->pos && !dst)
308 {
318 return projection_none; 309 return projection_none;
310 }
319 street = route->pos ? route->pos->street : dst->street; 311 street = route->pos ? route->pos->street : dst->street;
320 if (!street || !street->item.map) 312 if (!street || !street->item.map)
313 {
321 return projection_none; 314 return projection_none;
315 }
322 return map_projection(street->item.map); 316 return map_projection(street->item.map);
323} 317}
324 318
325/** 319/**
326 * @brief Creates a new graph point iterator 320 * @brief Creates a new graph point iterator
329 * iterate through all segments connected to the point. 323 * iterate through all segments connected to the point.
330 * 324 *
331 * @param p The route graph point to create the iterator from 325 * @param p The route graph point to create the iterator from
332 * @return A new iterator. 326 * @return A new iterator.
333 */ 327 */
334static struct route_graph_point_iterator rp_iterator_new( 328static struct route_graph_point_iterator rp_iterator_new(struct route_graph_point *p)
335 struct route_graph_point *p)
336{ 329{
330 //// dbg(0, "enter\n");
331
337 struct route_graph_point_iterator it; 332 struct route_graph_point_iterator it;
338 333
339 it.p = p; 334 it.p = p;
340 if (p->start) 335 if (p->start)
341 { 336 {
355 * @brief Gets the next segment connected to a route graph point from an iterator 350 * @brief Gets the next segment connected to a route graph point from an iterator
356 * 351 *
357 * @param it The route graph point iterator to get the segment from 352 * @param it The route graph point iterator to get the segment from
358 * @return The next segment or NULL if there are no more segments 353 * @return The next segment or NULL if there are no more segments
359 */ 354 */
360static struct route_graph_segment *rp_iterator_next( 355static struct route_graph_segment *rp_iterator_next(struct route_graph_point_iterator *it)
361 struct route_graph_point_iterator *it)
362{ 356{
357 //// dbg(0, "enter\n");
358
363 struct route_graph_segment *ret; 359 struct route_graph_segment *ret;
364 360
365 ret = it->next; 361 ret = it->next;
366 if (!ret) 362 if (!ret)
367 { 363 {
394 * @param it The route graph point iterator to be checked 390 * @param it The route graph point iterator to be checked
395 * @return 1 if the last segment returned comes from the end of the route graph point, 0 otherwise 391 * @return 1 if the last segment returned comes from the end of the route graph point, 0 otherwise
396 */ 392 */
397static int rp_iterator_end(struct route_graph_point_iterator *it) 393static int rp_iterator_end(struct route_graph_point_iterator *it)
398{ 394{
395 //// dbg(0, "enter\n");
396
399 if (it->end && (it->next != it->p->end)) 397 if (it->end && (it->next != it->p->end))
400 { 398 {
401 return 1; 399 return 1;
402 } 400 }
403 else 401 else
411 * 409 *
412 * @param this The route_path to be destroyed 410 * @param this The route_path to be destroyed
413 */ 411 */
414void route_path_destroy(struct route_path *this, int recurse) 412void route_path_destroy(struct route_path *this, int recurse)
415{ 413{
414 // dbg(0, "enter\n");
415
416 struct route_path_segment *c, *n; 416 struct route_path_segment *c, *n;
417 struct route_path *next; 417 struct route_path *next;
418 while (this) 418 while (this)
419 { 419 {
420 next = this->next; 420 next = this->next;
446 * @return The newly created route 446 * @return The newly created route
447 */ 447 */
448struct route * 448struct route *
449route_new(struct attr *parent, struct attr **attrs) 449route_new(struct attr *parent, struct attr **attrs)
450{ 450{
451 // dbg(0, "enter\n");
452
451 struct route *this=g_new0(struct route, 1); 453 struct route *this=g_new0(struct route, 1);
452 struct attr dest_attr; 454 struct attr dest_attr;
453 455
454 if (attr_generic_get_attr(attrs, NULL, attr_destination_distance, 456 if (attr_generic_get_attr(attrs, NULL, attr_destination_distance, &dest_attr, NULL))
455 &dest_attr, NULL))
456 { 457 {
457 this->destination_distance = dest_attr.u.num; 458 this->destination_distance = dest_attr.u.num;
458 } 459 }
459 else 460 else
460 { 461 {
474 * @param level How deep to scan the route graph 475 * @param level How deep to scan the route graph
475 * @param direction Set this to 1 if we're entering the segment through its end, to 0 otherwise 476 * @param direction Set this to 1 if we're entering the segment through its end, to 0 otherwise
476 * @param origin Used internally, set to NULL 477 * @param origin Used internally, set to NULL
477 * @return 1 If a roundabout was detected, 0 otherwise 478 * @return 1 If a roundabout was detected, 0 otherwise
478 */ 479 */
479static int route_check_roundabout(struct route_graph_segment *seg, int level, 480static int route_check_roundabout(struct route_graph_segment *seg, int level, int direction, struct route_graph_segment *origin)
480 int direction, struct route_graph_segment *origin)
481{ 481{
482 //// dbg(0, "enter\n");
483
482 struct route_graph_point_iterator it, it2; 484 struct route_graph_point_iterator it, it2;
483 struct route_graph_segment *cur; 485 struct route_graph_segment *cur;
484 int count = 0; 486 int count = 0;
485 487
486 if (!level) 488 if (!level)
538 { 540 {
539 seg->data.flags |= AF_ROUNDABOUT; 541 seg->data.flags |= AF_ROUNDABOUT;
540 return 1; 542 return 1;
541 } 543 }
542 544
543 if (route_check_roundabout(cur, (level - 1), rp_iterator_end(&it), 545 if (route_check_roundabout(cur, (level - 1), rp_iterator_end(&it), origin))
544 origin))
545 { 546 {
546 seg->data.flags |= AF_ROUNDABOUT; 547 seg->data.flags |= AF_ROUNDABOUT;
547 return 1; 548 return 1;
548 } 549 }
549 550
559 * @param this The route to set the mapset for 560 * @param this The route to set the mapset for
560 * @param ms The mapset to set for this route 561 * @param ms The mapset to set for this route
561 */ 562 */
562void route_set_mapset(struct route *this, struct mapset *ms) 563void route_set_mapset(struct route *this, struct mapset *ms)
563{ 564{
565 //// dbg(0, "enter\n");
566
564 this->ms = ms; 567 this->ms = ms;
565} 568}
566 569
567/** 570/**
568 * @brief Sets the vehicle profile of a route 571 * @brief Sets the vehicle profile of a route
571 * @param prof The vehicle profile 574 * @param prof The vehicle profile
572 */ 575 */
573 576
574void route_set_profile(struct route *this, struct vehicleprofile *prof) 577void route_set_profile(struct route *this, struct vehicleprofile *prof)
575{ 578{
579 // dbg(0, "enter\n");
580
576 if (this->vehicleprofile != prof) 581 if (this->vehicleprofile != prof)
577 { 582 {
578 this->vehicleprofile = prof; 583 this->vehicleprofile = prof;
579 route_path_update(this, 1, 1); 584 route_path_update(this, 1, 1);
580 } 585 }
587 * @return The mapset of the route passed 592 * @return The mapset of the route passed
588 */ 593 */
589struct mapset * 594struct mapset *
590route_get_mapset(struct route *this) 595route_get_mapset(struct route *this)
591{ 596{
597 //// dbg(0, "enter\n");
598
592 return this->ms; 599 return this->ms;
593} 600}
594 601
595/** 602/**
596 * @brief Returns the current position within the route passed 603 * @brief Returns the current position within the route passed
599 * @return The position within the route passed 606 * @return The position within the route passed
600 */ 607 */
601struct route_info * 608struct route_info *
602route_get_pos(struct route *this) 609route_get_pos(struct route *this)
603{ 610{
611 //// dbg(0, "enter\n");
612
604 return this->pos; 613 return this->pos;
605} 614}
606 615
607/** 616/**
608 * @brief Returns the destination of the route passed 617 * @brief Returns the destination of the route passed
611 * @return The destination of the route passed 620 * @return The destination of the route passed
612 */ 621 */
613struct route_info * 622struct route_info *
614route_get_dst(struct route *this) 623route_get_dst(struct route *this)
615{ 624{
625 //// dbg(0, "enter\n");
626
616 struct route_info *dst = NULL; 627 struct route_info *dst = NULL;
617 628
618 if (this->destinations) 629 if (this->destinations)
619 dst = g_list_last(this->destinations)->data; 630 dst = g_list_last(this->destinations)->data;
620 return dst; 631 return dst;
626 * @param this The route to check 637 * @param this The route to check
627 * @return True if the path is calculated, false if not 638 * @return True if the path is calculated, false if not
628 */ 639 */
629int route_get_path_set(struct route *this) 640int route_get_path_set(struct route *this)
630{ 641{
642 //// dbg(0, "enter\n");
643
631 return this->path2 != NULL; 644 return this->path2 != NULL;
632} 645}
633 646
634/** 647/**
635 * @brief Checks if the route passed contains a certain item within the route path 648 * @brief Checks if the route passed contains a certain item within the route path
642 * @param item The item to search for 655 * @param item The item to search for
643 * @return True if the item was found, false if the item was not found or the route was not calculated 656 * @return True if the item was found, false if the item was not found or the route was not calculated
644 */ 657 */
645int route_contains(struct route *this, struct item *item) 658int route_contains(struct route *this, struct item *item)
646{ 659{
660 //// dbg(0, "enter\n");
661
647 if (!this->path2 || !this->path2->path_hash) 662 if (!this->path2 || !this->path2->path_hash)
648 return 0; 663 return 0;
649 if (item_hash_lookup(this->path2->path_hash, item)) 664 if (item_hash_lookup(this->path2->path_hash, item))
650 return 1; 665 return 1;
651 if (!this->pos || !this->pos->street) 666 if (!this->pos || !this->pos->street)
655} 670}
656 671
657static struct route_info * 672static struct route_info *
658route_next_destination(struct route *this) 673route_next_destination(struct route *this)
659{ 674{
675 // dbg(0, "enter\n");
676
660 if (!this->destinations) 677 if (!this->destinations)
661 return NULL; 678 return NULL;
662 return this->destinations->data; 679 return this->destinations->data;
663} 680}
664 681
668 * @param this The route to be checked 685 * @param this The route to be checked
669 * @return True if the destination is "reached", false otherwise. 686 * @return True if the destination is "reached", false otherwise.
670 */ 687 */
671int route_destination_reached(struct route *this) 688int route_destination_reached(struct route *this)
672{ 689{
690 // dbg(0, "enter\n");
691
673 struct street_data *sd = NULL; 692 struct street_data *sd = NULL;
674 enum projection pro; 693 enum projection pro;
675 struct route_info *dst = route_next_destination(this); 694 struct route_info *dst = route_next_destination(this);
676 695
677 if (!this->pos) 696 if (!this->pos)
701 } 720 }
702 pro = route_projection(this); 721 pro = route_projection(this);
703 if (pro == projection_none) 722 if (pro == projection_none)
704 return 0; 723 return 0;
705 724
706 if (transform_distance(pro, &this->pos->c, &dst->lp) 725 if (transform_distance(pro, &this->pos->c, &dst->lp) > this->destination_distance)
707 > this->destination_distance)
708 { 726 {
709 return 0; 727 return 0;
710 } 728 }
711 729
712 if (g_list_next(this->destinations)) 730 if (g_list_next(this->destinations))
716} 734}
717 735
718static struct route_info * 736static struct route_info *
719route_previous_destination(struct route *this) 737route_previous_destination(struct route *this)
720{ 738{
739 // dbg(0, "enter\n");
740
721 GList *l = g_list_find(this->destinations, this->current_dst); 741 GList *l = g_list_find(this->destinations, this->current_dst);
722 if (!l) 742 if (!l)
723 return this->pos; 743 return this->pos;
724 l = g_list_previous(l); 744 l = g_list_previous(l);
725 if (!l) 745 if (!l)
727 return l->data; 747 return l->data;
728} 748}
729 749
730static void route_path_update_done(struct route *this, int new_graph) 750static void route_path_update_done(struct route *this, int new_graph)
731{ 751{
752 // dbg(0, "enter\n");
753
732 struct route_path *oldpath = this->path2; 754 struct route_path *oldpath = this->path2;
733 struct attr route_status; 755 struct attr route_status;
734 struct route_info *prev_dst; 756 struct route_info *prev_dst;
735 route_status.type = attr_route_status; 757 route_status.type = attr_route_status;
736 if (this->path2 && (this->path2->in_use > 1)) 758 if (this->path2 && (this->path2->in_use > 1))
741 route_status.u.num = route_status_building_path; 763 route_status.u.num = route_status_building_path;
742 route_set_attr(this, &route_status); 764 route_set_attr(this, &route_status);
743 prev_dst = route_previous_destination(this); 765 prev_dst = route_previous_destination(this);
744 if (this->link_path) 766 if (this->link_path)
745 { 767 {
746 this->path2 = route_path_new(this->graph, NULL, prev_dst, 768 this->path2 = route_path_new(this->graph, NULL, prev_dst, this->current_dst, this->vehicleprofile);
747 this->current_dst, this->vehicleprofile);
748 if (this->path2) 769 if (this->path2)
749 this->path2->next = oldpath; 770 this->path2->next = oldpath;
750 } 771 }
751 else 772 else
752 { 773 {
753 this->path2 = route_path_new(this->graph, oldpath, prev_dst, 774 this->path2 = route_path_new(this->graph, oldpath, prev_dst, this->current_dst, this->vehicleprofile);
754 this->current_dst, this->vehicleprofile);
755 if (oldpath && this->path2) 775 if (oldpath && this->path2)
756 { 776 {
757 this->path2->next = oldpath->next; 777 this->path2->next = oldpath->next;
758 route_path_destroy(oldpath, 0); 778 route_path_destroy(oldpath, 0);
759 } 779 }
763 struct route_path_segment *seg = this->path2->path; 783 struct route_path_segment *seg = this->path2->path;
764 int path_time = 0, path_len = 0; 784 int path_time = 0, path_len = 0;
765 while (seg) 785 while (seg)
766 { 786 {
767 /* FIXME */ 787 /* FIXME */
768 int seg_time =
769 route_time_seg(this->vehicleprofile, seg->data, NULL); 788 int seg_time = route_time_seg(this->vehicleprofile, seg->data, NULL);
789
770 if (seg_time == INT_MAX) 790 if (seg_time == INT_MAX)
771 { 791 {
772 dbg(1, "error\n"); 792 // dbg(1, "error\n");
773 } 793 }
774 else 794 else
795 {
775 path_time += seg_time; 796 path_time += seg_time;
797 }
776 path_len += seg->data->len; 798 path_len += seg->data->len;
777 seg = seg->next; 799 seg = seg->next;
778 } 800 }
801
779 this->path2->path_time = path_time; 802 this->path2->path_time = path_time;
780 this->path2->path_len = path_len; 803 this->path2->path_len = path_len;
804
781 if (prev_dst != this->pos) 805 if (prev_dst != this->pos)
782 { 806 {
783 this->link_path = 1; 807 this->link_path = 1;
784 this->current_dst = prev_dst; 808 this->current_dst = prev_dst;
785 route_graph_reset(this->graph); 809 route_graph_reset(this->graph);
786 route_graph_flood(this->graph, this->current_dst, 810 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb);
787 this->vehicleprofile, this->route_graph_flood_done_cb);
788 return; 811 return;
789 } 812 }
813
790 if (!new_graph && this->path2->updated) 814 if (!new_graph && this->path2->updated)
791 { 815 {
792 route_status.u.num = route_status_path_done_incremental; 816 route_status.u.num = route_status_path_done_incremental;
793 } 817 }
794 else 818 else
807 route_graph_destroy(this->graph); 831 route_graph_destroy(this->graph);
808 this->graph = NULL; 832 this->graph = NULL;
809 route_path_update(this, 1, 1); 833 route_path_update(this, 1, 1);
810 } 834 }
811 } 835 }
836
812 this->link_path = 0; 837 this->link_path = 0;
813 route_set_attr(this, &route_status); 838 route_set_attr(this, &route_status);
814} 839}
815 840
816/** 841/**
824 * 849 *
825 * @param this The route to update 850 * @param this The route to update
826 */ 851 */
827void route_path_update(struct route *this, int cancel, int async) 852void route_path_update(struct route *this, int cancel, int async)
828{ 853{
854 // dbg(0, "enter\n");
855
829 //dbg(1, "enter %d\n", cancel); 856 //dbg(1, "enter %d\n", cancel);
830 if (!this->pos || !this->destinations) 857 if (!this->pos || !this->destinations)
831 { 858 {
832 //dbg(1, "destroy\n"); 859 //dbg(1, "destroy\n");
833 route_path_destroy(this->path2, 1); 860 route_path_destroy(this->path2, 1);
859 if (!this->graph || !this->path2) 886 if (!this->graph || !this->path2)
860 { 887 {
861 //dbg(1, "rebuild graph\n"); 888 //dbg(1, "rebuild graph\n");
862 if (!this->route_graph_flood_done_cb) 889 if (!this->route_graph_flood_done_cb)
863 { 890 {
864 this->route_graph_flood_done_cb = callback_new_2( 891 this->route_graph_flood_done_cb = callback_new_2(callback_cast(route_path_update_done), this, (long) 1);
865 callback_cast(route_path_update_done), this, (long) 1); 892 callback_add_names(this->route_graph_flood_done_cb, "route_path_update", "route_path_update_done");
866 } 893 }
867 //dbg(1, "route_graph_update\n"); 894 //dbg(1, "route_graph_update\n");
868 route_graph_update(this, this->route_graph_flood_done_cb, async); 895 route_graph_update(this, this->route_graph_flood_done_cb, async);
869 } 896 }
870} 897}
875 * @param ri The route_info to calculate the distances for 902 * @param ri The route_info to calculate the distances for
876 * @param pro The projection used for this route 903 * @param pro The projection used for this route
877 */ 904 */
878static void route_info_distances(struct route_info *ri, enum projection pro) 905static void route_info_distances(struct route_info *ri, enum projection pro)
879{ 906{
907 //// dbg(0, "enter\n");
908
880 int npos = ri->pos + 1; 909 int npos = ri->pos + 1;
881 struct street_data *sd = ri->street; 910 struct street_data *sd = ri->street;
911
882 /* 0 1 2 X 3 4 5 6 pos=2 npos=3 count=7 0,1,2 3,4,5,6*/ 912 /* 0 1 2 X 3 4 5 6 pos=2 npos=3 count=7 0,1,2 3,4,5,6*/
913
883 ri->lenextra = transform_distance(pro, &ri->lp, &ri->c); 914 ri->lenextra = transform_distance(pro, &ri->lp, &ri->c);
884 ri->lenneg = transform_polyline_length(pro, sd->c, npos) 915
885 + transform_distance(pro, &sd->c[ri->pos], &ri->lp); 916 ri->lenneg = transform_polyline_length(pro, sd->c, npos) + transform_distance(pro, &sd->c[ri->pos], &ri->lp);
917
886 ri->lenpos = transform_polyline_length(pro, sd->c + npos, sd->count - npos) 918 ri->lenpos = transform_polyline_length(pro, sd->c + npos, sd->count - npos) + transform_distance(pro, &sd->c[npos], &ri->lp);
887 + transform_distance(pro, &sd->c[npos], &ri->lp); 919
888 if (ri->lenneg || ri->lenpos) 920 if (ri->lenneg || ri->lenpos)
921 {
889 ri->percent = (ri->lenneg * 100) / (ri->lenneg + ri->lenpos); 922 ri->percent = (ri->lenneg * 100) / (ri->lenneg + ri->lenpos);
923 }
890 else 924 else
925 {
891 ri->percent = 50; 926 ri->percent = 50;
927 }
892} 928}
893 929
894/** 930/**
895 * @brief This sets the current position of the route passed 931 * @brief This sets the current position of the route passed
896 * 932 *
900 * @param this The route to set the position of 936 * @param this The route to set the position of
901 * @param pos Coordinates to set as position 937 * @param pos Coordinates to set as position
902 */ 938 */
903void route_set_position(struct route *this, struct pcoord *pos) 939void route_set_position(struct route *this, struct pcoord *pos)
904{ 940{
941 // dbg(0, "enter\n");
942
905 if (this->pos) 943 if (this->pos)
906 route_info_free(this->pos); 944 route_info_free(this->pos);
945
907 this->pos = NULL; 946 this->pos = NULL;
908 this->pos = route_find_nearest_street(this->vehicleprofile, this->ms, pos); 947 this->pos = route_find_nearest_street(this->vehicleprofile, this->ms, pos);
909 948
910 // If there is no nearest street, bail out. 949 // If there is no nearest street, bail out.
911 if (!this->pos) 950 if (!this->pos)
921 * @brief Sets a route's current position based on coordinates from tracking 960 * @brief Sets a route's current position based on coordinates from tracking
922 * 961 *
923 * @param this The route to set the current position of 962 * @param this The route to set the current position of
924 * @param tracking The tracking to get the coordinates from 963 * @param tracking The tracking to get the coordinates from
925 */ 964 */
926void route_set_position_from_tracking(struct route *this, 965void route_set_position_from_tracking(struct route *this, struct tracking *tracking, enum projection pro)
927 struct tracking *tracking, enum projection pro)
928{ 966{
967 //// dbg(0, "enter\n");
968
929 struct coord *c; 969 struct coord *c;
930 struct route_info *ret; 970 struct route_info *ret;
931 struct street_data *sd; 971 struct street_data *sd;
932 972
933 //dbg(2, "enter\n"); 973 //dbg(2, "enter\n");
934 c = tracking_get_pos(tracking); 974 c = tracking_get_pos(tracking);
935 ret=g_new0(struct route_info, 1); 975 ret=g_new0(struct route_info, 1);
976
936 if (!ret) 977 if (!ret)
937 { 978 {
938 printf("%s:Out of memory\n", __FUNCTION__); 979 dbg(0, "Out of memory\n");
939 return; 980 return;
940 } 981 }
982
941 if (this->pos) 983 if (this->pos)
984 {
942 route_info_free(this->pos); 985 route_info_free(this->pos);
986 }
987
943 this->pos = NULL; 988 this->pos = NULL;
944 ret->c = *c; 989 ret->c = *c;
945 ret->lp = *c; 990 ret->lp = *c;
946 ret->pos = tracking_get_segment_pos(tracking); 991 ret->pos = tracking_get_segment_pos(tracking);
947 ret->street_direction = tracking_get_street_direction(tracking); 992 ret->street_direction = tracking_get_street_direction(tracking);
965 // ret->street ? ret->street->count - 1 : 0, 1010 // ret->street ? ret->street->count - 1 : 0,
966 // ret->street ? ret->street->c[ret->street->count - 1].x : 0, 1011 // ret->street ? ret->street->c[ret->street->count - 1].x : 0,
967 // ret->street ? ret->street->c[ret->street->count - 1].y : 0); 1012 // ret->street ? ret->street->c[ret->street->count - 1].y : 0);
968 this->pos = ret; 1013 this->pos = ret;
969 if (this->destinations) 1014 if (this->destinations)
1015 {
970 route_path_update(this, 0, 1); 1016 route_path_update(this, 0, 1);
1017 }
971 //dbg(2, "ret\n"); 1018 //dbg(2, "ret\n");
972} 1019}
973 1020
974/* Used for debuging of route_rect, what routing sees */ 1021/* Used for debuging of route_rect, what routing sees */
975struct map_selection *route_selection; 1022struct map_selection *route_selection;
978 * @brief Returns a single map selection 1025 * @brief Returns a single map selection
979 */ 1026 */
980struct map_selection * 1027struct map_selection *
981route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs) 1028route_rect(int order, struct coord *c1, struct coord *c2, int rel, int abs)
982{ 1029{
1030 //// dbg(0, "enter\n");
1031
983 int dx, dy, sx = 1, sy = 1, d, m; 1032 int dx, dy, sx = 1, sy = 1, d, m;
984 struct map_selection *sel=g_new(struct map_selection, 1); 1033 struct map_selection *sel=g_new(struct map_selection, 1);
1034
985 if (!sel) 1035 if (!sel)
986 { 1036 {
1037 dbg(0, "Out of memory\n");
987 printf("%s:Out of memory\n", __FUNCTION__); 1038 // printf("%s:Out of memory\n", __FUNCTION__);
988 return sel; 1039 return sel;
989 } 1040 }
1041
990 sel->order = order; 1042 sel->order = order;
991 sel->range.min = route_item_first; 1043 sel->range.min = route_item_first;
992 sel->range.max = route_item_last; 1044 sel->range.max = route_item_last;
993 dbg(1, "%p %p\n", c1, c2); 1045 // dbg(1, "%p %p\n", c1, c2);
994 dx = c1->x - c2->x; 1046 dx = c1->x - c2->x;
995 dy = c1->y - c2->y; 1047 dy = c1->y - c2->y;
1048
996 if (dx < 0) 1049 if (dx < 0)
997 { 1050 {
998 sx = -1; 1051 sx = -1;
999 sel->u.c_rect.lu.x = c1->x; 1052 sel->u.c_rect.lu.x = c1->x;
1000 sel->u.c_rect.rl.x = c2->x; 1053 sel->u.c_rect.rl.x = c2->x;
1002 else 1055 else
1003 { 1056 {
1004 sel->u.c_rect.lu.x = c2->x; 1057 sel->u.c_rect.lu.x = c2->x;
1005 sel->u.c_rect.rl.x = c1->x; 1058 sel->u.c_rect.rl.x = c1->x;
1006 } 1059 }
1060
1007 if (dy < 0) 1061 if (dy < 0)
1008 { 1062 {
1009 sy = -1; 1063 sy = -1;
1010 sel->u.c_rect.lu.y = c2->y; 1064 sel->u.c_rect.lu.y = c2->y;
1011 sel->u.c_rect.rl.y = c1->y; 1065 sel->u.c_rect.rl.y = c1->y;
1013 else 1067 else
1014 { 1068 {
1015 sel->u.c_rect.lu.y = c1->y; 1069 sel->u.c_rect.lu.y = c1->y;
1016 sel->u.c_rect.rl.y = c2->y; 1070 sel->u.c_rect.rl.y = c2->y;
1017 } 1071 }
1072
1018 if (dx * sx > dy * sy) 1073 if (dx * sx > dy * sy)
1074 {
1019 d = dx * sx; 1075 d = dx * sx;
1076 }
1020 else 1077 else
1078 {
1021 d = dy * sy; 1079 d = dy * sy;
1080 }
1081
1022 m = d * rel / 100 + abs; 1082 m = d * rel / 100 + abs;
1023 sel->u.c_rect.lu.x -= m; 1083 sel->u.c_rect.lu.x -= m;
1024 sel->u.c_rect.rl.x += m; 1084 sel->u.c_rect.rl.x += m;
1025 sel->u.c_rect.lu.y += m; 1085 sel->u.c_rect.lu.y += m;
1026 sel->u.c_rect.rl.y -= m; 1086 sel->u.c_rect.rl.y -= m;
1039 * @param c2 Corder 2 of the rectangle 1099 * @param c2 Corder 2 of the rectangle
1040 */ 1100 */
1041static struct map_selection * 1101static struct map_selection *
1042route_calc_selection(struct coord *c, int count, int try_harder) 1102route_calc_selection(struct coord *c, int count, int try_harder)
1043{ 1103{
1104 // dbg(0, "enter\n");
1105
1044 struct map_selection *ret, *sel; 1106 struct map_selection *ret, *sel;
1045 int i; 1107 int i;
1046 struct coord_rect r; 1108 struct coord_rect r;
1047 1109
1048 if (!count) 1110 if (!count)
1091 * 1153 *
1092 * @param sel Start of the list to be destroyed 1154 * @param sel Start of the list to be destroyed
1093 */ 1155 */
1094static void route_free_selection(struct map_selection *sel) 1156static void route_free_selection(struct map_selection *sel)
1095{ 1157{
1158 //// dbg(0, "enter\n");
1159
1096 struct map_selection *next; 1160 struct map_selection *next;
1097 while (sel) 1161 while (sel)
1098 { 1162 {
1099 next = sel->next; 1163 next = sel->next;
1100 g_free(sel); 1164 g_free(sel);
1102 } 1166 }
1103} 1167}
1104 1168
1105static void route_clear_destinations(struct route *this_) 1169static void route_clear_destinations(struct route *this_)
1106{ 1170{
1171 // dbg(0, "enter\n");
1172
1107 g_list_foreach(this_->destinations, (GFunc) route_info_free, NULL); 1173 g_list_foreach(this_->destinations, (GFunc) route_info_free, NULL);
1108 g_list_free(this_->destinations); 1174 g_list_free(this_->destinations);
1109 this_->destinations = NULL; 1175 this_->destinations = NULL;
1110} 1176}
1111 1177
1121 * @param async: If set, do routing asynchronously 1187 * @param async: If set, do routing asynchronously
1122 */ 1188 */
1123 1189
1124void route_set_destinations(struct route *this, struct pcoord *dst, int count, int async) 1190void route_set_destinations(struct route *this, struct pcoord *dst, int count, int async)
1125{ 1191{
1192 // dbg(0, "enter\n");
1193
1126 struct attr route_status; 1194 struct attr route_status;
1127 struct route_info *dsti; 1195 struct route_info *dsti;
1128 int i; 1196 int i;
1129 route_status.type = attr_route_status; 1197 route_status.type = attr_route_status;
1130 1198
1163 //profile(0,"end"); 1231 //profile(0,"end");
1164} 1232}
1165 1233
1166void route_add_destination(struct route *this, struct pcoord *dst, int async) 1234void route_add_destination(struct route *this, struct pcoord *dst, int async)
1167{ 1235{
1236 // dbg(0, "enter\n");
1237
1168 struct attr route_status; 1238 struct attr route_status;
1169 struct route_info *dsti; 1239 struct route_info *dsti;
1170 route_status.type = attr_route_status; 1240 route_status.type = attr_route_status;
1171 1241
1172 dsti = route_find_nearest_street(this->vehicleprofile, this->ms, &dst[0]); 1242 dsti = route_find_nearest_street(this->vehicleprofile, this->ms, &dst[0]);
1192 route_path_update(this, 1, async); 1262 route_path_update(this, 1, async);
1193} 1263}
1194 1264
1195int route_get_destinations(struct route *this, struct pcoord *pc, int count) 1265int route_get_destinations(struct route *this, struct pcoord *pc, int count)
1196{ 1266{
1267 // dbg(0, "enter\n");
1268
1197 int ret = 0; 1269 int ret = 0;
1198 GList *l = this->destinations; 1270 GList *l = this->destinations;
1199 while (l && ret < count) 1271 while (l && ret < count)
1200 { 1272 {
1201 struct route_info *dst = l->data; 1273 struct route_info *dst = l->data;
1209 return ret; 1281 return ret;
1210} 1282}
1211 1283
1212void route_set_destination(struct route *this, struct pcoord *dst, int async) 1284void route_set_destination(struct route *this, struct pcoord *dst, int async)
1213{ 1285{
1286 // dbg(0, "enter\n");
1287
1214 route_set_destinations(this, dst, dst ? 1 : 0, async); 1288 route_set_destinations(this, dst, dst ? 1 : 0, async);
1215} 1289}
1216 1290
1217void route_remove_waypoint(struct route *this) 1291void route_remove_waypoint(struct route *this)
1218{ 1292{
1293 // dbg(0, "enter\n");
1294
1219 struct route_path *path = this->path2; 1295 struct route_path *path = this->path2;
1220 this->destinations = g_list_remove(this->destinations, 1296 this->destinations = g_list_remove(this->destinations, this->destinations->data);
1221 this->destinations->data);
1222 this->path2 = this->path2->next; 1297 this->path2 = this->path2->next;
1223 route_path_destroy(path, 0); 1298 route_path_destroy(path, 0);
1299
1224 if (!this->destinations) 1300 if (!this->destinations)
1225 return; 1301 return;
1302
1226 route_graph_reset(this->graph); 1303 route_graph_reset(this->graph);
1227 this->current_dst = this->destinations->data; 1304 this->current_dst = this->destinations->data;
1305
1228 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, 1306 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, this->route_graph_flood_done_cb);
1229 this->route_graph_flood_done_cb);
1230 1307
1231} 1308}
1232 1309
1233/** 1310/**
1234 * @brief Gets the route_graph_point with the specified coordinates 1311 * @brief Gets the route_graph_point with the specified coordinates
1237 * @param c Coordinates to search for 1314 * @param c Coordinates to search for
1238 * @param last The last route graph point returned to iterate over multiple points with the same coordinates 1315 * @param last The last route graph point returned to iterate over multiple points with the same coordinates
1239 * @return The point at the specified coordinates or NULL if not found 1316 * @return The point at the specified coordinates or NULL if not found
1240 */ 1317 */
1241static struct route_graph_point * 1318static struct route_graph_point *
1242route_graph_get_point_next(struct route_graph *this, struct coord *c, 1319route_graph_get_point_next(struct route_graph *this, struct coord *c, struct route_graph_point *last)
1243 struct route_graph_point *last)
1244{ 1320{
1321 //// dbg(0, "enter\n");
1322
1245 struct route_graph_point *p; 1323 struct route_graph_point *p;
1246 int seen = 0, hashval = HASHCOORD(c); 1324 int seen = 0, hashval = HASHCOORD(c);
1247 p = this->hash[hashval]; 1325 p = this->hash[hashval];
1248 while (p) 1326 while (p)
1249 { 1327 {
1260} 1338}
1261 1339
1262static struct route_graph_point * 1340static struct route_graph_point *
1263route_graph_get_point(struct route_graph *this, struct coord *c) 1341route_graph_get_point(struct route_graph *this, struct coord *c)
1264{ 1342{
1343 //// dbg(0, "enter\n");
1344
1265 return route_graph_get_point_next(this, c, NULL); 1345 return route_graph_get_point_next(this, c, NULL);
1266} 1346}
1267 1347
1268/** 1348/**
1269 * @brief Gets the last route_graph_point with the specified coordinates 1349 * @brief Gets the last route_graph_point with the specified coordinates
1273 * @return The point at the specified coordinates or NULL if not found 1353 * @return The point at the specified coordinates or NULL if not found
1274 */ 1354 */
1275static struct route_graph_point * 1355static struct route_graph_point *
1276route_graph_get_point_last(struct route_graph *this, struct coord *c) 1356route_graph_get_point_last(struct route_graph *this, struct coord *c)
1277{ 1357{
1358 //// dbg(0, "enter\n");
1359
1278 struct route_graph_point *p, *ret = NULL; 1360 struct route_graph_point *p, *ret = NULL;
1279 int hashval = HASHCOORD(c); 1361 int hashval = HASHCOORD(c);
1280 p = this->hash[hashval]; 1362 p = this->hash[hashval];
1281 while (p) 1363 while (p)
1282 { 1364 {
1292 * 1374 *
1293 * @param this The route to insert the point into 1375 * @param this The route to insert the point into
1294 * @param f The coordinates at which the point should be created 1376 * @param f The coordinates at which the point should be created
1295 * @return The point created 1377 * @return The point created
1296 */ 1378 */
1297
1298static struct route_graph_point * 1379static struct route_graph_point *
1299route_graph_point_new(struct route_graph *this, struct coord *f) 1380route_graph_point_new(struct route_graph *this, struct coord *f)
1300{ 1381{
1382 //// dbg(0, "enter\n");
1383
1301 int hashval; 1384 int hashval;
1302 struct route_graph_point *p; 1385 struct route_graph_point *p;
1303 1386
1304 hashval = HASHCOORD(f); 1387 hashval = HASHCOORD(f);
1305 if (debug_route) 1388 if (debug_route)
1306 printf("p (0x%x,0x%x)\n", f->x, f->y); 1389 printf("p (0x%x,0x%x)\n", f->x, f->y);
1390
1307 p=g_slice_new0(struct route_graph_point); 1391 p=g_slice_new0(struct route_graph_point);
1308 p->hash_next = this->hash[hashval]; 1392 p->hash_next = this->hash[hashval];
1309 this->hash[hashval] = p; 1393 this->hash[hashval] = p;
1310 p->value = INT_MAX; 1394 p->value = INT_MAX;
1311 p->c = *f; 1395 p->c = *f;
1396
1312 return p; 1397 return p;
1313} 1398}
1314 1399
1315/** 1400/**
1316 * @brief Inserts a point into the route graph at the specified coordinates 1401 * @brief Inserts a point into the route graph at the specified coordinates
1323 * @return The point inserted or NULL on failure 1408 * @return The point inserted or NULL on failure
1324 */ 1409 */
1325static struct route_graph_point * 1410static struct route_graph_point *
1326route_graph_add_point(struct route_graph *this, struct coord *f) 1411route_graph_add_point(struct route_graph *this, struct coord *f)
1327{ 1412{
1413 //// dbg(0, "enter\n");
1414
1328 struct route_graph_point *p; 1415 struct route_graph_point *p;
1329 1416
1330 p = route_graph_get_point(this, f); 1417 p = route_graph_get_point(this, f);
1331 if (!p) 1418 if (!p)
1332 p = route_graph_point_new(this, f); 1419 p = route_graph_point_new(this, f);
1338 * 1425 *
1339 * @param this The route graph to delete all points from 1426 * @param this The route graph to delete all points from
1340 */ 1427 */
1341static void route_graph_free_points(struct route_graph *this) 1428static void route_graph_free_points(struct route_graph *this)
1342{ 1429{
1430 //// dbg(0, "enter\n");
1431
1343 struct route_graph_point *curr, *next; 1432 struct route_graph_point *curr, *next;
1344 int i; 1433 int i;
1345 for (i = 0; i < HASH_SIZE; i++) 1434 for (i = 0; i < HASH_SIZE; i++)
1346 { 1435 {
1347 curr = this->hash[i]; 1436 curr = this->hash[i];
1360 * 1449 *
1361 * @param this The route graph to reset 1450 * @param this The route graph to reset
1362 */ 1451 */
1363static void route_graph_reset(struct route_graph *this) 1452static void route_graph_reset(struct route_graph *this)
1364{ 1453{
1454 // dbg(0, "enter\n");
1455
1365 struct route_graph_point *curr; 1456 struct route_graph_point *curr;
1366 int i; 1457 int i;
1367 for (i = 0; i < HASH_SIZE; i++) 1458 for (i = 0; i < HASH_SIZE; i++)
1368 { 1459 {
1369 curr = this->hash[i]; 1460 curr = this->hash[i];
1386 * @param seg The route graph segment the field is appended to 1477 * @param seg The route graph segment the field is appended to
1387 * @param type Type of the field that should be returned 1478 * @param type Type of the field that should be returned
1388 * @return A pointer to a field of a certain type, or NULL if no such field is present 1479 * @return A pointer to a field of a certain type, or NULL if no such field is present
1389 */ 1480 */
1390static void * 1481static void *
1391route_segment_data_field_pos(struct route_segment_data *seg, 1482route_segment_data_field_pos(struct route_segment_data *seg, enum attr_type type)
1392 enum attr_type type)
1393{ 1483{
1484 // // dbg(0, "enter\n");
1485
1394 unsigned char *ptr; 1486 unsigned char *ptr;
1395 1487
1396 ptr = ((unsigned char*) seg) + sizeof(struct route_segment_data); 1488 ptr = ((unsigned char*) seg) + sizeof(struct route_segment_data);
1397 1489
1398 if (seg->flags & AF_SPEED_LIMIT) 1490 if (seg->flags & AF_SPEED_LIMIT)
1425/** 1517/**
1426 * @brief Calculates the size of a route_segment_data struct with given flags 1518 * @brief Calculates the size of a route_segment_data struct with given flags
1427 * 1519 *
1428 * @param flags The flags of the route_segment_data 1520 * @param flags The flags of the route_segment_data
1429 */ 1521 */
1430
1431static int route_segment_data_size(int flags) 1522static int route_segment_data_size(int flags)
1432{ 1523{
1524 //// dbg(0, "enter\n");
1525
1433 int ret = sizeof(struct route_segment_data); 1526 int ret = sizeof(struct route_segment_data);
1434 if (flags & AF_SPEED_LIMIT) 1527 if (flags & AF_SPEED_LIMIT)
1435 ret += sizeof(int); 1528 ret += sizeof(int);
1436 if (flags & AF_SEGMENTED) 1529 if (flags & AF_SEGMENTED)
1437 ret += sizeof(int); 1530 ret += sizeof(int);
1440 if (flags & AF_DANGEROUS_GOODS) 1533 if (flags & AF_DANGEROUS_GOODS)
1441 ret += sizeof(int); 1534 ret += sizeof(int);
1442 return ret; 1535 return ret;
1443} 1536}
1444 1537
1445static int route_graph_segment_is_duplicate(struct route_graph_point *start, 1538static int route_graph_segment_is_duplicate(struct route_graph_point *start, struct route_graph_segment_data *data)
1446 struct route_graph_segment_data *data)
1447{ 1539{
1540 //// dbg(0, "enter\n");
1541
1448 struct route_graph_segment *s; 1542 struct route_graph_segment *s;
1449 s = start->start; 1543 s = start->start;
1450 while (s) 1544 while (s)
1451 { 1545 {
1452 if (item_is_equal(*data->item, s->data.item)) 1546 if (item_is_equal(*data->item, s->data.item))
1479 * @param item The item that is represented by this segment 1573 * @param item The item that is represented by this segment
1480 * @param flags Flags for this segment 1574 * @param flags Flags for this segment
1481 * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item 1575 * @param offset If the item passed in "item" is segmented (i.e. divided into several segments), this indicates the position of this segment within the item
1482 * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known. 1576 * @param maxspeed The maximum speed allowed on this segment in km/h. -1 if not known.
1483 */ 1577 */
1484static void route_graph_add_segment(struct route_graph *this, 1578static void route_graph_add_segment(struct route_graph *this, struct route_graph_point *start, struct route_graph_point *end, struct route_graph_segment_data *data)
1485 struct route_graph_point *start, struct route_graph_point *end,
1486 struct route_graph_segment_data *data)
1487{ 1579{
1580 //// dbg(0, "enter\n");
1581
1488 struct route_graph_segment *s; 1582 struct route_graph_segment *s;
1489 int size; 1583 int size;
1490 1584
1491 size = sizeof(struct route_graph_segment) 1585 size = sizeof(struct route_graph_segment) - sizeof(struct route_segment_data) + route_segment_data_size(data->flags);
1492 - sizeof(struct route_segment_data) + route_segment_data_size( 1586
1493 data->flags);
1494 s = g_slice_alloc0(size); 1587 s = g_slice_alloc0(size);
1588
1495 if (!s) 1589 if (!s)
1496 { 1590 {
1497 printf("%s:Out of memory\n", __FUNCTION__); 1591 printf("%s:Out of memory\n", __FUNCTION__);
1498 return; 1592 return;
1499 } 1593 }
1594
1500 s->start = start; 1595 s->start = start;
1501 s->start_next = start->start; 1596 s->start_next = start->start;
1502 start->start = s; 1597 start->start = s;
1503 s->end = end; 1598 s->end = end;
1504 s->end_next = end->end; 1599 s->end_next = end->end;
1508 s->data.item = *data->item; 1603 s->data.item = *data->item;
1509 s->data.flags = data->flags; 1604 s->data.flags = data->flags;
1510 1605
1511 if (data->flags & AF_SPEED_LIMIT) 1606 if (data->flags & AF_SPEED_LIMIT)
1512 RSD_MAXSPEED(&s->data) = data->maxspeed; 1607 RSD_MAXSPEED(&s->data) = data->maxspeed;
1608
1513 if (data->flags & AF_SEGMENTED) 1609 if (data->flags & AF_SEGMENTED)
1514 RSD_OFFSET(&s->data) = data->offset; 1610 RSD_OFFSET(&s->data) = data->offset;
1611
1515 if (data->flags & AF_SIZE_OR_WEIGHT_LIMIT) 1612 if (data->flags & AF_SIZE_OR_WEIGHT_LIMIT)
1516 RSD_SIZE_WEIGHT(&s->data) = data->size_weight; 1613 RSD_SIZE_WEIGHT(&s->data) = data->size_weight;
1614
1517 if (data->flags & AF_DANGEROUS_GOODS) 1615 if (data->flags & AF_DANGEROUS_GOODS)
1518 RSD_DANGEROUS_GOODS(&s->data) = data->dangerous_goods; 1616 RSD_DANGEROUS_GOODS(&s->data) = data->dangerous_goods;
1519 1617
1520 s->next = this->route_segments; 1618 s->next = this->route_segments;
1521 this->route_segments = s; 1619 this->route_segments = s;
1620
1522 if (debug_route) 1621 if (debug_route)
1622 {
1523 printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x, 1623 printf("l (0x%x,0x%x)-(0x%x,0x%x)\n", start->c.x, start->c.y, end->c.x, end->c.y);
1524 end->c.y); 1624 }
1525} 1625}
1526 1626
1527/** 1627/**
1528 * @brief Gets all the coordinates of an item 1628 * @brief Gets all the coordinates of an item
1529 * 1629 *
1540 * @param max Maximum number of coordinates to return 1640 * @param max Maximum number of coordinates to return
1541 * @param start First coordinate to get 1641 * @param start First coordinate to get
1542 * @param end Last coordinate to get 1642 * @param end Last coordinate to get
1543 * @return The number of coordinates returned 1643 * @return The number of coordinates returned
1544 */ 1644 */
1545static int get_item_seg_coords(struct item *i, struct coord *c, int max, 1645static int get_item_seg_coords(struct item *i, struct coord *c, int max, struct coord *start, struct coord *end)
1546 struct coord *start, struct coord *end)
1547{ 1646{
1647 //// dbg(0, "enter\n");
1648
1548 struct map_rect *mr; 1649 struct map_rect *mr;
1549 struct item *item; 1650 struct item *item;
1550 int rc = 0, p = 0; 1651 int rc = 0, p = 0;
1551 struct coord c1; 1652 struct coord c1;
1552 mr = map_rect_new(i->map, NULL); 1653 mr = map_rect_new(i->map, NULL);
1654
1553 if (!mr) 1655 if (!mr)
1554 return 0; 1656 return 0;
1657
1555 item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo); 1658 item = map_rect_get_item_byid(mr, i->id_hi, i->id_lo);
1659
1556 if (item) 1660 if (item)
1557 { 1661 {
1558 rc = item_coord_get(item, &c1, 1); 1662 rc = item_coord_get(item, &c1, 1);
1663
1559 while (rc && (c1.x != start->x || c1.y != start->y)) 1664 while (rc && (c1.x != start->x || c1.y != start->y))
1560 { 1665 {
1561 rc = item_coord_get(item, &c1, 1); 1666 rc = item_coord_get(item, &c1, 1);
1562 } 1667 }
1668
1563 while (rc && p < max) 1669 while (rc && p < max)
1564 { 1670 {
1565 c[p++] = c1; 1671 c[p++] = c1;
1566 if (c1.x == end->x && c1.y == end->y) 1672 if (c1.x == end->x && c1.y == end->y)
1567 break; 1673 break;
1579 * @param item The item whose segment to remove 1685 * @param item The item whose segment to remove
1580 * @param offset Offset of the segment within the item to remove. If the item is not segmented this should be 1. 1686 * @param offset Offset of the segment within the item to remove. If the item is not segmented this should be 1.
1581 * @return The segment removed 1687 * @return The segment removed
1582 */ 1688 */
1583static struct route_path_segment * 1689static struct route_path_segment *
1584route_extract_segment_from_path(struct route_path *path, struct item *item, 1690route_extract_segment_from_path(struct route_path *path, struct item *item, int offset)
1585 int offset)
1586{ 1691{
1692 //// dbg(0, "enter\n");
1693
1587 int soffset; 1694 int soffset;
1588 struct route_path_segment *sp = NULL, *s; 1695 struct route_path_segment *sp = NULL, *s;
1589 s = path->path; 1696 s = path->path;
1590 while (s) 1697 while (s)
1591 { 1698 {
1621 * @brief Adds a segment and the end of a path 1728 * @brief Adds a segment and the end of a path
1622 * 1729 *
1623 * @param this The path to add the segment to 1730 * @param this The path to add the segment to
1624 * @param segment The segment to add 1731 * @param segment The segment to add
1625 */ 1732 */
1626static void route_path_add_segment(struct route_path *this, 1733static void route_path_add_segment(struct route_path *this, struct route_path_segment *segment)
1627 struct route_path_segment *segment)
1628{ 1734{
1735 //// dbg(0, "enter\n");
1736
1629 if (!this->path) 1737 if (!this->path)
1630 this->path = segment; 1738 this->path = segment;
1631 if (this->path_last) 1739 if (this->path_last)
1632 this->path_last->next = segment; 1740 this->path_last->next = segment;
1633 this->path_last = segment; 1741 this->path_last = segment;
1641 * @param this The path to add the item to 1749 * @param this The path to add the item to
1642 * @param start coordinate to add to the start of the item. If none should be added, make this NULL. 1750 * @param start coordinate to add to the start of the item. If none should be added, make this NULL.
1643 * @param end coordinate to add to the end of the item. If none should be added, make this NULL. 1751 * @param end coordinate to add to the end of the item. If none should be added, make this NULL.
1644 * @param len The length of the item 1752 * @param len The length of the item
1645 */ 1753 */
1646static void route_path_add_line(struct route_path *this, struct coord *start, 1754static void route_path_add_line(struct route_path *this, struct coord *start, struct coord *end, int len)
1647 struct coord *end, int len)
1648{ 1755{
1756 //// dbg(0, "enter\n");
1757
1649 int ccnt = 2; 1758 int ccnt = 2;
1650 struct route_path_segment *segment; 1759 struct route_path_segment *segment;
1651 int seg_size, seg_dat_size; 1760 int seg_size, seg_dat_size;
1652 1761
1653 //dbg(1, "line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x, 1762 //dbg(1, "line from 0x%x,0x%x-0x%x,0x%x\n", start->x, start->y, end->x,
1681 * @param rgs Segment of the route graph that should be "copied" to the route path 1790 * @param rgs Segment of the route graph that should be "copied" to the route path
1682 * @param dir Order in which to add the coordinates. See route_path_add_item() 1791 * @param dir Order in which to add the coordinates. See route_path_add_item()
1683 * @param pos Information about start point if this is the first segment 1792 * @param pos Information about start point if this is the first segment
1684 * @param dst Information about end point if this is the last segment 1793 * @param dst Information about end point if this is the last segment
1685 */ 1794 */
1686 1795static 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)
1687static int route_path_add_item_from_graph(struct route_path *this,
1688 struct route_path *oldpath, struct route_graph_segment *rgs, int dir,
1689 struct route_info *pos, struct route_info *dst)
1690{ 1796{
1797 //// dbg(0, "enter\n");
1798
1691 struct route_path_segment *segment; 1799 struct route_path_segment *segment;
1692 int i, ccnt, extra = 0, ret = 0; 1800 int i, ccnt, extra = 0, ret = 0;
1693 struct coord *c, *cd, ca[2048]; 1801 struct coord *c, *cd, ca[2048];
1694 int offset = 1; 1802 int offset = 1;
1695 int seg_size, seg_dat_size; 1803 int seg_size, seg_dat_size;
1704 if (oldpath) 1812 if (oldpath)
1705 { 1813 {
1706 segment = item_hash_lookup(oldpath->path_hash, &rgs->data.item); 1814 segment = item_hash_lookup(oldpath->path_hash, &rgs->data.item);
1707 if (segment && segment->direction == dir) 1815 if (segment && segment->direction == dir)
1708 { 1816 {
1709 segment = route_extract_segment_from_path(oldpath, &rgs->data.item, 1817 segment = route_extract_segment_from_path(oldpath, &rgs->data.item, offset);
1710 offset);
1711 if (segment) 1818 if (segment)
1712 { 1819 {
1713 ret = 1; 1820 ret = 1;
1714 if (!pos) 1821 if (!pos)
1715 goto linkold; 1822 goto linkold;
1776 len = dst->lenneg; 1883 len = dst->lenneg;
1777 } 1884 }
1778 } 1885 }
1779 else 1886 else
1780 { 1887 {
1781 ccnt = get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, 1888 ccnt = get_item_seg_coords(&rgs->data.item, ca, 2047, &rgs->start->c, &rgs->end->c);
1782 &rgs->end->c);
1783 c = ca; 1889 c = ca;
1784 } 1890 }
1785 seg_size = sizeof(*segment) + sizeof(struct coord) * (ccnt + extra); 1891 seg_size = sizeof(*segment) + sizeof(struct coord) * (ccnt + extra);
1786 seg_dat_size = route_segment_data_size(rgs->data.flags); 1892 seg_dat_size = route_segment_data_size(rgs->data.flags);
1787 segment = g_malloc0(seg_size + seg_dat_size); 1893 segment = g_malloc0(seg_size + seg_dat_size);
1829 * 1935 *
1830 * @param this The graph to destroy all segments from 1936 * @param this The graph to destroy all segments from
1831 */ 1937 */
1832static void route_graph_free_segments(struct route_graph *this) 1938static void route_graph_free_segments(struct route_graph *this)
1833{ 1939{
1940 //// dbg(0, "enter\n");
1941
1834 struct route_graph_segment *curr, *next; 1942 struct route_graph_segment *curr, *next;
1835 int size; 1943 int size;
1836 curr = this->route_segments; 1944 curr = this->route_segments;
1837 while (curr) 1945 while (curr)
1838 { 1946 {
1839 next = curr->next; 1947 next = curr->next;
1840 size = sizeof(struct route_graph_segment) 1948 size = sizeof(struct route_graph_segment) - sizeof(struct route_segment_data) + route_segment_data_size(curr->data.flags);
1841 - sizeof(struct route_segment_data) + route_segment_data_size(
1842 curr->data.flags);
1843 g_slice_free1(size, curr); 1949 g_slice_free1(size, curr);
1844 curr = next; 1950 curr = next;
1845 } 1951 }
1846 this->route_segments = NULL; 1952 this->route_segments = NULL;
1847} 1953}
1851 * 1957 *
1852 * @param this The route graph to be destroyed 1958 * @param this The route graph to be destroyed
1853 */ 1959 */
1854void route_graph_destroy(struct route_graph *this) 1960void route_graph_destroy(struct route_graph *this)
1855{ 1961{
1962 // dbg(0, "enter\n");
1963
1856 if (this) 1964 if (this)
1857 { 1965 {
1858 route_graph_build_done(this, 1); 1966 route_graph_build_done(this, 1);
1859 route_graph_free_points(this); 1967 route_graph_free_points(this);
1860 route_graph_free_segments(this); 1968 route_graph_free_segments(this);
1870 * @param profile The routing preferences 1978 * @param profile The routing preferences
1871 * @param over The segment which is passed 1979 * @param over The segment which is passed
1872 * @param dist A traffic distortion if applicable 1980 * @param dist A traffic distortion if applicable
1873 * @return The estimated speed 1981 * @return The estimated speed
1874 */ 1982 */
1875static int route_seg_speed(struct vehicleprofile *profile, 1983static int route_seg_speed(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist)
1876 struct route_segment_data *over, struct route_traffic_distortion *dist)
1877{ 1984{
1985 //// dbg(0, "enter\n");
1986
1878 struct roadprofile *roadprofile = vehicleprofile_get_roadprofile(profile, 1987 struct roadprofile *roadprofile = vehicleprofile_get_roadprofile(profile, over->item.type);
1879 over->item.type);
1880 int speed, maxspeed; 1988 int speed, maxspeed;
1881 if (!roadprofile || !roadprofile->route_weight) 1989 if (!roadprofile || !roadprofile->route_weight)
1882 return 0; 1990 return 0;
1883 /* maxspeed_handling: 0=always, 1 only if maxspeed restricts the speed, 2 never */ 1991 /* maxspeed_handling: 0=always, 1 only if maxspeed restricts the speed, 2 never */
1884 speed = roadprofile->route_weight; 1992 speed = roadprofile->route_weight;
1892 } 2000 }
1893 else 2001 else
1894 maxspeed = INT_MAX; 2002 maxspeed = INT_MAX;
1895 if (dist && maxspeed > dist->maxspeed) 2003 if (dist && maxspeed > dist->maxspeed)
1896 maxspeed = dist->maxspeed; 2004 maxspeed = dist->maxspeed;
1897 if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed 2005 if (maxspeed != INT_MAX && (profile->maxspeed_handling != 1 || maxspeed < speed))
1898 < speed))
1899 speed = maxspeed; 2006 speed = maxspeed;
1900 } 2007 }
1901 if (over->flags & AF_DANGEROUS_GOODS) 2008 if (over->flags & AF_DANGEROUS_GOODS)
1902 { 2009 {
1903 if (profile->dangerous_goods & RSD_DANGEROUS_GOODS(over)) 2010 if (profile->dangerous_goods & RSD_DANGEROUS_GOODS(over))
1904 return 0; 2011 return 0;
1905 } 2012 }
1906 if (over->flags & AF_SIZE_OR_WEIGHT_LIMIT) 2013 if (over->flags & AF_SIZE_OR_WEIGHT_LIMIT)
1907 { 2014 {
1908 struct size_weight_limit *size_weight = &RSD_SIZE_WEIGHT(over); 2015 struct size_weight_limit *size_weight = &RSD_SIZE_WEIGHT(over);
1909 if (size_weight->width != -1 && profile->width != -1 && profile->width 2016 if (size_weight->width != -1 && profile->width != -1 && profile->width > size_weight->width)
1910 > size_weight->width)
1911 return 0; 2017 return 0;
1912 if (size_weight->height != -1 && profile->height != -1 2018 if (size_weight->height != -1 && profile->height != -1 && profile->height > size_weight->height)
1913 && profile->height > size_weight->height)
1914 return 0; 2019 return 0;
1915 if (size_weight->length != -1 && profile->length != -1 2020 if (size_weight->length != -1 && profile->length != -1 && profile->length > size_weight->length)
1916 && profile->length > size_weight->length)
1917 return 0; 2021 return 0;
1918 if (size_weight->weight != -1 && profile->weight != -1 2022 if (size_weight->weight != -1 && profile->weight != -1 && profile->weight > size_weight->weight)
1919 && profile->weight > size_weight->weight)
1920 return 0; 2023 return 0;
1921 if (size_weight->axle_weight != -1 && profile->axle_weight != -1 2024 if (size_weight->axle_weight != -1 && profile->axle_weight != -1 && profile->axle_weight > size_weight->axle_weight)
1922 && profile->axle_weight > size_weight->axle_weight)
1923 return 0; 2025 return 0;
1924 } 2026 }
1925 return speed; 2027 return speed;
1926} 2028}
1927 2029
1932 * the item passed in item in tenth of seconds. 2034 * the item passed in item in tenth of seconds.
1933 * 2035 *
1934 * @param profile The routing preferences 2036 * @param profile The routing preferences
1935 * @param over The segment which is passed 2037 * @param over The segment which is passed
1936 * @param dist A traffic distortion if applicable 2038 * @param dist A traffic distortion if applicable
1937 * @return The time needed to drive len on item in thenth of senconds 2039 * @return The time needed to drive len on item in thenth of seconds
1938 */ 2040 */
1939 2041static int route_time_seg(struct vehicleprofile *profile, struct route_segment_data *over, struct route_traffic_distortion *dist)
1940static int route_time_seg(struct vehicleprofile *profile,
1941 struct route_segment_data *over, struct route_traffic_distortion *dist)
1942{ 2042{
2043 // // dbg(0, "enter\n");
2044
1943 int speed = route_seg_speed(profile, over, dist); 2045 int speed = route_seg_speed(profile, over, dist);
1944 if (!speed) 2046 if (!speed)
2047 {
1945 return INT_MAX; 2048 return INT_MAX;
2049 }
1946 return over->len * 36 / speed + (dist ? dist->delay : 0); 2050 return over->len * 36 / speed + (dist ? dist->delay : 0);
1947} 2051}
1948 2052
1949static int route_get_traffic_distortion(struct route_graph_segment *seg, 2053static int route_get_traffic_distortion(struct route_graph_segment *seg, struct route_traffic_distortion *ret)
1950 struct route_traffic_distortion *ret)
1951{ 2054{
2055 // // dbg(0, "enter\n");
2056
1952 struct route_graph_point *start = seg->start; 2057 struct route_graph_point *start = seg->start;
1953 struct route_graph_point *end = seg->end; 2058 struct route_graph_point *end = seg->end;
1954 struct route_graph_segment *tmp, *found = NULL; 2059 struct route_graph_segment *tmp, *found = NULL;
1955 tmp = start->start; 2060 tmp = start->start;
1956 while (tmp && !found) 2061 while (tmp && !found)
1957 { 2062 {
1958 if (tmp->data.item.type == type_traffic_distortion && tmp->start 2063 if (tmp->data.item.type == type_traffic_distortion && tmp->start == start && tmp->end == end)
1959 == start && tmp->end == end)
1960 found = tmp; 2064 found = tmp;
1961 tmp = tmp->start_next; 2065 tmp = tmp->start_next;
1962 } 2066 }
1963 tmp = start->end; 2067 tmp = start->end;
1964 while (tmp && !found) 2068 while (tmp && !found)
1965 { 2069 {
1966 if (tmp->data.item.type == type_traffic_distortion && tmp->end == start 2070 if (tmp->data.item.type == type_traffic_distortion && tmp->end == start && tmp->start == end)
1967 && tmp->start == end)
1968 found = tmp; 2071 found = tmp;
1969 tmp = tmp->end_next; 2072 tmp = tmp->end_next;
1970 } 2073 }
1971 if (found) 2074 if (found)
1972 { 2075 {
1978 return 1; 2081 return 1;
1979 } 2082 }
1980 return 0; 2083 return 0;
1981} 2084}
1982 2085
1983static int route_through_traffic_allowed(struct vehicleprofile *profile, 2086static int route_through_traffic_allowed(struct vehicleprofile *profile, struct route_graph_segment *seg)
1984 struct route_graph_segment *seg)
1985{ 2087{
2088 //// dbg(0, "enter\n");
2089
1986 return (seg->data.flags & AF_THROUGH_TRAFFIC_LIMIT) == 0; 2090 return (seg->data.flags & AF_THROUGH_TRAFFIC_LIMIT) == 0;
1987} 2091}
1988 2092
1989/** 2093/**
1990 * @brief Returns the "costs" of driving from point from over segment over in direction dir 2094 * @brief Returns the "costs" of driving from point "from" over segment "over" in direction "dir"
1991 * 2095 *
1992 * @param profile The routing preferences 2096 * @param profile The routing preferences
1993 * @param from The point where we are starting 2097 * @param from The point where we are starting
1994 * @param over The segment we are using 2098 * @param over The segment we are using
1995 * @param dir The direction of segment which we are driving 2099 * @param dir The direction of segment which we are driving
1996 * @return The "costs" needed to drive len on item 2100 * @return The "costs" needed to drive len on item
1997 */ 2101 */
1998 2102static int route_value_seg(struct vehicleprofile *profile, struct route_graph_point *from, struct route_graph_segment *over, int dir)
1999static int route_value_seg(struct vehicleprofile *profile,
2000 struct route_graph_point *from, struct route_graph_segment *over,
2001 int dir)
2002{ 2103{
2104 //// dbg(0, "enter\n");
2105
2003 int ret; 2106 int ret;
2004 struct route_traffic_distortion dist, *distp = NULL; 2107 struct route_traffic_distortion dist, *distp = NULL;
2005#if 0 2108#if 0
2006 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); 2109 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);
2007#endif 2110#endif
2008 if ((over->data.flags & (dir >= 0 ? profile->flags_forward_mask 2111 if ((over->data.flags & (dir >= 0 ? profile->flags_forward_mask : profile->flags_reverse_mask)) != profile->flags)
2009 : profile->flags_reverse_mask)) != profile->flags)
2010 return INT_MAX; 2112 return INT_MAX;
2011 if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION)) 2113 if (dir > 0 && (over->start->flags & RP_TURN_RESTRICTION))
2012 return INT_MAX; 2114 return INT_MAX;
2013 if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION)) 2115 if (dir < 0 && (over->end->flags & RP_TURN_RESTRICTION))
2014 return INT_MAX; 2116 return INT_MAX;
2015 if (from && from->seg == over) 2117 if (from && from->seg == over)
2016 return INT_MAX; 2118 return INT_MAX;
2017 if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags 2119 if ((over->start->flags & RP_TRAFFIC_DISTORTION) && (over->end->flags & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over, &dist))
2018 & RP_TRAFFIC_DISTORTION) && route_get_traffic_distortion(over,
2019 &dist))
2020 { 2120 {
2021 distp = &dist; 2121 distp = &dist;
2022 } 2122 }
2023 ret = route_time_seg(profile, &over->data, distp); 2123 ret = route_time_seg(profile, &over->data, distp);
2024 if (ret == INT_MAX) 2124 if (ret == INT_MAX)
2025 return ret; 2125 return ret;
2026 if (!route_through_traffic_allowed(profile, over) && from 2126 if (!route_through_traffic_allowed(profile, over) && from && route_through_traffic_allowed(profile, from->seg))
2027 && route_through_traffic_allowed(profile, from->seg))
2028 ret += profile->through_traffic_penalty; 2127 ret += profile->through_traffic_penalty;
2029 return ret; 2128 return ret;
2030} 2129}
2031 2130
2032/** 2131/**
2033 * @brief Adds a route distortion item to the route graph 2132 * @brief Adds a route distortion item to the route graph
2034 * 2133 *
2035 * @param this The route graph to add to 2134 * @param this The route graph to add to
2036 * @param item The item to add 2135 * @param item The item to add
2037 */ 2136 */
2038static void route_process_traffic_distortion(struct route_graph *this, 2137static void route_process_traffic_distortion(struct route_graph *this, struct item *item)
2039 struct item *item)
2040{ 2138{
2041 //dbg(0,"EEnter\n"); 2139 // dbg(0, "enter\n");
2042 2140
2043 struct route_graph_point *s_pnt, *e_pnt; 2141 struct route_graph_point *s_pnt, *e_pnt;
2044 struct coord c, l; 2142 struct coord c, l;
2045 struct attr delay_attr, maxspeed_attr; 2143 struct attr delay_attr, maxspeed_attr;
2046 struct route_graph_segment_data data; 2144 struct route_graph_segment_data data;
2082 * @brief Adds a route distortion item to the route graph 2180 * @brief Adds a route distortion item to the route graph
2083 * 2181 *
2084 * @param this The route graph to add to 2182 * @param this The route graph to add to
2085 * @param item The item to add 2183 * @param item The item to add
2086 */ 2184 */
2087static void route_process_turn_restriction(struct route_graph *this, 2185static void route_process_turn_restriction(struct route_graph *this, struct item *item)
2088 struct item *item)
2089{ 2186{
2187 // dbg(0, "enter\n");
2188
2090 struct route_graph_point *pnt[4]; 2189 struct route_graph_point *pnt[4];
2091 struct coord c[5]; 2190 struct coord c[5];
2092 int i, count; 2191 int i, count;
2093 struct route_graph_segment_data data; 2192 struct route_graph_segment_data data;
2094 2193
2095 count = item_coord_get(item, c, 5); 2194 count = item_coord_get(item, c, 5);
2096 if (count != 3 && count != 4) 2195 if (count != 3 && count != 4)
2097 { 2196 {
2098 dbg(0, "wrong count %d\n", count); 2197 //dbg(0, "wrong count %d\n", count);
2099 return; 2198 return;
2100 } 2199 }
2101 if (count == 4) 2200 if (count == 4)
2102 { 2201 {
2103 return; 2202 return;
2136 * 2235 *
2137 * @param this The route graph to add to 2236 * @param this The route graph to add to
2138 * @param item The item to add 2237 * @param item The item to add
2139 * @param profile The vehicle profile currently in use 2238 * @param profile The vehicle profile currently in use
2140 */ 2239 */
2141static void route_process_street_graph(struct route_graph *this, 2240static void route_process_street_graph(struct route_graph *this, struct item *item, struct vehicleprofile *profile)
2142 struct item *item, struct vehicleprofile *profile)
2143{ 2241{
2242 //// dbg(0, "enter\n");
2243
2144#ifdef AVOID_FLOAT 2244#ifdef AVOID_FLOAT
2145 int len=0; 2245 int len=0;
2146#else 2246#else
2147 double len = 0; 2247 double len = 0;
2148#endif 2248#endif
2166 2266
2167 if (item_coord_get(item, &l, 1)) 2267 if (item_coord_get(item, &l, 1))
2168 { 2268 {
2169 int *default_flags = item_get_default_flags(item->type); 2269 int *default_flags = item_get_default_flags(item->type);
2170 if (!default_flags) 2270 if (!default_flags)
2271 {
2171 return; 2272 return;
2273 }
2172 if (item_attr_get(item, attr_flags, &attr)) 2274 if (item_attr_get(item, attr_flags, &attr))
2173 { 2275 {
2174 data.flags = attr.u.num; 2276 data.flags = attr.u.num;
2175 if (data.flags & AF_SEGMENTED) 2277 if (data.flags & AF_SEGMENTED)
2278 {
2176 segmented = 1; 2279 segmented = 1;
2280 }
2177 } 2281 }
2178 else 2282 else
2283 {
2179 data.flags = *default_flags; 2284 data.flags = *default_flags;
2285 }
2180 2286
2181 if (data.flags & AF_SPEED_LIMIT) 2287 if (data.flags & AF_SPEED_LIMIT)
2182 { 2288 {
2183 if (item_attr_get(item, attr_maxspeed, &attr)) 2289 if (item_attr_get(item, attr_maxspeed, &attr))
2290 {
2184 data.maxspeed = attr.u.num; 2291 data.maxspeed = attr.u.num;
2292 }
2185 } 2293 }
2186 if (data.flags & AF_DANGEROUS_GOODS) 2294 if (data.flags & AF_DANGEROUS_GOODS)
2187 { 2295 {
2188 if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr)) 2296 if (item_attr_get(item, attr_vehicle_dangerous_goods, &attr))
2297 {
2189 data.dangerous_goods = attr.u.num; 2298 data.dangerous_goods = attr.u.num;
2299 }
2190 else 2300 else
2301 {
2191 data.flags &= ~AF_DANGEROUS_GOODS; 2302 data.flags &= ~AF_DANGEROUS_GOODS;
2303 }
2192 } 2304 }
2193 if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT) 2305 if (data.flags & AF_SIZE_OR_WEIGHT_LIMIT)
2194 { 2306 {
2195 if (item_attr_get(item, attr_vehicle_width, &attr)) 2307 if (item_attr_get(item, attr_vehicle_width, &attr))
2196 data.size_weight.width = attr.u.num; 2308 data.size_weight.width = attr.u.num;
2224 } 2336 }
2225 e_pnt = route_graph_add_point(this, &l); 2337 e_pnt = route_graph_add_point(this, &l);
2226 dbg_assert(len >= 0); 2338 dbg_assert(len >= 0);
2227 data.len = len; 2339 data.len = len;
2228 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2340 if (!route_graph_segment_is_duplicate(s_pnt, &data))
2341 {
2229 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2342 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2343 }
2230 } 2344 }
2231 else 2345 else
2232 { 2346 {
2233 int isseg, rc; 2347 int isseg, rc;
2234 int sc = 0; 2348 int sc = 0;
2236 { 2350 {
2237 isseg = item_coord_is_node(item); 2351 isseg = item_coord_is_node(item);
2238 rc = item_coord_get(item, &c, 1); 2352 rc = item_coord_get(item, &c, 1);
2239 if (rc) 2353 if (rc)
2240 { 2354 {
2241 len
2242 += transform_distance(map_projection(item->map), 2355 len += transform_distance(map_projection(item->map), &l, &c);
2243 &l, &c);
2244 l = c; 2356 l = c;
2245 if (isseg) 2357 if (isseg)
2246 { 2358 {
2247 e_pnt = route_graph_add_point(this, &l); 2359 e_pnt = route_graph_add_point(this, &l);
2248 data.len = len; 2360 data.len = len;
2249 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2361 if (!route_graph_segment_is_duplicate(s_pnt, &data))
2362 {
2250 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2363 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2364 }
2251 data.offset++; 2365 data.offset++;
2252 s_pnt = route_graph_add_point(this, &l); 2366 s_pnt = route_graph_add_point(this, &l);
2253 len = 0; 2367 len = 0;
2254 } 2368 }
2255 } 2369 }
2256 } 2370 }
2257 while (rc); 2371 while (rc);
2372
2258 e_pnt = route_graph_add_point(this, &l); 2373 e_pnt = route_graph_add_point(this, &l);
2259 dbg_assert(len >= 0); 2374 dbg_assert(len >= 0);
2260 sc++; 2375 sc++;
2261 data.len = len; 2376 data.len = len;
2262 if (!route_graph_segment_is_duplicate(s_pnt, &data)) 2377 if (!route_graph_segment_is_duplicate(s_pnt, &data))
2378 {
2263 route_graph_add_segment(this, s_pnt, e_pnt, &data); 2379 route_graph_add_segment(this, s_pnt, e_pnt, &data);
2380 }
2264 } 2381 }
2265 } 2382 }
2266} 2383}
2267 2384
2268static struct route_graph_segment * 2385static struct route_graph_segment *
2269route_graph_get_segment(struct route_graph *graph, struct street_data *sd, 2386route_graph_get_segment(struct route_graph *graph, struct street_data *sd, struct route_graph_segment *last)
2270 struct route_graph_segment *last)
2271{ 2387{
2388 //// dbg(0, "enter\n");
2389
2272 struct route_graph_point *start = NULL; 2390 struct route_graph_point *start = NULL;
2273 struct route_graph_segment *s; 2391 struct route_graph_segment *s;
2274 int seen = 0; 2392 int seen = 0;
2275 2393
2276 while ((start = route_graph_get_point_next(graph, &sd->c[0], start))) 2394 while ((start = route_graph_get_point_next(graph, &sd->c[0], start)))
2300 * stated costs. 2418 * stated costs.
2301 * 2419 *
2302 * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look 2420 * This function uses Dijkstra's algorithm to do the routing. To understand it you should have a look
2303 * at this algorithm. 2421 * at this algorithm.
2304 */ 2422 */
2305static void route_graph_flood(struct route_graph *this, struct route_info *dst, 2423static void route_graph_flood(struct route_graph *this, struct route_info *dst, struct vehicleprofile *profile, struct callback *cb)
2306 struct vehicleprofile *profile, struct callback *cb)
2307{ 2424{
2425 // dbg(0, "enter\n");
2426
2308 struct route_graph_point *p_min; 2427 struct route_graph_point *p_min;
2309 struct route_graph_segment *s = NULL; 2428 struct route_graph_segment *s = NULL;
2310 int min, new, old, val; 2429 int min, new, old, val;
2311 struct fibheap *heap; /* This heap will hold all points with "temporarily" calculated costs */ 2430 struct fibheap *heap; /* This heap will hold all points with "temporarily" calculated costs */
2312 2431
2313 heap = fh_makekeyheap(); 2432 heap = fh_makekeyheap();
2314 2433
2434 // start from "wanted destination" and loop until "start position" is reached
2315 while ((s = route_graph_get_segment(this, dst->street, s))) 2435 while ((s = route_graph_get_segment(this, dst->street, s)))
2316 { 2436 {
2317 val = route_value_seg(profile, NULL, s, -1); 2437 val = route_value_seg(profile, NULL, s, -1);
2318 if (val != INT_MAX) 2438 if (val != INT_MAX)
2319 { 2439 {
2320 val = val * (100 - dst->percent) / 100; 2440 val = val * (100 - dst->percent) / 100;
2321 s->end->seg = s; 2441 s->end->seg = s;
2322 s->end->value = val; 2442 s->end->value = val;
2323 s->end->el = fh_insertkey(heap, s->end->value, s->end); 2443 s->end->el = fh_insertkey(heap, s->end->value, s->end);
2324 } 2444 }
2445
2325 val = route_value_seg(profile, NULL, s, 1); 2446 val = route_value_seg(profile, NULL, s, 1);
2326 if (val != INT_MAX) 2447 if (val != INT_MAX)
2327 { 2448 {
2328 val = val * dst->percent / 100; 2449 val = val * dst->percent / 100;
2329 s->start->seg = s; 2450 s->start->seg = s;
2330 s->start->value = val; 2451 s->start->value = val;
2331 s->start->el = fh_insertkey(heap, s->start->value, s->start); 2452 s->start->el = fh_insertkey(heap, s->start->value, s->start);
2332 } 2453 }
2333 } 2454 }
2455
2334 for (;;) 2456 for (;;)
2335 { 2457 {
2336 p_min = fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */ 2458 p_min = fh_extractmin(heap); /* Starting Dijkstra by selecting the point with the minimum costs on the heap */
2459
2337 if (!p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */ 2460 if (!p_min) /* There are no more points with temporarily calculated costs, Dijkstra has finished */
2461 {
2338 break; 2462 break;
2463 }
2464
2339 min = p_min->value; 2465 min = p_min->value;
2340 if (debug_route) 2466 if (debug_route)
2467 {
2341 printf("extract p=%p free el=%p min=%d, 0x%x, 0x%x\n", p_min, 2468 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);
2342 p_min->el, min, p_min->c.x, p_min->c.y); 2469 }
2470
2343 p_min->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */ 2471 p_min->el = NULL; /* This point is permanently calculated now, we've taken it out of the heap */
2472
2344 s = p_min->start; 2473 s = p_min->start;
2474
2345 while (s) 2475 while (s)
2346 { /* Iterating all the segments leading away from our point to update the points at their ends */ 2476 { /* Iterating all the segments leading away from our point to update the points at their ends */
2347 val = route_value_seg(profile, p_min, s, -1); 2477 val = route_value_seg(profile, p_min, s, -1);
2348 if (val != INT_MAX && !item_is_equal(s->data.item, 2478 if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg->data.item))
2349 p_min->seg->data.item))
2350 { 2479 {
2351 new = min + val; 2480 new = min + val;
2352 if (debug_route) 2481 if (debug_route)
2353 printf("begin %d len %d vs %d (0x%x,0x%x)\n", new, val, 2482 {
2354 s->end->value, s->end->c.x, s->end->c.y); 2483 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);
2484 }
2485
2355 if (new < s->end->value) 2486 if (new < s->end->value)
2356 { /* We've found a less costly way to reach the end of s, update it */ 2487 { /* We've found a less costly way to reach the end of s, update it */
2357 s->end->value = new; 2488 s->end->value = new;
2358 s->end->seg = s; 2489 s->end->seg = s;
2359 if (!s->end->el) 2490 if (!s->end->el)
2360 { 2491 {
2361 if (debug_route) 2492 if (debug_route)
2493 {
2362 printf("insert_end p=%p el=%p val=%d ", s->end, 2494 printf("insert_end p=%p el=%p val=%d ", s->end, s->end->el, s->end->value);
2363 s->end->el, s->end->value); 2495 }
2496
2364 s->end->el = fh_insertkey(heap, new, s->end); 2497 s->end->el = fh_insertkey(heap, new, s->end);
2498
2365 if (debug_route) 2499 if (debug_route)
2500 {
2366 printf("el new=%p\n", s->end->el); 2501 printf("el new=%p\n", s->end->el);
2502 }
2367 } 2503 }
2368 else 2504 else
2369 { 2505 {
2370 if (debug_route) 2506 if (debug_route)
2507 {
2371 printf("replace_end p=%p el=%p val=%d\n", s->end, 2508 printf("replace_end p=%p el=%p val=%d\n", s->end, s->end->el, s->end->value);
2372 s->end->el, s->end->value); 2509 }
2373 fh_replacekey(heap, s->end->el, new); 2510 fh_replacekey(heap, s->end->el, new);
2374 } 2511 }
2375 } 2512 }
2513
2376 if (debug_route) 2514 if (debug_route)
2515 {
2377 printf("\n"); 2516 printf("\n");
2517 }
2378 } 2518 }
2379 s = s->start_next; 2519 s = s->start_next;
2380 } 2520 }
2521
2381 s = p_min->end; 2522 s = p_min->end;
2523
2382 while (s) 2524 while (s)
2383 { /* Doing the same as above with the segments leading towards our point */ 2525 { /* Doing the same as above with the segments leading towards our point */
2384 val = route_value_seg(profile, p_min, s, 1); 2526 val = route_value_seg(profile, p_min, s, 1);
2385 if (val != INT_MAX && !item_is_equal(s->data.item, 2527 if (val != INT_MAX && !item_is_equal(s->data.item, p_min->seg->data.item))
2386 p_min->seg->data.item))
2387 { 2528 {
2388 new = min + val; 2529 new = min + val;
2389 if (debug_route) 2530 if (debug_route)
2390 printf("end %d len %d vs %d (0x%x,0x%x)\n", new, val, 2531 {
2391 s->start->value, s->start->c.x, s->start->c.y); 2532 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);
2533 }
2534
2392 if (new < s->start->value) 2535 if (new < s->start->value)
2393 { 2536 {
2394 old = s->start->value; 2537 old = s->start->value;
2395 s->start->value = new; 2538 s->start->value = new;
2396 s->start->seg = s; 2539 s->start->seg = s;
2397 if (!s->start->el) 2540 if (!s->start->el)
2398 { 2541 {
2399 if (debug_route) 2542 if (debug_route)
2543 {
2400 printf("insert_start p=%p el=%p val=%d ", s->start, 2544 printf("insert_start p=%p el=%p val=%d ", s->start, s->start->el, s->start->value);
2401 s->start->el, s->start->value); 2545 }
2402 s->start->el = fh_insertkey(heap, new, s->start); 2546 s->start->el = fh_insertkey(heap, new, s->start);
2403 if (debug_route) 2547 if (debug_route)
2548 {
2404 printf("el new=%p\n", s->start->el); 2549 printf("el new=%p\n", s->start->el);
2550 }
2405 } 2551 }
2406 else 2552 else
2407 { 2553 {
2408 if (debug_route) 2554 if (debug_route)
2409 printf("replace_start p=%p el=%p val=%d\n", 2555 {
2410 s->start, s->start->el, s->start->value); 2556 printf("replace_start p=%p el=%p val=%d\n", s->start, s->start->el, s->start->value);
2557 }
2411 fh_replacekey(heap, s->start->el, new); 2558 fh_replacekey(heap, s->start->el, new);
2412 } 2559 }
2413 } 2560 }
2414 if (debug_route) 2561 if (debug_route)
2562 {
2415 printf("\n"); 2563 printf("\n");
2564 }
2416 } 2565 }
2417 s = s->end_next; 2566 s = s->end_next;
2418 } 2567 }
2419 } 2568 }
2569
2420 fh_deleteheap(heap); 2570 fh_deleteheap(heap);
2571
2421 callback_call_0(cb); 2572 callback_call_0(cb);
2422 //dbg(1, "return\n");
2423} 2573}
2424 2574
2425/** 2575/**
2426 * @brief Starts an "offroad" path 2576 * @brief Starts an "offroad" path
2427 * 2577 *
2433 * @param dst The destination of the new path 2583 * @param dst The destination of the new path
2434 * @param dir Not used 2584 * @param dir Not used
2435 * @return The new path 2585 * @return The new path
2436 */ 2586 */
2437static struct route_path * 2587static struct route_path *
2438route_path_new_offroad(struct route_graph *this, struct route_info *pos, 2588route_path_new_offroad(struct route_graph *this, struct route_info *pos, struct route_info *dst)
2439 struct route_info *dst)
2440{ 2589{
2590 // dbg(0, "enter\n");
2591
2441 struct route_path *ret; 2592 struct route_path *ret;
2442 2593
2443 ret=g_new0(struct route_path, 1); 2594 ret=g_new0(struct route_path, 1);
2444 ret->in_use = 1; 2595 ret->in_use = 1;
2445 ret->path_hash = item_hash_new(); 2596 ret->path_hash = item_hash_new();
2459 * @param dist The distance in meters 2610 * @param dist The distance in meters
2460 * @return The coordinate where the user will be in that distance 2611 * @return The coordinate where the user will be in that distance
2461 */ 2612 */
2462struct coord route_get_coord_dist(struct route *this_, int dist) 2613struct coord route_get_coord_dist(struct route *this_, int dist)
2463{ 2614{
2615 // dbg(0, "enter\n");
2616
2464 int d, l, i, len; 2617 int d, l, i, len;
2465 int dx, dy; 2618 int dx, dy;
2466 double frac; 2619 double frac;
2467 struct route_path_segment *cur; 2620 struct route_path_segment *cur;
2468 struct coord ret; 2621 struct coord ret;
2524 * @param dst The destination of the route 2677 * @param dst The destination of the route
2525 * @param preferences The routing preferences 2678 * @param preferences The routing preferences
2526 * @return The new route path 2679 * @return The new route path
2527 */ 2680 */
2528static struct route_path * 2681static struct route_path *
2529route_path_new(struct route_graph *this, struct route_path *oldpath, 2682route_path_new(struct route_graph *this, struct route_path *oldpath, struct route_info *pos, struct route_info *dst, struct vehicleprofile *profile)
2530 struct route_info *pos, struct route_info *dst,
2531 struct vehicleprofile *profile)
2532{ 2683{
2684 // dbg(0, "enter\n");
2685
2533 struct route_graph_segment *first, *s = NULL, *s1 = NULL, *s2 = NULL; 2686 struct route_graph_segment *first, *s = NULL, *s1 = NULL, *s2 = NULL;
2534 struct route_graph_point *start; 2687 struct route_graph_point *start;
2535 struct route_info *posinfo, *dstinfo; 2688 struct route_info *posinfo, *dstinfo;
2536 int segs = 0; 2689 int segs = 0;
2537 int val1 = INT_MAX, val2 = INT_MAX; 2690 int val1 = INT_MAX, val2 = INT_MAX;
2538 int val, val1_new, val2_new; 2691 int val, val1_new, val2_new;
2539 struct route_path *ret; 2692 struct route_path *ret;
2540 2693
2541 if (!pos->street || !dst->street) 2694 if (!pos->street || !dst->street)
2542 { 2695 {
2543 dbg(0, "pos or dest not set\n"); 2696 // dbg(0, "pos or dest not set\n");
2544 return NULL; 2697 return NULL;
2545 } 2698 }
2546 2699
2547 if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra 2700 if (profile->mode == 2 || (profile->mode == 0 && pos->lenextra + dst->lenextra > transform_distance(map_projection(pos->street->item.map), &pos->c, &dst->c)))
2548 + dst->lenextra > transform_distance( 2701 {
2549 map_projection(pos->street->item.map), &pos->c, &dst->c)))
2550 return route_path_new_offroad(this, pos, dst); 2702 return route_path_new_offroad(this, pos, dst);
2703 }
2704
2705 // ------ just calculate the smallest cost to reach destination ----------
2706 // ------ just calculate the smallest cost to reach destination ----------
2551 while ((s = route_graph_get_segment(this, pos->street, s))) 2707 while ((s = route_graph_get_segment(this, pos->street, s)))
2552 { 2708 {
2553 val = route_value_seg(profile, NULL, s, 1); 2709 val = route_value_seg(profile, NULL, s, 1);
2554 if (val != INT_MAX && s->end->value != INT_MAX) 2710 if (val != INT_MAX && s->end->value != INT_MAX)
2555 { 2711 {
2571 val2 = val2_new; 2727 val2 = val2_new;
2572 s2 = s; 2728 s2 = s;
2573 } 2729 }
2574 } 2730 }
2575 } 2731 }
2732 // ------ just calculate the smallest cost to reach destination ----------
2733 // ------ just calculate the smallest cost to reach destination ----------
2734
2576 if (val1 == INT_MAX && val2 == INT_MAX) 2735 if (val1 == INT_MAX && val2 == INT_MAX)
2577 { 2736 {
2578 dbg(0, "no route found, pos blocked\n"); 2737 //dbg(0, "no route found, pos blocked\n");
2579 return NULL; 2738 return NULL;
2580 } 2739 }
2740
2581 if (val1 == val2) 2741 if (val1 == val2)
2582 { 2742 {
2583 val1 = s1->end->value; 2743 val1 = s1->end->value;
2584 val2 = s2->start->value; 2744 val2 = s2->start->value;
2585 } 2745 }
2746
2586 if (val1 < val2) 2747 if (val1 < val2)
2587 { 2748 {
2588 start = s1->start; 2749 start = s1->start;
2589 s = s1; 2750 s = s1;
2590 } 2751 }
2591 else 2752 else
2592 { 2753 {
2593 start = s2->end; 2754 start = s2->end;
2594 s = s2; 2755 s = s2;
2756 }
2757
2595 }ret=g_new0(struct route_path, 1); 2758 ret=g_new0(struct route_path, 1);
2596 ret->in_use = 1; 2759 ret->in_use = 1;
2597 ret->updated = 1; 2760 ret->updated = 1;
2761
2598 if (pos->lenextra) 2762 if (pos->lenextra)
2763 {
2599 route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra); 2764 route_path_add_line(ret, &pos->c, &pos->lp, pos->lenextra);
2765 }
2766
2600 ret->path_hash = item_hash_new(); 2767 ret->path_hash = item_hash_new();
2601 dstinfo = NULL; 2768 dstinfo = NULL;
2602 posinfo = pos; 2769 posinfo = pos;
2603 first = s; 2770 first = s;
2771
2772
2773
2774 // ------- build the real route here ------------------------
2775 // ------- build the real route here ------------------------
2604 while (s && !dstinfo) 2776 while (s && !dstinfo)
2605 { /* following start->seg, which indicates the least costly way to reach our destination */ 2777 { /* following start->seg, which indicates the least costly way to reach our destination */
2606 segs++; 2778 segs++;
2607#if 0 2779#if 0
2608 printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y); 2780 printf("start->value=%d 0x%x,0x%x\n", start->value, start->c.x, start->c.y);
2609#endif 2781#endif
2610 if (s->start == start) 2782 if (s->start == start)
2611 { 2783 {
2612 if (item_is_equal(s->data.item, dst->street->item) && (s->end->seg 2784 if (item_is_equal(s->data.item, dst->street->item) && (s->end->seg == s || !posinfo))
2613 == s || !posinfo)) 2785 {
2614 dstinfo = dst; 2786 dstinfo = dst;
2787 }
2788
2615 if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo, 2789 if (!route_path_add_item_from_graph(ret, oldpath, s, 1, posinfo, dstinfo))
2616 dstinfo)) 2790 {
2617 ret->updated = 0; 2791 ret->updated = 0;
2792 }
2793
2618 start = s->end; 2794 start = s->end;
2619 } 2795 }
2620 else 2796 else
2621 { 2797 {
2622 if (item_is_equal(s->data.item, dst->street->item) 2798 if (item_is_equal(s->data.item, dst->street->item) && (s->start->seg == s || !posinfo))
2623 && (s->start->seg == s || !posinfo)) 2799 {
2624 dstinfo = dst; 2800 dstinfo = dst;
2801 }
2625 if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo, 2802 if (!route_path_add_item_from_graph(ret, oldpath, s, -1, posinfo, dstinfo))
2626 dstinfo)) 2803 {
2627 ret->updated = 0; 2804 ret->updated = 0;
2805 }
2628 start = s->start; 2806 start = s->start;
2629 } 2807 }
2630 posinfo = NULL; 2808 posinfo = NULL;
2631 s = start->seg; 2809 s = start->seg;
2632 } 2810 }
2811 // ------- build the real route here ------------------------
2812 // ------- build the real route here ------------------------
2813
2633 if (dst->lenextra) 2814 if (dst->lenextra)
2815 {
2634 route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra); 2816 route_path_add_line(ret, &dst->lp, &dst->c, dst->lenextra);
2817 }
2818
2635 //dbg(1, "%d segments\n", segs); 2819 //dbg(1, "%d segments\n", segs);
2636 return ret; 2820 return ret;
2637} 2821}
2638 2822
2639static int route_graph_build_next_map(struct route_graph *rg) 2823static int route_graph_build_next_map(struct route_graph *rg)
2640{ 2824{
2825 // dbg(0, "enter\n");
2826
2641 do 2827 do
2642 { 2828 {
2643 rg->m = mapset_next(rg->h, 2); 2829 rg->m = mapset_next(rg->h, 2);
2644 if (!rg->m) 2830 if (!rg->m)
2645 return 0; 2831 return 0;
2649 while (!rg->mr); 2835 while (!rg->mr);
2650 2836
2651 return 1; 2837 return 1;
2652} 2838}
2653 2839
2654static int is_turn_allowed(struct route_graph_point *p, 2840static int is_turn_allowed(struct route_graph_point *p, struct route_graph_segment *from, struct route_graph_segment *to)
2655 struct route_graph_segment *from, struct route_graph_segment *to)
2656{ 2841{
2842 // dbg(0, "enter\n");
2843
2657 struct route_graph_point *prev, *next; 2844 struct route_graph_point *prev, *next;
2658 struct route_graph_segment *tmp1, *tmp2; 2845 struct route_graph_segment *tmp1, *tmp2;
2659 if (item_is_equal(from->data.item, to->data.item)) 2846 if (item_is_equal(from->data.item, to->data.item))
2660 return 0; 2847 return 0;
2661 if (from->start == p) 2848 if (from->start == p)
2667 else 2854 else
2668 next = to->start; 2855 next = to->start;
2669 tmp1 = p->end; 2856 tmp1 = p->end;
2670 while (tmp1) 2857 while (tmp1)
2671 { 2858 {
2672 if (tmp1->start->c.x == prev->c.x && tmp1->start->c.y == prev->c.y 2859 if (tmp1->start->c.x == prev->c.x && tmp1->start->c.y == prev->c.y && (tmp1->data.item.type == type_street_turn_restriction_no || tmp1->data.item.type == type_street_turn_restriction_only))
2673 && (tmp1->data.item.type == type_street_turn_restriction_no
2674 || tmp1->data.item.type
2675 == type_street_turn_restriction_only))
2676 { 2860 {
2677 tmp2 = p->start; 2861 tmp2 = p->start;
2678 //dbg(1, "found %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n", 2862 //dbg(1, "found %s (0x%x,0x%x) (0x%x,0x%x)-(0x%x,0x%x) %p-%p\n",
2679 // item_to_name(tmp1->data.item.type), tmp1->data.item.id_hi, 2863 // item_to_name(tmp1->data.item.type), tmp1->data.item.id_hi,
2680 // tmp1->data.item.id_lo, tmp1->start->c.x, tmp1->start->c.y, 2864 // tmp1->data.item.id_lo, tmp1->start->c.x, tmp1->start->c.y,
2687 // item_to_name(tmp2->data.item.type), 2871 // item_to_name(tmp2->data.item.type),
2688 // tmp2->data.item.id_hi, tmp2->data.item.id_lo, 2872 // tmp2->data.item.id_hi, tmp2->data.item.id_lo,
2689 // tmp2->start->c.x, tmp2->start->c.y, tmp2->end->c.x, 2873 // tmp2->start->c.x, tmp2->start->c.y, tmp2->end->c.x,
2690 // tmp2->end->c.y, tmp2->start, tmp2->end); 2874 // tmp2->end->c.y, tmp2->start, tmp2->end);
2691 if (item_is_equal(tmp1->data.item, tmp2->data.item)) 2875 if (item_is_equal(tmp1->data.item, tmp2->data.item))
2876 {
2692 break; 2877 break;
2878 }
2693 tmp2 = tmp2->start_next; 2879 tmp2 = tmp2->start_next;
2694 } 2880 }
2695 //dbg(1, "tmp2=%p\n", tmp2); 2881 //dbg(1, "tmp2=%p\n", tmp2);
2696 if (tmp2) 2882 if (tmp2)
2697 { 2883 {
2698 //dbg(1, "%s tmp2->end=%p next=%p\n", 2884 //dbg(1, "%s tmp2->end=%p next=%p\n",
2699 // item_to_name(tmp1->data.item.type), tmp2->end, next); 2885 // item_to_name(tmp1->data.item.type), tmp2->end, next);
2700 } 2886 }
2701 if (tmp1->data.item.type == type_street_turn_restriction_no && tmp2 2887 if (tmp1->data.item.type == type_street_turn_restriction_no && tmp2 && tmp2->end->c.x == next->c.x && tmp2->end->c.y == next->c.y)
2702 && tmp2->end->c.x == next->c.x && tmp2->end->c.y
2703 == next->c.y)
2704 { 2888 {
2705 //dbg( 2889 //dbg(
2706 // 1, 2890 // 1,
2707 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (no)\n", 2891 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (no)\n",
2708 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x, 2892 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x,
2709 // next->c.y); 2893 // next->c.y);
2710 return 0; 2894 return 0;
2711 } 2895 }
2712 if (tmp1->data.item.type == type_street_turn_restriction_only 2896 if (tmp1->data.item.type == type_street_turn_restriction_only && tmp2 && (tmp2->end->c.x != next->c.x || tmp2->end->c.y != next->c.y))
2713 && tmp2 && (tmp2->end->c.x != next->c.x || tmp2->end->c.y
2714 != next->c.y))
2715 { 2897 {
2716 //dbg( 2898 //dbg(
2717 // 1, 2899 // 1,
2718 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (only)\n", 2900 // "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x not allowed (only)\n",
2719 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x, 2901 // prev->c.x, prev->c.y, p->c.x, p->c.y, next->c.x,
2726 //dbg(1, "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x allowed\n", prev->c.x, 2908 //dbg(1, "from 0x%x,0x%x over 0x%x,0x%x to 0x%x,0x%x allowed\n", prev->c.x,
2727 // prev->c.y, p->c.x, p->c.y, next->c.x, next->c.y); 2909 // prev->c.y, p->c.x, p->c.y, next->c.x, next->c.y);
2728 return 1; 2910 return 1;
2729} 2911}
2730 2912
2731static void route_graph_clone_segment(struct route_graph *this, 2913static void route_graph_clone_segment(struct route_graph *this, struct route_graph_segment *s, struct route_graph_point *start, struct route_graph_point *end, int flags)
2732 struct route_graph_segment *s, struct route_graph_point *start,
2733 struct route_graph_point *end, int flags)
2734{ 2914{
2915 // dbg(0, "enter\n");
2916
2735 struct route_graph_segment_data data; 2917 struct route_graph_segment_data data;
2736 data.flags = s->data.flags | flags; 2918 data.flags = s->data.flags | flags;
2737 data.offset = 1; 2919 data.offset = 1;
2738 data.maxspeed = -1; 2920 data.maxspeed = -1;
2739 data.item = &s->data.item; 2921 data.item = &s->data.item;
2745 //dbg(1, "cloning segment from %p (0x%x,0x%x) to %p (0x%x,0x%x)\n", start, 2927 //dbg(1, "cloning segment from %p (0x%x,0x%x) to %p (0x%x,0x%x)\n", start,
2746 // start->c.x, start->c.y, end, end->c.x, end->c.y); 2928 // start->c.x, start->c.y, end, end->c.x, end->c.y);
2747 route_graph_add_segment(this, start, end, &data); 2929 route_graph_add_segment(this, start, end, &data);
2748} 2930}
2749 2931
2750static void route_graph_process_restriction_segment(struct route_graph *this, 2932static void route_graph_process_restriction_segment(struct route_graph *this, struct route_graph_point *p, struct route_graph_segment *s, int dir)
2751 struct route_graph_point *p, struct route_graph_segment *s, int dir)
2752{ 2933{
2934 // dbg(0, "enter\n");
2935
2753 struct route_graph_segment *tmp; 2936 struct route_graph_segment *tmp;
2754 struct route_graph_point *pn; 2937 struct route_graph_point *pn;
2755 struct coord c = p->c; 2938 struct coord c = p->c;
2756 int dx = 0; 2939 int dx = 0;
2757 int dy = 0; 2940 int dy = 0;
2777 //dbg(1, "Not possible\n"); 2960 //dbg(1, "Not possible\n");
2778 return; 2961 return;
2779 } 2962 }
2780 route_graph_clone_segment(this, s, s->start, pn, AF_ONEWAY); 2963 route_graph_clone_segment(this, s, s->start, pn, AF_ONEWAY);
2781 } 2964 }
2965
2966
2782 tmp = p->start; 2967 tmp = p->start;
2783 while (tmp) 2968 while (tmp)
2784 { 2969 {
2785 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no 2970 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no && tmp->data.item.type != type_street_turn_restriction_only && !(tmp->data.flags & AF_ONEWAYREV) && is_turn_allowed(p, s, tmp))
2786 && tmp->data.item.type != type_street_turn_restriction_only
2787 && !(tmp->data.flags & AF_ONEWAYREV) && is_turn_allowed(p, s,
2788 tmp))
2789 { 2971 {
2790 route_graph_clone_segment(this, tmp, pn, tmp->end, AF_ONEWAY); 2972 route_graph_clone_segment(this, tmp, pn, tmp->end, AF_ONEWAY);
2791 //dbg(1, "To start %s\n", item_to_name(tmp->data.item.type)); 2973 //dbg(1, "To start %s\n", item_to_name(tmp->data.item.type));
2792 } 2974 }
2793 tmp = tmp->start_next; 2975 tmp = tmp->start_next;
2794 } 2976 }
2977
2978
2795 tmp = p->end; 2979 tmp = p->end;
2796 while (tmp) 2980 while (tmp)
2797 { 2981 {
2798 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no 2982 if (tmp != s && tmp->data.item.type != type_street_turn_restriction_no && tmp->data.item.type != type_street_turn_restriction_only && !(tmp->data.flags & AF_ONEWAY) && is_turn_allowed(p, s, tmp))
2799 && tmp->data.item.type != type_street_turn_restriction_only
2800 && !(tmp->data.flags & AF_ONEWAY) && is_turn_allowed(p, s, tmp))
2801 { 2983 {
2802 route_graph_clone_segment(this, tmp, tmp->start, pn, AF_ONEWAYREV); 2984 route_graph_clone_segment(this, tmp, tmp->start, pn, AF_ONEWAYREV);
2803 //dbg(1, "To end %s\n", item_to_name(tmp->data.item.type)); 2985 //dbg(1, "To end %s\n", item_to_name(tmp->data.item.type));
2804 } 2986 }
2805 tmp = tmp->end_next; 2987 tmp = tmp->end_next;
2806 } 2988 }
2807} 2989}
2808 2990
2809static void route_graph_process_restriction_point(struct route_graph *this, 2991static void route_graph_process_restriction_point(struct route_graph *this, struct route_graph_point *p)
2810 struct route_graph_point *p)
2811{ 2992{
2993 // dbg(0, "enter\n");
2994
2812 struct route_graph_segment *tmp; 2995 struct route_graph_segment *tmp;
2996
2997 // -------------------------------------------------------------
2998 // p->start ==> a list of all streets that start from this point
2999 // -------------------------------------------------------------
2813 tmp = p->start; 3000 tmp = p->start;
2814 //dbg(1, "node 0x%x,0x%x\n", p->c.x, p->c.y); 3001 //dbg(1, "node 0x%x,0x%x\n", p->c.x, p->c.y);
2815 while (tmp) 3002 while (tmp)
2816 { 3003 {
2817 if (tmp->data.item.type != type_street_turn_restriction_no 3004 if (tmp->data.item.type != type_street_turn_restriction_no && tmp->data.item.type != type_street_turn_restriction_only)
2818 && tmp->data.item.type != type_street_turn_restriction_only) 3005 {
2819 route_graph_process_restriction_segment(this, p, tmp, 1); 3006 route_graph_process_restriction_segment(this, p, tmp, 1);
3007 }
2820 tmp = tmp->start_next; 3008 tmp = tmp->start_next;
2821 } 3009 }
3010
3011 // -------------------------------------------------------------
3012 // p->end ==> a list of all streets that end at this point
3013 // -------------------------------------------------------------
2822 tmp = p->end; 3014 tmp = p->end;
2823 while (tmp) 3015 while (tmp)
2824 { 3016 {
2825 if (tmp->data.item.type != type_street_turn_restriction_no 3017 if (tmp->data.item.type != type_street_turn_restriction_no && tmp->data.item.type != type_street_turn_restriction_only)
2826 && tmp->data.item.type != type_street_turn_restriction_only) 3018 {
2827 route_graph_process_restriction_segment(this, p, tmp, -1); 3019 route_graph_process_restriction_segment(this, p, tmp, -1);
3020 }
2828 tmp = tmp->end_next; 3021 tmp = tmp->end_next;
2829 } 3022 }
3023
2830 p->flags |= RP_TURN_RESTRICTION_RESOLVED; 3024 p->flags |= RP_TURN_RESTRICTION_RESOLVED;
2831} 3025}
2832 3026
2833static void route_graph_process_restrictions(struct route_graph *this) 3027static void route_graph_process_restrictions(struct route_graph *this)
2834{ 3028{
3029 // dbg(0, "enter\n");
3030
2835 struct route_graph_point *curr; 3031 struct route_graph_point *curr;
2836 int i; 3032 int i;
2837 //dbg(1, "enter\n"); 3033 //dbg(1, "enter\n");
2838 for (i = 0; i < HASH_SIZE; i++) 3034 for (i = 0; i < HASH_SIZE; i++)
2839 { 3035 {
2840 curr = this->hash[i]; 3036 curr = this->hash[i];
2841 while (curr) 3037 while (curr)
2842 { 3038 {
2843 if (curr->flags & RP_TURN_RESTRICTION) 3039 if (curr->flags & RP_TURN_RESTRICTION)
3040 {
2844 route_graph_process_restriction_point(this, curr); 3041 route_graph_process_restriction_point(this, curr);
3042 }
2845 curr = curr->hash_next; 3043 curr = curr->hash_next;
2846 } 3044 }
2847 } 3045 }
2848} 3046}
2849 3047
2850static void route_graph_build_done(struct route_graph *rg, int cancel) 3048static void route_graph_build_done(struct route_graph *rg, int cancel)
2851{ 3049{
3050 // dbg(0, "enter\n");
3051
2852 //dbg(1, "cancel=%d\n", cancel); 3052 //dbg(1, "cancel=%d\n", cancel);
2853 if (rg->idle_ev) 3053 if (rg->idle_ev)
3054 {
2854 event_remove_idle(rg->idle_ev); 3055 event_remove_idle(rg->idle_ev);
3056 rg->idle_ev = NULL;
3057 }
3058
2855 if (rg->idle_cb) 3059 if (rg->idle_cb)
3060 {
2856 callback_destroy(rg->idle_cb); 3061 callback_destroy(rg->idle_cb);
3062 rg->idle_cb = NULL;
3063 }
3064
2857 map_rect_destroy(rg->mr); 3065 map_rect_destroy(rg->mr);
2858 mapset_close(rg->h); 3066 mapset_close(rg->h);
2859 route_free_selection(rg->sel); 3067 route_free_selection(rg->sel);
2860 rg->idle_ev = NULL;
2861 rg->idle_cb = NULL;
2862 rg->mr = NULL; 3068 rg->mr = NULL;
2863 rg->h = NULL; 3069 rg->h = NULL;
2864 rg->sel = NULL; 3070 rg->sel = NULL;
3071
2865 if (!cancel) 3072 if (!cancel)
2866 { 3073 {
2867 route_graph_process_restrictions(rg); 3074 route_graph_process_restrictions(rg);
3075 //dbg(0, "callback\n");
2868 callback_call_0(rg->done_cb); 3076 callback_call_0(rg->done_cb);
2869 } 3077 }
3078
2870 rg->busy = 0; 3079 rg->busy = 0;
2871} 3080}
2872 3081
3082// this function gets called in a loop until route is ready ----------
3083// this function gets called in a loop until route is ready ----------
3084// this function gets called in a loop until route is ready ----------
2873static void route_graph_build_idle(struct route_graph *rg, 3085static void route_graph_build_idle(struct route_graph *rg, struct vehicleprofile *profile)
2874 struct vehicleprofile *profile)
2875{ 3086{
3087 // // dbg(0, "enter\n");
3088
2876 int count = 1000; 3089 // int count = 1000;
3090 int count = 5000; // process 5000 items in one step
2877 struct item *item; 3091 struct item *item;
2878 3092
2879 while (count > 0) 3093 while (count > 0)
2880 { 3094 {
3095 // loop until an item is found ---------
2881 for (;;) 3096 for (;;)
2882 { 3097 {
2883 item = map_rect_get_item(rg->mr); 3098 item = map_rect_get_item(rg->mr);
2884 if (item) 3099 if (item)
3100 {
2885 break; 3101 break;
3102 }
3103
2886 if (!route_graph_build_next_map(rg)) 3104 if (!route_graph_build_next_map(rg))
2887 { 3105 {
2888 route_graph_build_done(rg, 0); 3106 route_graph_build_done(rg, 0);
2889 return; 3107 return;
2890 } 3108 }
2891 } 3109 }
3110 // loop until an item is found ---------
3111
3112
2892 if (item->type == type_traffic_distortion) 3113 if (item->type == type_traffic_distortion)
2893 { 3114 {
2894 route_process_traffic_distortion(rg, item); 3115 route_process_traffic_distortion(rg, item);
2895 } 3116 }
2896 else if (item->type == type_street_turn_restriction_no || item->type 3117 else if (item->type == type_street_turn_restriction_no || item->type == type_street_turn_restriction_only)
2897 == type_street_turn_restriction_only) 3118 {
2898 route_process_turn_restriction(rg, item); 3119 route_process_turn_restriction(rg, item);
3120 }
2899 else 3121 else
3122 {
2900 route_process_street_graph(rg, item, profile); 3123 route_process_street_graph(rg, item, profile);
3124 }
3125
2901 count--; 3126 count--;
2902 } 3127 }
2903} 3128}
2904 3129
2905/** 3130/**
2917 * @param c2 Corner 2 of the rectangle to use from the map 3142 * @param c2 Corner 2 of the rectangle to use from the map
2918 * @param done_cb The callback which will be called when graph is complete 3143 * @param done_cb The callback which will be called when graph is complete
2919 * @return The new route graph. 3144 * @return The new route graph.
2920 */ 3145 */
2921static struct route_graph * 3146static struct route_graph *
2922route_graph_build(struct mapset *ms, struct coord *c, int count, 3147route_graph_build(struct mapset *ms, struct coord *c, int count, struct callback *done_cb, int async, struct vehicleprofile *profile, int try_harder)
2923 struct callback *done_cb, int async, struct vehicleprofile *profile,
2924 int try_harder)
2925{ 3148{
3149 // // dbg(0, "enter\n");
3150
2926 struct route_graph *ret=g_new0(struct route_graph, 1); 3151 struct route_graph *ret=g_new0(struct route_graph, 1);
2927 3152
2928 //dbg(1, "enter\n"); 3153 // // dbg(0, "enter\n");
2929 3154
2930 ret->sel = route_calc_selection(c, count, try_harder); 3155 ret->sel = route_calc_selection(c, count, try_harder);
2931 ret->h = mapset_open(ms); 3156 ret->h = mapset_open(ms);
2932 ret->done_cb = done_cb; 3157 ret->done_cb = done_cb;
2933 ret->busy = 1; 3158 ret->busy = 1;
2934 3159
2935 if (route_graph_build_next_map(ret)) 3160 if (route_graph_build_next_map(ret))
2936 { 3161 {
2937
2938// ------ xxxxxx ---- 3162 // ------ xxxxxx ----
3163 // dbg(0,"async=%d\n", async);
2939 if (async) 3164 if (async)
2940 { 3165 {
3166 //dbg(0,"route_graph_build_idle sync callback\n");
2941 ret->idle_cb = callback_new_2(callback_cast(route_graph_build_idle), ret, profile); 3167 ret->idle_cb = callback_new_2(callback_cast(route_graph_build_idle), ret, profile);
3168 callback_add_names(ret->idle_cb, "route_graph_build", "route_graph_build_idle");
2942 ret->idle_ev = event_add_idle(50, ret->idle_cb); 3169 ret->idle_ev = event_add_idle(10, ret->idle_cb);
3170 }
3171 else
3172 {
3173 // ?? do we need this ?? // route_graph_build_idle(ret, profile);
2943 } 3174 }
2944 } 3175 }
2945 else 3176 else
2946 { 3177 {
2947 route_graph_build_done(ret, 0); 3178 route_graph_build_done(ret, 0);
2950 return ret; 3181 return ret;
2951} 3182}
2952 3183
2953static void route_graph_update_done(struct route *this, struct callback *cb) 3184static void route_graph_update_done(struct route *this, struct callback *cb)
2954{ 3185{
3186 // dbg(0, "enter\n");
3187
2955 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, cb); 3188 route_graph_flood(this->graph, this->current_dst, this->vehicleprofile, cb);
2956} 3189}
2957 3190
2958/** 3191/**
2959 * @brief Updates the route graph 3192 * @brief Updates the route graph
2961 * This updates the route graph after settings in the route have changed. It also 3194 * This updates the route graph after settings in the route have changed. It also
2962 * adds routing information afterwards by calling route_graph_flood(). 3195 * adds routing information afterwards by calling route_graph_flood().
2963 * 3196 *
2964 * @param this The route to update the graph for 3197 * @param this The route to update the graph for
2965 */ 3198 */
2966static void route_graph_update(struct route *this, struct callback *cb, 3199static void route_graph_update(struct route *this, struct callback *cb, int async)
2967 int async)
2968{ 3200{
3201 // dbg(0, "enter\n");
3202
2969 struct attr route_status; 3203 struct attr route_status;
2970 struct coord *c = g_alloca(
2971 sizeof(struct coord) * (1 + g_list_length(this->destinations))); 3204 struct coord *c = g_alloca(sizeof(struct coord) * (1 + g_list_length(this->destinations)));
2972 int i = 0; 3205 int i = 0;
2973 GList *tmp; 3206 GList *tmp;
2974 3207
2975 route_status.type = attr_route_status; 3208 route_status.type = attr_route_status;
2976 route_graph_destroy(this->graph); 3209 route_graph_destroy(this->graph);
2977 this->graph = NULL; 3210 this->graph = NULL;
2978 callback_destroy(this->route_graph_done_cb); 3211 callback_destroy(this->route_graph_done_cb);
2979 this->route_graph_done_cb = callback_new_2( 3212
2980 callback_cast(route_graph_update_done), this, cb); 3213 this->route_graph_done_cb = callback_new_2(callback_cast(route_graph_update_done), this, cb);
3214 callback_add_names(this->route_graph_done_cb, "route_graph_update", "route_graph_update_done");
3215
2981 route_status.u.num = route_status_building_graph; 3216 route_status.u.num = route_status_building_graph;
2982 route_set_attr(this, &route_status); 3217 route_set_attr(this, &route_status);
2983 c[i++] = this->pos->c; 3218 c[i++] = this->pos->c;
2984 tmp = this->destinations; 3219 tmp = this->destinations;
2985 while (tmp) 3220 while (tmp)
2987 struct route_info *dst = tmp->data; 3222 struct route_info *dst = tmp->data;
2988 c[i++] = dst->c; 3223 c[i++] = dst->c;
2989 tmp = g_list_next(tmp); 3224 tmp = g_list_next(tmp);
2990 } 3225 }
2991 3226
2992 this->graph = route_graph_build(this->ms, c, i, this->route_graph_done_cb, 3227 this->graph = route_graph_build(this->ms, c, i, this->route_graph_done_cb, async, this->vehicleprofile, this->try_harder);
2993 async, this->vehicleprofile, this->try_harder);
2994 3228
2995 if (!async) 3229 if (!async)
2996 { 3230 {
2997 while (this->graph->busy) 3231 while (this->graph->busy)
2998 { 3232 {
3008 * @return Street data for the item 3242 * @return Street data for the item
3009 */ 3243 */
3010struct street_data * 3244struct street_data *
3011street_get_data(struct item *item) 3245street_get_data(struct item *item)
3012{ 3246{
3247 //// dbg(0, "enter\n");
3248
3013 int count = 0, *flags; 3249 int count = 0, *flags;
3014 struct street_data *ret = NULL, *ret1; 3250 struct street_data *ret = NULL, *ret1;
3015 struct attr flags_attr, maxspeed_attr; 3251 struct attr flags_attr, maxspeed_attr;
3016 const int step = 128; 3252 const int step = 128;
3017 int c; 3253 int c;
3018 3254
3019 do 3255 do
3020 { 3256 {
3021 ret1 = g_realloc(ret, sizeof(struct street_data) + (count + step) * sizeof(struct coord)); 3257 ret1 = g_realloc(ret, sizeof(struct street_data) + (count + step) * sizeof(struct coord));
3022 if (!ret1) 3258 if (!ret1)
3023 { 3259 {
3024 if (ret) 3260 if (ret)
3025 g_free(ret); 3261 g_free(ret);
3026 return NULL; 3262 return NULL;
3066 * @return The copied street data 3302 * @return The copied street data
3067 */ 3303 */
3068struct street_data * 3304struct street_data *
3069street_data_dup(struct street_data *orig) 3305street_data_dup(struct street_data *orig)
3070{ 3306{
3307 //// dbg(0, "enter\n");
3308
3071 struct street_data *ret; 3309 struct street_data *ret;
3072 int size = sizeof(struct street_data) + orig->count * sizeof(struct coord); 3310 int size = sizeof(struct street_data) + orig->count * sizeof(struct coord);
3073 3311
3074 ret = g_malloc(size); 3312 ret = g_malloc(size);
3075 memcpy(ret, orig, size); 3313 memcpy(ret, orig, size);
3082 * 3320 *
3083 * @param sd Street data to be freed 3321 * @param sd Street data to be freed
3084 */ 3322 */
3085void street_data_free(struct street_data *sd) 3323void street_data_free(struct street_data *sd)
3086{ 3324{
3325 //// dbg(0, "enter\n");
3326
3087 g_free(sd); 3327 g_free(sd);
3088} 3328}
3089 3329
3090/** 3330/**
3091 * @brief Finds the nearest street to a given coordinate 3331 * @brief Finds the nearest street to a given coordinate
3093 * @param ms The mapset to search in for the street 3333 * @param ms The mapset to search in for the street
3094 * @param pc The coordinate to find a street nearby 3334 * @param pc The coordinate to find a street nearby
3095 * @return The nearest street 3335 * @return The nearest street
3096 */ 3336 */
3097static struct route_info * 3337static struct route_info *
3098route_find_nearest_street(struct vehicleprofile *vehicleprofile, 3338route_find_nearest_street(struct vehicleprofile *vehicleprofile, struct mapset *ms, struct pcoord *pc)
3099 struct mapset *ms, struct pcoord *pc)
3100{ 3339{
3340 // dbg(0, "enter\n");
3341
3101 struct route_info *ret = NULL; 3342 struct route_info *ret = NULL;
3102 int max_dist = 1000; 3343 int max_dist = 2000; // was 1000 originally!!
3103 struct map_selection *sel; 3344 struct map_selection *sel;
3104 int dist, mindist = 0, pos; 3345 int dist, mindist = 0, pos;
3105 struct mapset_handle *h; 3346 struct mapset_handle *h;
3106 struct map *m; 3347 struct map *m;
3107 struct map_rect *mr; 3348 struct map_rect *mr;
3138 if (item_get_default_flags(item->type)) 3379 if (item_get_default_flags(item->type))
3139 { 3380 {
3140 sd = street_get_data(item); 3381 sd = street_get_data(item);
3141 if (!sd) 3382 if (!sd)
3142 continue; 3383 continue;
3143 dist = transform_distance_polyline_sq(sd->c, sd->count, &c, 3384 dist = transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
3144 &lp, &pos); 3385 if (dist < mindist && ((sd->flags & vehicleprofile->flags_forward_mask) == vehicleprofile->flags || (sd->flags & vehicleprofile->flags_reverse_mask) == vehicleprofile->flags))
3145 if (dist < mindist && ((sd->flags
3146 & vehicleprofile->flags_forward_mask)
3147 == vehicleprofile->flags || (sd->flags
3148 & vehicleprofile->flags_reverse_mask)
3149 == vehicleprofile->flags))
3150 { 3386 {
3151 mindist = dist; 3387 mindist = dist;
3152 if (ret->street) 3388 if (ret->street)
3153 { 3389 {
3154 street_data_free(ret->street); 3390 street_data_free(ret->street);
3174 if (!ret->street || mindist > max_dist * max_dist) 3410 if (!ret->street || mindist > max_dist * max_dist)
3175 { 3411 {
3176 if (ret->street) 3412 if (ret->street)
3177 { 3413 {
3178 street_data_free(ret->street); 3414 street_data_free(ret->street);
3179 //dbg(1, "Much too far %d > %d\n", mindist, max_dist); 3415 // dbg(0, "Much too far %d > %d\n", mindist, max_dist);
3180 } 3416 }
3181 g_free(ret); 3417 g_free(ret);
3182 ret = NULL; 3418 ret = NULL;
3183 } 3419 }
3184 3420
3190 * 3426 *
3191 * @param info The route info to be destroyed 3427 * @param info The route info to be destroyed
3192 */ 3428 */
3193void route_info_free(struct route_info *inf) 3429void route_info_free(struct route_info *inf)
3194{ 3430{
3431 //// dbg(0, "enter\n");
3432
3195 if (!inf) 3433 if (!inf)
3196 return; 3434 return;
3197 if (inf->street) 3435 if (inf->street)
3198 street_data_free(inf->street); 3436 street_data_free(inf->street);
3199 g_free(inf); 3437 g_free(inf);
3208 * @return Street data for the route info 3446 * @return Street data for the route info
3209 */ 3447 */
3210struct street_data * 3448struct street_data *
3211route_info_street(struct route_info *rinf) 3449route_info_street(struct route_info *rinf)
3212{ 3450{
3451 // dbg(0, "enter\n");
3452
3213 return rinf->street; 3453 return rinf->street;
3214} 3454}
3215 3455
3216#if 0 3456#if 0
3217struct route_crossings * 3457struct route_crossings *
3261 struct route_graph_point_iterator it; 3501 struct route_graph_point_iterator it;
3262}; 3502};
3263 3503
3264static void rm_coord_rewind(void *priv_data) 3504static void rm_coord_rewind(void *priv_data)
3265{ 3505{
3506 //// dbg(0, "enter\n");
3507
3266 struct map_rect_priv *mr = priv_data; 3508 struct map_rect_priv *mr = priv_data;
3267 mr->last_coord = 0; 3509 mr->last_coord = 0;
3268} 3510}
3269 3511
3270static void rm_attr_rewind(void *priv_data) 3512static void rm_attr_rewind(void *priv_data)
3271{ 3513{
3514 //// dbg(0, "enter\n");
3515
3272 struct map_rect_priv *mr = priv_data; 3516 struct map_rect_priv *mr = priv_data;
3273 mr->attr_next = attr_street_item; 3517 mr->attr_next = attr_street_item;
3274} 3518}
3275 3519
3276static int rm_attr_get(void *priv_data, enum attr_type attr_type, 3520static int rm_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
3277 struct attr *attr)
3278{ 3521{
3522 //// dbg(0, "enter\n");
3523
3279 struct map_rect_priv *mr = priv_data; 3524 struct map_rect_priv *mr = priv_data;
3280 struct route_path_segment *seg = mr->seg; 3525 struct route_path_segment *seg = mr->seg;
3281 struct route *route = mr->mpriv->route; 3526 struct route *route = mr->mpriv->route;
3282 if (mr->item.type != type_street_route) 3527 if (mr->item.type != type_street_route)
3283 return 0; 3528 return 0;
3329 return 0; 3574 return 0;
3330 return 1; 3575 return 1;
3331 case attr_time: 3576 case attr_time:
3332 mr->attr_next = attr_speed; 3577 mr->attr_next = attr_speed;
3333 if (seg) 3578 if (seg)
3334 attr->u.num = route_time_seg(route->vehicleprofile, seg->data, 3579 attr->u.num = route_time_seg(route->vehicleprofile, seg->data, NULL);
3335 NULL);
3336 else 3580 else
3337 return 0; 3581 return 0;
3338 return 1; 3582 return 1;
3339 case attr_speed: 3583 case attr_speed:
3340 mr->attr_next = attr_none; 3584 mr->attr_next = attr_none;
3341 if (seg) 3585 if (seg)
3342 attr->u.num = route_seg_speed(route->vehicleprofile, seg->data, 3586 attr->u.num = route_seg_speed(route->vehicleprofile, seg->data, NULL);
3343 NULL);
3344 else 3587 else
3345 return 0; 3588 return 0;
3346 return 1; 3589 return 1;
3347 case attr_label: 3590 case attr_label:
3348 mr->attr_next = attr_none; 3591 mr->attr_next = attr_none;
3355 return 0; 3598 return 0;
3356} 3599}
3357 3600
3358static int rm_coord_get(void *priv_data, struct coord *c, int count) 3601static int rm_coord_get(void *priv_data, struct coord *c, int count)
3359{ 3602{
3603 //// dbg(0, "enter\n");
3604
3360 struct map_rect_priv *mr = priv_data; 3605 struct map_rect_priv *mr = priv_data;
3361 struct route_path_segment *seg = mr->seg; 3606 struct route_path_segment *seg = mr->seg;
3362 int i, rc = 0; 3607 int i, rc = 0;
3363 struct route *r = mr->mpriv->route; 3608 struct route *r = mr->mpriv->route;
3364 enum projection pro = route_projection(r); 3609 enum projection pro = route_projection(r);
3365 3610
3366 if (pro == projection_none) 3611 if (pro == projection_none)
3367 return 0; 3612 return 0;
3368 if (mr->item.type == type_route_start || mr->item.type 3613 if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse || mr->item.type == type_route_end)
3369 == type_route_start_reverse || mr->item.type == type_route_end)
3370 { 3614 {
3371 if (!count || mr->last_coord) 3615 if (!count || mr->last_coord)
3372 return 0; 3616 return 0;
3373 mr->last_coord = 1; 3617 mr->last_coord = 1;
3374 if (mr->item.type == type_route_start || mr->item.type 3618 if (mr->item.type == type_route_start || mr->item.type == type_route_start_reverse)
3375 == type_route_start_reverse)
3376 c[0] = r->pos->c; 3619 c[0] = r->pos->c;
3377 else 3620 else
3378 { 3621 {
3379 c[0] = route_get_dst(r)->c; 3622 c[0] = route_get_dst(r)->c;
3380 } 3623 }
3387 if (mr->last_coord >= seg->ncoords) 3630 if (mr->last_coord >= seg->ncoords)
3388 break; 3631 break;
3389 if (i >= seg->ncoords) 3632 if (i >= seg->ncoords)
3390 break; 3633 break;
3391 if (pro != projection_mg) 3634 if (pro != projection_mg)
3392 transform_from_to(&seg->c[mr->last_coord++], pro, &c[i], 3635 transform_from_to(&seg->c[mr->last_coord++], pro, &c[i], projection_mg);
3393 projection_mg);
3394 else 3636 else
3395 c[i] = seg->c[mr->last_coord++]; 3637 c[i] = seg->c[mr->last_coord++];
3396 rc++; 3638 rc++;
3397 } 3639 }
3398 //dbg(1, "return %d\n", rc); 3640 //dbg(1, "return %d\n", rc);
3399 return rc; 3641 return rc;
3400} 3642}
3401 3643
3402static struct item_methods methods_route_item = 3644static struct item_methods methods_route_item = { rm_coord_rewind, rm_coord_get, rm_attr_rewind, rm_attr_get, };
3403{ rm_coord_rewind, rm_coord_get, rm_attr_rewind, rm_attr_get, };
3404 3645
3405static void rp_attr_rewind(void *priv_data) 3646static void rp_attr_rewind(void *priv_data)
3406{ 3647{
3648 //// dbg(0, "enter\n");
3649
3407 struct map_rect_priv *mr = priv_data; 3650 struct map_rect_priv *mr = priv_data;
3408 mr->attr_next = attr_label; 3651 mr->attr_next = attr_label;
3409} 3652}
3410 3653
3411static int rp_attr_get(void *priv_data, enum attr_type attr_type, 3654static int rp_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
3412 struct attr *attr)
3413{ 3655{
3656 //// dbg(0, "enter\n");
3657
3414 struct map_rect_priv *mr = priv_data; 3658 struct map_rect_priv *mr = priv_data;
3415 struct route_graph_point *p = mr->point; 3659 struct route_graph_point *p = mr->point;
3416 struct route_graph_segment *seg = mr->rseg; 3660 struct route_graph_segment *seg = mr->rseg;
3417 struct route *route = mr->mpriv->route; 3661 struct route *route = mr->mpriv->route;
3418 3662
3516 while (tmp) 3760 while (tmp)
3517 { 3761 {
3518 end++; 3762 end++;
3519 tmp = tmp->end_next; 3763 tmp = tmp->end_next;
3520 } 3764 }
3521 mr->str = g_strdup_printf("%d %d %p (0x%x,0x%x)", start, 3765 mr->str = g_strdup_printf("%d %d %p (0x%x,0x%x)", start, end, p, p->c.x, p->c.y);
3522 end, p, p->c.x, p->c.y);
3523 attr->u.str = mr->str; 3766 attr->u.str = mr->str;
3524 } 3767 }
3525 return 1; 3768 return 1;
3526 case type_rg_segment: 3769 case type_rg_segment:
3527 if (!seg) 3770 if (!seg)
3528 return 0; 3771 return 0;
3529 mr->str = g_strdup_printf( 3772 mr->str = g_strdup_printf("len %d time %d start %p end %p", seg->data.len, route_time_seg(route->vehicleprofile, &seg->data, NULL), seg->start, seg->end);
3530 "len %d time %d start %p end %p",
3531 seg->data.len,
3532 route_time_seg(route->vehicleprofile, &seg->data,
3533 NULL), seg->start, seg->end);
3534 attr->u.str = mr->str; 3773 attr->u.str = mr->str;
3535 return 1; 3774 return 1;
3536 default: 3775 default:
3537 return 0; 3776 return 0;
3538 } 3777 }
3551 * @param count How many coordinates to get at a max? 3790 * @param count How many coordinates to get at a max?
3552 * @return The number of coordinates retrieved 3791 * @return The number of coordinates retrieved
3553 */ 3792 */
3554static int rp_coord_get(void *priv_data, struct coord *c, int count) 3793static int rp_coord_get(void *priv_data, struct coord *c, int count)
3555{ 3794{
3795 //// dbg(0, "enter\n");
3796
3556 struct map_rect_priv *mr = priv_data; 3797 struct map_rect_priv *mr = priv_data;
3557 struct route_graph_point *p = mr->point; 3798 struct route_graph_point *p = mr->point;
3558 struct route_graph_segment *seg = mr->rseg; 3799 struct route_graph_segment *seg = mr->rseg;
3559 int rc = 0, i, dir; 3800 int rc = 0, i, dir;
3560 struct route *r = mr->mpriv->route; 3801 struct route *r = mr->mpriv->route;
3561 enum projection pro = route_projection(r); 3802 enum projection pro = route_projection(r);
3562 3803
3563 if (pro == projection_none) 3804 if (pro == projection_none)
3805 {
3564 return 0; 3806 return 0;
3807 }
3808
3565 for (i = 0; i < count; i++) 3809 for (i = 0; i < count; i++)
3566 { 3810 {
3567 if (mr->item.type == type_rg_point) 3811 if (mr->item.type == type_rg_point)
3568 { 3812 {
3569 if (mr->last_coord >= 1) 3813 if (mr->last_coord >= 1)
3601 rc++; 3845 rc++;
3602 } 3846 }
3603 return rc; 3847 return rc;
3604} 3848}
3605 3849
3606static struct item_methods methods_point_item = 3850static struct item_methods methods_point_item = { rm_coord_rewind, rp_coord_get, rp_attr_rewind, rp_attr_get, };
3607{ rm_coord_rewind, rp_coord_get, rp_attr_rewind, rp_attr_get, };
3608 3851
3609static void rp_destroy(struct map_priv *priv) 3852static void rp_destroy(struct map_priv *priv)
3610{ 3853{
3854 //// dbg(0, "enter\n");
3855
3611 g_free(priv); 3856 g_free(priv);
3612} 3857}
3613 3858
3614static void rm_destroy(struct map_priv *priv) 3859static void rm_destroy(struct map_priv *priv)
3615{ 3860{
3861 //// dbg(0, "enter\n");
3862
3616 g_free(priv); 3863 g_free(priv);
3617} 3864}
3618 3865
3619static struct map_rect_priv * 3866static struct map_rect_priv *
3620rm_rect_new(struct map_priv *priv, struct map_selection *sel) 3867rm_rect_new(struct map_priv *priv, struct map_selection *sel)
3621{ 3868{
3869 //// dbg(0, "enter\n");
3870
3622 struct map_rect_priv * mr; 3871 struct map_rect_priv * mr;
3623 //dbg(1, "enter\n"); 3872 //dbg(1, "enter\n");
3624 3873
3625#if 0 3874#if 0
3626 if (! route_get_pos(priv->route)) 3875 if (! route_get_pos(priv->route))
3665 * @return A new map rect's private data 3914 * @return A new map rect's private data
3666 */ 3915 */
3667static struct map_rect_priv * 3916static struct map_rect_priv *
3668rp_rect_new(struct map_priv *priv, struct map_selection *sel) 3917rp_rect_new(struct map_priv *priv, struct map_selection *sel)
3669{ 3918{
3919 //// dbg(0, "enter\n");
3920
3670 struct map_rect_priv * mr; 3921 struct map_rect_priv * mr;
3671 3922
3672 //dbg(1, "enter\n");
3673 if (!priv->route->graph) 3923 if (!priv->route->graph)
3674 return NULL;mr=g_new0(struct map_rect_priv, 1); 3924 return NULL;mr=g_new0(struct map_rect_priv, 1);
3925
3675 mr->mpriv = priv; 3926 mr->mpriv = priv;
3676 mr->item.priv_data = mr; 3927 mr->item.priv_data = mr;
3677 mr->item.type = type_rg_point; 3928 mr->item.type = type_rg_point;
3678 mr->item.meth = &methods_point_item; 3929 mr->item.meth = &methods_point_item;
3930
3679 if (sel) 3931 if (sel)
3680 { 3932 {
3681 if ((sel->u.c_rect.lu.x == sel->u.c_rect.rl.x) && (sel->u.c_rect.lu.y 3933 if ((sel->u.c_rect.lu.x == sel->u.c_rect.rl.x) && (sel->u.c_rect.lu.y == sel->u.c_rect.rl.y))
3682 == sel->u.c_rect.rl.y))
3683 { 3934 {
3684 mr->coord_sel = g_malloc(sizeof(struct coord)); 3935 mr->coord_sel = g_malloc(sizeof(struct coord));
3685 *(mr->coord_sel) = sel->u.c_rect.lu; 3936 *(mr->coord_sel) = sel->u.c_rect.lu;
3686 } 3937 }
3687 } 3938 }
3688 return mr; 3939 return mr;
3689} 3940}
3690 3941
3691static void rm_rect_destroy(struct map_rect_priv *mr) 3942static void rm_rect_destroy(struct map_rect_priv *mr)
3692{ 3943{
3944 //// dbg(0, "enter\n");
3945
3693 if (mr->str) 3946 if (mr->str)
3694 g_free(mr->str); 3947 g_free(mr->str);
3695 if (mr->coord_sel) 3948 if (mr->coord_sel)
3696 { 3949 {
3697 g_free(mr->coord_sel); 3950 g_free(mr->coord_sel);
3698 } 3951 }
3699 if (mr->path) 3952 if (mr->path)
3700 { 3953 {
3701 mr->path->in_use--; 3954 mr->path->in_use--;
3702 if (mr->path->update_required && (mr->path->in_use == 1)) 3955 if (mr->path->update_required && (mr->path->in_use == 1))
3703 route_path_update_done(mr->mpriv->route, 3956 route_path_update_done(mr->mpriv->route, mr->path->update_required - 1);
3704 mr->path->update_required - 1);
3705 else if (!mr->path->in_use) 3957 else if (!mr->path->in_use)
3706 g_free(mr->path); 3958 g_free(mr->path);
3707 } 3959 }
3708 3960
3709 g_free(mr); 3961 g_free(mr);
3710} 3962}
3711 3963
3712static struct item * 3964static struct item *
3713rp_get_item(struct map_rect_priv *mr) 3965rp_get_item(struct map_rect_priv *mr)
3714{ 3966{
3967 //// dbg(0, "enter\n");
3968
3715 struct route *r = mr->mpriv->route; 3969 struct route *r = mr->mpriv->route;
3716 struct route_graph_point *p = mr->point; 3970 struct route_graph_point *p = mr->point;
3717 struct route_graph_segment *seg = mr->rseg; 3971 struct route_graph_segment *seg = mr->rseg;
3718 3972
3719 if (mr->item.type == type_rg_point) 3973 if (mr->item.type == type_rg_point)
3796} 4050}
3797 4051
3798static struct item * 4052static struct item *
3799rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) 4053rp_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
3800{ 4054{
4055 //// dbg(0, "enter\n");
4056
3801 struct item *ret = NULL; 4057 struct item *ret = NULL;
3802 while (id_lo-- > 0) 4058 while (id_lo-- > 0)
3803 ret = rp_get_item(mr); 4059 ret = rp_get_item(mr);
3804 return ret; 4060 return ret;
3805} 4061}
3806 4062
3807static struct item * 4063static struct item *
3808rm_get_item(struct map_rect_priv *mr) 4064rm_get_item(struct map_rect_priv *mr)
3809{ 4065{
4066 //// dbg(0, "enter\n");
4067
3810 struct route *route = mr->mpriv->route; 4068 struct route *route = mr->mpriv->route;
3811 //dbg(1, "enter\n", mr->pos);
3812 4069
3813 switch (mr->item.type) 4070 switch (mr->item.type)
3814 { 4071 {
3815 case type_none: 4072 case type_none:
3816 if (route->pos && route->pos->street_direction 4073 if (route->pos && route->pos->street_direction && route->pos->street_direction != route->pos->dir)
3817 && route->pos->street_direction != route->pos->dir)
3818 mr->item.type = type_route_start_reverse; 4074 mr->item.type = type_route_start_reverse;
3819 else 4075 else
3820 mr->item.type = type_route_start; 4076 mr->item.type = type_route_start;
3821 if (route->pos) 4077 if (route->pos)
3822 break; 4078 break;
3854} 4110}
3855 4111
3856static struct item * 4112static struct item *
3857rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo) 4113rm_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
3858{ 4114{
4115 //// dbg(0, "enter\n");
4116
3859 struct item *ret = NULL; 4117 struct item *ret = NULL;
3860 while (id_lo-- > 0) 4118 while (id_lo-- > 0)
3861 ret = rm_get_item(mr); 4119 ret = rm_get_item(mr);
3862 return ret; 4120 return ret;
3863} 4121}
3864 4122
3865static struct map_methods route_meth = 4123static struct map_methods route_meth = { projection_mg, "utf-8", rm_destroy, rm_rect_new, rm_rect_destroy, rm_get_item, rm_get_item_byid, NULL, NULL, NULL, };
3866{ projection_mg, "utf-8", rm_destroy, rm_rect_new, rm_rect_destroy,
3867 rm_get_item, rm_get_item_byid, NULL, NULL, NULL, };
3868 4124
3869static struct map_methods route_graph_meth = 4125static struct map_methods route_graph_meth = { projection_mg, "utf-8", rp_destroy, rp_rect_new, rm_rect_destroy, rp_get_item, rp_get_item_byid, NULL, NULL, NULL, };
3870{ projection_mg, "utf-8", rp_destroy, rp_rect_new, rm_rect_destroy,
3871 rp_get_item, rp_get_item_byid, NULL, NULL, NULL, };
3872 4126
3873static struct map_priv * 4127static struct map_priv *
3874route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph) 4128route_map_new_helper(struct map_methods *meth, struct attr **attrs, int graph)
3875{ 4129{
4130 // dbg(0, "enter\n");
4131
3876 struct map_priv *ret; 4132 struct map_priv *ret;
3877 struct attr *route_attr; 4133 struct attr *route_attr;
3878 4134
3879 route_attr = attr_search(attrs, NULL, attr_route); 4135 route_attr = attr_search(attrs, NULL, attr_route);
3880 if (!route_attr) 4136 if (!route_attr)
3887 4143
3888 return ret; 4144 return ret;
3889} 4145}
3890 4146
3891static struct map_priv * 4147static struct map_priv *
3892route_map_new(struct map_methods *meth, struct attr **attrs, 4148route_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
3893 struct callback_list *cbl)
3894{ 4149{
4150 // dbg(0, "enter\n");
4151
3895 return route_map_new_helper(meth, attrs, 0); 4152 return route_map_new_helper(meth, attrs, 0);
3896} 4153}
3897 4154
3898static struct map_priv * 4155static struct map_priv *
3899route_graph_map_new(struct map_methods *meth, struct attr **attrs, 4156route_graph_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
3900 struct callback_list *cbl)
3901{ 4157{
4158 // dbg(0, "enter\n");
4159
3902 return route_map_new_helper(meth, attrs, 1); 4160 return route_map_new_helper(meth, attrs, 1);
3903} 4161}
3904 4162
3905static struct map * 4163static struct map *
3906route_get_map_helper(struct route *this_, struct map **map, char *type, 4164route_get_map_helper(struct route *this_, struct map **map, char *type, char *description)
3907 char *description)
3908{ 4165{
4166 //// dbg(0, "enter\n");
4167
3909 struct attr *attrs[5]; 4168 struct attr *attrs[5];
3910 struct attr a_type, navigation, data, a_description; 4169 struct attr a_type, navigation, data, a_description;
3911 a_type.type = attr_type; 4170 a_type.type = attr_type;
3912 a_type.u.str = type; 4171 a_type.u.str = type;
3913 navigation.type = attr_route; 4172 navigation.type = attr_route;
3943 * @return A new map containing the route path 4202 * @return A new map containing the route path
3944 */ 4203 */
3945struct map * 4204struct map *
3946route_get_map(struct route *this_) 4205route_get_map(struct route *this_)
3947{ 4206{
4207 //// dbg(0, "enter\n");
4208
3948 return route_get_map_helper(this_, &this_->map, "route", "Route"); 4209 return route_get_map_helper(this_, &this_->map, "route", "Route");
3949} 4210}
3950 4211
3951/** 4212/**
3952 * @brief Returns a new map containing the route graph 4213 * @brief Returns a new map containing the route graph
3959 * @return A new map containing the route graph 4220 * @return A new map containing the route graph
3960 */ 4221 */
3961struct map * 4222struct map *
3962route_get_graph_map(struct route *this_) 4223route_get_graph_map(struct route *this_)
3963{ 4224{
4225 //// dbg(0, "enter\n");
4226
3964 return route_get_map_helper(this_, &this_->graph_map, "route_graph", 4227 return route_get_map_helper(this_, &this_->graph_map, "route_graph", "Route Graph");
3965 "Route Graph");
3966} 4228}
3967 4229
3968void route_set_projection(struct route *this_, enum projection pro) 4230void route_set_projection(struct route *this_, enum projection pro)
3969{ 4231{
3970} 4232}
3971 4233
3972int route_set_attr(struct route *this_, struct attr *attr) 4234int route_set_attr(struct route *this_, struct attr *attr)
3973{ 4235{
4236 //// dbg(0, "enter\n");
4237
3974 int attr_updated = 0; 4238 int attr_updated = 0;
3975 switch (attr->type) 4239 switch (attr->type)
3976 { 4240 {
3977 case attr_route_status: 4241 case attr_route_status:
4242 // update global route_status notifier
4243 //dbg(0,"previous=%d\n", route_status_previous);
4244 //dbg(0,"this_->route_status=%d attr->u.num=%d\n", this_->route_status, attr->u.num);
4245
4246 if (this_->route_status != attr->u.num)
4247 {
4248 if (attr->u.num == 5)
4249 {
4250 }
4251 else
4252 {
4253 if (route_status_previous != attr->u.num)
4254 {
4255 //dbg(0,"update\n");
4256 this_->route_status_was_updated = 1;
4257 }
4258 route_status_previous = attr->u.num;
4259 }
4260 }
4261
3978 attr_updated = (this_->route_status != attr->u.num); 4262 attr_updated = (this_->route_status != attr->u.num);
3979 this_->route_status = attr->u.num; 4263 this_->route_status = attr->u.num;
3980 // update global route_status notifier
3981 this_->route_status_was_updated = 1;
3982 break; 4264 break;
3983 case attr_destination: 4265 case attr_destination:
3984 route_set_destination(this_, attr->u.pcoord, 1); 4266 route_set_destination(this_, attr->u.pcoord, 1);
3985 return 1; 4267 return 1;
3986 case attr_vehicle: 4268 case attr_vehicle:
3989 if (attr_updated) 4271 if (attr_updated)
3990 { 4272 {
3991 struct attr g; 4273 struct attr g;
3992 struct pcoord pc; 4274 struct pcoord pc;
3993 struct coord c; 4275 struct coord c;
3994 if (vehicle_get_attr(this_->v, attr_position_coord_geo, &g, 4276 if (vehicle_get_attr(this_->v, attr_position_coord_geo, &g, NULL))
3995 NULL))
3996 { 4277 {
3997 pc.pro = projection_mg; 4278 pc.pro = projection_mg;
3998 transform_from_geo(projection_mg, g.u.coord_geo, &c); 4279 transform_from_geo(projection_mg, g.u.coord_geo, &c);
3999 pc.x = c.x; 4280 pc.x = c.x;
4000 pc.y = c.y; 4281 pc.y = c.y;
4001 route_set_position(this_, &pc); 4282 route_set_position(this_, &pc);
4002 } 4283 }
4003 } 4284 }
4004 break; 4285 break;
4005 default: 4286 default:
4006 dbg(0, "unsupported attribute: %s\n", attr_to_name(attr->type)); 4287 // dbg(0, "unsupported attribute: %s\n", attr_to_name(attr->type));
4007 return 0; 4288 return 0;
4008 } 4289 }
4290
4009 if (attr_updated) 4291 if (attr_updated)
4292 {
4010 callback_list_call_attr_2(this_->cbl2, attr->type, this_, attr); 4293 callback_list_call_attr_2(this_->cbl2, attr->type, this_, attr);
4294 }
4011 return 1; 4295 return 1;
4012} 4296}
4013 4297
4014int route_add_attr(struct route *this_, struct attr *attr) 4298int route_add_attr(struct route *this_, struct attr *attr)
4015{ 4299{
4300 //// dbg(0, "enter\n");
4301
4016 switch (attr->type) 4302 switch (attr->type)
4017 { 4303 {
4018 case attr_callback: 4304 case attr_callback:
4019 callback_list_add(this_->cbl2, attr->u.callback); 4305 callback_list_add(this_->cbl2, attr->u.callback);
4020 return 1; 4306 return 1;
4023 } 4309 }
4024} 4310}
4025 4311
4026int route_remove_attr(struct route *this_, struct attr *attr) 4312int route_remove_attr(struct route *this_, struct attr *attr)
4027{ 4313{
4028 //dbg(0,"enter\n"); 4314 //// dbg(0, "enter\n");
4315
4029 switch (attr->type) 4316 switch (attr->type)
4030 { 4317 {
4031 case attr_callback: 4318 case attr_callback:
4032 callback_list_remove(this_->cbl2, attr->u.callback); 4319 callback_list_remove(this_->cbl2, attr->u.callback);
4033 return 1; 4320 return 1;
4037 default: 4324 default:
4038 return 0; 4325 return 0;
4039 } 4326 }
4040} 4327}
4041 4328
4042int route_get_attr(struct route *this_, enum attr_type type, struct attr *attr, 4329int route_get_attr(struct route *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
4043 struct attr_iter *iter)
4044{ 4330{
4331 //// dbg(0, "enter\n");
4332
4045 int ret = 1; 4333 int ret = 1;
4046 switch (type) 4334 switch (type)
4047 { 4335 {
4048 case attr_map: 4336 case attr_map:
4049 attr->u.map = route_get_map(this_); 4337 attr->u.map = route_get_map(this_);
4092 break; 4380 break;
4093 case attr_route_status: 4381 case attr_route_status:
4094 attr->u.num = this_->route_status; 4382 attr->u.num = this_->route_status;
4095 break; 4383 break;
4096 case attr_destination_time: 4384 case attr_destination_time:
4097 if (this_->path2 && (this_->route_status 4385 if (this_->path2 && (this_->route_status == route_status_path_done_new || this_->route_status == route_status_path_done_incremental))
4098 == route_status_path_done_new || this_->route_status
4099 == route_status_path_done_incremental))
4100 { 4386 {
4101 4387
4102 attr->u.num = this_->path2->path_time; 4388 attr->u.num = this_->path2->path_time;
4103 //dbg(1, "path_time %d\n", attr->u.num); 4389 //dbg(1, "path_time %d\n", attr->u.num);
4104 } 4390 }
4105 else 4391 else
4106 ret = 0; 4392 ret = 0;
4107 break; 4393 break;
4108 case attr_destination_length: 4394 case attr_destination_length:
4109 if (this_->path2 && (this_->route_status 4395 if (this_->path2 && (this_->route_status == route_status_path_done_new || this_->route_status == route_status_path_done_incremental))
4110 == route_status_path_done_new || this_->route_status
4111 == route_status_path_done_incremental))
4112 attr->u.num = this_->path2->path_len; 4396 attr->u.num = this_->path2->path_len;
4113 else 4397 else
4114 ret = 0; 4398 ret = 0;
4115 break; 4399 break;
4116 default: 4400 default:
4121} 4405}
4122 4406
4123struct attr_iter * 4407struct attr_iter *
4124route_attr_iter_new(void) 4408route_attr_iter_new(void)
4125{ 4409{
4410 //// dbg(0, "enter\n");
4411
4126return g_new0(struct attr_iter, 1); 4412return g_new0(struct attr_iter, 1);
4127} 4413}
4128 4414
4129void route_attr_iter_destroy(struct attr_iter *iter) 4415void route_attr_iter_destroy(struct attr_iter *iter)
4130{ 4416{
4417 //// dbg(0, "enter\n");
4418
4131 g_free(iter); 4419 g_free(iter);
4132} 4420}
4133 4421
4134void route_init(void) 4422void route_init(void)
4135{ 4423{
4424 //// dbg(0, "enter\n");
4425
4136 plugin_register_map_type("route", route_map_new); 4426 plugin_register_map_type("route", route_map_new);
4137 plugin_register_map_type("route_graph", route_graph_map_new); 4427 plugin_register_map_type("route_graph", route_graph_map_new);
4138} 4428}
4139 4429
4140void route_destroy(struct route *this_) 4430void route_destroy(struct route *this_)
4141{ 4431{
4432 // dbg(0, "enter\n");
4433
4142 route_path_destroy(this_->path2, 1); 4434 route_path_destroy(this_->path2, 1);
4143 route_graph_destroy(this_->graph); 4435 route_graph_destroy(this_->graph);
4144 route_clear_destinations(this_); 4436 route_clear_destinations(this_);
4145 route_info_free(this_->pos); 4437 route_info_free(this_->pos);
4146 map_destroy(this_->map); 4438 map_destroy(this_->map);

Legend:
Removed from v.28  
changed lines
  Added in v.30

   
Visit the ZANavi Wiki