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 885 - (show annotations) (download) (as text)
Sat Oct 29 15:20:30 2011 UTC (13 years, 4 months ago) by amb
File MIME type: text/x-csrc
File size: 19791 byte(s)
Rationalise and reduce the usage of LookUpNode() function.

1 /***************************************
2 Extract data from Routino.
3
4 Part of the Routino routing software.
5 ******************/ /******************
6 This file Copyright 2008-2011 Andrew M. Bishop
7
8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Affero General Public License for more details.
17
18 You should have received a copy of the GNU Affero General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***************************************/
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "types.h"
28 #include "visualiser.h"
29 #include "nodes.h"
30 #include "segments.h"
31 #include "ways.h"
32 #include "relations.h"
33
34
35 /* Limit types */
36
37 #define SPEED_LIMIT 1
38 #define WEIGHT_LIMIT 2
39 #define HEIGHT_LIMIT 3
40 #define WIDTH_LIMIT 4
41 #define LENGTH_LIMIT 5
42
43 /* Local types */
44
45 typedef void (*callback_t)(index_t node,double latitude,double longitude);
46
47 /* Local variables */
48
49 static Nodes *OSMNodes;
50 static Segments *OSMSegments;
51 static Ways *OSMWays;
52 static Relations *OSMRelations;
53
54 static double LatMin;
55 static double LatMax;
56 static double LonMin;
57 static double LonMax;
58
59 static int limit_type=0;
60
61 /* Local functions */
62
63 static void find_all_nodes(Nodes *nodes,callback_t callback);
64 static void output_junctions(index_t node,double latitude,double longitude);
65 static void output_super(index_t node,double latitude,double longitude);
66 static void output_oneway(index_t node,double latitude,double longitude);
67 static void output_turnrestriction(index_t node,double latitude,double longitude);
68 static void output_limits(index_t node,double latitude,double longitude);
69
70
71 /*++++++++++++++++++++++++++++++++++++++
72 Output the data for junctions.
73
74 Nodes *nodes The set of nodes to use.
75
76 Segments *segments The set of segments to use.
77
78 Ways *ways The set of ways to use.
79
80 Relations *relations The set of relations to use.
81
82 double latmin The minimum latitude.
83
84 double latmax The maximum latitude.
85
86 double lonmin The minimum longitude.
87
88 double lonmax The maximum longitude.
89 ++++++++++++++++++++++++++++++++++++++*/
90
91 void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
92 {
93 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
94
95 OSMNodes=nodes;
96 OSMSegments=segments;
97 OSMWays=ways;
98 OSMRelations=relations;
99
100 LatMin=latmin;
101 LatMax=latmax;
102 LonMin=lonmin;
103 LonMax=lonmax;
104
105 /* Iterate through the nodes and process them */
106
107 find_all_nodes(nodes,(callback_t)output_junctions);
108 }
109
110
111 /*++++++++++++++++++++++++++++++++++++++
112 Process a single node as a junction (called as a callback).
113
114 index_t node The node to output.
115
116 double latitude The latitude of the node.
117
118 double longitude The longitude of the node.
119 ++++++++++++++++++++++++++++++++++++++*/
120
121 static void output_junctions(index_t node,double latitude,double longitude)
122 {
123 Node *nodep=LookupNode(OSMNodes,node,1);
124 Segment *segment;
125 Way *firstway;
126 int count=0,difference=0;
127
128 segment=FirstSegment(OSMSegments,nodep,1);
129 firstway=LookupWay(OSMWays,segment->way,1);
130
131 do
132 {
133 Way *way=LookupWay(OSMWays,segment->way,2);
134
135 if(IsNormalSegment(segment))
136 count++;
137
138 if(WaysCompare(firstway,way))
139 difference=1;
140
141 segment=NextSegment(OSMSegments,segment,node);
142 }
143 while(segment);
144
145 if(count!=2 || difference)
146 printf("%.6f %.6f %d\n",radians_to_degrees(latitude),radians_to_degrees(longitude),count);
147 }
148
149
150 /*++++++++++++++++++++++++++++++++++++++
151 Output the data for super-nodes and super-segments.
152
153 Nodes *nodes The set of nodes to use.
154
155 Segments *segments The set of segments to use.
156
157 Ways *ways The set of ways to use.
158
159 Relations *relations The set of relations to use.
160
161 double latmin The minimum latitude.
162
163 double latmax The maximum latitude.
164
165 double lonmin The minimum longitude.
166
167 double lonmax The maximum longitude.
168 ++++++++++++++++++++++++++++++++++++++*/
169
170 void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
171 {
172 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
173
174 OSMNodes=nodes;
175 OSMSegments=segments;
176 OSMWays=ways;
177 OSMRelations=relations;
178
179 LatMin=latmin;
180 LatMax=latmax;
181 LonMin=lonmin;
182 LonMax=lonmax;
183
184 /* Iterate through the nodes and process them */
185
186 find_all_nodes(nodes,(callback_t)output_super);
187 }
188
189
190 /*++++++++++++++++++++++++++++++++++++++
191 Process a single node as a super-node (called as a callback).
192
193 index_t node The node to output.
194
195 double latitude The latitude of the node.
196
197 double longitude The longitude of the node.
198 ++++++++++++++++++++++++++++++++++++++*/
199
200 static void output_super(index_t node,double latitude,double longitude)
201 {
202 Node *nodep=LookupNode(OSMNodes,node,1);
203 Segment *segment;
204
205 if(!IsSuperNode(nodep))
206 return;
207
208 printf("%.6f %.6f n\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
209
210 segment=FirstSegment(OSMSegments,nodep,1);
211
212 do
213 {
214 if(IsSuperSegment(segment))
215 {
216 index_t othernode=OtherNode(segment,node);
217 double lat,lon;
218
219 GetLatLong(OSMNodes,othernode,&lat,&lon);
220
221 if(node>othernode || (lat<LatMin || lat>LatMax || lon<LonMin || lon>LonMax))
222 printf("%.6f %.6f s\n",radians_to_degrees(lat),radians_to_degrees(lon));
223 }
224
225 segment=NextSegment(OSMSegments,segment,node);
226 }
227 while(segment);
228 }
229
230
231 /*++++++++++++++++++++++++++++++++++++++
232 Output the data for one-way segments.
233
234 Nodes *nodes The set of nodes to use.
235
236 Segments *segments The set of segments to use.
237
238 Ways *ways The set of ways to use.
239
240 Relations *relations The set of relations to use.
241
242 double latmin The minimum latitude.
243
244 double latmax The maximum latitude.
245
246 double lonmin The minimum longitude.
247
248 double lonmax The maximum longitude.
249 ++++++++++++++++++++++++++++++++++++++*/
250
251 void OutputOneway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
252 {
253 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
254
255 OSMNodes=nodes;
256 OSMSegments=segments;
257 OSMWays=ways;
258 OSMRelations=relations;
259
260 LatMin=latmin;
261 LatMax=latmax;
262 LonMin=lonmin;
263 LonMax=lonmax;
264
265 /* Iterate through the nodes and process them */
266
267 find_all_nodes(nodes,(callback_t)output_oneway);
268 }
269
270
271 /*++++++++++++++++++++++++++++++++++++++
272 Process a single node and all connected one-way segments (called as a callback).
273
274 index_t node The node to output.
275
276 double latitude The latitude of the node.
277
278 double longitude The longitude of the node.
279 ++++++++++++++++++++++++++++++++++++++*/
280
281 static void output_oneway(index_t node,double latitude,double longitude)
282 {
283 Node *nodep=LookupNode(OSMNodes,node,1);
284 Segment *segment;
285
286 segment=FirstSegment(OSMSegments,nodep,1);
287
288 do
289 {
290 if(IsNormalSegment(segment))
291 {
292 index_t othernode=OtherNode(segment,node);
293
294 if(node>othernode)
295 {
296 double lat,lon;
297
298 GetLatLong(OSMNodes,othernode,&lat,&lon);
299
300 if(IsOnewayFrom(segment,node))
301 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
302 else if(IsOnewayFrom(segment,othernode))
303 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude));
304 }
305 }
306
307 segment=NextSegment(OSMSegments,segment,node);
308 }
309 while(segment);
310 }
311
312
313 /*++++++++++++++++++++++++++++++++++++++
314 Output the data for turn restrictions.
315
316 Nodes *nodes The set of nodes to use.
317
318 Segments *segments The set of segments to use.
319
320 Ways *ways The set of ways to use.
321
322 Relations *relations The set of relations to use.
323
324 double latmin The minimum latitude.
325
326 double latmax The maximum latitude.
327
328 double lonmin The minimum longitude.
329
330 double lonmax The maximum longitude.
331 ++++++++++++++++++++++++++++++++++++++*/
332
333 void OutputTurnRestrictions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double 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 OSMRelations=relations;
341
342 LatMin=latmin;
343 LatMax=latmax;
344 LonMin=lonmin;
345 LonMax=lonmax;
346
347 /* Iterate through the nodes and process them */
348
349 find_all_nodes(nodes,(callback_t)output_turnrestriction);
350 }
351
352
353 /*++++++++++++++++++++++++++++++++++++++
354 Process a single node as the 'via' node for a turn restriction (called as a callback).
355
356 index_t node The node to output.
357
358 double latitude The latitude of the node.
359
360 double longitude The longitude of the node.
361 ++++++++++++++++++++++++++++++++++++++*/
362
363 static void output_turnrestriction(index_t node,double latitude,double longitude)
364 {
365 Node *nodep=LookupNode(OSMNodes,node,1);
366 index_t turnrelation=NO_RELATION;
367
368 if(!IsTurnRestrictedNode(nodep))
369 return;
370
371 turnrelation=FindFirstTurnRelation1(OSMRelations,node);
372
373 do
374 {
375 TurnRelation *relation;
376 Segment *from_segment,*to_segment;
377 index_t from_node,to_node;
378 double from_lat,from_lon,to_lat,to_lon;
379
380 relation=LookupTurnRelation(OSMRelations,turnrelation,1);
381
382 from_segment=LookupSegment(OSMSegments,relation->from,1);
383 to_segment =LookupSegment(OSMSegments,relation->to ,2);
384
385 from_node=OtherNode(from_segment,node);
386 to_node=OtherNode(to_segment,node);
387
388 GetLatLong(OSMNodes,from_node,&from_lat,&from_lon);
389 GetLatLong(OSMNodes,to_node,&to_lat,&to_lon);
390
391 printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",radians_to_degrees(from_lat),radians_to_degrees(from_lon),
392 radians_to_degrees(latitude),radians_to_degrees(longitude),
393 radians_to_degrees(to_lat),radians_to_degrees(to_lon));
394
395 turnrelation=FindNextTurnRelation1(OSMRelations,turnrelation);
396 }
397 while(turnrelation!=NO_RELATION);
398 }
399
400
401 /*++++++++++++++++++++++++++++++++++++++
402 Output the data for speed limits.
403
404 Nodes *nodes The set of nodes to use.
405
406 Segments *segments The set of segments to use.
407
408 Ways *ways The set of ways to use.
409
410 Relations *relations The set of relations to use.
411
412 double latmin The minimum latitude.
413
414 double latmax The maximum latitude.
415
416 double lonmin The minimum longitude.
417
418 double lonmax The maximum longitude.
419 ++++++++++++++++++++++++++++++++++++++*/
420
421 void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
422 {
423 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
424
425 OSMNodes=nodes;
426 OSMSegments=segments;
427 OSMWays=ways;
428 OSMRelations=relations;
429
430 LatMin=latmin;
431 LatMax=latmax;
432 LonMin=lonmin;
433 LonMax=lonmax;
434
435 /* Iterate through the nodes and process them */
436
437 limit_type=SPEED_LIMIT;
438
439 find_all_nodes(nodes,(callback_t)output_limits);
440 }
441
442
443 /*++++++++++++++++++++++++++++++++++++++
444 Output the data for weight limits.
445
446 Nodes *nodes The set of nodes to use.
447
448 Segments *segments The set of segments to use.
449
450 Ways *ways The set of ways to use.
451
452 Relations *relations The set of relations to use.
453
454 double latmin The minimum latitude.
455
456 double latmax The maximum latitude.
457
458 double lonmin The minimum longitude.
459
460 double lonmax The maximum longitude.
461 ++++++++++++++++++++++++++++++++++++++*/
462
463 void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
464 {
465 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
466
467 OSMNodes=nodes;
468 OSMSegments=segments;
469 OSMWays=ways;
470 OSMRelations=relations;
471
472 LatMin=latmin;
473 LatMax=latmax;
474 LonMin=lonmin;
475 LonMax=lonmax;
476
477 /* Iterate through the nodes and process them */
478
479 limit_type=WEIGHT_LIMIT;
480
481 find_all_nodes(nodes,(callback_t)output_limits);
482 }
483
484
485 /*++++++++++++++++++++++++++++++++++++++
486 Output the data for height limits.
487
488 Nodes *nodes The set of nodes to use.
489
490 Segments *segments The set of segments to use.
491
492 Ways *ways The set of ways to use.
493
494 Relations *relations The set of relations to use.
495
496 double latmin The minimum latitude.
497
498 double latmax The maximum latitude.
499
500 double lonmin The minimum longitude.
501
502 double lonmax The maximum longitude.
503 ++++++++++++++++++++++++++++++++++++++*/
504
505 void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
506 {
507 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
508
509 OSMNodes=nodes;
510 OSMSegments=segments;
511 OSMWays=ways;
512 OSMRelations=relations;
513
514 LatMin=latmin;
515 LatMax=latmax;
516 LonMin=lonmin;
517 LonMax=lonmax;
518
519 /* Iterate through the nodes and process them */
520
521 limit_type=HEIGHT_LIMIT;
522
523 find_all_nodes(nodes,(callback_t)output_limits);
524 }
525
526
527 /*++++++++++++++++++++++++++++++++++++++
528 Output the data for width limits.
529
530 Nodes *nodes The set of nodes to use.
531
532 Segments *segments The set of segments to use.
533
534 Ways *ways The set of ways to use.
535
536 Relations *relations The set of relations to use.
537
538 double latmin The minimum latitude.
539
540 double latmax The maximum latitude.
541
542 double lonmin The minimum longitude.
543
544 double lonmax The maximum longitude.
545 ++++++++++++++++++++++++++++++++++++++*/
546
547 void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
548 {
549 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
550
551 OSMNodes=nodes;
552 OSMSegments=segments;
553 OSMWays=ways;
554 OSMRelations=relations;
555
556 LatMin=latmin;
557 LatMax=latmax;
558 LonMin=lonmin;
559 LonMax=lonmax;
560
561 /* Iterate through the nodes and process them */
562
563 limit_type=WIDTH_LIMIT;
564
565 find_all_nodes(nodes,(callback_t)output_limits);
566 }
567
568
569 /*++++++++++++++++++++++++++++++++++++++
570 Output the data for length limits.
571
572 Nodes *nodes The set of nodes to use.
573
574 Segments *segments The set of segments to use.
575
576 Ways *ways The set of ways to use.
577
578 Relations *relations The set of relations to use.
579
580 double latmin The minimum latitude.
581
582 double latmax The maximum latitude.
583
584 double lonmin The minimum longitude.
585
586 double lonmax The maximum longitude.
587 ++++++++++++++++++++++++++++++++++++++*/
588
589 void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
590 {
591 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
592
593 OSMNodes=nodes;
594 OSMSegments=segments;
595 OSMWays=ways;
596 OSMRelations=relations;
597
598 LatMin=latmin;
599 LatMax=latmax;
600 LonMin=lonmin;
601 LonMax=lonmax;
602
603 /* Iterate through the nodes and process them */
604
605 limit_type=LENGTH_LIMIT;
606
607 find_all_nodes(nodes,(callback_t)output_limits);
608 }
609
610
611 /*++++++++++++++++++++++++++++++++++++++
612 Process a single node as a speed, weight, height, length, width limit (called as a callback).
613
614 index_t node The node to output.
615
616 double latitude The latitude of the node.
617
618 double longitude The longitude of the node.
619 ++++++++++++++++++++++++++++++++++++++*/
620
621 static void output_limits(index_t node,double latitude,double longitude)
622 {
623 #define MAX_STORED 32
624 Node *nodep=LookupNode(OSMNodes,node,1);
625 Segment *segment,*segments[MAX_STORED];
626 Way *ways[MAX_STORED];
627 int limits[MAX_STORED];
628 int count=0;
629 int i,j,same=0;
630
631 segment=FirstSegment(OSMSegments,nodep,1);
632
633 do
634 {
635 if(IsNormalSegment(segment) && count<MAX_STORED)
636 {
637 ways [count]=LookupWay(OSMWays,segment->way,1);
638 segments[count]=segment;
639
640 switch(limit_type)
641 {
642 case SPEED_LIMIT: limits[count]=ways[count]->speed; break;
643 case WEIGHT_LIMIT: limits[count]=ways[count]->weight; break;
644 case HEIGHT_LIMIT: limits[count]=ways[count]->height; break;
645 case WIDTH_LIMIT: limits[count]=ways[count]->width; break;
646 case LENGTH_LIMIT: limits[count]=ways[count]->length; break;
647 }
648
649 if(limits[count] || ways[count]->type<Way_Track)
650 count++;
651 }
652
653 segment=NextSegment(OSMSegments,segment,node);
654 }
655 while(segment);
656
657 /* Nodes with only one limit are not interesting */
658
659 if(count==1)
660 return;
661
662 /* Nodes with all segments the same limit is not interesting */
663
664 same=0;
665 for(j=0;j<count;j++)
666 if(limits[0]==limits[j])
667 same++;
668
669 if(same==count)
670 return;
671
672 /* Display the interesting speed limits */
673
674 printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
675
676 for(i=0;i<count;i++)
677 {
678 same=0;
679 for(j=0;j<count;j++)
680 if(limits[i]==limits[j])
681 same++;
682
683 if(count==2 || same!=(count-1))
684 {
685 double lat,lon;
686
687 GetLatLong(OSMNodes,OtherNode(segments[i],node),&lat,&lon);
688
689 switch(limit_type)
690 {
691 case SPEED_LIMIT:
692 printf("%.6f %.6f %d\n",radians_to_degrees(lat),radians_to_degrees(lon),speed_to_kph(limits[i]));
693 break;
694 case WEIGHT_LIMIT:
695 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),weight_to_tonnes(limits[i]));
696 break;
697 case HEIGHT_LIMIT:
698 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),height_to_metres(limits[i]));
699 break;
700 case WIDTH_LIMIT:
701 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),width_to_metres(limits[i]));
702 break;
703 case LENGTH_LIMIT:
704 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),length_to_metres(limits[i]));
705 break;
706 }
707 }
708 }
709 }
710
711
712 /*++++++++++++++++++++++++++++++++++++++
713 A function to iterate through all nodes and call a callback function for each one.
714
715 Nodes *nodes The set of nodes to use.
716
717 callback_t callback The callback function for each node.
718 ++++++++++++++++++++++++++++++++++++++*/
719
720 static void find_all_nodes(Nodes *nodes,callback_t callback)
721 {
722 ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->file.latzero;
723 ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero;
724 ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero;
725 ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero;
726 ll_bin_t latb,lonb;
727 index_t i,index1,index2;
728
729 /* Loop through all of the nodes. */
730
731 for(latb=latminbin;latb<=latmaxbin;latb++)
732 for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
733 {
734 ll_bin2_t llbin=lonb*nodes->file.latbins+latb;
735
736 if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins))
737 continue;
738
739 index1=LookupNodeOffset(nodes,llbin);
740 index2=LookupNodeOffset(nodes,llbin+1);
741
742 for(i=index1;i<index2;i++)
743 {
744 Node *node=LookupNode(nodes,i,1);
745
746 double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
747 double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
748
749 if(lat>LatMin && lat<LatMax && lon>LonMin && lon<LonMax)
750 (*callback)(i,lat,lon);
751 }
752 }
753 }

Properties

Name Value
cvs:description Functions for data visualisation.