routino-2.4.1/ 40755 233 144 0 12063564162 6356 5 routino-2.4.1/src/ 40755 233 144 0 12063564022 7140 5 routino-2.4.1/src/filedumperx.c 644 233 144 24036 12063560526 11676 0 /***************************************
Memory file dumper for the intermediate files containing parsed data.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2012 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#include
#include
#include
#include
#include "typesx.h"
#include "nodesx.h"
#include "segmentsx.h"
#include "waysx.h"
#include "relationsx.h"
#include "files.h"
#include "sorting.h"
/* Local functions */
static void print_nodes(const char *filename);
static void print_segments(const char *filename);
static void print_ways(const char *filename);
static void print_route_relations(const char *filename);
static void print_turn_relations(const char *filename);
static void print_usage(int detail,const char *argerr,const char *err);
/*++++++++++++++++++++++++++++++++++++++
The main program for the file dumper.
++++++++++++++++++++++++++++++++++++++*/
int main(int argc,char** argv)
{
int arg;
char *dirname=NULL,*prefix=NULL;
char *nodes_filename,*segments_filename,*ways_filename,*route_relations_filename,*turn_relations_filename;
int option_dump;
/* Parse the command line arguments */
for(arg=1;arg] [--prefix=]\n"
" [--dump [--nodes]\n"
" [--segments]\n"
" [--ways]\n"
" [--route-relations]\n"
" [--turn-relations]]\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"
"--help Prints this information.\n"
"\n"
"--dir= The directory containing the routing database.\n"
"--prefix= The filename prefix for the routing database.\n"
"\n"
"--dump Dump the intermediate files after parsing.\n"
" --nodes * all of the nodes.\n"
" --segments * all of the segments.\n"
" --ways * all of the ways.\n"
" --route-relations * all of the route relations.\n"
" --turn-relations * all of the turn relations.\n");
exit(!detail);
}
routino-2.4.1/src/waysx.c 644 233 144 43502 12063562207 10522 0 /***************************************
Extended Way data type functions.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2012 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#include
#include
#include "types.h"
#include "ways.h"
#include "typesx.h"
#include "segmentsx.h"
#include "waysx.h"
#include "files.h"
#include "logging.h"
#include "sorting.h"
/* Global variables */
/*+ The command line '--tmpdir' option or its default value. +*/
extern char *option_tmpdirname;
/* Local variables */
/*+ Temporary file-local variables for use by the sort functions. +*/
static WaysX *sortwaysx;
static SegmentsX *sortsegmentsx;
/* Local functions */
static int sort_by_id(WayX *a,WayX *b);
static int deduplicate_by_id(WayX *wayx,index_t index);
static int sort_by_name(WayX *a,WayX *b);
static int index_by_id(WayX *wayx,index_t index);
static int delete_unused(WayX *wayx,index_t index);
static int sort_by_name_and_prop_and_id(WayX *a,WayX *b);
static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index);
/*++++++++++++++++++++++++++++++++++++++
Allocate a new way list (create a new file or open an existing one).
WaysX *NewWayList Returns the way list.
int append Set to 1 if the file is to be opened for appending.
int readonly Set to 1 if the file is to be opened for reading.
++++++++++++++++++++++++++++++++++++++*/
WaysX *NewWayList(int append,int readonly)
{
WaysX *waysx;
waysx=(WaysX*)calloc(1,sizeof(WaysX));
logassert(waysx,"Failed to allocate memory (try using slim mode?)"); /* Check calloc() worked */
waysx->filename =(char*)malloc(strlen(option_tmpdirname)+32);
waysx->filename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
sprintf(waysx->filename ,"%s/waysx.parsed.mem",option_tmpdirname);
sprintf(waysx->filename_tmp,"%s/waysx.%p.tmp" ,option_tmpdirname,(void*)waysx);
if(append || readonly)
if(ExistsFile(waysx->filename))
{
off_t size,position=0;
int fd;
size=SizeFile(waysx->filename);
fd=ReOpenFile(waysx->filename);
while(positionnumber++;
position+=waysize+FILESORT_VARSIZE;
}
CloseFile(fd);
RenameFile(waysx->filename,waysx->filename_tmp);
}
if(append)
waysx->fd=OpenFileAppend(waysx->filename_tmp);
else if(!readonly)
waysx->fd=OpenFileNew(waysx->filename_tmp);
else
waysx->fd=-1;
waysx->nfilename_tmp=(char*)malloc(strlen(option_tmpdirname)+32);
sprintf(waysx->nfilename_tmp,"%s/waynames.%p.tmp",option_tmpdirname,(void*)waysx);
return(waysx);
}
/*++++++++++++++++++++++++++++++++++++++
Free a way list.
WaysX *waysx The set of ways to be freed.
int keep If set then the results file is to be kept.
++++++++++++++++++++++++++++++++++++++*/
void FreeWayList(WaysX *waysx,int keep)
{
if(keep)
RenameFile(waysx->filename_tmp,waysx->filename);
else
DeleteFile(waysx->filename_tmp);
free(waysx->filename);
free(waysx->filename_tmp);
if(waysx->idata)
free(waysx->idata);
if(waysx->cdata)
free(waysx->cdata);
DeleteFile(waysx->nfilename_tmp);
free(waysx->nfilename_tmp);
free(waysx);
}
/*++++++++++++++++++++++++++++++++++++++
Append a single way to an unsorted way list.
WaysX *waysx The set of ways to process.
way_t id The ID of the way.
Way *way The way data itself.
const char *name The name or reference of the way.
++++++++++++++++++++++++++++++++++++++*/
void AppendWayList(WaysX *waysx,way_t id,Way *way,const char *name)
{
WayX wayx;
FILESORT_VARINT size;
wayx.id=id;
wayx.way=*way;
size=sizeof(WayX)+strlen(name)+1;
WriteFile(waysx->fd,&size,FILESORT_VARSIZE);
WriteFile(waysx->fd,&wayx,sizeof(WayX));
WriteFile(waysx->fd,name,strlen(name)+1);
waysx->number++;
logassert(waysx->number!=0,"Too many ways (change index_t to 64-bits?)"); /* Zero marks the high-water mark for ways. */
}
/*++++++++++++++++++++++++++++++++++++++
Finish appending ways and change the filename over.
WaysX *waysx The ways that have been appended.
++++++++++++++++++++++++++++++++++++++*/
void FinishWayList(WaysX *waysx)
{
if(waysx->fd!=-1)
waysx->fd=CloseFile(waysx->fd);
}
/*++++++++++++++++++++++++++++++++++++++
Find a particular way index.
index_t IndexWayX Returns the index of the extended way with the specified id.
WaysX *waysx The set of ways to process.
way_t id The way id to look for.
++++++++++++++++++++++++++++++++++++++*/
index_t IndexWayX(WaysX *waysx,way_t id)
{
index_t start=0;
index_t end=waysx->number-1;
index_t mid;
if(waysx->number==0) /* There are no ways */
return(NO_WAY);
if(ididata[start]) /* Key is before start */
return(NO_WAY);
if(id>waysx->idata[end]) /* Key is after end */
return(NO_WAY);
/* Binary search - search key exact match only is required.
*
* # <- start | Check mid and move start or end if it doesn't match
* # |
* # | Since an exact match is wanted we can set end=mid-1
* # <- mid | or start=mid+1 because we know that mid doesn't match.
* # |
* # | Eventually either end=start or end=start+1 and one of
* # <- end | start or end is the wanted one.
*/
do
{
mid=(start+end)/2; /* Choose mid point */
if(waysx->idata[mid]idata[mid]>id) /* Mid point is too high */
end=mid?(mid-1):mid;
else /* Mid point is correct */
return(mid);
}
while((end-start)>1);
if(waysx->idata[start]==id) /* Start is correct */
return(start);
if(waysx->idata[end]==id) /* End is correct */
return(end);
return(NO_WAY);
}
/*++++++++++++++++++++++++++++++++++++++
Sort the list of ways.
WaysX *waysx The set of ways to process.
++++++++++++++++++++++++++++++++++++++*/
void SortWayList(WaysX *waysx)
{
index_t xnumber;
int fd;
/* Print the start message */
printf_first("Sorting Ways");
/* Re-open the file read-only and a new file writeable */
waysx->fd=ReOpenFile(waysx->filename_tmp);
DeleteFile(waysx->filename_tmp);
fd=OpenFileNew(waysx->filename_tmp);
/* Sort the ways by ID and index them */
xnumber=waysx->number;
waysx->number=filesort_vary(waysx->fd,fd,NULL,
(int (*)(const void*,const void*))sort_by_id,
(int (*)(void*,index_t))deduplicate_by_id);
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
CloseFile(fd);
/* Print the final message */
printf_last("Sorted Ways: Ways=%"Pindex_t" Duplicates=%"Pindex_t,xnumber,xnumber-waysx->number);
}
/*++++++++++++++++++++++++++++++++++++++
Sort the ways into id order.
int sort_by_id Returns the comparison of the id fields.
WayX *a The first extended way.
WayX *b The second extended way.
++++++++++++++++++++++++++++++++++++++*/
static int sort_by_id(WayX *a,WayX *b)
{
way_t a_id=a->id;
way_t b_id=b->id;
if(a_idb_id)
return(1);
else
return(-FILESORT_PRESERVE_ORDER(a,b)); /* latest version first */
}
/*++++++++++++++++++++++++++++++++++++++
Discard duplicate ways.
int deduplicate_by_id Return 1 if the value is to be kept, otherwise 0.
WayX *wayx The extended way.
index_t index The number of sorted ways that have already been written to the output file.
++++++++++++++++++++++++++++++++++++++*/
static int deduplicate_by_id(WayX *wayx,index_t index)
{
static way_t previd=NO_WAY_ID;
if(wayx->id!=previd)
{
previd=wayx->id;
if(wayx->way.type==WAY_DELETED)
return(0);
else
return(1);
}
else
return(0);
}
/*++++++++++++++++++++++++++++++++++++++
Extract the way names from the ways and reference the list of names from the ways.
WaysX *waysx The set of ways to process.
int keep If set to 1 then keep the old data file otherwise delete it.
++++++++++++++++++++++++++++++++++++++*/
void ExtractWayNames(WaysX *waysx,int keep)
{
index_t i;
int fd;
char *names[2]={NULL,NULL};
int namelen[2]={0,0};
int nnames=0;
uint32_t lastlength=0;
/* Print the start message */
printf_first("Sorting Ways by Name");
/* Re-open the file read-only and a new file writeable */
waysx->fd=ReOpenFile(waysx->filename_tmp);
if(keep)
RenameFile(waysx->filename_tmp,waysx->filename);
else
DeleteFile(waysx->filename_tmp);
fd=OpenFileNew(waysx->filename_tmp);
/* Sort the ways to allow separating the names */
filesort_vary(waysx->fd,fd,NULL,
(int (*)(const void*,const void*))sort_by_name,
NULL);
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
CloseFile(fd);
/* Print the final message */
printf_last("Sorted Ways by Name: Ways=%"Pindex_t,waysx->number);
/* Print the start message */
printf_first("Separating Way Names: Ways=0 Names=0");
/* Re-open the file read-only and new files writeable */
waysx->fd=ReOpenFile(waysx->filename_tmp);
DeleteFile(waysx->filename_tmp);
fd=OpenFileNew(waysx->filename_tmp);
waysx->nfd=OpenFileNew(waysx->nfilename_tmp);
/* Copy from the single file into two files */
for(i=0;inumber;i++)
{
WayX wayx;
FILESORT_VARINT size;
ReadFile(waysx->fd,&size,FILESORT_VARSIZE);
if(namelen[nnames%2]fd,&wayx,sizeof(WayX));
ReadFile(waysx->fd,names[nnames%2],size-sizeof(WayX));
if(nnames==0 || strcmp(names[0],names[1]))
{
WriteFile(waysx->nfd,names[nnames%2],size-sizeof(WayX));
lastlength=waysx->nlength;
waysx->nlength+=size-sizeof(WayX);
nnames++;
}
wayx.way.name=lastlength;
WriteFile(fd,&wayx,sizeof(WayX));
if(!((i+1)%1000))
printf_middle("Separating Way Names: Ways=%"Pindex_t" Names=%"Pindex_t,i+1,nnames);
}
if(names[0]) free(names[0]);
if(names[1]) free(names[1]);
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
CloseFile(fd);
waysx->nfd=CloseFile(waysx->nfd);
/* Print the final message */
printf_last("Separated Way Names: Ways=%"Pindex_t" Names=%"Pindex_t,waysx->number,nnames);
/* Print the start message */
printf_first("Sorting Ways");
/* Re-open the file read-only and a new file writeable */
waysx->fd=ReOpenFile(waysx->filename_tmp);
DeleteFile(waysx->filename_tmp);
fd=OpenFileNew(waysx->filename_tmp);
/* Allocate the array of indexes */
waysx->idata=(way_t*)malloc(waysx->number*sizeof(way_t));
logassert(waysx->idata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
/* Sort the ways by ID */
sortwaysx=waysx;
filesort_fixed(waysx->fd,fd,sizeof(WayX),NULL,
(int (*)(const void*,const void*))sort_by_id,
(int (*)(void*,index_t))index_by_id);
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
CloseFile(fd);
/* Print the final message */
printf_last("Sorted Ways: Ways=%"Pindex_t,waysx->number);
}
/*++++++++++++++++++++++++++++++++++++++
Sort the ways into name order and then id order.
int sort_by_name Returns the comparison of the name fields.
WayX *a The first extended Way.
WayX *b The second extended Way.
++++++++++++++++++++++++++++++++++++++*/
static int sort_by_name(WayX *a,WayX *b)
{
int compare;
char *a_name=(char*)a+sizeof(WayX);
char *b_name=(char*)b+sizeof(WayX);
compare=strcmp(a_name,b_name);
if(compare)
return(compare);
else
return(FILESORT_PRESERVE_ORDER(a,b));
}
/*++++++++++++++++++++++++++++++++++++++
Create the index of identifiers.
int index_by_id Return 1 if the value is to be kept, otherwise 0.
WayX *wayx The extended way.
index_t index The number of sorted ways that have already been written to the output file.
++++++++++++++++++++++++++++++++++++++*/
static int index_by_id(WayX *wayx,index_t index)
{
sortwaysx->idata[index]=wayx->id;
return(1);
}
/*++++++++++++++++++++++++++++++++++++++
Compact the way list, removing duplicated ways and unused ways.
WaysX *waysx The set of ways to process.
SegmentsX *segmentsx The set of segments to check.
++++++++++++++++++++++++++++++++++++++*/
void CompactWayList(WaysX *waysx,SegmentsX *segmentsx)
{
int fd;
index_t cnumber;
if(waysx->number==0)
return;
/* Print the start message */
printf_first("Sorting Ways and Compacting");
/* Allocate the array of indexes */
waysx->cdata=(index_t*)malloc(waysx->number*sizeof(index_t));
logassert(waysx->cdata,"Failed to allocate memory (try using slim mode?)"); /* Check malloc() worked */
/* Re-open the file read-only and a new file writeable */
waysx->fd=ReOpenFile(waysx->filename_tmp);
DeleteFile(waysx->filename_tmp);
fd=OpenFileNew(waysx->filename_tmp);
/* Sort the ways to allow compacting according to the properties */
sortwaysx=waysx;
sortsegmentsx=segmentsx;
cnumber=filesort_fixed(waysx->fd,fd,sizeof(WayX),(int (*)(void*,index_t))delete_unused,
(int (*)(const void*,const void*))sort_by_name_and_prop_and_id,
(int (*)(void*,index_t))deduplicate_and_index_by_compact_id);
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
CloseFile(fd);
/* Print the final message */
printf_last("Sorted and Compacted Ways: Ways=%"Pindex_t" Unique=%"Pindex_t,waysx->number,cnumber);
waysx->number=cnumber;
free(segmentsx->usedway);
segmentsx->usedway=NULL;
}
/*++++++++++++++++++++++++++++++++++++++
Delete the ways that are no longer being used.
int delete_unused Return 1 if the value is to be kept, otherwise 0.
WayX *wayx The extended way.
index_t index The number of unsorted ways that have been read from the input file.
++++++++++++++++++++++++++++++++++++++*/
static int delete_unused(WayX *wayx,index_t index)
{
if(sortsegmentsx && !IsBitSet(sortsegmentsx->usedway,index))
{
sortwaysx->cdata[index]=NO_WAY;
return(0);
}
else
{
wayx->id=index;
return(1);
}
}
/*++++++++++++++++++++++++++++++++++++++
Sort the ways into name, properties and id order.
int sort_by_name_and_prop_and_id Returns the comparison of the name, properties and id fields.
WayX *a The first extended Way.
WayX *b The second extended Way.
++++++++++++++++++++++++++++++++++++++*/
static int sort_by_name_and_prop_and_id(WayX *a,WayX *b)
{
int compare;
index_t a_name=a->way.name;
index_t b_name=b->way.name;
if(a_nameb_name)
return(1);
compare=WaysCompare(&a->way,&b->way);
if(compare)
return(compare);
return(sort_by_id(a,b));
}
/*++++++++++++++++++++++++++++++++++++++
Create the index of compacted Way identifiers and ignore Ways with duplicated properties.
int deduplicate_and_index_by_compact_id Return 1 if the value is to be kept, otherwise 0.
WayX *wayx The extended way.
index_t index The number of sorted ways that have already been written to the output file.
++++++++++++++++++++++++++++++++++++++*/
static int deduplicate_and_index_by_compact_id(WayX *wayx,index_t index)
{
static Way lastway;
if(index==0 || wayx->way.name!=lastway.name || WaysCompare(&lastway,&wayx->way))
{
lastway=wayx->way;
sortwaysx->cdata[wayx->id]=index;
wayx->id=index;
return(1);
}
else
{
sortwaysx->cdata[wayx->id]=index-1;
return(0);
}
}
/*++++++++++++++++++++++++++++++++++++++
Save the way list to a file.
WaysX *waysx The set of ways to save.
const char *filename The name of the file to save.
++++++++++++++++++++++++++++++++++++++*/
void SaveWayList(WaysX *waysx,const char *filename)
{
index_t i;
int fd;
int position=0;
WayX wayx;
WaysFile waysfile={0};
highways_t highways=0;
transports_t allow=0;
properties_t props=0;
/* Print the start message */
printf_first("Writing Ways: Ways=0");
/* Re-open the files */
waysx->fd=ReOpenFile(waysx->filename_tmp);
waysx->nfd=ReOpenFile(waysx->nfilename_tmp);
/* Write out the ways data */
fd=OpenFileNew(filename);
SeekFile(fd,sizeof(WaysFile));
for(i=0;inumber;i++)
{
ReadFile(waysx->fd,&wayx,sizeof(WayX));
highways|=HIGHWAYS(wayx.way.type);
allow |=wayx.way.allow;
props |=wayx.way.props;
WriteFile(fd,&wayx.way,sizeof(Way));
if(!((i+1)%1000))
printf_middle("Writing Ways: Ways=%"Pindex_t,i+1);
}
/* Write out the ways names */
SeekFile(fd,sizeof(WaysFile)+(off_t)waysx->number*sizeof(Way));
while(positionnlength)
{
int len=1024;
char temp[1024];
if((waysx->nlength-position)<1024)
len=waysx->nlength-position;
ReadFile(waysx->nfd,temp,len);
WriteFile(fd,temp,len);
position+=len;
}
/* Close the files */
waysx->fd=CloseFile(waysx->fd);
waysx->nfd=CloseFile(waysx->nfd);
/* Write out the header structure */
waysfile.number =waysx->number;
waysfile.highways=highways;
waysfile.allow =allow;
waysfile.props =props;
SeekFile(fd,0);
WriteFile(fd,&waysfile,sizeof(WaysFile));
CloseFile(fd);
/* Print the final message */
printf_last("Wrote Ways: Ways=%"Pindex_t,waysx->number);
}
routino-2.4.1/src/ways.h 644 233 144 12074 12063560526 10341 0 /***************************************
A header file for the ways.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2012 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#ifndef WAYS_H
#define WAYS_H /*+ To stop multiple inclusions. +*/
#include
#include
#include "types.h"
#include "files.h"
/* Data structures */
/*+ A structure containing a single way (members ordered to minimise overall size). +*/
struct _Way
{
index_t name; /*+ The offset of the name of the way in the names array. +*/
transports_t allow; /*+ The type of traffic allowed on the way. +*/
highway_t type; /*+ The highway type of the way. +*/
properties_t props; /*+ The properties of the way. +*/
speed_t speed; /*+ The defined maximum speed limit of the way. +*/
weight_t weight; /*+ The defined maximum weight of traffic on the way. +*/
height_t height; /*+ The defined maximum height of traffic on the way. +*/
width_t width; /*+ The defined maximum width of traffic on the way. +*/
length_t length; /*+ The defined maximum length of traffic on the way. +*/
};
/*+ A structure containing the header from the file. +*/
typedef struct _WaysFile
{
index_t number; /*+ The number of ways. +*/
highways_t highways; /*+ The types of highways that were seen when parsing. +*/
transports_t allow; /*+ The types of traffic that were seen when parsing. +*/
properties_t props; /*+ The properties that were seen when parsing. +*/
}
WaysFile;
/*+ A structure containing a set of ways (and pointers to mmap file). +*/
struct _Ways
{
WaysFile file; /*+ The header data from the file. +*/
#if !SLIM
void *data; /*+ The memory mapped data. +*/
Way *ways; /*+ An array of ways. +*/
char *names; /*+ An array of characters containing the names. +*/
#else
int fd; /*+ The file descriptor for the file. +*/
off_t namesoffset; /*+ The offset of the names within the file. +*/
Way cached[3]; /*+ Two cached nodes read from the file in slim mode. +*/
index_t incache[3]; /*+ The indexes of the cached ways. +*/
char *ncached[3]; /*+ The cached way name. +*/
#endif
};
/* Functions in ways.c */
Ways *LoadWayList(const char *filename);
int WaysCompare(Way *way1p,Way *way2p);
/* Macros and inline functions */
#if !SLIM
/*+ Return a Way* pointer given a set of ways and an index. +*/
#define LookupWay(xxx,yyy,zzz) (&(xxx)->ways[yyy])
/*+ Return the name of a way given the Way pointer and a set of ways. +*/
#define WayName(xxx,yyy) (&(xxx)->names[(yyy)->name])
#else
static Way *LookupWay(Ways *ways,index_t index,int position);
static char *WayName(Ways *ways,Way *wayp);
/*++++++++++++++++++++++++++++++++++++++
Find the Way information for a particular way.
Way *LookupWay Returns a pointer to the cached way information.
Ways *ways The set of ways to use.
index_t index The index of the way.
int position The position in the cache to store the value.
++++++++++++++++++++++++++++++++++++++*/
static inline Way *LookupWay(Ways *ways,index_t index,int position)
{
if(ways->incache[position-1]!=index)
{
SeekReadFile(ways->fd,&ways->cached[position-1],sizeof(Way),sizeof(WaysFile)+(off_t)index*sizeof(Way));
ways->incache[position-1]=index;
}
return(&ways->cached[position-1]);
}
/*++++++++++++++++++++++++++++++++++++++
Find the name of a way.
char *WayName Returns a pointer to the name of the way.
Ways *ways The set of ways to use.
Way *wayp The Way pointer.
++++++++++++++++++++++++++++++++++++++*/
static inline char *WayName(Ways *ways,Way *wayp)
{
int position=wayp-&ways->cached[-1];
int n=0;
SeekFile(ways->fd,ways->namesoffset+wayp->name);
if(!ways->ncached[position-1])
ways->ncached[position-1]=(char*)malloc(32);
while(1)
{
int i;
int m=ReadFile(ways->fd,ways->ncached[position-1]+n,32);
if(m<0)
break;
for(i=n;incached[position-1][i]==0)
goto exitloop;
n+=32;
ways->ncached[position-1]=(char*)realloc((void*)ways->ncached[position-1],n+32);
}
exitloop:
return(ways->ncached[position-1]);
}
#endif
#endif /* WAYS_H */
routino-2.4.1/src/superx.h 644 233 144 2420 12063560526 10656 0 /***************************************
Header for super-node and super-segment functions.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2011 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#ifndef SUPERX_H
#define SUPERX_H /*+ To stop multiple inclusions. +*/
#include "typesx.h"
/* Functions in superx.c */
void ChooseSuperNodes(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx);
SegmentsX *CreateSuperSegments(NodesX *nodesx,SegmentsX *segmentsx,WaysX *waysx);
SegmentsX *MergeSuperSegments(SegmentsX *segmentsx,SegmentsX *supersegmentsx);
#endif /* SUPERX_H */
routino-2.4.1/src/logging.c 644 233 144 20000 12063562163 10762 0 /***************************************
Functions to handle logging functions.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2012 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#include
#include
#include
#include
#include
#include
#include "logging.h"
/* Global variables */
/*+ The option to print the output in a way that allows logging to a file. +*/
int option_loggable=0;
/*+ The option to print timestamps with the output. +*/
int option_logtime=0;
/* Local functions */
static void vfprintf_first(FILE *file,const char *format,va_list ap);
static void vfprintf_middle(FILE *file,const char *format,va_list ap);
static void vfprintf_last(FILE *file,const char *format,va_list ap);
/* Local variables */
/*+ The time that printf_first was called. +*/
static struct timeval start_time;
/*+ The length of the string printed out last time. +*/
static int printed_length=0;
/*+ The file handle for the error log file. +*/
static FILE *errorlogfile;
/*++++++++++++++++++++++++++++++++++++++
Print the first message in an overwriting sequence (to stdout).
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void printf_first(const char *format, ...)
{
va_list ap;
if(option_logtime)
gettimeofday(&start_time,NULL);
if(option_loggable)
return;
va_start(ap,format);
vfprintf_first(stdout,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Print the middle message in an overwriting sequence (to stdout).
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void printf_middle(const char *format, ...)
{
va_list ap;
if(option_loggable)
return;
va_start(ap,format);
vfprintf_middle(stdout,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Print the last message in an overwriting sequence (to stdout).
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void printf_last(const char *format, ...)
{
va_list ap;
va_start(ap,format);
vfprintf_last(stdout,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Print the first message in an overwriting sequence to a specified file.
FILE *file The file to write to.
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void fprintf_first(FILE *file,const char *format, ...)
{
va_list ap;
if(option_logtime)
gettimeofday(&start_time,NULL);
if(option_loggable)
return;
va_start(ap,format);
vfprintf_first(file,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Print the middle message in an overwriting sequence to a specified file.
FILE *file The file to write to.
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void fprintf_middle(FILE *file,const char *format, ...)
{
va_list ap;
if(option_loggable)
return;
va_start(ap,format);
vfprintf_middle(file,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Print the last message in an overwriting sequence to a specified file.
FILE *file The file to write to.
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void fprintf_last(FILE *file,const char *format, ...)
{
va_list ap;
va_start(ap,format);
vfprintf_last(file,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Do the work to print the first message in an overwriting sequence.
FILE *file The file to write to.
const char *format The format string.
va_list ap The other arguments.
++++++++++++++++++++++++++++++++++++++*/
static void vfprintf_first(FILE *file,const char *format,va_list ap)
{
int retval;
if(option_logtime)
fprintf_elapsed_time(file,&start_time);
retval=vfprintf(file,format,ap);
fflush(file);
if(retval>0)
printed_length=retval;
}
/*++++++++++++++++++++++++++++++++++++++
Do the work to print the middle message in an overwriting sequence.
FILE *file The file to write to.
const char *format The format string.
va_list ap The other arguments.
++++++++++++++++++++++++++++++++++++++*/
static void vfprintf_middle(FILE *file,const char *format,va_list ap)
{
int retval;
fputc('\r',file);
if(option_logtime)
fprintf_elapsed_time(file,&start_time);
retval=vfprintf(file,format,ap);
fflush(file);
if(retval>0)
{
int new_printed_length=retval;
while(retval++0)
while(retval++tv_sec;
elapsed.tv_usec=finish.tv_usec-start->tv_usec;
if(elapsed.tv_usec<0)
{
elapsed.tv_sec -=1;
elapsed.tv_usec+=1000000;
}
fprintf(file,"[%2ld:%02ld.%03ld] ",elapsed.tv_sec/60,elapsed.tv_sec%60,elapsed.tv_usec/10000);
}
/*++++++++++++++++++++++++++++++++++++++
Create the error log file.
const char *filename The name of the file to create.
int append The option to append to an existing file.
++++++++++++++++++++++++++++++++++++++*/
void open_errorlog(const char *filename,int append)
{
errorlogfile=fopen(filename,append?"a":"w");
if(!errorlogfile)
{
fprintf(stderr,"Cannot open file '%s' for writing [%s].\n",filename,strerror(errno));
exit(EXIT_FAILURE);
}
}
/*++++++++++++++++++++++++++++++++++++++
Close the error log file.
++++++++++++++++++++++++++++++++++++++*/
void close_errorlog(void)
{
if(errorlogfile)
fclose(errorlogfile);
}
/*++++++++++++++++++++++++++++++++++++++
Log a message to the error log file.
const char *format The format string.
... The other arguments.
++++++++++++++++++++++++++++++++++++++*/
void logerror(const char *format, ...)
{
va_list ap;
if(!errorlogfile)
return;
va_start(ap,format);
vfprintf(errorlogfile,format,ap);
va_end(ap);
}
/*++++++++++++++++++++++++++++++++++++++
Log a fatal error and exit
const char *message The error message.
const char *file The file in which the error occured.
int line The line number in the file at which the error occured.
++++++++++++++++++++++++++++++++++++++*/
void _logassert(const char *message,const char *file,int line)
{
fprintf(stderr,"Routino Fatal Error (%s:%d): %s\n",file,line,message);
exit(EXIT_FAILURE);
}
routino-2.4.1/src/xmlparse.h 644 233 144 10261 12063560526 11205 0 /***************************************
A simple XML parser
Part of the Routino routing software.
******************/ /******************
This file Copyright 2010-2011 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#ifndef XMLPARSE_H
#define XMLPARSE_H /*+ To stop multiple inclusions. +*/
#include
/*+ The maximum number of attributes per tag. +*/
#define XMLPARSE_MAX_ATTRS 16
/*+ The maximum number of subtags per tag. +*/
#define XMLPARSE_MAX_SUBTAGS 16
/*+ A flag to indicate the start and/or end of a tag. +*/
#define XMLPARSE_TAG_START 1
#define XMLPARSE_TAG_END 2
/*+ A forward definition of the xmltag +*/
typedef struct _xmltag xmltag;
/*+ A structure to hold the definition of a tag. +*/
struct _xmltag
{
char *name; /*+ The name of the tag. +*/
int nattributes; /*+ The number of valid attributes for the tag. +*/
char *attributes[XMLPARSE_MAX_ATTRS]; /*+ The valid attributes for the tag. +*/
int (*callback)(); /*+ The callback function when the tag is seen. +*/
xmltag *subtags[XMLPARSE_MAX_SUBTAGS]; /*+ The list of valid tags contained within this one (null terminated). +*/
};
/* XML Parser options */
#define XMLPARSE_UNKNOWN_ATTRIBUTES 0x0003
#define XMLPARSE_UNKNOWN_ATTR_ERROR 0x0000 /* Flag an error and exit. */
#define XMLPARSE_UNKNOWN_ATTR_ERRNONAME 0x0001 /* Flag an error and exit unless a namespace is specified. */
#define XMLPARSE_UNKNOWN_ATTR_WARN 0x0002 /* Warn about the problem and continue. */
#define XMLPARSE_UNKNOWN_ATTR_IGNORE 0x0003 /* Ignore the potential problem. */
#define XMLPARSE_RETURN_ATTR_ENCODED 0x0004 /* Return the XML attribute strings without decoding them. */
/* XML parser functions */
int ParseXML(FILE *file,xmltag **tags,int options);
unsigned long long ParseXML_LineNumber(void);
char *ParseXML_Decode_Entity_Ref(const char *string);
char *ParseXML_Decode_Char_Ref(const char *string);
char *ParseXML_Encode_Safe_XML(const char *string);
int ParseXML_IsInteger(const char *string);
int ParseXML_IsFloating(const char *string);
/* Macros to simplify the callback functions */
#define XMLPARSE_MESSAGE(tag,message) \
do \
{ \
fprintf(stderr,"XML Parser: Error on line %llu: " message " in <%s> tag.\n",ParseXML_LineNumber(),tag); \
return(1); \
} \
while(0)
#define XMLPARSE_INVALID(tag,attribute) \
do \
{ \
fprintf(stderr,"XML Parser: Error on line %llu: Invalid value for '" #attribute "' attribute in <%s> tag.\n",ParseXML_LineNumber(),tag); \
return(1); \
} \
while(0)
#define XMLPARSE_ASSERT_STRING(tag,attribute) \
do \
{ \
if(!attribute) \
{ \
fprintf(stderr,"XML Parser: Error on line %llu: '" #attribute "' attribute must be specified in <%s> tag.\n",ParseXML_LineNumber(),tag); \
return(1); \
} \
} \
while(0)
#define XMLPARSE_ASSERT_INTEGER(tag,attribute) \
do \
{ \
if(!attribute || !*attribute || !ParseXML_IsInteger(attribute)) \
{ \
fprintf(stderr,"XML Parser: Error on line %llu: '" #attribute "' attribute must be a integer in <%s> tag.\n",ParseXML_LineNumber(),tag); \
return(1); \
} \
} \
while(0)
#define XMLPARSE_ASSERT_FLOATING(tag,attribute) \
do \
{ \
if(!attribute || !*attribute || !ParseXML_IsFloating(attribute)) \
{ \
fprintf(stderr,"XML Parser: Error on line %llu: '" #attribute "' attribute must be a number in <%s> tag.\n",ParseXML_LineNumber(),tag); \
return(1); \
} \
} \
while(0)
#endif /* XMLPARSE_H */
routino-2.4.1/src/visualiser.c 644 233 144 63000 12063560526 11532 0 /***************************************
Extract data from Routino.
Part of the Routino routing software.
******************/ /******************
This file Copyright 2008-2012 Andrew M. Bishop
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see .
***************************************/
#include
#include
#include
#include "types.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
#include "relations.h"
#include "visualiser.h"
/*+ The maximum number of segments per node (used to size temporary storage). +*/
#define MAX_SEG_PER_NODE 32
/* Limit types */
#define SPEED_LIMIT 1
#define WEIGHT_LIMIT 2
#define HEIGHT_LIMIT 3
#define WIDTH_LIMIT 4
#define LENGTH_LIMIT 5
/* Local types */
typedef void (*callback_t)(index_t node,double latitude,double longitude);
/* Local variables */
static Nodes *OSMNodes;
static Segments *OSMSegments;
static Ways *OSMWays;
static Relations *OSMRelations;
static double LatMin;
static double LatMax;
static double LonMin;
static double LonMax;
static int limit_type=0;
static Highway highways=Highway_None;
static Transports transports=Transports_None;
/* Local functions */
static void find_all_nodes(Nodes *nodes,callback_t callback);
static void output_junctions(index_t node,double latitude,double longitude);
static void output_super(index_t node,double latitude,double longitude);
static void output_oneway(index_t node,double latitude,double longitude);
static void output_highway(index_t node,double latitude,double longitude);
static void output_transport(index_t node,double latitude,double longitude);
static void output_barrier(index_t node,double latitude,double longitude);
static void output_turnrestriction(index_t node,double latitude,double longitude);
static void output_limits(index_t node,double latitude,double longitude);
/*++++++++++++++++++++++++++++++++++++++
Output the data for junctions.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
find_all_nodes(nodes,(callback_t)output_junctions);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node as a junction (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_junctions(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp;
Way *firstwayp;
int count=0,difference=0;
segmentp=FirstSegment(OSMSegments,nodep,1);
firstwayp=LookupWay(OSMWays,segmentp->way,1);
do
{
Way *wayp=LookupWay(OSMWays,segmentp->way,2);
if(IsNormalSegment(segmentp))
count++;
if(WaysCompare(firstwayp,wayp))
difference=1;
segmentp=NextSegment(OSMSegments,segmentp,node);
}
while(segmentp);
if(count!=2 || difference)
printf("%.6f %.6f %d\n",radians_to_degrees(latitude),radians_to_degrees(longitude),count);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for super-nodes and super-segments.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
find_all_nodes(nodes,(callback_t)output_super);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node as a super-node (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_super(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp;
if(!IsSuperNode(nodep))
return;
printf("%.6f %.6f n\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
segmentp=FirstSegment(OSMSegments,nodep,1);
do
{
if(IsSuperSegment(segmentp))
{
index_t othernode=OtherNode(segmentp,node);
double lat,lon;
GetLatLong(OSMNodes,othernode,&lat,&lon);
if(node>othernode || (latLatMax || lonLonMax))
printf("%.6f %.6f s\n",radians_to_degrees(lat),radians_to_degrees(lon));
}
segmentp=NextSegment(OSMSegments,segmentp,node);
}
while(segmentp);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for one-way segments.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputOneway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
find_all_nodes(nodes,(callback_t)output_oneway);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node and all connected one-way segments (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_oneway(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp;
segmentp=FirstSegment(OSMSegments,nodep,1);
do
{
if(IsNormalSegment(segmentp))
{
index_t othernode=OtherNode(segmentp,node);
if(node>othernode)
{
double lat,lon;
GetLatLong(OSMNodes,othernode,&lat,&lon);
if(IsOnewayFrom(segmentp,node))
printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
else if(IsOnewayFrom(segmentp,othernode))
printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude));
}
}
segmentp=NextSegment(OSMSegments,segmentp,node);
}
while(segmentp);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for segments of a particular highway type.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
Highway highway The type of highway.
++++++++++++++++++++++++++++++++++++++*/
void OutputHighway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Highway highway)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
highways=highway;
find_all_nodes(nodes,(callback_t)output_highway);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node and all connected one-way segments (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_highway(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp;
segmentp=FirstSegment(OSMSegments,nodep,1);
do
{
if(IsNormalSegment(segmentp))
{
index_t othernode=OtherNode(segmentp,node);
if(node>othernode)
{
Way *wayp=LookupWay(OSMWays,segmentp->way,1);
if(HIGHWAY(wayp->type)==highways)
{
double lat,lon;
GetLatLong(OSMNodes,othernode,&lat,&lon);
printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
}
}
}
segmentp=NextSegment(OSMSegments,segmentp,node);
}
while(segmentp);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for segments allowed for a paticular type of traffic.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
Transport transport The type of transport.
++++++++++++++++++++++++++++++++++++++*/
void OutputTransport(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
transports=TRANSPORTS(transport);
find_all_nodes(nodes,(callback_t)output_transport);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node and all connected one-way segments (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_transport(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp;
segmentp=FirstSegment(OSMSegments,nodep,1);
do
{
if(IsNormalSegment(segmentp))
{
index_t othernode=OtherNode(segmentp,node);
if(node>othernode)
{
Way *wayp=LookupWay(OSMWays,segmentp->way,1);
if(wayp->allow&transports)
{
double lat,lon;
GetLatLong(OSMNodes,othernode,&lat,&lon);
printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
}
}
}
segmentp=NextSegment(OSMSegments,segmentp,node);
}
while(segmentp);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for nodes disallowed for a paticular type of traffic.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
Transport transport The type of transport.
++++++++++++++++++++++++++++++++++++++*/
void OutputBarrier(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
transports=TRANSPORTS(transport);
find_all_nodes(nodes,(callback_t)output_barrier);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_barrier(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
if(!(nodep->allow&transports))
printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for turn restrictions.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputTurnRestrictions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
find_all_nodes(nodes,(callback_t)output_turnrestriction);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node as the 'via' node for a turn restriction (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_turnrestriction(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
index_t turnrelation=NO_RELATION;
if(!IsTurnRestrictedNode(nodep))
return;
turnrelation=FindFirstTurnRelation1(OSMRelations,node);
do
{
TurnRelation *relation;
Segment *from_segmentp,*to_segmentp;
index_t from_node,to_node;
double from_lat,from_lon,to_lat,to_lon;
relation=LookupTurnRelation(OSMRelations,turnrelation,1);
from_segmentp=LookupSegment(OSMSegments,relation->from,1);
to_segmentp =LookupSegment(OSMSegments,relation->to ,2);
from_node=OtherNode(from_segmentp,node);
to_node=OtherNode(to_segmentp,node);
GetLatLong(OSMNodes,from_node,&from_lat,&from_lon);
GetLatLong(OSMNodes,to_node,&to_lat,&to_lon);
printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",radians_to_degrees(from_lat),radians_to_degrees(from_lon),
radians_to_degrees(latitude),radians_to_degrees(longitude),
radians_to_degrees(to_lat),radians_to_degrees(to_lon));
turnrelation=FindNextTurnRelation1(OSMRelations,turnrelation);
}
while(turnrelation!=NO_RELATION);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for speed limits.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
limit_type=SPEED_LIMIT;
find_all_nodes(nodes,(callback_t)output_limits);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for weight limits.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
limit_type=WEIGHT_LIMIT;
find_all_nodes(nodes,(callback_t)output_limits);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for height limits.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
limit_type=HEIGHT_LIMIT;
find_all_nodes(nodes,(callback_t)output_limits);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for width limits.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
limit_type=WIDTH_LIMIT;
find_all_nodes(nodes,(callback_t)output_limits);
}
/*++++++++++++++++++++++++++++++++++++++
Output the data for length limits.
Nodes *nodes The set of nodes to use.
Segments *segments The set of segments to use.
Ways *ways The set of ways to use.
Relations *relations The set of relations to use.
double latmin The minimum latitude.
double latmax The maximum latitude.
double lonmin The minimum longitude.
double lonmax The maximum longitude.
++++++++++++++++++++++++++++++++++++++*/
void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
{
/* Use local variables so that the callback doesn't need to pass them backwards and forwards */
OSMNodes=nodes;
OSMSegments=segments;
OSMWays=ways;
OSMRelations=relations;
LatMin=latmin;
LatMax=latmax;
LonMin=lonmin;
LonMax=lonmax;
/* Iterate through the nodes and process them */
limit_type=LENGTH_LIMIT;
find_all_nodes(nodes,(callback_t)output_limits);
}
/*++++++++++++++++++++++++++++++++++++++
Process a single node as a speed, weight, height, length, width limit (called as a callback).
index_t node The node to output.
double latitude The latitude of the node.
double longitude The longitude of the node.
++++++++++++++++++++++++++++++++++++++*/
static void output_limits(index_t node,double latitude,double longitude)
{
Node *nodep=LookupNode(OSMNodes,node,1);
Segment *segmentp,segmentps[MAX_SEG_PER_NODE];
int limits[MAX_SEG_PER_NODE];
int count=0;
int i,j,same=0;
segmentp=FirstSegment(OSMSegments,nodep,1);
do
{
if(IsNormalSegment(segmentp) && countway,1);
segmentps[count]=*segmentp;
switch(limit_type)
{
case SPEED_LIMIT: limits[count]=wayp->speed; break;
case WEIGHT_LIMIT: limits[count]=wayp->weight; break;
case HEIGHT_LIMIT: limits[count]=wayp->height; break;
case WIDTH_LIMIT: limits[count]=wayp->width; break;
case LENGTH_LIMIT: limits[count]=wayp->length; break;
}
if(limits[count] || HIGHWAY(wayp->type)file.latzero;
ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero;
ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero;
ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero;
ll_bin_t latb,lonb;
index_t i,index1,index2;
/* Loop through all of the nodes. */
for(latb=latminbin;latb<=latmaxbin;latb++)
for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
{
ll_bin2_t llbin=lonb*nodes->file.latbins+latb;
if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins))
continue;
index1=LookupNodeOffset(nodes,llbin);
index2=LookupNodeOffset(nodes,llbin+1);
for(i=index1;ifile.latzero+latb)+off_to_latlong(nodep->latoffset));
double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset));
if(lat>LatMin && latLonMin && lon