/***************************************
- $Header: /home/amb/routino/src/RCS/nodes.c,v 1.39 2010/07/08 17:54:54 amb Exp $
+ $Header: /home/amb/routino/src/RCS/nodes.c,v 1.44 2010/07/26 18:17:20 amb Exp $
Node data type functions.
#include <stdlib.h>
#include <math.h>
-#include "profiles.h"
#include "nodes.h"
#include "segments.h"
#include "ways.h"
-#include "functions.h"
+
+#include "files.h"
+#include "profiles.h"
/*++++++++++++++++++++++++++++++++++++++
Nodes *LoadNodeList(const char *filename)
{
- void *data;
Nodes *nodes;
nodes=(Nodes*)malloc(sizeof(Nodes));
- data=MapFile(filename);
+#if !SLIM
+
+ nodes->data=MapFile(filename);
+
+ /* Copy the NodesFile header structure from the loaded data */
+
+ nodes->file=*((NodesFile*)nodes->data);
+
+ /* Set the pointers in the Nodes structure. */
+
+ nodes->offsets=(index_t*)(nodes->data+sizeof(NodesFile));
+ nodes->nodes =(Node* )(nodes->data+sizeof(NodesFile)+(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t));
+
+#else
+
+ nodes->fd=ReOpenFile(filename);
- /* Copy the Nodes structure from the loaded data */
+ /* Copy the NodesFile header structure from the loaded data */
- *nodes=*((Nodes*)data);
+ ReadFile(nodes->fd,&nodes->file,sizeof(NodesFile));
- /* Adjust the pointers in the Nodes structure. */
+ nodes->nodesoffset=sizeof(NodesFile)+(nodes->file.latbins*nodes->file.lonbins+1)*sizeof(index_t);
- nodes->data=data;
- nodes->offsets=(index_t*)(data+sizeof(Nodes));
- nodes->nodes=(Node*)(data+(sizeof(Nodes)+(nodes->latbins*nodes->lonbins+1)*sizeof(index_t)));
+ nodes->incache[0]=NO_NODE;
+ nodes->incache[1]=NO_NODE;
+ nodes->incache[2]=NO_NODE;
+
+#endif
return(nodes);
}
index_t FindClosestNode(Nodes* nodes,Segments *segments,Ways *ways,double latitude,double longitude,
distance_t distance,Profile *profile,distance_t *bestdist)
{
- ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->latzero;
- ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->lonzero;
+ ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->file.latzero;
+ ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero;
int delta=0,count;
- index_t i,bestn=NO_NODE;
+ index_t i,index1,index2;
+ index_t bestn=NO_NODE;
distance_t bestd=INF_DISTANCE;
/* Start with the bin containing the location, then spiral outwards. */
int latb,lonb,llbin;
count=0;
-
+
for(latb=latbin-delta;latb<=latbin+delta;latb++)
{
- if(latb<0 || latb>=nodes->latbins)
+ if(latb<0 || latb>=nodes->file.latbins)
continue;
for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++)
{
- if(lonb<0 || lonb>=nodes->lonbins)
+ if(lonb<0 || lonb>=nodes->file.lonbins)
continue;
if(abs(latb-latbin)<delta && abs(lonb-lonbin)<delta)
continue;
- llbin=lonb*nodes->latbins+latb;
+ llbin=lonb*nodes->file.latbins+latb;
/* Check if this grid square has any hope of being close enough */
if(delta>0)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb));
- double lat2=latlong_to_radians(bin_to_latlong(nodes->latzero+latb+1));
- double lon2=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb+1));
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb));
+ double lat2=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb+1));
+ double lon2=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb+1));
if(latb==latbin)
{
/* Check every node in this grid square. */
- for(i=nodes->offsets[llbin];i<nodes->offsets[llbin+1];i++)
+ index1=LookupNodeOffset(nodes,llbin);
+ index2=LookupNodeOffset(nodes,llbin+1);
+
+ for(i=index1;i<index2;i++)
{
- double lat=latlong_to_radians(bin_to_latlong(nodes->latzero+latb)+off_to_latlong(nodes->nodes[i].latoffset));
- double lon=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb)+off_to_latlong(nodes->nodes[i].lonoffset));
+ Node *node=LookupNode(nodes,i,1);
+ double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
distance_t dist=Distance(lat,lon,latitude,longitude);
do
{
- Way *way=LookupWay(ways,segment->way);
+ Way *way=LookupWay(ways,segment->way,1);
if(way->allow&profile->allow)
break;
/*++++++++++++++++++++++++++++++++++++++
Find the closest segment to a latitude, longitude and optionally profile.
- Segment *FindClosestSegment Returns the closest segment.
+ index_t FindClosestSegment Returns the closest segment index.
Nodes* nodes The set of nodes to search.
distance_t *bestdist2 Returns the distance to the best node at the other end.
++++++++++++++++++++++++++++++++++++++*/
-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)
{
- ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->latzero;
- ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->lonzero;
+ ll_bin_t latbin=latlong_to_bin(radians_to_latlong(latitude ))-nodes->file.latzero;
+ ll_bin_t lonbin=latlong_to_bin(radians_to_latlong(longitude))-nodes->file.lonzero;
int delta=0,count;
- index_t i,bestn1=NO_NODE,bestn2=NO_NODE;
+ index_t i,index1,index2;
+ index_t bestn1=NO_NODE,bestn2=NO_NODE;
distance_t bestd=INF_DISTANCE,bestd1=INF_DISTANCE,bestd2=INF_DISTANCE;
- Segment *bests=NULL;
+ index_t bests=NO_SEGMENT;
/* Start with the bin containing the location, then spiral outwards. */
int latb,lonb,llbin;
count=0;
-
+
for(latb=latbin-delta;latb<=latbin+delta;latb++)
{
- if(latb<0 || latb>=nodes->latbins)
+ if(latb<0 || latb>=nodes->file.latbins)
continue;
for(lonb=lonbin-delta;lonb<=lonbin+delta;lonb++)
{
- if(lonb<0 || lonb>=nodes->lonbins)
+ if(lonb<0 || lonb>=nodes->file.lonbins)
continue;
if(abs(latb-latbin)<delta && abs(lonb-lonbin)<delta)
continue;
- llbin=lonb*nodes->latbins+latb;
+ llbin=lonb*nodes->file.latbins+latb;
/* Check if this grid square has any hope of being close enough */
if(delta>0)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb));
- double lat2=latlong_to_radians(bin_to_latlong(nodes->latzero+latb+1));
- double lon2=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb+1));
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb));
+ double lat2=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb+1));
+ double lon2=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb+1));
if(latb==latbin)
{
/* Check every node in this grid square. */
- for(i=nodes->offsets[llbin];i<nodes->offsets[llbin+1];i++)
+ index1=LookupNodeOffset(nodes,llbin);
+ index2=LookupNodeOffset(nodes,llbin+1);
+
+ for(i=index1;i<index2;i++)
{
- double lat1=latlong_to_radians(bin_to_latlong(nodes->latzero+latb)+off_to_latlong(nodes->nodes[i].latoffset));
- double lon1=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonb)+off_to_latlong(nodes->nodes[i].lonoffset));
+ Node *node=LookupNode(nodes,i,1);
+ double lat1=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
+ double lon1=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
distance_t dist1;
dist1=Distance(lat1,lon1,latitude,longitude);
Way *way=NULL;
if(profile)
- way=LookupWay(ways,segment->way);
+ way=LookupWay(ways,segment->way,1);
if(!profile || way->allow&profile->allow)
{
if(distp<(double)bestd)
{
- bests=segment;
+ bests=IndexSegment(segments,segment);
bestn1=i;
bestn2=OtherNode(segment,i);
bestd1=(distance_t)dist3a;
void GetLatLong(Nodes *nodes,index_t index,double *latitude,double *longitude)
{
- Node *node=&nodes->nodes[index];
+ Node *node=LookupNode(nodes,index,2);
int latbin=-1,lonbin=-1;
int start,end,mid;
+ index_t offset;
/* Binary search - search key closest below is required.
*
/* Search for longitude */
start=0;
- end=nodes->lonbins-1;
+ end=nodes->file.lonbins-1;
do
{
- mid=(start+end)/2; /* Choose mid point */
+ mid=(start+end)/2; /* Choose mid point */
- if(nodes->offsets[nodes->latbins*mid]<index) /* Mid point is too low */
+ offset=LookupNodeOffset(nodes,nodes->file.latbins*mid);
+
+ if(offset<index) /* Mid point is too low */
start=mid;
- else if(nodes->offsets[nodes->latbins*mid]>index) /* Mid point is too high */
+ else if(offset>index) /* Mid point is too high */
end=mid-1;
- else /* Mid point is correct */
+ else /* Mid point is correct */
{lonbin=mid;break;}
}
while((end-start)>1);
if(lonbin==-1)
{
- if(nodes->offsets[nodes->latbins*end]>index)
+ offset=LookupNodeOffset(nodes,nodes->file.latbins*end);
+
+ if(offset>index)
lonbin=start;
else
lonbin=end;
}
- while(lonbin<nodes->lonbins && nodes->offsets[lonbin*nodes->latbins]==nodes->offsets[(lonbin+1)*nodes->latbins])
+ while(lonbin<nodes->file.lonbins &&
+ LookupNodeOffset(nodes,lonbin*nodes->file.latbins)==LookupNodeOffset(nodes,(lonbin+1)*nodes->file.latbins))
lonbin++;
/* Search for latitude */
start=0;
- end=nodes->latbins-1;
+ end=nodes->file.latbins-1;
do
{
- mid=(start+end)/2; /* Choose mid point */
+ mid=(start+end)/2; /* Choose mid point */
- if(nodes->offsets[lonbin*nodes->latbins+mid]<index) /* Mid point is too low */
+ offset=LookupNodeOffset(nodes,lonbin*nodes->file.latbins+mid);
+
+ if(offset<index) /* Mid point is too low */
start=mid;
- else if(nodes->offsets[lonbin*nodes->latbins+mid]>index) /* Mid point is too high */
+ else if(offset>index) /* Mid point is too high */
end=mid-1;
- else /* Mid point is correct */
+ else /* Mid point is correct */
{latbin=mid;break;}
}
while((end-start)>1);
if(latbin==-1)
{
- if(nodes->offsets[lonbin*nodes->latbins+end]>index)
+ offset=LookupNodeOffset(nodes,lonbin*nodes->file.latbins+end);
+
+ if(offset>index)
latbin=start;
else
latbin=end;
}
- while(latbin<nodes->latbins && nodes->offsets[lonbin*nodes->latbins+latbin]==nodes->offsets[lonbin*nodes->latbins+latbin+1])
+ while(latbin<nodes->file.latbins &&
+ LookupNodeOffset(nodes,lonbin*nodes->file.latbins+latbin)==LookupNodeOffset(nodes,lonbin*nodes->file.latbins+latbin+1))
latbin++;
/* Return the values */
- *latitude =latlong_to_radians(bin_to_latlong(nodes->latzero+latbin)+off_to_latlong(node->latoffset));
- *longitude=latlong_to_radians(bin_to_latlong(nodes->lonzero+lonbin)+off_to_latlong(node->lonoffset));
+ *latitude =latlong_to_radians(bin_to_latlong(nodes->file.latzero+latbin)+off_to_latlong(node->latoffset));
+ *longitude=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonbin)+off_to_latlong(node->lonoffset));
}