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 955 - (show annotations) (download) (as text)
Sat Jan 28 14:40:54 2012 UTC (13 years, 2 months ago) by amb
File MIME type: text/x-csrc
File size: 19826 byte(s)
Simplify and standardise the included headers.

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

Properties

Name Value
cvs:description Functions for data visualisation.