X-Git-Url: http://git.maemo.org/git/?p=routino;a=blobdiff_plain;f=src%2Fnodes.h;h=a1722cdfda56d40a18c767bc6e087086d984ef89;hp=8bfc2b611ca743eb9b48c38f97f1d129b679a043;hb=HEAD;hpb=20283c6cf5c6951cc1f2787492c67a7fb72aee9a diff --git a/src/nodes.h b/src/nodes.h index 8bfc2b6..a1722cd 100644 --- a/src/nodes.h +++ b/src/nodes.h @@ -1,11 +1,11 @@ /*************************************** - $Header: /home/amb/routino/src/RCS/nodes.h,v 1.30 2009/11/14 19:39:19 amb Exp $ + $Header: /home/amb/routino/src/RCS/nodes.h,v 1.37 2010/08/03 18:28:30 amb Exp $ A header file for the nodes. Part of the Routino routing software. ******************/ /****************** - This file Copyright 2008,2009 Andrew M. Bishop + This file Copyright 2008-2010 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 @@ -28,6 +28,8 @@ #include #include "types.h" + +#include "files.h" #include "profiles.h" @@ -41,54 +43,195 @@ struct _Node ll_off_t latoffset; /*+ The node latitude offset within its bin. +*/ ll_off_t lonoffset; /*+ The node longitude offset within its bin. +*/ + + allow_t allow; /*+ The types of transport that are allowed through the node. +*/ + uint16_t flags; /*+ Flags containing extra information (super-node, turn restriction). +*/ }; -/*+ A structure containing a set of nodes (mmap format). +*/ -struct _Nodes +/*+ A structure containing the header from the file. +*/ +typedef struct _NodesFile { - uint32_t number; /*+ How many nodes in total? +*/ - uint32_t snumber; /*+ How many super-nodes? +*/ + index_t number; /*+ How many nodes in total? +*/ + index_t snumber; /*+ How many super-nodes? +*/ - uint32_t latbins; /*+ The number of bins containing latitude. +*/ - uint32_t lonbins; /*+ The number of bins containing longitude. +*/ + index_t latbins; /*+ The number of bins containing latitude. +*/ + index_t lonbins; /*+ The number of bins containing longitude. +*/ ll_bin_t latzero; /*+ The bin number of the furthest south bin. +*/ ll_bin_t lonzero; /*+ The bin number of the furthest west bin. +*/ +} + NodesFile; - index_t *offsets; /*+ An array of offset to the first node in each bin. +*/ - Node *nodes; /*+ An array of nodes. +*/ +/*+ A structure containing a set of nodes (and pointers to mmap file). +*/ +struct _Nodes +{ + NodesFile file; /*+ The header data from the file. +*/ - void *data; /*+ The memory mapped data. +*/ -}; +#if !SLIM + void *data; /*+ The memory mapped data. +*/ -/* Macros */ + index_t *offsets; /*+ An array of offsets to the first node in each bin. +*/ -/*+ Return a Node pointer given a set of nodes and an index. +*/ -#define LookupNode(xxx,yyy) (&(xxx)->nodes[yyy]) + Node *nodes; /*+ An array of nodes. +*/ -/*+ Return a Segment points given a Node pointer and a set of segments. +*/ -#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),SEGMENT((yyy)->nodes[zzz].firstseg)) +#else -/*+ Return true if this is a super-node. +*/ -#define IsSuperNode(xxx,yyy) (((xxx)->nodes[yyy].firstseg)&NODE_SUPER) + int fd; /*+ The file descriptor for the file. +*/ + off_t nodesoffset; /*+ The offset of the nodes within the file. +*/ + Node cached[3]; /*+ The cached nodes. +*/ + index_t incache[3]; /*+ The indexes of the cached nodes. +*/ -/* Functions */ +#endif +}; +/* Functions */ + Nodes *LoadNodeList(const char *filename); index_t FindClosestNode(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude, distance_t distance,Profile *profile,distance_t *bestdist); -Segment *FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude, - distance_t distance,Profile *profile, distance_t *bestdist, - index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2); +index_t FindClosestSegment(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude, + distance_t distance,Profile *profile, distance_t *bestdist, + index_t *bestnode1,index_t *bestnode2,distance_t *bestdist1,distance_t *bestdist2); void GetLatLong(Nodes *nodes,index_t index,double *latitude,double *longitude); +/* Macros and inline functions */ + +#if !SLIM + +/*+ Return a Node pointer given a set of nodes and an index. +*/ +#define LookupNode(xxx,yyy,zzz) (&(xxx)->nodes[yyy]) + +/*+ Return a Segment points given a Node pointer and a set of segments. +*/ +#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),(yyy)->nodes[zzz].firstseg,1) + +/*+ Return true if this is a super-node. +*/ +#define IsSuperNode(xxx,yyy) (((xxx)->nodes[yyy].flags)&NODE_SUPER) + +/*+ Return the offset of a geographical region given a set of nodes and an index. +*/ +#define LookupNodeOffset(xxx,yyy) ((xxx)->offsets[yyy]) + +#else + +static Node *LookupNode(Nodes *nodes,index_t index,int position); + +#define FirstSegment(xxx,yyy,zzz) LookupSegment((xxx),FirstSegment_internal(yyy,zzz),1) + +static index_t FirstSegment_internal(Nodes *nodes,index_t index); + +static int IsSuperNode(Nodes *nodes,index_t index); + +static index_t LookupNodeOffset(Nodes *nodes,index_t index); + + +/*++++++++++++++++++++++++++++++++++++++ + Find the Node information for a particular node. + + Node *LookupNode Returns a pointer to the cached node information. + + Nodes *nodes The nodes structure to use. + + index_t index The index of the node. + + int position The position in the cache to store the value. + ++++++++++++++++++++++++++++++++++++++*/ + +static inline Node *LookupNode(Nodes *nodes,index_t index,int position) +{ + SeekFile(nodes->fd,nodes->nodesoffset+(off_t)index*sizeof(Node)); + + ReadFile(nodes->fd,&nodes->cached[position-1],sizeof(Node)); + + nodes->incache[position-1]=index; + + return(&nodes->cached[position-1]); +} + + +/*++++++++++++++++++++++++++++++++++++++ + Find the index of the first segment of a node (called by FirstSegment() macro). + + index_t FirstSegment_internal Returns the index of the first segment. + + Nodes *nodes The nodes structure to use. + + index_t index The index of the node. + ++++++++++++++++++++++++++++++++++++++*/ + +static inline index_t FirstSegment_internal(Nodes *nodes,index_t index) +{ + if(nodes->incache[0]==index) + return(nodes->cached[0].firstseg); + else if(nodes->incache[1]==index) + return(nodes->cached[1].firstseg); + else if(nodes->incache[2]==index) + return(nodes->cached[2].firstseg); + else + { + Node *node=LookupNode(nodes,index,3); + + return(node->firstseg); + } +} + + +/*++++++++++++++++++++++++++++++++++++++ + Decide if a node is a super-node. + + int IsSuperNode Return true if it is a supernode. + + Nodes *nodes The nodes structure to use. + + index_t index The index of the node. + ++++++++++++++++++++++++++++++++++++++*/ + +static inline int IsSuperNode(Nodes *nodes,index_t index) +{ + if(nodes->incache[0]==index) + return(nodes->cached[0].flags&NODE_SUPER); + else if(nodes->incache[1]==index) + return(nodes->cached[1].flags&NODE_SUPER); + else if(nodes->incache[2]==index) + return(nodes->cached[2].flags&NODE_SUPER); + else + { + Node *node=LookupNode(nodes,index,3); + + return(node->flags&NODE_SUPER); + } +} + + +/*++++++++++++++++++++++++++++++++++++++ + Find the offset of nodes in a geographical region. + + index_t LookupNodeOffset Returns the value of the index offset. + + Nodes *nodes The nodes structure to use. + + index_t index The index of the offset. + ++++++++++++++++++++++++++++++++++++++*/ + +static inline index_t LookupNodeOffset(Nodes *nodes,index_t index) +{ + index_t offset; + + SeekFile(nodes->fd,sizeof(NodesFile)+(off_t)index*sizeof(index_t)); + + ReadFile(nodes->fd,&offset,sizeof(index_t)); + + return(offset); +} + +#endif + + #endif /* NODES_H */