Imported Upstream version 1.5
[routino] / src / router.c
index 46ca0b4..c9eb13b 100644 (file)
@@ -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.89 2010/09/15 18:19:36 amb Exp $
 
  OSM router.
 
 #include <ctype.h>
 
 #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 "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 +57,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 +84,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;arg<argc;arg++)
    {
     if(!strcmp(argv[arg],"--help"))
-       print_usage(1);
+       print_usage(1,NULL,NULL);
     else if(!strcmp(argv[arg],"--help-profile"))
        help_profile=1;
     else if(!strcmp(argv[arg],"--help-profile-xml"))
@@ -140,7 +133,7 @@ int main(int argc,char** argv)
        transport=TransportType(&argv[arg][12]);
 
        if(transport==Transport_None)
-         print_usage(0);
+          print_usage(0,argv[arg],NULL);
       }
     else
        continue;
@@ -165,6 +158,8 @@ int main(int argc,char** argv)
    {
     if(ExistsFile(FileName(dirname,prefix,"profiles.xml")))
        profiles=FileName(dirname,prefix,"profiles.xml");
+    else if(ExistsFile(FileName(DATADIR,NULL,"tagging.xml")))
+       profiles=FileName(DATADIR,NULL,"profiles.xml");
     else
       {
        fprintf(stderr,"Error: The '--profiles' option was not used and the default 'profiles.xml' does not exist.\n");
@@ -172,7 +167,7 @@ int main(int argc,char** argv)
       }
    }
 
- if(profiles && ParseXMLProfiles(profiles))
+ if(ParseXMLProfiles(profiles))
    {
     fprintf(stderr,"Error: Cannot read the profiles in the file '%s'.\n",profiles);
     return(1);
@@ -231,11 +226,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]&1)
-           print_usage(0);
+           print_usage(0,argv[arg],NULL);
  
        point_lon[point]=degrees_to_radians(atof(p));
        point_used[point]+=1;
@@ -245,11 +240,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 +258,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 +266,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 +279,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 +287,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 +300,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 +308,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 +325,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 +364,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 +413,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 +431,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 +455,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,
@@ -556,176 +563,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(dist1<km_to_distance(MINSEGMENT) && dist2>km_to_distance(MINSEGMENT))
-    return(node1);
-
- if(dist2<km_to_distance(MINSEGMENT) && dist1>km_to_distance(MINSEGMENT))
-    return(node2);
-
- if(dist1<km_to_distance(MINSEGMENT) && dist2<km_to_distance(MINSEGMENT))
-   {
-    if(dist1<dist2)
-       return(node1);
-    else
-       return(node2);
-   }
-
- /* Create the fake node */
-
- fakenode=point|NODE_SUPER;
-
- GetLatLong(nodes,node1,&lat1,&lon1);
- GetLatLong(nodes,node2,&lat2,&lon2);
-
- if(lat1>3 && 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"
@@ -752,6 +599,16 @@ static void print_usage(int detail)
          "              [--weight=<weight>]\n"
          "              [--height=<height>] [--width=<width>] [--length=<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,10 +620,14 @@ static void print_usage(int detail)
             "\n"
             "--dir=<dirname>         The directory containing the routing database.\n"
             "--prefix=<name>         The filename prefix for the routing database.\n"
-            "--profiles=<filename>   The name of the profiles (defaults to 'profiles.xml'\n"
-            "                        with '--dirname' and '--prefix' options).\n"
-            "--translations=<fname>  The filename of the translations (defaults to\n"
-            "                         'translations.xml' with '--dirname' and '--prefix').\n"
+            "--profiles=<filename>   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=<fname>  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"