X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Frouter.c;fp=src%2Frouter.c;h=2b58f3bbff534fbb90e20d61db268b31252980bf;hb=9dffc9de96014e24d1fd1030a79317ba34c504e8;hp=46ca0b4d86521492b10b00187ea294c22e5e3aa2;hpb=42c9226fc71c19af4d755c6900120bfa07f7e99c;p=routino diff --git a/src/router.c b/src/router.c index 46ca0b4..2b58f3b 100644 --- a/src/router.c +++ b/src/router.c @@ -1,5 +1,5 @@ /*************************************** - $Header: /home/amb/routino/src/RCS/router.c,v 1.83 2010/06/28 17:56:26 amb Exp $ + $Header: /home/amb/routino/src/RCS/router.c,v 1.90 2010/11/13 14:22:28 amb Exp $ OSM router. @@ -28,28 +28,22 @@ #include #include "types.h" -#include "functions.h" -#include "translations.h" -#include "profiles.h" #include "nodes.h" #include "segments.h" #include "ways.h" +#include "files.h" +#include "logging.h" +#include "functions.h" +#include "translations.h" +#include "profiles.h" -/*+ The number of waypoints allowed to be specified. +*/ -#define NWAYPOINTS 99 /*+ The maximum distance from the specified point to search for a node or segment (in km). +*/ #define MAXSEARCH 1 -/*+ The minimum distance along a segment from a node to insert a fake node. (in km). +*/ -#define MINSEGMENT 0.005 - - -/*+ A set of fake segments to allow start/finish in the middle of a segment. +*/ -static Segment fake_segments[2*NWAYPOINTS]; -/*+ A set of fake node latitudes and longitudes. +*/ +/*+ A set of waypoint latitudes and longitudes. +*/ static double point_lon[NWAYPOINTS+1],point_lat[NWAYPOINTS+1]; /*+ The option not to print any progress information. +*/ @@ -64,7 +58,7 @@ int option_quickest=0; /* Local functions */ -static void print_usage(int detail); +static void print_usage(int detail,const char *argerr,const char *err); /*++++++++++++++++++++++++++++++++++++++ @@ -91,14 +85,14 @@ int main(int argc,char** argv) /* Parse the command line arguments */ if(argc<2) - print_usage(0); + print_usage(0,NULL,NULL); /* Get the non-routing, general program options */ for(arg=1;argNWAYPOINTS || point_used[point]&1) - print_usage(0); + print_usage(0,argv[arg],NULL); point_lon[point]=degrees_to_radians(atof(p)); point_used[point]+=1; @@ -245,11 +243,11 @@ int main(int argc,char** argv) char *p=&argv[arg][6]; while(isdigit(*p)) p++; if(*p++!='=') - print_usage(0); + print_usage(0,argv[arg],NULL); point=atoi(&argv[arg][5]); if(point>NWAYPOINTS || point_used[point]&2) - print_usage(0); + print_usage(0,argv[arg],NULL); point_lat[point]=degrees_to_radians(atof(p)); point_used[point]+=2; @@ -263,7 +261,7 @@ int main(int argc,char** argv) char *string; if(!equal) - print_usage(0); + print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+10); string[equal-argv[arg]-10]=0; @@ -271,7 +269,7 @@ int main(int argc,char** argv) highway=HighwayType(string); if(highway==Way_Count) - print_usage(0); + print_usage(0,argv[arg],NULL); profile->highway[highway]=atof(equal+1); @@ -284,7 +282,7 @@ int main(int argc,char** argv) char *string; if(!equal) - print_usage(0); + print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+8); string[equal-argv[arg]-8]=0; @@ -292,7 +290,7 @@ int main(int argc,char** argv) highway=HighwayType(string); if(highway==Way_Count) - print_usage(0); + print_usage(0,argv[arg],NULL); profile->speed[highway]=kph_to_speed(atof(equal+1)); @@ -305,7 +303,7 @@ int main(int argc,char** argv) char *string; if(!equal) - print_usage(0); + print_usage(0,argv[arg],NULL); string=strcpy((char*)malloc(strlen(argv[arg])),argv[arg]+11); string[equal-argv[arg]-11]=0; @@ -313,7 +311,7 @@ int main(int argc,char** argv) property=PropertyType(string); if(property==Way_Count) - print_usage(0); + print_usage(0,argv[arg],NULL); profile->props_yes[property]=atof(equal+1); @@ -330,12 +328,12 @@ int main(int argc,char** argv) else if(!strncmp(argv[arg],"--length=",9)) profile->length=metres_to_length(atof(&argv[arg][9])); else - print_usage(0); + print_usage(0,argv[arg],NULL); } for(point=1;point<=NWAYPOINTS;point++) if(point_used[point]==1 || point_used[point]==2) - print_usage(0); + print_usage(0,NULL,"All waypoints must have latitude and longitude."); if(help_profile) { @@ -369,18 +367,28 @@ int main(int argc,char** argv) if(option_html || option_gpx_route || option_gpx_track) { - if(translations && ExistsFile(translations)) - ; - else if(!translations && ExistsFile(FileName(dirname,prefix,"translations.xml"))) - translations=FileName(dirname,prefix,"translations.xml"); - - if(!translations && language) + if(translations) { - fprintf(stderr,"Error: Cannot use '--language' option without reading some translations.\n"); - return(1); + if(!ExistsFile(translations)) + { + fprintf(stderr,"Error: The '--translations' option specifies a file that does not exist.\n"); + return(1); + } + } + else + { + if(ExistsFile(FileName(dirname,prefix,"translations.xml"))) + translations=FileName(dirname,prefix,"translations.xml"); + else if(ExistsFile(FileName(DATADIR,NULL,"translations.xml"))) + translations=FileName(DATADIR,NULL,"translations.xml"); + else + { + fprintf(stderr,"Error: The '--translations' option was not used and the default 'translations.xml' does not exist.\n"); + return(1); + } } - if(translations && ParseXMLTranslations(translations,language)) + if(ParseXMLTranslations(translations,language)) { fprintf(stderr,"Error: Cannot read the translations in the file '%s'.\n",translations); return(1); @@ -408,7 +416,7 @@ int main(int argc,char** argv) Results *begin,*end; distance_t distmax=km_to_distance(MAXSEARCH); distance_t distmin; - Segment *segment=NULL; + index_t segment=NO_SEGMENT; index_t node1,node2; if(point_used[point]!=3) @@ -426,8 +434,10 @@ int main(int argc,char** argv) { distance_t dist1,dist2; - if((segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2))) - finish=CreateFakes(OSMNodes,point,segment,node1,node2,dist1,dist2); + segment=FindClosestSegment(OSMNodes,OSMSegments,OSMWays,point_lat[point],point_lon[point],distmax,profile,&distmin,&node1,&node2,&dist1,&dist2); + + if(segment!=NO_SEGMENT) + finish=CreateFakes(OSMNodes,point,LookupSegment(OSMSegments,segment,1),node1,node2,dist1,dist2); else finish=NO_NODE; } @@ -448,7 +458,7 @@ int main(int argc,char** argv) GetLatLong(OSMNodes,finish,&lat,&lon); if(IsFakeNode(finish)) - printf("Point %d is segment %d (node %d -> %d): %3.6f %4.6f = %2.3f km\n",point,IndexSegment(OSMSegments,segment),node1,node2, + printf("Point %d is segment %d (node %d -> %d): %3.6f %4.6f = %2.3f km\n",point,segment,node1,node2, radians_to_degrees(lon),radians_to_degrees(lat),distance_to_km(distmin)); else printf("Point %d is node %d: %3.6f %4.6f = %2.3f km\n",point,finish, @@ -494,7 +504,7 @@ int main(int argc,char** argv) if(!option_quiet) { - printf("\rRouted: Super-Nodes Checked = %d\n",begin->number); + printf("Routed: Super-Nodes Checked = %d\n",begin->number); fflush(stdout); } } @@ -556,176 +566,16 @@ int main(int argc,char** argv) /*++++++++++++++++++++++++++++++++++++++ - Create a pair of fake segments corresponding to the given segment split in two. - - index_t CreateFakes Returns the fake node index (or a real one in special cases). - - Nodes *nodes The set of nodes to use. - - int point Which of the waypoints is this. - - Segment *segment The segment to split. - - index_t node1 The first node at the end of this segment. - - index_t node2 The second node at the end of this segment. - - distance_t dist1 The distance to the first node. - - distance_t dist2 The distance to the second node. - ++++++++++++++++++++++++++++++++++++++*/ - -index_t CreateFakes(Nodes *nodes,int point,Segment *segment,index_t node1,index_t node2,distance_t dist1,distance_t dist2) -{ - index_t fakenode; - double lat1,lon1,lat2,lon2; - - /* Check if we are actually close enough to an existing node */ - - if(dist1km_to_distance(MINSEGMENT)) - return(node1); - - if(dist2km_to_distance(MINSEGMENT)) - return(node2); - - if(dist13 && lat2<-3) - lat2+=2*M_PI; - else if(lat1<-3 && lat2>3) - lat1+=2*M_PI; - - point_lat[point]=lat1+(lat2-lat1)*(double)dist1/(double)(dist1+dist2); - point_lon[point]=lon1+(lon2-lon1)*(double)dist1/(double)(dist1+dist2); - - if(point_lat[point]>M_PI) point_lat[point]-=2*M_PI; - - /* Create the first fake segment */ - - fake_segments[2*point-2]=*segment; - - if(segment->node1==node1) - fake_segments[2*point-2].node1=fakenode; - else - fake_segments[2*point-2].node2=fakenode; - - fake_segments[2*point-2].distance=DISTANCE(dist1)|DISTFLAG(segment->distance); - - /* Create the second fake segment */ - - fake_segments[2*point-1]=*segment; - - if(segment->node1==node2) - fake_segments[2*point-1].node1=fakenode; - else - fake_segments[2*point-1].node2=fakenode; - - fake_segments[2*point-1].distance=DISTANCE(dist2)|DISTFLAG(segment->distance); - - return(fakenode); -} - - -/*++++++++++++++++++++++++++++++++++++++ - Lookup the latitude and longitude of a fake node. - - index_t fakenode The node to lookup. - - double *latitude Returns the latitude - - double *longitude Returns the longitude. - ++++++++++++++++++++++++++++++++++++++*/ - -void GetFakeLatLong(index_t fakenode, double *latitude,double *longitude) -{ - index_t realnode=fakenode&(~NODE_SUPER); - - *latitude =point_lat[realnode]; - *longitude=point_lon[realnode]; -} - - -/*++++++++++++++++++++++++++++++++++++++ - Finds the first fake segment associated to a fake node. - - Segment *FirstFakeSegment Returns the first fake segment. - - index_t fakenode The node to lookup. - ++++++++++++++++++++++++++++++++++++++*/ - -Segment *FirstFakeSegment(index_t fakenode) -{ - index_t realnode=fakenode&(~NODE_SUPER); - - return(&fake_segments[2*realnode-2]); -} - - -/*++++++++++++++++++++++++++++++++++++++ - Finds the next (there can only be two) fake segment associated to a fake node. - - Segment *NextFakeSegment Returns the second fake segment. - - Segment *segment The first fake segment. - - index_t fakenode The node to lookup. - ++++++++++++++++++++++++++++++++++++++*/ - -Segment *NextFakeSegment(Segment *segment,index_t fakenode) -{ - index_t realnode=fakenode&(~NODE_SUPER); - - if(segment==&fake_segments[2*realnode-2]) - return(&fake_segments[2*realnode-1]); - else - return(NULL); -} - - -/*++++++++++++++++++++++++++++++++++++++ - Finds the next (there can only be two) fake segment associated to a fake node. - - Segment *ExtraFakeSegment Returns a segment between the two specified nodes if it exists. - - index_t node The real node. - - index_t fakenode The fake node to lookup. - ++++++++++++++++++++++++++++++++++++++*/ - -Segment *ExtraFakeSegment(index_t node,index_t fakenode) -{ - index_t realnode=fakenode&(~NODE_SUPER); - - if(fake_segments[2*realnode-2].node1==node || fake_segments[2*realnode-2].node2==node) - return(&fake_segments[2*realnode-2]); - - if(fake_segments[2*realnode-1].node1==node || fake_segments[2*realnode-1].node2==node) - return(&fake_segments[2*realnode-1]); - - return(NULL); -} - - -/*++++++++++++++++++++++++++++++++++++++ Print out the usage information. int detail The level of detail to use - 0 = low, 1 = high. + + const char *argerr The argument that gave the error (if there is one). + + const char *err Other error message (if there is one). ++++++++++++++++++++++++++++++++++++++*/ -static void print_usage(int detail) +static void print_usage(int detail,const char *argerr,const char *err) { fprintf(stderr, "Usage: router [--help | --help-profile | --help-profile-xml |\n" @@ -733,7 +583,7 @@ static void print_usage(int detail) " [--dir=] [--prefix=]\n" " [--profiles=] [--translations=]\n" " [--exact-nodes-only]\n" - " [--quiet]\n" + " [--loggable | --quiet]\n" " [--language=]\n" " [--output-html]\n" " [--output-gpx-track] [--output-gpx-route]\n" @@ -752,6 +602,16 @@ static void print_usage(int detail) " [--weight=]\n" " [--height=] [--width=] [--length=]\n"); + if(argerr) + fprintf(stderr, + "\n" + "Error with command line parameter: %s\n",argerr); + + if(err) + fprintf(stderr, + "\n" + "Error: %s\n",err); + if(detail) fprintf(stderr, "\n" @@ -763,14 +623,20 @@ static void print_usage(int detail) "\n" "--dir= The directory containing the routing database.\n" "--prefix= The filename prefix for the routing database.\n" - "--profiles= The name of the profiles (defaults to 'profiles.xml'\n" - " with '--dirname' and '--prefix' options).\n" - "--translations= The filename of the translations (defaults to\n" - " 'translations.xml' with '--dirname' and '--prefix').\n" + "--profiles= The name of the XML file containing the profiles\n" + " (defaults to 'profiles.xml' with '--dir' and\n" + " '--prefix' options or the file installed in\n" + " '" DATADIR "').\n" + "--translations= The name of the XML file containing the translations\n" + " (defaults to 'translations.xml' with '--dir' and\n" + " '--prefix' options or the file installed in\n" + " '" DATADIR "').\n" "\n" "--exact-nodes-only Only route between nodes (don't find closest segment).\n" "\n" + "--loggable Print progress messages suitable for logging to file.\n" "--quiet Don't print any screen output when running.\n" + "\n" "--language= Use the translations for specified language.\n" "--output-html Write an HTML description of the route.\n" "--output-gpx-track Write a GPX track file with all route points.\n"