Routino SVN Repository Browser

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

ViewVC logotype

Contents of /trunk/src/nodes.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 98 - (show annotations) (download) (as text)
Mon Feb 2 18:53:13 2009 UTC (16 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 8081 byte(s)
More variable and function name changes.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/nodes.c,v 1.16 2009-02-02 18:53:12 amb Exp $
3
4 Node data type functions.
5 ******************/ /******************
6 Written by Andrew M. Bishop
7
8 This file Copyright 2008,2009 Andrew M. Bishop
9 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 <assert.h>
16 #include <stdlib.h>
17
18 #include "functions.h"
19 #include "nodes.h"
20
21
22 /* Constants */
23
24 /*+ The array size increment for nodes - expect ~8,000,000 nodes. +*/
25 #define INCREMENT_NODES 1024*1024
26
27
28 /* Functions */
29
30 static int sort_by_id(NodeX *a,NodeX *b);
31
32
33 /*++++++++++++++++++++++++++++++++++++++
34 Load in a node list from a file.
35
36 Nodes* LoadNodeList Returns the node list.
37
38 const char *filename The name of the file to load.
39 ++++++++++++++++++++++++++++++++++++++*/
40
41 Nodes *LoadNodeList(const char *filename)
42 {
43 void *data;
44 Nodes *nodes;
45
46 nodes=(Nodes*)malloc(sizeof(Nodes));
47
48 data=MapFile(filename);
49
50 /* Copy the Nodes structure from the loaded data */
51
52 *nodes=*((Nodes*)data);
53
54 /* Adjust the pointers in the Nodes structure. */
55
56 nodes->data =data;
57 nodes->nodes=(Node*)(data+(off_t)nodes->nodes);
58
59 return(nodes);
60 }
61
62
63 /*++++++++++++++++++++++++++++++++++++++
64 Allocate a new node list.
65
66 NodesX *NewNodeList Returns the node list.
67 ++++++++++++++++++++++++++++++++++++++*/
68
69 NodesX *NewNodeList(void)
70 {
71 NodesX *nodesx;
72
73 nodesx=(NodesX*)malloc(sizeof(NodesX));
74
75 nodesx->alloced=INCREMENT_NODES;
76 nodesx->number=0;
77 nodesx->sorted=0;
78
79 nodesx->xdata=(NodeX*)malloc(nodesx->alloced*sizeof(NodeX));
80
81 return(nodesx);
82 }
83
84
85 /*++++++++++++++++++++++++++++++++++++++
86 Save the node list to a file.
87
88 NodesX* nodesx The set of nodes to save.
89
90 const char *filename The name of the file to save.
91 ++++++++++++++++++++++++++++++++++++++*/
92
93 void SaveNodeList(NodesX* nodesx,const char *filename)
94 {
95 int i;
96 int fd;
97 Nodes *nodes=calloc(1,sizeof(Nodes));
98
99 assert(nodesx->sorted); /* Must be sorted */
100
101 /* Fill in a Nodes structure with the offset of the real data in the file after
102 the Node structure itself. */
103
104 nodes->number=nodesx->number;
105 nodes->data=NULL;
106 nodes->nodes=(void*)sizeof(Nodes);
107
108 /* Write out the Nodes structure and then the real data. */
109
110 fd=OpenFile(filename);
111
112 WriteFile(fd,nodes,sizeof(Nodes));
113
114 for(i=0;i<nodesx->number;i++)
115 {
116 if(nodesx->xdata[i].id==10319449)
117 printf("\n10319449 -> %d\n",i);
118
119 if(nodesx->xdata[i].id==30810456)
120 printf("\n30810456 -> %d\n",i);
121
122 if(nodesx->xdata[i].id==21734658)
123 printf("\n21734658 -> %d\n",i);
124
125 if(nodesx->xdata[i].id==206231001)
126 printf("\n206231001 -> %d\n",i);
127
128 WriteFile(fd,&nodesx->xdata[i].node,sizeof(Node));
129 }
130
131 CloseFile(fd);
132
133 /* Free the fake Nodes */
134
135 free(nodes);
136 }
137
138
139 /*++++++++++++++++++++++++++++++++++++++
140 Find a particular node.
141
142 NodeX *FindNodeX Returns the extended node with the specified id.
143
144 NodesX* nodesx The set of nodes to process.
145
146 node_t id The node id to look for.
147 ++++++++++++++++++++++++++++++++++++++*/
148
149 NodeX *FindNodeX(NodesX* nodesx,node_t id)
150 {
151 int start=0;
152 int end=nodesx->number-1;
153 int mid;
154
155 /* Binary search - search key exact match only is required.
156 *
157 * # <- start | Check mid and move start or end if it doesn't match
158 * # |
159 * # | Since an exact match is wanted we can set end=mid-1
160 * # <- mid | or start=mid+1 because we know that mid doesn't match.
161 * # |
162 * # | Eventually either end=start or end=start+1 and one of
163 * # <- end | start or end is the wanted one.
164 */
165
166 if(end<start) /* There are no nodes */
167 return(NULL);
168 else if(id<nodesx->xdata[start].id) /* Check key is not before start */
169 return(NULL);
170 else if(id>nodesx->xdata[end].id) /* Check key is not after end */
171 return(NULL);
172 else
173 {
174 do
175 {
176 mid=(start+end)/2; /* Choose mid point */
177
178 if(nodesx->xdata[mid].id<id) /* Mid point is too low */
179 start=mid+1;
180 else if(nodesx->xdata[mid].id>id) /* Mid point is too high */
181 end=mid-1;
182 else /* Mid point is correct */
183 return(LookupNodeX(nodesx,mid));
184 }
185 while((end-start)>1);
186
187 if(nodesx->xdata[start].id==id) /* Start is correct */
188 return(LookupNodeX(nodesx,start));
189
190 if(nodesx->xdata[end].id==id) /* End is correct */
191 return(LookupNodeX(nodesx,end));
192 }
193
194 return(NULL);
195 }
196
197
198 /*++++++++++++++++++++++++++++++++++++++
199 Append a node to a newly created node list (unsorted).
200
201 Node *AppendNode Return a pointer to the new node.
202
203 NodesX* nodesx The set of nodes to process.
204
205 node_t id The node identification.
206
207 float latitude The latitude of the node.
208
209 float longitude The longitude of the node.
210 ++++++++++++++++++++++++++++++++++++++*/
211
212 Node *AppendNode(NodesX* nodesx,node_t id,float latitude,float longitude)
213 {
214 /* Check that the array has enough space. */
215
216 if(nodesx->number==nodesx->alloced)
217 {
218 nodesx->alloced+=INCREMENT_NODES;
219
220 nodesx->xdata=(NodeX*)realloc((void*)nodesx->xdata,nodesx->alloced*sizeof(NodeX));
221 }
222
223 /* Insert the node */
224
225 nodesx->xdata[nodesx->number].id=id;
226 nodesx->xdata[nodesx->number].super=0;
227 nodesx->xdata[nodesx->number].node.latitude=latitude;
228 nodesx->xdata[nodesx->number].node.longitude=longitude;
229
230 nodesx->number++;
231
232 nodesx->sorted=0;
233
234 return(&nodesx->xdata[nodesx->number-1].node);
235 }
236
237
238 /*++++++++++++++++++++++++++++++++++++++
239 Sort the node list.
240
241 NodesX* nodesx The set of nodes to process.
242 ++++++++++++++++++++++++++++++++++++++*/
243
244 void SortNodeList(NodesX* nodesx)
245 {
246 qsort(nodesx->xdata,nodesx->number,sizeof(NodeX),(int (*)(const void*,const void*))sort_by_id);
247
248 while(nodesx->xdata[nodesx->number-1].id==~0)
249 nodesx->number--;
250
251 nodesx->sorted=1;
252 }
253
254
255 /*++++++++++++++++++++++++++++++++++++++
256 Sort the nodes into id order.
257
258 int sort_by_id Returns the comparison of the id fields.
259
260 NodeX *a The first Node.
261
262 NodeX *b The second Node.
263 ++++++++++++++++++++++++++++++++++++++*/
264
265 static int sort_by_id(NodeX *a,NodeX *b)
266 {
267 node_t a_id=a->id;
268 node_t b_id=b->id;
269
270 if(a_id<b_id)
271 return(-1);
272 else
273 return(1);
274 }
275
276
277 /*++++++++++++++++++++++++++++++++++++++
278 Remove any nodes that are not part of a highway.
279
280 NodesX *nodesx The complete node list.
281
282 SegmentsX *segmentsx The list of segments.
283 ++++++++++++++++++++++++++++++++++++++*/
284
285 void RemoveNonHighwayNodes(NodesX *nodesx,SegmentsX *segmentsx)
286 {
287 int i;
288 int highway=0,nothighway=0;
289
290 for(i=0;i<nodesx->number;i++)
291 {
292 if(FindFirstSegmentX(segmentsx,nodesx->xdata[i].id))
293 highway++;
294 else
295 {
296 nodesx->xdata[i].id=~0;
297 nothighway++;
298 }
299
300 if(!((i+1)%10000))
301 {
302 printf("\rChecking: Nodes=%d Highway=%d not-Highway=%d",i+1,highway,nothighway);
303 fflush(stdout);
304 }
305 }
306
307 printf("\rChecked: Nodes=%d Highway=%d not-Highway=%d \n",nodesx->number,highway,nothighway);
308 fflush(stdout);
309 }
310
311
312 /*++++++++++++++++++++++++++++++++++++++
313 Fix the node indexes to the segments.
314
315 NodesX* nodesx The set of nodes to process.
316
317 SegmentsX *segmentsx The list of segments to use.
318
319 int iteration The current super-node / super-segment iteration number.
320 ++++++++++++++++++++++++++++++++++++++*/
321
322 void FixupNodes(NodesX *nodesx,SegmentsX* segmentsx,int iteration)
323 {
324 int i;
325
326 assert(nodesx->sorted); /* Must be sorted */
327
328 for(i=0;i<nodesx->number;i++)
329 {
330 SegmentX *firstseg=FindFirstSegmentX(segmentsx,nodesx->xdata[i].id);
331
332 nodesx->xdata[i].node.firstseg=IndexSegmentX(segmentsx,firstseg);
333
334 if(nodesx->xdata[i].super==iteration)
335 nodesx->xdata[i].node.firstseg|=SUPER_FLAG;
336
337 if(!((i+1)%10000))
338 {
339 printf("\rFixing Nodes: Nodes=%d",i+1);
340 fflush(stdout);
341 }
342 }
343
344 printf("\rFixed Nodes: Nodes=%d \n",nodesx->number);
345 fflush(stdout);
346 }

Properties

Name Value
cvs:description Node data type.