Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Annotation of /trunk/src/relationsx.c
Parent Directory
|
Revision Log
Revision 507 -
(hide annotations)
(download)
(as text)
Sun Oct 3 15:01:04 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 8361 byte(s)
Sun Oct 3 15:01:04 2010 UTC (14 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 8361 byte(s)
Add a function to map a file writeable and use it for updating the ways when processing route relations.
1 | amb | 496 | /*************************************** |
2 | amb | 507 | $Header: /home/amb/CVS/routino/src/relationsx.c,v 1.5 2010-10-03 15:01:04 amb Exp $ |
3 | amb | 496 | |
4 | Extended Relation data type functions. | ||
5 | |||
6 | Part of the Routino routing software. | ||
7 | ******************/ /****************** | ||
8 | This file Copyright 2010 Andrew M. Bishop | ||
9 | |||
10 | This program is free software: you can redistribute it and/or modify | ||
11 | it under the terms of the GNU Affero General Public License as published by | ||
12 | the Free Software Foundation, either version 3 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU Affero General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Affero General Public License | ||
21 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
22 | ***************************************/ | ||
23 | |||
24 | |||
25 | #include <assert.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <stdio.h> | ||
28 | #include <string.h> | ||
29 | #include <sys/stat.h> | ||
30 | |||
31 | #include "waysx.h" | ||
32 | #include "relationsx.h" | ||
33 | |||
34 | #include "files.h" | ||
35 | #include "functions.h" | ||
36 | |||
37 | |||
38 | /* Variables */ | ||
39 | |||
40 | /*+ The command line '--tmpdir' option or its default value. +*/ | ||
41 | extern char *option_tmpdirname; | ||
42 | |||
43 | |||
44 | /*++++++++++++++++++++++++++++++++++++++ | ||
45 | Allocate a new relation list (create a new file or open an existing one). | ||
46 | |||
47 | RelationsX *NewRelationList Returns the relation list. | ||
48 | |||
49 | int append Set to 1 if the file is to be opened for appending (now or later). | ||
50 | ++++++++++++++++++++++++++++++++++++++*/ | ||
51 | |||
52 | RelationsX *NewRelationList(int append) | ||
53 | { | ||
54 | RelationsX *relationsx; | ||
55 | |||
56 | relationsx=(RelationsX*)calloc(1,sizeof(RelationsX)); | ||
57 | |||
58 | assert(relationsx); /* Check calloc() worked */ | ||
59 | |||
60 | relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32); | ||
61 | |||
62 | if(append) | ||
63 | sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname); | ||
64 | else | ||
65 | sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx); | ||
66 | |||
67 | if(append) | ||
68 | { | ||
69 | off_t size,position=0; | ||
70 | |||
71 | amb | 505 | relationsx->rfd=OpenFileAppend(relationsx->rfilename); |
72 | amb | 496 | |
73 | size=SizeFile(relationsx->rfilename); | ||
74 | |||
75 | while(position<size) | ||
76 | { | ||
77 | FILESORT_VARINT relationsize; | ||
78 | |||
79 | SeekFile(relationsx->rfd,position); | ||
80 | ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE); | ||
81 | |||
82 | relationsx->rxnumber++; | ||
83 | position+=relationsize+FILESORT_VARSIZE; | ||
84 | } | ||
85 | |||
86 | SeekFile(relationsx->rfd,size); | ||
87 | } | ||
88 | else | ||
89 | amb | 505 | relationsx->rfd=OpenFileNew(relationsx->rfilename); |
90 | amb | 496 | |
91 | return(relationsx); | ||
92 | } | ||
93 | |||
94 | |||
95 | /*++++++++++++++++++++++++++++++++++++++ | ||
96 | Free a relation list. | ||
97 | |||
98 | RelationsX *relationsx The list to be freed. | ||
99 | |||
100 | int keep Set to 1 if the file is to be kept. | ||
101 | ++++++++++++++++++++++++++++++++++++++*/ | ||
102 | |||
103 | void FreeRelationList(RelationsX *relationsx,int keep) | ||
104 | { | ||
105 | if(!keep) | ||
106 | DeleteFile(relationsx->rfilename); | ||
107 | |||
108 | free(relationsx->rfilename); | ||
109 | |||
110 | free(relationsx); | ||
111 | } | ||
112 | |||
113 | |||
114 | /*++++++++++++++++++++++++++++++++++++++ | ||
115 | Append a single relation to an unsorted route relation list. | ||
116 | |||
117 | RelationsX* relationsx The set of relations to process. | ||
118 | |||
119 | relation_t id The ID of the relation. | ||
120 | |||
121 | allow_t routes The types of routes that this relation is for. | ||
122 | |||
123 | way_t *ways The array of ways that are members of the relation. | ||
124 | |||
125 | int nways The number of ways that are members of the relation. | ||
126 | |||
127 | relation_t *relations The array of relations that are members of the relation. | ||
128 | |||
129 | int nrelations The number of relations that are members of the relation. | ||
130 | ++++++++++++++++++++++++++++++++++++++*/ | ||
131 | |||
132 | void AppendRouteRelation(RelationsX* relationsx,relation_t id,allow_t routes, | ||
133 | way_t *ways,int nways, | ||
134 | relation_t *relations,int nrelations) | ||
135 | { | ||
136 | RouteRelX relationx; | ||
137 | amb | 505 | FILESORT_VARINT size; |
138 | amb | 496 | way_t zeroway=0; |
139 | relation_t zerorelation=0; | ||
140 | |||
141 | relationx.id=id; | ||
142 | relationx.routes=routes; | ||
143 | |||
144 | size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t); | ||
145 | |||
146 | amb | 505 | WriteFile(relationsx->rfd,&size,FILESORT_VARSIZE); |
147 | amb | 496 | WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX)); |
148 | |||
149 | WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t)); | ||
150 | WriteFile(relationsx->rfd,&zeroway, sizeof(way_t)); | ||
151 | |||
152 | WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t)); | ||
153 | WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t)); | ||
154 | |||
155 | relationsx->rxnumber++; | ||
156 | |||
157 | assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */ | ||
158 | } | ||
159 | |||
160 | |||
161 | /*++++++++++++++++++++++++++++++++++++++ | ||
162 | Sort the list of relations. | ||
163 | |||
164 | RelationsX* relationsx The set of relations to process. | ||
165 | ++++++++++++++++++++++++++++++++++++++*/ | ||
166 | |||
167 | void SortRelationList(RelationsX* relationsx) | ||
168 | { | ||
169 | amb | 501 | /* Don't need to sort route relations */ |
170 | amb | 496 | } |
171 | |||
172 | |||
173 | /*++++++++++++++++++++++++++++++++++++++ | ||
174 | Process the route relations and apply the information to the ways. | ||
175 | |||
176 | RelationsX *relationsx The set of relations to process. | ||
177 | |||
178 | WaysX *waysx The set of ways to update. | ||
179 | ++++++++++++++++++++++++++++++++++++++*/ | ||
180 | |||
181 | void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx) | ||
182 | { | ||
183 | amb | 505 | RouteRelX *unmatched=NULL,*lastunmatched=NULL; |
184 | int nunmatched=0,lastnunmatched=0,iteration=0; | ||
185 | int i,j; | ||
186 | amb | 496 | |
187 | amb | 505 | /* Map into memory */ |
188 | amb | 496 | |
189 | amb | 505 | #if !SLIM |
190 | amb | 507 | waysx->xdata=MapFileWriteable(waysx->filename); |
191 | amb | 505 | #endif |
192 | amb | 496 | |
193 | /* Open the file and read through it */ | ||
194 | |||
195 | relationsx->rfd=ReOpenFile(relationsx->rfilename); | ||
196 | |||
197 | amb | 505 | do |
198 | amb | 496 | { |
199 | amb | 505 | SeekFile(relationsx->rfd,0); |
200 | amb | 496 | |
201 | amb | 505 | /* Print the start message */ |
202 | amb | 496 | |
203 | amb | 505 | printf("Processing Route Relations: Iteration=%d Relations=0",iteration); |
204 | fflush(stdout); | ||
205 | amb | 496 | |
206 | amb | 505 | for(i=0;i<relationsx->rxnumber;i++) |
207 | amb | 496 | { |
208 | amb | 505 | FILESORT_VARINT size; |
209 | RouteRelX relationx; | ||
210 | way_t wayid; | ||
211 | relation_t relationid; | ||
212 | allow_t routes=Allow_None; | ||
213 | amb | 496 | |
214 | amb | 505 | /* Read each route relation */ |
215 | amb | 496 | |
216 | amb | 505 | ReadFile(relationsx->rfd,&size,FILESORT_VARSIZE); |
217 | ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX)); | ||
218 | amb | 496 | |
219 | amb | 505 | /* Decide what type of route it is */ |
220 | amb | 496 | |
221 | amb | 505 | if(iteration==0) |
222 | routes=relationx.routes; | ||
223 | else | ||
224 | amb | 506 | { |
225 | if((lastunmatched[j].routes|relationx.routes)==relationx.routes) | ||
226 | routes=0; /* Nothing new to add */ | ||
227 | else | ||
228 | for(j=0;j<lastnunmatched;j++) | ||
229 | if(lastunmatched[j].id==relationx.id) | ||
230 | { | ||
231 | routes=lastunmatched[j].routes; | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | amb | 496 | |
236 | amb | 505 | /* Loop through the ways */ |
237 | |||
238 | do | ||
239 | { | ||
240 | ReadFile(relationsx->rfd,&wayid,sizeof(way_t)); | ||
241 | |||
242 | /* Update the ways that are listed for the relation */ | ||
243 | |||
244 | if(wayid && routes) | ||
245 | { | ||
246 | amb | 506 | index_t way=IndexWayX(waysx,wayid); |
247 | amb | 505 | |
248 | if(way!=NO_WAY) | ||
249 | { | ||
250 | WayX *wayx=LookupWayX(waysx,way,1); | ||
251 | |||
252 | if(routes&Allow_Foot) | ||
253 | wayx->way.props|=Properties_FootRoute; | ||
254 | |||
255 | if(routes&Allow_Bicycle) | ||
256 | wayx->way.props|=Properties_BicycleRoute; | ||
257 | |||
258 | #if SLIM | ||
259 | PutBackWayX(waysx,way,1); | ||
260 | #endif | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | while(wayid); | ||
265 | |||
266 | /* Loop through the relations */ | ||
267 | |||
268 | do | ||
269 | { | ||
270 | ReadFile(relationsx->rfd,&relationid,sizeof(relation_t)); | ||
271 | |||
272 | /* Add the relations that are listed for this relation to the list for next time */ | ||
273 | |||
274 | amb | 506 | if(relationid && routes && relationid!=relationx.id) |
275 | amb | 505 | { |
276 | if(nunmatched%256==0) | ||
277 | unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX)); | ||
278 | |||
279 | unmatched[nunmatched].id=relationid; | ||
280 | unmatched[nunmatched].routes=routes; | ||
281 | |||
282 | nunmatched++; | ||
283 | } | ||
284 | } | ||
285 | while(relationid); | ||
286 | |||
287 | if(!((i+1)%10000)) | ||
288 | { | ||
289 | printf("\rProcessing Route Relations: Iteration=%d Relations=%d",iteration,i+1); | ||
290 | fflush(stdout); | ||
291 | } | ||
292 | amb | 496 | } |
293 | |||
294 | amb | 505 | if(lastunmatched) |
295 | free(lastunmatched); | ||
296 | |||
297 | lastunmatched=unmatched; | ||
298 | lastnunmatched=nunmatched; | ||
299 | |||
300 | unmatched=NULL; | ||
301 | nunmatched=0; | ||
302 | |||
303 | /* Print the final message */ | ||
304 | |||
305 | printf("\rProcessed Route Relations: Iteration=%d Relations=%d \n",iteration,relationsx->rxnumber); | ||
306 | fflush(stdout); | ||
307 | amb | 496 | } |
308 | amb | 505 | while(lastnunmatched && ++iteration<5); |
309 | amb | 496 | |
310 | amb | 505 | if(lastunmatched) |
311 | free(lastunmatched); | ||
312 | |||
313 | amb | 496 | CloseFile(relationsx->rfd); |
314 | |||
315 | amb | 505 | /* Unmap from memory */ |
316 | amb | 496 | |
317 | amb | 505 | #if !SLIM |
318 | waysx->xdata=UnmapFile(waysx->filename); | ||
319 | #endif | ||
320 | amb | 496 | } |