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

Parent Directory Parent Directory | Revision Log 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)
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 }