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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 198 - (show annotations) (download) (as text)
Mon Jun 15 18:52:54 2009 UTC (15 years, 9 months ago) by amb
File MIME type: text/x-csrc
File size: 15581 byte(s)
Add a macro for converting degrees to radians and radians to degrees.

1 /***************************************
2 $Header: /home/amb/CVS/routino/src/visualiser.c,v 1.3 2009-06-15 18:52:54 amb Exp $
3
4 Extract data from Routino.
5
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008,2009 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 <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "types.h"
30 #include "visualiser.h"
31 #include "nodes.h"
32 #include "segments.h"
33 #include "ways.h"
34
35
36 #define SPEED_LIMIT 1
37 #define WEIGHT_LIMIT 2
38 #define HEIGHT_LIMIT 3
39 #define WIDTH_LIMIT 4
40 #define LENGTH_LIMIT 5
41
42 /* Local types */
43
44 typedef void (*callback_t)(index_t node,float latitude,float longitude);
45
46 /* Local variables */
47
48 static Nodes *OSMNodes;
49 static Segments *OSMSegments;
50 static Ways *OSMWays;
51
52 static int limit_type=0;
53
54 /* Local functions */
55
56 static void find_all_nodes(Nodes *nodes,float latmin,float latmax,float lonmin,float lonmax,callback_t callback);
57 static void output_junctions(index_t node,float latitude,float longitude);
58 static void output_super(index_t node,float latitude,float longitude);
59 static void output_oneway(index_t node,float latitude,float longitude);
60 static void output_limits(index_t node,float latitude,float longitude);
61
62
63 /*++++++++++++++++++++++++++++++++++++++
64 Output the data for junctions.
65
66 Nodes *nodes The set of nodes to use.
67
68 Segments *segments The set of segments to use.
69
70 Ways *ways The set of ways to use.
71
72 float latmin The minimum latitude.
73
74 float latmax The maximum latitude.
75
76 float lonmin The minimum longitude.
77
78 float lonmax The maximum longitude.
79 ++++++++++++++++++++++++++++++++++++++*/
80
81 void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
82 {
83 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
84
85 OSMNodes=nodes;
86 OSMSegments=segments;
87 OSMWays=ways;
88
89 /* Iterate through the nodes and process them */
90
91 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_junctions);
92 }
93
94
95 /*++++++++++++++++++++++++++++++++++++++
96 Process a single node (called as a callback).
97
98 index_t node The node to output.
99
100 float latitude The latitude of the node.
101
102 float longitude The longitude of the node.
103 ++++++++++++++++++++++++++++++++++++++*/
104
105 static void output_junctions(index_t node,float latitude,float longitude)
106 {
107 Segment *segment;
108 Way *firstway;
109 int count=0,difference=0;
110
111 segment=FirstSegment(OSMSegments,OSMNodes,node);
112 firstway=LookupWay(OSMWays,segment->way);
113
114 do
115 {
116 Way *way=LookupWay(OSMWays,segment->way);
117
118 if(IsNormalSegment(segment))
119 count++;
120
121 if(!WaysSame(firstway,way))
122 difference=1;
123
124 segment=NextSegment(OSMSegments,segment,node);
125 }
126 while(segment);
127
128 if(count!=2 || difference)
129 printf("%.6f %.6f %d\n",radians_to_degrees(latitude),radians_to_degrees(longitude),count);
130 }
131
132
133 /*++++++++++++++++++++++++++++++++++++++
134 Output the data for super-nodes and super-segments.
135
136 Nodes *nodes The set of nodes to use.
137
138 Segments *segments The set of segments to use.
139
140 Ways *ways The set of ways to use.
141
142 float latmin The minimum latitude.
143
144 float latmax The maximum latitude.
145
146 float lonmin The minimum longitude.
147
148 float lonmax The maximum longitude.
149 ++++++++++++++++++++++++++++++++++++++*/
150
151 void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
152 {
153 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
154
155 OSMNodes=nodes;
156 OSMSegments=segments;
157 OSMWays=ways;
158
159 /* Iterate through the nodes and process them */
160
161 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_super);
162 }
163
164
165 /*++++++++++++++++++++++++++++++++++++++
166 Process a single node (called as a callback).
167
168 index_t node The node to output.
169
170 float latitude The latitude of the node.
171
172 float longitude The longitude of the node.
173 ++++++++++++++++++++++++++++++++++++++*/
174
175 static void output_super(index_t node,float latitude,float longitude)
176 {
177 Segment *segment;
178
179 if(!IsSuperNode(OSMNodes,node))
180 return;
181
182 printf("%.6f %.6f n\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
183
184 segment=FirstSegment(OSMSegments,OSMNodes,node);
185
186 do
187 {
188 if(IsSuperSegment(segment))
189 {
190 index_t othernode=OtherNode(segment,node);
191
192 if(node>othernode)
193 {
194 float lat,lon;
195
196 GetLatLong(OSMNodes,othernode,&lat,&lon);
197
198 printf("%.6f %.6f s\n",radians_to_degrees(lat),radians_to_degrees(lon));
199 }
200 }
201
202 segment=NextSegment(OSMSegments,segment,node);
203 }
204 while(segment);
205 }
206
207
208 /*++++++++++++++++++++++++++++++++++++++
209 Output the data for one-way segments.
210
211 Nodes *nodes The set of nodes to use.
212
213 Segments *segments The set of segments to use.
214
215 Ways *ways The set of ways to use.
216
217 float latmin The minimum latitude.
218
219 float latmax The maximum latitude.
220
221 float lonmin The minimum longitude.
222
223 float lonmax The maximum longitude.
224 ++++++++++++++++++++++++++++++++++++++*/
225
226 void OutputOneway(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
227 {
228 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
229
230 OSMNodes=nodes;
231 OSMSegments=segments;
232 OSMWays=ways;
233
234 /* Iterate through the nodes and process them */
235
236 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_oneway);
237 }
238
239
240 /*++++++++++++++++++++++++++++++++++++++
241 Process a single node (called as a callback).
242
243 index_t node The node to output.
244
245 float latitude The latitude of the node.
246
247 float longitude The longitude of the node.
248 ++++++++++++++++++++++++++++++++++++++*/
249
250 static void output_oneway(index_t node,float latitude,float longitude)
251 {
252 Segment *segment;
253
254 segment=FirstSegment(OSMSegments,OSMNodes,node);
255
256 do
257 {
258 if(IsNormalSegment(segment))
259 {
260 index_t othernode=OtherNode(segment,node);
261
262 if(node>othernode)
263 {
264 float lat,lon;
265
266 GetLatLong(OSMNodes,othernode,&lat,&lon);
267
268 if(IsOnewayFrom(segment,node))
269 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
270 else if(IsOnewayFrom(segment,othernode))
271 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude));
272 }
273 }
274
275 segment=NextSegment(OSMSegments,segment,node);
276 }
277 while(segment);
278 }
279
280
281 /*++++++++++++++++++++++++++++++++++++++
282 Output the data for speed limits.
283
284 Nodes *nodes The set of nodes to use.
285
286 Segments *segments The set of segments to use.
287
288 Ways *ways The set of ways to use.
289
290 float latmin The minimum latitude.
291
292 float latmax The maximum latitude.
293
294 float lonmin The minimum longitude.
295
296 float lonmax The maximum longitude.
297 ++++++++++++++++++++++++++++++++++++++*/
298
299 void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
300 {
301 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
302
303 OSMNodes=nodes;
304 OSMSegments=segments;
305 OSMWays=ways;
306
307 /* Iterate through the nodes and process them */
308
309 limit_type=SPEED_LIMIT;
310
311 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_limits);
312 }
313
314
315 /*++++++++++++++++++++++++++++++++++++++
316 Output the data for weight limits.
317
318 Nodes *nodes The set of nodes to use.
319
320 Segments *segments The set of segments to use.
321
322 Ways *ways The set of ways to use.
323
324 float latmin The minimum latitude.
325
326 float latmax The maximum latitude.
327
328 float lonmin The minimum longitude.
329
330 float lonmax The maximum longitude.
331 ++++++++++++++++++++++++++++++++++++++*/
332
333 void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
334 {
335 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
336
337 OSMNodes=nodes;
338 OSMSegments=segments;
339 OSMWays=ways;
340
341 /* Iterate through the nodes and process them */
342
343 limit_type=WEIGHT_LIMIT;
344
345 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_limits);
346 }
347
348
349 /*++++++++++++++++++++++++++++++++++++++
350 Output the data for height limits.
351
352 Nodes *nodes The set of nodes to use.
353
354 Segments *segments The set of segments to use.
355
356 Ways *ways The set of ways to use.
357
358 float latmin The minimum latitude.
359
360 float latmax The maximum latitude.
361
362 float lonmin The minimum longitude.
363
364 float lonmax The maximum longitude.
365 ++++++++++++++++++++++++++++++++++++++*/
366
367 void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
368 {
369 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
370
371 OSMNodes=nodes;
372 OSMSegments=segments;
373 OSMWays=ways;
374
375 /* Iterate through the nodes and process them */
376
377 limit_type=HEIGHT_LIMIT;
378
379 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_limits);
380 }
381
382
383 /*++++++++++++++++++++++++++++++++++++++
384 Output the data for width limits.
385
386 Nodes *nodes The set of nodes to use.
387
388 Segments *segments The set of segments to use.
389
390 Ways *ways The set of ways to use.
391
392 float latmin The minimum latitude.
393
394 float latmax The maximum latitude.
395
396 float lonmin The minimum longitude.
397
398 float lonmax The maximum longitude.
399 ++++++++++++++++++++++++++++++++++++++*/
400
401 void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
402 {
403 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
404
405 OSMNodes=nodes;
406 OSMSegments=segments;
407 OSMWays=ways;
408
409 /* Iterate through the nodes and process them */
410
411 limit_type=WIDTH_LIMIT;
412
413 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_limits);
414 }
415
416
417 /*++++++++++++++++++++++++++++++++++++++
418 Output the data for length limits.
419
420 Nodes *nodes The set of nodes to use.
421
422 Segments *segments The set of segments to use.
423
424 Ways *ways The set of ways to use.
425
426 float latmin The minimum latitude.
427
428 float latmax The maximum latitude.
429
430 float lonmin The minimum longitude.
431
432 float lonmax The maximum longitude.
433 ++++++++++++++++++++++++++++++++++++++*/
434
435 void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,float latmin,float latmax,float lonmin,float lonmax)
436 {
437 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
438
439 OSMNodes=nodes;
440 OSMSegments=segments;
441 OSMWays=ways;
442
443 /* Iterate through the nodes and process them */
444
445 limit_type=LENGTH_LIMIT;
446
447 find_all_nodes(nodes,latmin,latmax,lonmin,lonmax,(callback_t)output_limits);
448 }
449
450
451 /*++++++++++++++++++++++++++++++++++++++
452 Process a single node (called as a callback).
453
454 index_t node The node to output.
455
456 float latitude The latitude of the node.
457
458 float longitude The longitude of the node.
459 ++++++++++++++++++++++++++++++++++++++*/
460
461 static void output_limits(index_t node,float latitude,float longitude)
462 {
463 Segment *segment,*segments[16];
464 Way *ways[16];
465 int limits[16];
466 int count=0;
467 int i,j,same=0;
468
469 segment=FirstSegment(OSMSegments,OSMNodes,node);
470
471 do
472 {
473 if(IsNormalSegment(segment) && count<16)
474 {
475 ways [count]=LookupWay(OSMWays,segment->way);
476 segments[count]=segment;
477
478 switch(limit_type)
479 {
480 case SPEED_LIMIT: limits[count]=ways[count]->speed; break;
481 case WEIGHT_LIMIT: limits[count]=ways[count]->weight; break;
482 case HEIGHT_LIMIT: limits[count]=ways[count]->height; break;
483 case WIDTH_LIMIT: limits[count]=ways[count]->width; break;
484 case LENGTH_LIMIT: limits[count]=ways[count]->length; break;
485 }
486
487 count++;
488 }
489
490 segment=NextSegment(OSMSegments,segment,node);
491 }
492 while(segment);
493
494 /* Nodes with only one limit are not interesting */
495
496 if(count==1)
497 return;
498
499 /* Nodes with all segments the same limit is not interesting */
500
501 same=0;
502 for(j=0;j<count;j++)
503 if(limits[0]==limits[j])
504 same++;
505
506 if(same==count)
507 return;
508
509 /* Display the interesting speed limits */
510
511 printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
512
513 for(i=0;i<count;i++)
514 {
515 same=0;
516 for(j=0;j<count;j++)
517 if(limits[i]==limits[j])
518 same++;
519
520 if(count==2 || same!=(count-1))
521 {
522 float lat,lon;
523
524 GetLatLong(OSMNodes,OtherNode(segments[i],node),&lat,&lon);
525
526 switch(limit_type)
527 {
528 case SPEED_LIMIT:
529 printf("%.6f %.6f %.0f\n",radians_to_degrees(lat),radians_to_degrees(lon),(float)speed_to_kph(limits[i]));
530 break;
531 case WEIGHT_LIMIT:
532 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),weight_to_tonnes(limits[i]));
533 break;
534 case HEIGHT_LIMIT:
535 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),height_to_metres(limits[i]));
536 break;
537 case WIDTH_LIMIT:
538 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),width_to_metres(limits[i]));
539 break;
540 case LENGTH_LIMIT:
541 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),length_to_metres(limits[i]));
542 break;
543 }
544 }
545 }
546 }
547
548
549 /*++++++++++++++++++++++++++++++++++++++
550 A function to iterate through all nodes and call a callback function for each one.
551
552 Nodes *nodes The list of nodes to process.
553
554 float latmin The minimum latitude.
555
556 float latmax The maximum latitude.
557
558 float lonmin The minimum longitude.
559
560 float lonmax The maximum longitude.
561
562 callback_t callback The callback function for each node.
563 ++++++++++++++++++++++++++++++++++++++*/
564
565 static void find_all_nodes(Nodes *nodes,float latmin,float latmax,float lonmin,float lonmax,callback_t callback)
566 {
567 int32_t latminbin=lat_long_to_bin(latmin)-nodes->latzero;
568 int32_t latmaxbin=lat_long_to_bin(latmax)-nodes->latzero;
569 int32_t lonminbin=lat_long_to_bin(lonmin)-nodes->lonzero;
570 int32_t lonmaxbin=lat_long_to_bin(lonmax)-nodes->lonzero;
571 int latb,lonb,llbin;
572 index_t node;
573
574 /* Loop through all of the nodes. */
575
576 for(latb=latminbin;latb<=latmaxbin;latb++)
577 for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
578 {
579 llbin=lonb*nodes->latbins+latb;
580
581 if(llbin<0 || llbin>(nodes->latbins*nodes->lonbins))
582 continue;
583
584 for(node=nodes->offsets[llbin];node<nodes->offsets[llbin+1];node++)
585 {
586 float lat=(float)((nodes->latzero+latb)*LAT_LONG_BIN+nodes->nodes[node].latoffset)/LAT_LONG_SCALE;
587 float lon=(float)((nodes->lonzero+lonb)*LAT_LONG_BIN+nodes->nodes[node].lonoffset)/LAT_LONG_SCALE;
588
589 if(lat>latmin && lat<latmax && lon>lonmin && lon<lonmax)
590 (*callback)(node,lat,lon);
591 }
592 }
593 }

Properties

Name Value
cvs:description Functions for data visualisation.