Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Annotation of /trunk/src/nodes.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 121 - (hide annotations) (download) (as text)
Sun Feb 15 14:30:11 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 5058 byte(s)
Store radians rather than degrees.

1 amb 2 /***************************************
2 amb 121 $Header: /home/amb/CVS/routino/src/nodes.c,v 1.24 2009-02-15 14:30:10 amb Exp $
3 amb 2
4     Node data type functions.
5     ******************/ /******************
6     Written by Andrew M. Bishop
7    
8 amb 4 This file Copyright 2008,2009 Andrew M. Bishop
9 amb 2 It may be distributed under the GNU Public License, version 2, or
10     any higher version. See section COPYING of the GNU Public license
11     for conditions under which this file may be redistributed.
12     ***************************************/
13    
14    
15     #include <stdlib.h>
16 amb 118 #include <math.h>
17 amb 2
18 amb 109 #include "nodes.h"
19 amb 114 #include "segments.h"
20 amb 2 #include "functions.h"
21    
22    
23 amb 17 /*++++++++++++++++++++++++++++++++++++++
24 amb 2 Load in a node list from a file.
25    
26 amb 19 Nodes* LoadNodeList Returns the node list.
27 amb 17
28 amb 2 const char *filename The name of the file to load.
29     ++++++++++++++++++++++++++++++++++++++*/
30    
31 amb 19 Nodes *LoadNodeList(const char *filename)
32 amb 2 {
33 amb 88 void *data;
34     Nodes *nodes;
35    
36     nodes=(Nodes*)malloc(sizeof(Nodes));
37    
38     data=MapFile(filename);
39    
40 amb 100 if(!data)
41     return(NULL);
42    
43 amb 88 /* Copy the Nodes structure from the loaded data */
44    
45     *nodes=*((Nodes*)data);
46    
47     /* Adjust the pointers in the Nodes structure. */
48    
49 amb 99 nodes->data=data;
50     nodes->offsets=(index_t*)(data+(off_t)nodes->offsets);
51 amb 88 nodes->nodes=(Node*)(data+(off_t)nodes->nodes);
52    
53     return(nodes);
54 amb 2 }
55    
56    
57     /*++++++++++++++++++++++++++++++++++++++
58 amb 99 Find a node given its latitude and longitude.
59    
60     Node *FindNode Returns the node.
61    
62     Nodes* nodes The set of nodes to search.
63    
64     float latitude The latitude to look for.
65    
66     float longitude The longitude to look for.
67     ++++++++++++++++++++++++++++++++++++++*/
68    
69     Node *FindNode(Nodes* nodes,float latitude,float longitude)
70     {
71 amb 118 int32_t latbin=lat_long_to_bin(latitude )-nodes->latzero;
72     int32_t lonbin=lat_long_to_bin(longitude)-nodes->lonzero;
73 amb 99 int llbin=lonbin*nodes->latbins+latbin;
74 amb 108 int i,best=~0;
75 amb 114 distance_t distance=km_to_distance(10);
76 amb 99
77 amb 118 // FIXME - closest could be outside of this square
78    
79 amb 121 if(llbin<0 || llbin>nodes->number)
80     return(NULL);
81    
82 amb 99 for(i=nodes->offsets[llbin];i<nodes->offsets[llbin+1];i++)
83     {
84 amb 118 float lat=(float)((nodes->latzero+latbin)*LAT_LONG_BIN+nodes->nodes[i].latoffset)/LAT_LONG_SCALE;
85     float lon=(float)((nodes->lonzero+lonbin)*LAT_LONG_BIN+nodes->nodes[i].lonoffset)/LAT_LONG_SCALE;
86 amb 99
87     float dist=Distance(lat,lon,latitude,longitude);
88    
89     if(dist<distance)
90     {best=i; distance=dist;}
91     }
92    
93 amb 108 if(best==~0)
94     return(NULL);
95     else
96     return(&nodes->nodes[best]);
97 amb 99 }
98    
99    
100     /*++++++++++++++++++++++++++++++++++++++
101     Get the latitude and longitude associated with a node.
102    
103     Nodes *nodes The set of nodes.
104    
105     Node *node The node.
106    
107     float *latitude Returns the latitude.
108    
109     float *longitude Returns the logitude.
110     ++++++++++++++++++++++++++++++++++++++*/
111    
112     void GetLatLong(Nodes *nodes,Node *node,float *latitude,float *longitude)
113     {
114     index_t index=IndexNode(nodes,node);
115     int latbin=-1,lonbin=-1;
116     int start,end,mid;
117    
118     /* Binary search - search key closest below is required.
119     *
120     * # <- start | Check mid and move start or end if it doesn't match
121     * # |
122     * # | Since an inexact match is wanted we must set end=mid-1
123     * # <- mid | or start=mid because we know that mid doesn't match.
124     * # |
125     * # | Eventually either end=start or end=start+1 and one of
126     * # <- end | start or end is the wanted one.
127     */
128    
129     /* Search for longitude */
130    
131     start=0;
132     end=nodes->lonbins-1;
133    
134     do
135     {
136     mid=(start+end)/2; /* Choose mid point */
137    
138     if(nodes->offsets[nodes->latbins*mid]<index) /* Mid point is too low */
139     start=mid;
140     else if(nodes->offsets[nodes->latbins*mid]>index) /* Mid point is too high */
141     end=mid-1;
142     else /* Mid point is correct */
143     {lonbin=mid;break;}
144     }
145     while((end-start)>1);
146    
147     if(lonbin==-1)
148     {
149     if(nodes->offsets[nodes->latbins*end]>index)
150     lonbin=start;
151     else
152     lonbin=end;
153     }
154    
155     while(lonbin<nodes->lonbins && nodes->offsets[lonbin*nodes->latbins]==nodes->offsets[(lonbin+1)*nodes->latbins])
156     lonbin++;
157    
158     /* Search for latitude */
159    
160     start=0;
161     end=nodes->latbins-1;
162    
163     do
164     {
165     mid=(start+end)/2; /* Choose mid point */
166    
167     if(nodes->offsets[lonbin*nodes->latbins+mid]<index) /* Mid point is too low */
168     start=mid;
169     else if(nodes->offsets[lonbin*nodes->latbins+mid]>index) /* Mid point is too high */
170     end=mid-1;
171     else /* Mid point is correct */
172     {latbin=mid;break;}
173     }
174     while((end-start)>1);
175    
176     if(latbin==-1)
177     {
178     if(nodes->offsets[lonbin*nodes->latbins+end]>index)
179     latbin=start;
180     else
181     latbin=end;
182     }
183    
184     while(latbin<nodes->latbins && nodes->offsets[lonbin*nodes->latbins+latbin]==nodes->offsets[lonbin*nodes->latbins+latbin+1])
185     latbin++;
186    
187     /* Return the values */
188    
189 amb 118 *latitude =(float)((nodes->latzero+latbin)*LAT_LONG_BIN+node->latoffset)/LAT_LONG_SCALE;
190     *longitude=(float)((nodes->lonzero+lonbin)*LAT_LONG_BIN+node->lonoffset)/LAT_LONG_SCALE;
191 amb 99 }

Properties

Name Value
cvs:description Node data type.