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/relationsx.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 519 - (show annotations) (download) (as text)
Sat Nov 13 14:22:28 2010 UTC (14 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 8589 byte(s)
Add an option to make the output more suitable for a log file.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/relationsx.c,v 1.9 2010-11-13 14:22:28 amb Exp $
3
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 "logging.h"
36 #include "functions.h"
37
38
39 /* Variables */
40
41 /*+ The command line '--tmpdir' option or its default value. +*/
42 extern char *option_tmpdirname;
43
44
45 /*++++++++++++++++++++++++++++++++++++++
46 Allocate a new relation list (create a new file or open an existing one).
47
48 RelationsX *NewRelationList Returns the relation list.
49
50 int append Set to 1 if the file is to be opened for appending (now or later).
51 ++++++++++++++++++++++++++++++++++++++*/
52
53 RelationsX *NewRelationList(int append)
54 {
55 RelationsX *relationsx;
56
57 relationsx=(RelationsX*)calloc(1,sizeof(RelationsX));
58
59 assert(relationsx); /* Check calloc() worked */
60
61 relationsx->rfilename=(char*)malloc(strlen(option_tmpdirname)+32);
62
63 if(append)
64 sprintf(relationsx->rfilename,"%s/relationsx.route.input.tmp",option_tmpdirname);
65 else
66 sprintf(relationsx->rfilename,"%s/relationsx.route.%p.tmp",option_tmpdirname,relationsx);
67
68 if(append)
69 {
70 off_t size,position=0;
71
72 relationsx->rfd=OpenFileAppend(relationsx->rfilename);
73
74 size=SizeFile(relationsx->rfilename);
75
76 while(position<size)
77 {
78 FILESORT_VARINT relationsize;
79
80 SeekFile(relationsx->rfd,position);
81 ReadFile(relationsx->rfd,&relationsize,FILESORT_VARSIZE);
82
83 relationsx->rxnumber++;
84 position+=relationsize+FILESORT_VARSIZE;
85 }
86
87 SeekFile(relationsx->rfd,size);
88 }
89 else
90 relationsx->rfd=OpenFileNew(relationsx->rfilename);
91
92 return(relationsx);
93 }
94
95
96 /*++++++++++++++++++++++++++++++++++++++
97 Free a relation list.
98
99 RelationsX *relationsx The list to be freed.
100
101 int keep Set to 1 if the file is to be kept.
102 ++++++++++++++++++++++++++++++++++++++*/
103
104 void FreeRelationList(RelationsX *relationsx,int keep)
105 {
106 if(!keep)
107 DeleteFile(relationsx->rfilename);
108
109 free(relationsx->rfilename);
110
111 free(relationsx);
112 }
113
114
115 /*++++++++++++++++++++++++++++++++++++++
116 Append a single relation to an unsorted route relation list.
117
118 RelationsX* relationsx The set of relations to process.
119
120 relation_t id The ID of the relation.
121
122 allow_t routes The types of routes that this relation is for.
123
124 way_t *ways The array of ways that are members of the relation.
125
126 int nways The number of ways that are members of the relation.
127
128 relation_t *relations The array of relations that are members of the relation.
129
130 int nrelations The number of relations that are members of the relation.
131 ++++++++++++++++++++++++++++++++++++++*/
132
133 void AppendRouteRelation(RelationsX* relationsx,relation_t id,allow_t routes,
134 way_t *ways,int nways,
135 relation_t *relations,int nrelations)
136 {
137 RouteRelX relationx;
138 FILESORT_VARINT size;
139 way_t zeroway=0;
140 relation_t zerorelation=0;
141
142 relationx.id=id;
143 relationx.routes=routes;
144
145 size=sizeof(RouteRelX)+(nways+1)*sizeof(way_t)+(nrelations+1)*sizeof(relation_t);
146
147 WriteFile(relationsx->rfd,&size,FILESORT_VARSIZE);
148 WriteFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
149
150 WriteFile(relationsx->rfd,ways ,nways*sizeof(way_t));
151 WriteFile(relationsx->rfd,&zeroway, sizeof(way_t));
152
153 WriteFile(relationsx->rfd,relations ,nrelations*sizeof(relation_t));
154 WriteFile(relationsx->rfd,&zerorelation, sizeof(relation_t));
155
156 relationsx->rxnumber++;
157
158 assert(!(relationsx->rxnumber==0)); /* Zero marks the high-water mark for relations. */
159 }
160
161
162 /*++++++++++++++++++++++++++++++++++++++
163 Sort the list of relations.
164
165 RelationsX* relationsx The set of relations to process.
166 ++++++++++++++++++++++++++++++++++++++*/
167
168 void SortRelationList(RelationsX* relationsx)
169 {
170 /* Don't need to sort route relations */
171 }
172
173
174 /*++++++++++++++++++++++++++++++++++++++
175 Process the route relations and apply the information to the ways.
176
177 RelationsX *relationsx The set of relations to process.
178
179 WaysX *waysx The set of ways to update.
180 ++++++++++++++++++++++++++++++++++++++*/
181
182 void ProcessRouteRelations(RelationsX *relationsx,WaysX *waysx)
183 {
184 RouteRelX *unmatched=NULL,*lastunmatched=NULL;
185 int nunmatched=0,lastnunmatched=0,iteration=0;
186 int i,j;
187
188 if(waysx->number==0)
189 return;
190
191 /* Map into memory */
192
193 #if !SLIM
194 waysx->xdata=MapFileWriteable(waysx->filename);
195 #endif
196
197 /* Re-open the ways file read/write */
198
199 #if SLIM
200 CloseFile(waysx->fd);
201 waysx->fd=ReOpenFileWriteable(waysx->filename);
202 #endif
203
204 /* Open the file and read through it */
205
206 relationsx->rfd=ReOpenFile(relationsx->rfilename);
207
208 do
209 {
210 SeekFile(relationsx->rfd,0);
211
212 /* Print the start message */
213
214 printf_first("Processing Route Relations: Iteration=%d Relations=0",iteration);
215
216 for(i=0;i<relationsx->rxnumber;i++)
217 {
218 FILESORT_VARINT size;
219 RouteRelX relationx;
220 way_t wayid;
221 relation_t relationid;
222 allow_t routes=Allow_None;
223
224 /* Read each route relation */
225
226 ReadFile(relationsx->rfd,&size,FILESORT_VARSIZE);
227 ReadFile(relationsx->rfd,&relationx,sizeof(RouteRelX));
228
229 /* Decide what type of route it is */
230
231 if(iteration==0)
232 routes=relationx.routes;
233 else
234 {
235 if((lastunmatched[j].routes|relationx.routes)==relationx.routes)
236 routes=0; /* Nothing new to add */
237 else
238 for(j=0;j<lastnunmatched;j++)
239 if(lastunmatched[j].id==relationx.id)
240 {
241 routes=lastunmatched[j].routes;
242 break;
243 }
244 }
245
246 /* Loop through the ways */
247
248 do
249 {
250 ReadFile(relationsx->rfd,&wayid,sizeof(way_t));
251
252 /* Update the ways that are listed for the relation */
253
254 if(wayid && routes)
255 {
256 index_t way=IndexWayX(waysx,wayid);
257
258 if(way!=NO_WAY)
259 {
260 WayX *wayx=LookupWayX(waysx,way,1);
261
262 if(routes&Allow_Foot)
263 wayx->way.props|=Properties_FootRoute;
264
265 if(routes&Allow_Bicycle)
266 wayx->way.props|=Properties_BicycleRoute;
267
268 #if SLIM
269 PutBackWayX(waysx,way,1);
270 #endif
271 }
272 }
273 }
274 while(wayid);
275
276 /* Loop through the relations */
277
278 do
279 {
280 ReadFile(relationsx->rfd,&relationid,sizeof(relation_t));
281
282 /* Add the relations that are listed for this relation to the list for next time */
283
284 if(relationid && routes && relationid!=relationx.id)
285 {
286 if(nunmatched%256==0)
287 unmatched=(RouteRelX*)realloc((void*)unmatched,(nunmatched+256)*sizeof(RouteRelX));
288
289 unmatched[nunmatched].id=relationid;
290 unmatched[nunmatched].routes=routes;
291
292 nunmatched++;
293 }
294 }
295 while(relationid);
296
297 if(!((i+1)%10000))
298 printf_middle("Processing Route Relations: Iteration=%d Relations=%d",iteration,i+1);
299 }
300
301 if(lastunmatched)
302 free(lastunmatched);
303
304 lastunmatched=unmatched;
305 lastnunmatched=nunmatched;
306
307 unmatched=NULL;
308 nunmatched=0;
309
310 /* Print the final message */
311
312 printf_last("Processed Route Relations: Iteration=%d Relations=%d",iteration,relationsx->rxnumber);
313 }
314 while(lastnunmatched && ++iteration<5);
315
316 if(lastunmatched)
317 free(lastunmatched);
318
319 CloseFile(relationsx->rfd);
320
321 /* Unmap from memory */
322
323 #if !SLIM
324 waysx->xdata=UnmapFile(waysx->filename);
325 #endif
326
327 /* Re-open the ways file read only */
328
329 #if SLIM
330 CloseFile(waysx->fd);
331 waysx->fd=ReOpenFile(waysx->filename);
332 #endif
333 }