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 65 - (show annotations) (download) (as text)
Thu Jan 22 18:57:16 2009 UTC (16 years, 1 month ago) by amb
File MIME type: text/x-csrc
File size: 6790 byte(s)
Remove the choice of indexed or non-indexed data structures.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/nodes.c,v 1.9 2009-01-22 18:57:16 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 /* Functions */
23
24 static int sort_by_id(Node *a,Node *b);
25
26
27 /*++++++++++++++++++++++++++++++++++++++
28 Allocate a new node list.
29
30 NodesMem *NewNodeList Returns the node list.
31 ++++++++++++++++++++++++++++++++++++++*/
32
33 NodesMem *NewNodeList(void)
34 {
35 NodesMem *nodes;
36
37 nodes=(NodesMem*)malloc(sizeof(NodesMem));
38
39 nodes->alloced=INCREMENT_NODES;
40 nodes->number=0;
41 nodes->sorted=0;
42
43 nodes->nodes=(Nodes*)malloc(sizeof(Nodes)+nodes->alloced*sizeof(Node));
44
45 return(nodes);
46 }
47
48
49 /*++++++++++++++++++++++++++++++++++++++
50 Load in a node list from a file.
51
52 Nodes* LoadNodeList Returns the node list.
53
54 const char *filename The name of the file to load.
55 ++++++++++++++++++++++++++++++++++++++*/
56
57 Nodes *LoadNodeList(const char *filename)
58 {
59 return((Nodes*)MapFile(filename));
60 }
61
62
63 /*++++++++++++++++++++++++++++++++++++++
64 Save the node list to a file.
65
66 Nodes* SaveNodeList Returns the node list that has just been saved.
67
68 NodesMem* nodes The set of nodes to save.
69
70 const char *filename The name of the file to save.
71 ++++++++++++++++++++++++++++++++++++++*/
72
73 Nodes *SaveNodeList(NodesMem* nodes,const char *filename)
74 {
75 assert(nodes->sorted); /* Must be sorted */
76
77 if(WriteFile(filename,(void*)nodes->nodes,sizeof(Nodes)-sizeof(nodes->nodes->nodes)+nodes->number*sizeof(Node)))
78 assert(0);
79
80 free(nodes->nodes);
81 free(nodes);
82
83 return(LoadNodeList(filename));
84 }
85
86
87 /*++++++++++++++++++++++++++++++++++++++
88 Find a particular node.
89
90 Node *FindNode Returns a pointer to the node with the specified id.
91
92 Nodes* nodes The set of nodes to process.
93
94 node_t id The node id to look for.
95 ++++++++++++++++++++++++++++++++++++++*/
96
97 Node *FindNode(Nodes* nodes,node_t id)
98 {
99 int bin=id%NBINS_NODES;
100 int start=nodes->offset[bin];
101 int end=nodes->offset[bin+1]-1; /* &offset[NBINS+1] == &number */
102 int mid;
103
104 /* Binary search - search key exact match only is required.
105 *
106 * # <- start | Check mid and move start or end if it doesn't match
107 * # |
108 * # | Since an exact match is wanted we can set end=mid-1
109 * # <- mid | or start=mid+1 because we know that mid doesn't match.
110 * # |
111 * # | Eventually either end=start or end=start+1 and one of
112 * # <- end | start or end is the wanted one.
113 */
114
115 if(end<start) /* There are no nodes */
116 return(NULL);
117 else if(id<nodes->nodes[start].id) /* Check key is not before start */
118 return(NULL);
119 else if(id>nodes->nodes[end].id) /* Check key is not after end */
120 return(NULL);
121 else
122 {
123 do
124 {
125 mid=(start+end)/2; /* Choose mid point */
126
127 if(nodes->nodes[mid].id<id) /* Mid point is too low */
128 start=mid+1;
129 else if(nodes->nodes[mid].id>id) /* Mid point is too high */
130 end=mid-1;
131 else /* Mid point is correct */
132 return(&nodes->nodes[mid]);
133 }
134 while((end-start)>1);
135
136 if(nodes->nodes[start].id==id) /* Start is correct */
137 return(&nodes->nodes[start]);
138
139 if(nodes->nodes[end].id==id) /* End is correct */
140 return(&nodes->nodes[end]);
141 }
142
143 return(NULL);
144 }
145
146
147 /*++++++++++++++++++++++++++++++++++++++
148 Append a node to a newly created node list (unsorted).
149
150 Node *AppendNode Return a pointer to the new node.
151
152 NodesMem* nodes The set of nodes to process.
153
154 node_t id The node identification.
155
156 latlong_t latitude The latitude of the node.
157
158 latlong_t longitude The longitude of the node.
159 ++++++++++++++++++++++++++++++++++++++*/
160
161 Node *AppendNode(NodesMem* nodes,node_t id,latlong_t latitude,latlong_t longitude)
162 {
163 /* Check that the array has enough space. */
164
165 if(nodes->number==nodes->alloced)
166 {
167 nodes->alloced+=INCREMENT_NODES;
168
169 nodes->nodes=(Nodes*)realloc((void*)nodes->nodes,sizeof(Nodes)+nodes->alloced*sizeof(Node));
170 }
171
172 /* Insert the node */
173
174 nodes->nodes->nodes[nodes->number].id=id;
175 nodes->nodes->nodes[nodes->number].latitude=latitude;
176 nodes->nodes->nodes[nodes->number].longitude=longitude;
177
178 nodes->number++;
179
180 nodes->sorted=0;
181
182 return(&nodes->nodes->nodes[nodes->number-1]);
183 }
184
185
186 /*++++++++++++++++++++++++++++++++++++++
187 Sort the node list.
188
189 NodesMem* nodes The set of nodes to process.
190 ++++++++++++++++++++++++++++++++++++++*/
191
192 void SortNodeList(NodesMem* nodes)
193 {
194 int i,bin=0;
195
196 qsort(nodes->nodes->nodes,nodes->number,sizeof(Node),(int (*)(const void*,const void*))sort_by_id);
197
198 while(nodes->nodes->nodes[nodes->number-1].id==~0)
199 nodes->number--;
200
201 nodes->sorted=1;
202
203 /* Make it searchable */
204
205 nodes->nodes->number=nodes->number;
206
207 for(i=0;i<nodes->number;i++)
208 for(;bin<=(nodes->nodes->nodes[i].id%NBINS_NODES);bin++)
209 nodes->nodes->offset[bin]=i;
210
211 for(;bin<NBINS_NODES;bin++)
212 nodes->nodes->offset[bin]=nodes->number;
213 }
214
215
216 /*++++++++++++++++++++++++++++++++++++++
217 Sort the nodes into id order.
218
219 int sort_by_id Returns the comparison of the id fields.
220
221 Node *a The first Node.
222
223 Node *b The second Node.
224 ++++++++++++++++++++++++++++++++++++++*/
225
226 static int sort_by_id(Node *a,Node *b)
227 {
228 node_t a_id=a->id;
229 node_t b_id=b->id;
230
231 int a_bin=a->id%NBINS_NODES;
232 int b_bin=b->id%NBINS_NODES;
233
234 if(a_bin!=b_bin)
235 return(a_bin-b_bin);
236
237 if(a_id<b_id)
238 return(-1);
239 else if(a_id>b_id)
240 return(1);
241 else /* if(a_id==b_id) */
242 return(0);
243 }
244
245
246 /*++++++++++++++++++++++++++++++++++++++
247 Remove any nodes that are not part of a way.
248
249 NodesMem *nodesmem The node list to create.
250
251 Nodes *nodes The complete node list.
252
253 Segments *segments The list of segments.
254 ++++++++++++++++++++++++++++++++++++++*/
255
256 void RemoveNonWayNodes(NodesMem *nodesmem,Nodes *nodes,Segments *segments)
257 {
258 int i;
259 int inway=0,notinway=0;
260
261 for(i=0;i<nodes->number;i++)
262 {
263 Node *node=LookupNode(nodes,i);
264
265 if(FindFirstSegment(segments,node->id))
266 {
267 inway++;
268 AppendNode(nodesmem,node->id,node->latitude,node->longitude);
269 }
270 else
271 notinway++;
272
273 if(!((i+1)%10000))
274 {
275 printf("\rChecking: Nodes=%d in-Way=%d not-in-Way=%d",i+1,inway,notinway);
276 fflush(stdout);
277 }
278 }
279
280 printf("\rChecked: Nodes=%d in-Way=%d not-in-Way=%d \n",i,inway,notinway);
281 fflush(stdout);
282 }

Properties

Name Value
cvs:description Node data type.