Routino SVN Repository Browser

Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino

ViewVC logotype

Contents of /branches/2.3.2-dev/src/visualiser.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1086 - (show annotations) (download) (as text)
Sat Oct 6 13:26:02 2012 UTC (12 years, 5 months ago) by amb
File MIME type: text/x-csrc
File size: 26105 byte(s)
Merge the rest of the trunk into the branch to prepare to merge back to the trunk.

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 static Highway highways=Way_Count;
65 static Transports transports=Transports_None;
66
67 /* Local functions */
68
69 static void find_all_nodes(Nodes *nodes,callback_t callback);
70 static void output_junctions(index_t node,double latitude,double longitude);
71 static void output_super(index_t node,double latitude,double longitude);
72 static void output_oneway(index_t node,double latitude,double longitude);
73 static void output_highway(index_t node,double latitude,double longitude);
74 static void output_transport(index_t node,double latitude,double longitude);
75 static void output_barrier(index_t node,double latitude,double longitude);
76 static void output_turnrestriction(index_t node,double latitude,double longitude);
77 static void output_limits(index_t node,double latitude,double longitude);
78
79
80 /*++++++++++++++++++++++++++++++++++++++
81 Output the data for junctions.
82
83 Nodes *nodes The set of nodes to use.
84
85 Segments *segments The set of segments to use.
86
87 Ways *ways The set of ways to use.
88
89 Relations *relations The set of relations to use.
90
91 double latmin The minimum latitude.
92
93 double latmax The maximum latitude.
94
95 double lonmin The minimum longitude.
96
97 double lonmax The maximum longitude.
98 ++++++++++++++++++++++++++++++++++++++*/
99
100 void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
101 {
102 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
103
104 OSMNodes=nodes;
105 OSMSegments=segments;
106 OSMWays=ways;
107 OSMRelations=relations;
108
109 LatMin=latmin;
110 LatMax=latmax;
111 LonMin=lonmin;
112 LonMax=lonmax;
113
114 /* Iterate through the nodes and process them */
115
116 find_all_nodes(nodes,(callback_t)output_junctions);
117 }
118
119
120 /*++++++++++++++++++++++++++++++++++++++
121 Process a single node as a junction (called as a callback).
122
123 index_t node The node to output.
124
125 double latitude The latitude of the node.
126
127 double longitude The longitude of the node.
128 ++++++++++++++++++++++++++++++++++++++*/
129
130 static void output_junctions(index_t node,double latitude,double longitude)
131 {
132 Node *nodep=LookupNode(OSMNodes,node,1);
133 Segment *segmentp;
134 Way *firstwayp;
135 int count=0,difference=0;
136
137 segmentp=FirstSegment(OSMSegments,nodep,1);
138 firstwayp=LookupWay(OSMWays,segmentp->way,1);
139
140 do
141 {
142 Way *wayp=LookupWay(OSMWays,segmentp->way,2);
143
144 if(IsNormalSegment(segmentp))
145 count++;
146
147 if(WaysCompare(firstwayp,wayp))
148 difference=1;
149
150 segmentp=NextSegment(OSMSegments,segmentp,node);
151 }
152 while(segmentp);
153
154 if(count!=2 || difference)
155 printf("%.6f %.6f %d\n",radians_to_degrees(latitude),radians_to_degrees(longitude),count);
156 }
157
158
159 /*++++++++++++++++++++++++++++++++++++++
160 Output the data for super-nodes and super-segments.
161
162 Nodes *nodes The set of nodes to use.
163
164 Segments *segments The set of segments to use.
165
166 Ways *ways The set of ways to use.
167
168 Relations *relations The set of relations to use.
169
170 double latmin The minimum latitude.
171
172 double latmax The maximum latitude.
173
174 double lonmin The minimum longitude.
175
176 double lonmax The maximum longitude.
177 ++++++++++++++++++++++++++++++++++++++*/
178
179 void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
180 {
181 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
182
183 OSMNodes=nodes;
184 OSMSegments=segments;
185 OSMWays=ways;
186 OSMRelations=relations;
187
188 LatMin=latmin;
189 LatMax=latmax;
190 LonMin=lonmin;
191 LonMax=lonmax;
192
193 /* Iterate through the nodes and process them */
194
195 find_all_nodes(nodes,(callback_t)output_super);
196 }
197
198
199 /*++++++++++++++++++++++++++++++++++++++
200 Process a single node as a super-node (called as a callback).
201
202 index_t node The node to output.
203
204 double latitude The latitude of the node.
205
206 double longitude The longitude of the node.
207 ++++++++++++++++++++++++++++++++++++++*/
208
209 static void output_super(index_t node,double latitude,double longitude)
210 {
211 Node *nodep=LookupNode(OSMNodes,node,1);
212 Segment *segmentp;
213
214 if(!IsSuperNode(nodep))
215 return;
216
217 printf("%.6f %.6f n\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
218
219 segmentp=FirstSegment(OSMSegments,nodep,1);
220
221 do
222 {
223 if(IsSuperSegment(segmentp))
224 {
225 index_t othernode=OtherNode(segmentp,node);
226 double lat,lon;
227
228 GetLatLong(OSMNodes,othernode,&lat,&lon);
229
230 if(node>othernode || (lat<LatMin || lat>LatMax || lon<LonMin || lon>LonMax))
231 printf("%.6f %.6f s\n",radians_to_degrees(lat),radians_to_degrees(lon));
232 }
233
234 segmentp=NextSegment(OSMSegments,segmentp,node);
235 }
236 while(segmentp);
237 }
238
239
240 /*++++++++++++++++++++++++++++++++++++++
241 Output the data for one-way segments.
242
243 Nodes *nodes The set of nodes to use.
244
245 Segments *segments The set of segments to use.
246
247 Ways *ways The set of ways to use.
248
249 Relations *relations The set of relations to use.
250
251 double latmin The minimum latitude.
252
253 double latmax The maximum latitude.
254
255 double lonmin The minimum longitude.
256
257 double lonmax The maximum longitude.
258 ++++++++++++++++++++++++++++++++++++++*/
259
260 void OutputOneway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
261 {
262 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
263
264 OSMNodes=nodes;
265 OSMSegments=segments;
266 OSMWays=ways;
267 OSMRelations=relations;
268
269 LatMin=latmin;
270 LatMax=latmax;
271 LonMin=lonmin;
272 LonMax=lonmax;
273
274 /* Iterate through the nodes and process them */
275
276 find_all_nodes(nodes,(callback_t)output_oneway);
277 }
278
279
280 /*++++++++++++++++++++++++++++++++++++++
281 Process a single node and all connected one-way segments (called as a callback).
282
283 index_t node The node to output.
284
285 double latitude The latitude of the node.
286
287 double longitude The longitude of the node.
288 ++++++++++++++++++++++++++++++++++++++*/
289
290 static void output_oneway(index_t node,double latitude,double longitude)
291 {
292 Node *nodep=LookupNode(OSMNodes,node,1);
293 Segment *segmentp;
294
295 segmentp=FirstSegment(OSMSegments,nodep,1);
296
297 do
298 {
299 if(IsNormalSegment(segmentp))
300 {
301 index_t othernode=OtherNode(segmentp,node);
302
303 if(node>othernode)
304 {
305 double lat,lon;
306
307 GetLatLong(OSMNodes,othernode,&lat,&lon);
308
309 if(IsOnewayFrom(segmentp,node))
310 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
311 else if(IsOnewayFrom(segmentp,othernode))
312 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude));
313 }
314 }
315
316 segmentp=NextSegment(OSMSegments,segmentp,node);
317 }
318 while(segmentp);
319 }
320
321
322 /*++++++++++++++++++++++++++++++++++++++
323 Output the data for segments of a particular highway type.
324
325 Nodes *nodes The set of nodes to use.
326
327 Segments *segments The set of segments to use.
328
329 Ways *ways The set of ways to use.
330
331 Relations *relations The set of relations to use.
332
333 double latmin The minimum latitude.
334
335 double latmax The maximum latitude.
336
337 double lonmin The minimum longitude.
338
339 double lonmax The maximum longitude.
340
341 Highway highway The type of highway.
342 ++++++++++++++++++++++++++++++++++++++*/
343
344 void OutputHighway(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Highway highway)
345 {
346 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
347
348 OSMNodes=nodes;
349 OSMSegments=segments;
350 OSMWays=ways;
351 OSMRelations=relations;
352
353 LatMin=latmin;
354 LatMax=latmax;
355 LonMin=lonmin;
356 LonMax=lonmax;
357
358 /* Iterate through the nodes and process them */
359
360 highways=highway;
361
362 find_all_nodes(nodes,(callback_t)output_highway);
363 }
364
365
366 /*++++++++++++++++++++++++++++++++++++++
367 Process a single node and all connected one-way segments (called as a callback).
368
369 index_t node The node to output.
370
371 double latitude The latitude of the node.
372
373 double longitude The longitude of the node.
374 ++++++++++++++++++++++++++++++++++++++*/
375
376 static void output_highway(index_t node,double latitude,double longitude)
377 {
378 Node *nodep=LookupNode(OSMNodes,node,1);
379 Segment *segmentp;
380
381 segmentp=FirstSegment(OSMSegments,nodep,1);
382
383 do
384 {
385 if(IsNormalSegment(segmentp))
386 {
387 index_t othernode=OtherNode(segmentp,node);
388
389 if(node>othernode)
390 {
391 Way *wayp=LookupWay(OSMWays,segmentp->way,1);
392
393 if(HIGHWAY(wayp->type)==highways)
394 {
395 double lat,lon;
396
397 GetLatLong(OSMNodes,othernode,&lat,&lon);
398
399 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
400 }
401 }
402 }
403
404 segmentp=NextSegment(OSMSegments,segmentp,node);
405 }
406 while(segmentp);
407 }
408
409
410 /*++++++++++++++++++++++++++++++++++++++
411 Output the data for segments allowed for a paticular type of traffic.
412
413 Nodes *nodes The set of nodes to use.
414
415 Segments *segments The set of segments to use.
416
417 Ways *ways The set of ways to use.
418
419 Relations *relations The set of relations to use.
420
421 double latmin The minimum latitude.
422
423 double latmax The maximum latitude.
424
425 double lonmin The minimum longitude.
426
427 double lonmax The maximum longitude.
428
429 Transport transport The type of transport.
430 ++++++++++++++++++++++++++++++++++++++*/
431
432 void OutputTransport(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport)
433 {
434 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
435
436 OSMNodes=nodes;
437 OSMSegments=segments;
438 OSMWays=ways;
439 OSMRelations=relations;
440
441 LatMin=latmin;
442 LatMax=latmax;
443 LonMin=lonmin;
444 LonMax=lonmax;
445
446 /* Iterate through the nodes and process them */
447
448 transports=TRANSPORTS(transport);
449
450 find_all_nodes(nodes,(callback_t)output_transport);
451 }
452
453
454 /*++++++++++++++++++++++++++++++++++++++
455 Process a single node and all connected one-way segments (called as a callback).
456
457 index_t node The node to output.
458
459 double latitude The latitude of the node.
460
461 double longitude The longitude of the node.
462 ++++++++++++++++++++++++++++++++++++++*/
463
464 static void output_transport(index_t node,double latitude,double longitude)
465 {
466 Node *nodep=LookupNode(OSMNodes,node,1);
467 Segment *segmentp;
468
469 segmentp=FirstSegment(OSMSegments,nodep,1);
470
471 do
472 {
473 if(IsNormalSegment(segmentp))
474 {
475 index_t othernode=OtherNode(segmentp,node);
476
477 if(node>othernode)
478 {
479 Way *wayp=LookupWay(OSMWays,segmentp->way,1);
480
481 if(wayp->allow&transports)
482 {
483 double lat,lon;
484
485 GetLatLong(OSMNodes,othernode,&lat,&lon);
486
487 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
488 }
489 }
490 }
491
492 segmentp=NextSegment(OSMSegments,segmentp,node);
493 }
494 while(segmentp);
495 }
496
497
498 /*++++++++++++++++++++++++++++++++++++++
499 Output the data for nodes disallowed for a paticular type of traffic.
500
501 Nodes *nodes The set of nodes to use.
502
503 Segments *segments The set of segments to use.
504
505 Ways *ways The set of ways to use.
506
507 Relations *relations The set of relations to use.
508
509 double latmin The minimum latitude.
510
511 double latmax The maximum latitude.
512
513 double lonmin The minimum longitude.
514
515 double lonmax The maximum longitude.
516
517 Transport transport The type of transport.
518 ++++++++++++++++++++++++++++++++++++++*/
519
520 void OutputBarrier(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax,Transport transport)
521 {
522 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
523
524 OSMNodes=nodes;
525 OSMSegments=segments;
526 OSMWays=ways;
527 OSMRelations=relations;
528
529 LatMin=latmin;
530 LatMax=latmax;
531 LonMin=lonmin;
532 LonMax=lonmax;
533
534 /* Iterate through the nodes and process them */
535
536 transports=TRANSPORTS(transport);
537
538 find_all_nodes(nodes,(callback_t)output_barrier);
539 }
540
541
542 /*++++++++++++++++++++++++++++++++++++++
543 Process a single node (called as a callback).
544
545 index_t node The node to output.
546
547 double latitude The latitude of the node.
548
549 double longitude The longitude of the node.
550 ++++++++++++++++++++++++++++++++++++++*/
551
552 static void output_barrier(index_t node,double latitude,double longitude)
553 {
554 Node *nodep=LookupNode(OSMNodes,node,1);
555
556 if(!(nodep->allow&transports))
557 printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
558 }
559
560
561 /*++++++++++++++++++++++++++++++++++++++
562 Output the data for turn restrictions.
563
564 Nodes *nodes The set of nodes to use.
565
566 Segments *segments The set of segments to use.
567
568 Ways *ways The set of ways to use.
569
570 Relations *relations The set of relations to use.
571
572 double latmin The minimum latitude.
573
574 double latmax The maximum latitude.
575
576 double lonmin The minimum longitude.
577
578 double lonmax The maximum longitude.
579 ++++++++++++++++++++++++++++++++++++++*/
580
581 void OutputTurnRestrictions(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
582 {
583 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
584
585 OSMNodes=nodes;
586 OSMSegments=segments;
587 OSMWays=ways;
588 OSMRelations=relations;
589
590 LatMin=latmin;
591 LatMax=latmax;
592 LonMin=lonmin;
593 LonMax=lonmax;
594
595 /* Iterate through the nodes and process them */
596
597 find_all_nodes(nodes,(callback_t)output_turnrestriction);
598 }
599
600
601 /*++++++++++++++++++++++++++++++++++++++
602 Process a single node as the 'via' node for a turn restriction (called as a callback).
603
604 index_t node The node to output.
605
606 double latitude The latitude of the node.
607
608 double longitude The longitude of the node.
609 ++++++++++++++++++++++++++++++++++++++*/
610
611 static void output_turnrestriction(index_t node,double latitude,double longitude)
612 {
613 Node *nodep=LookupNode(OSMNodes,node,1);
614 index_t turnrelation=NO_RELATION;
615
616 if(!IsTurnRestrictedNode(nodep))
617 return;
618
619 turnrelation=FindFirstTurnRelation1(OSMRelations,node);
620
621 do
622 {
623 TurnRelation *relation;
624 Segment *from_segmentp,*to_segmentp;
625 index_t from_node,to_node;
626 double from_lat,from_lon,to_lat,to_lon;
627
628 relation=LookupTurnRelation(OSMRelations,turnrelation,1);
629
630 from_segmentp=LookupSegment(OSMSegments,relation->from,1);
631 to_segmentp =LookupSegment(OSMSegments,relation->to ,2);
632
633 from_node=OtherNode(from_segmentp,node);
634 to_node=OtherNode(to_segmentp,node);
635
636 GetLatLong(OSMNodes,from_node,&from_lat,&from_lon);
637 GetLatLong(OSMNodes,to_node,&to_lat,&to_lon);
638
639 printf("%.6f %.6f %.6f %.6f %.6f %.6f\n",radians_to_degrees(from_lat),radians_to_degrees(from_lon),
640 radians_to_degrees(latitude),radians_to_degrees(longitude),
641 radians_to_degrees(to_lat),radians_to_degrees(to_lon));
642
643 turnrelation=FindNextTurnRelation1(OSMRelations,turnrelation);
644 }
645 while(turnrelation!=NO_RELATION);
646 }
647
648
649 /*++++++++++++++++++++++++++++++++++++++
650 Output the data for speed limits.
651
652 Nodes *nodes The set of nodes to use.
653
654 Segments *segments The set of segments to use.
655
656 Ways *ways The set of ways to use.
657
658 Relations *relations The set of relations to use.
659
660 double latmin The minimum latitude.
661
662 double latmax The maximum latitude.
663
664 double lonmin The minimum longitude.
665
666 double lonmax The maximum longitude.
667 ++++++++++++++++++++++++++++++++++++++*/
668
669 void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
670 {
671 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
672
673 OSMNodes=nodes;
674 OSMSegments=segments;
675 OSMWays=ways;
676 OSMRelations=relations;
677
678 LatMin=latmin;
679 LatMax=latmax;
680 LonMin=lonmin;
681 LonMax=lonmax;
682
683 /* Iterate through the nodes and process them */
684
685 limit_type=SPEED_LIMIT;
686
687 find_all_nodes(nodes,(callback_t)output_limits);
688 }
689
690
691 /*++++++++++++++++++++++++++++++++++++++
692 Output the data for weight limits.
693
694 Nodes *nodes The set of nodes to use.
695
696 Segments *segments The set of segments to use.
697
698 Ways *ways The set of ways to use.
699
700 Relations *relations The set of relations to use.
701
702 double latmin The minimum latitude.
703
704 double latmax The maximum latitude.
705
706 double lonmin The minimum longitude.
707
708 double lonmax The maximum longitude.
709 ++++++++++++++++++++++++++++++++++++++*/
710
711 void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
712 {
713 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
714
715 OSMNodes=nodes;
716 OSMSegments=segments;
717 OSMWays=ways;
718 OSMRelations=relations;
719
720 LatMin=latmin;
721 LatMax=latmax;
722 LonMin=lonmin;
723 LonMax=lonmax;
724
725 /* Iterate through the nodes and process them */
726
727 limit_type=WEIGHT_LIMIT;
728
729 find_all_nodes(nodes,(callback_t)output_limits);
730 }
731
732
733 /*++++++++++++++++++++++++++++++++++++++
734 Output the data for height limits.
735
736 Nodes *nodes The set of nodes to use.
737
738 Segments *segments The set of segments to use.
739
740 Ways *ways The set of ways to use.
741
742 Relations *relations The set of relations to use.
743
744 double latmin The minimum latitude.
745
746 double latmax The maximum latitude.
747
748 double lonmin The minimum longitude.
749
750 double lonmax The maximum longitude.
751 ++++++++++++++++++++++++++++++++++++++*/
752
753 void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
754 {
755 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
756
757 OSMNodes=nodes;
758 OSMSegments=segments;
759 OSMWays=ways;
760 OSMRelations=relations;
761
762 LatMin=latmin;
763 LatMax=latmax;
764 LonMin=lonmin;
765 LonMax=lonmax;
766
767 /* Iterate through the nodes and process them */
768
769 limit_type=HEIGHT_LIMIT;
770
771 find_all_nodes(nodes,(callback_t)output_limits);
772 }
773
774
775 /*++++++++++++++++++++++++++++++++++++++
776 Output the data for width limits.
777
778 Nodes *nodes The set of nodes to use.
779
780 Segments *segments The set of segments to use.
781
782 Ways *ways The set of ways to use.
783
784 Relations *relations The set of relations to use.
785
786 double latmin The minimum latitude.
787
788 double latmax The maximum latitude.
789
790 double lonmin The minimum longitude.
791
792 double lonmax The maximum longitude.
793 ++++++++++++++++++++++++++++++++++++++*/
794
795 void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
796 {
797 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
798
799 OSMNodes=nodes;
800 OSMSegments=segments;
801 OSMWays=ways;
802 OSMRelations=relations;
803
804 LatMin=latmin;
805 LatMax=latmax;
806 LonMin=lonmin;
807 LonMax=lonmax;
808
809 /* Iterate through the nodes and process them */
810
811 limit_type=WIDTH_LIMIT;
812
813 find_all_nodes(nodes,(callback_t)output_limits);
814 }
815
816
817 /*++++++++++++++++++++++++++++++++++++++
818 Output the data for length limits.
819
820 Nodes *nodes The set of nodes to use.
821
822 Segments *segments The set of segments to use.
823
824 Ways *ways The set of ways to use.
825
826 Relations *relations The set of relations to use.
827
828 double latmin The minimum latitude.
829
830 double latmax The maximum latitude.
831
832 double lonmin The minimum longitude.
833
834 double lonmax The maximum longitude.
835 ++++++++++++++++++++++++++++++++++++++*/
836
837 void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,Relations *relations,double latmin,double latmax,double lonmin,double lonmax)
838 {
839 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
840
841 OSMNodes=nodes;
842 OSMSegments=segments;
843 OSMWays=ways;
844 OSMRelations=relations;
845
846 LatMin=latmin;
847 LatMax=latmax;
848 LonMin=lonmin;
849 LonMax=lonmax;
850
851 /* Iterate through the nodes and process them */
852
853 limit_type=LENGTH_LIMIT;
854
855 find_all_nodes(nodes,(callback_t)output_limits);
856 }
857
858
859 /*++++++++++++++++++++++++++++++++++++++
860 Process a single node as a speed, weight, height, length, width limit (called as a callback).
861
862 index_t node The node to output.
863
864 double latitude The latitude of the node.
865
866 double longitude The longitude of the node.
867 ++++++++++++++++++++++++++++++++++++++*/
868
869 static void output_limits(index_t node,double latitude,double longitude)
870 {
871 Node *nodep=LookupNode(OSMNodes,node,1);
872 Segment *segmentp,segmentps[MAX_SEG_PER_NODE];
873 int limits[MAX_SEG_PER_NODE];
874 int count=0;
875 int i,j,same=0;
876
877 segmentp=FirstSegment(OSMSegments,nodep,1);
878
879 do
880 {
881 if(IsNormalSegment(segmentp) && count<MAX_SEG_PER_NODE)
882 {
883 Way *wayp=LookupWay(OSMWays,segmentp->way,1);
884
885 segmentps[count]=*segmentp;
886
887 switch(limit_type)
888 {
889 case SPEED_LIMIT: limits[count]=wayp->speed; break;
890 case WEIGHT_LIMIT: limits[count]=wayp->weight; break;
891 case HEIGHT_LIMIT: limits[count]=wayp->height; break;
892 case WIDTH_LIMIT: limits[count]=wayp->width; break;
893 case LENGTH_LIMIT: limits[count]=wayp->length; break;
894 }
895
896 if(limits[count] || HIGHWAY(wayp->type)<Way_Track)
897 count++;
898 }
899
900 segmentp=NextSegment(OSMSegments,segmentp,node);
901 }
902 while(segmentp);
903
904 /* Nodes with only one limit are not interesting */
905
906 if(count==1)
907 return;
908
909 /* Nodes with all segments the same limit are not interesting */
910
911 same=0;
912 for(j=0;j<count;j++)
913 if(limits[0]==limits[j])
914 same++;
915
916 if(same==count)
917 return;
918
919 /* Display the interesting limits */
920
921 printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
922
923 for(i=0;i<count;i++)
924 {
925 same=0;
926 for(j=0;j<count;j++)
927 if(limits[i]==limits[j])
928 same++;
929
930 if(count==2 || same!=(count-1))
931 {
932 double lat,lon;
933
934 GetLatLong(OSMNodes,OtherNode(&segmentps[i],node),&lat,&lon);
935
936 switch(limit_type)
937 {
938 case SPEED_LIMIT:
939 printf("%.6f %.6f %d\n",radians_to_degrees(lat),radians_to_degrees(lon),speed_to_kph(limits[i]));
940 break;
941 case WEIGHT_LIMIT:
942 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),weight_to_tonnes(limits[i]));
943 break;
944 case HEIGHT_LIMIT:
945 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),height_to_metres(limits[i]));
946 break;
947 case WIDTH_LIMIT:
948 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),width_to_metres(limits[i]));
949 break;
950 case LENGTH_LIMIT:
951 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),length_to_metres(limits[i]));
952 break;
953 }
954 }
955 }
956 }
957
958
959 /*++++++++++++++++++++++++++++++++++++++
960 A function to iterate through all nodes and call a callback function for each one.
961
962 Nodes *nodes The set of nodes to use.
963
964 callback_t callback The callback function for each node.
965 ++++++++++++++++++++++++++++++++++++++*/
966
967 static void find_all_nodes(Nodes *nodes,callback_t callback)
968 {
969 ll_bin_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->file.latzero;
970 ll_bin_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero;
971 ll_bin_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero;
972 ll_bin_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero;
973 ll_bin_t latb,lonb;
974 index_t i,index1,index2;
975
976 /* Loop through all of the nodes. */
977
978 for(latb=latminbin;latb<=latmaxbin;latb++)
979 for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
980 {
981 ll_bin2_t llbin=lonb*nodes->file.latbins+latb;
982
983 if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins))
984 continue;
985
986 index1=LookupNodeOffset(nodes,llbin);
987 index2=LookupNodeOffset(nodes,llbin+1);
988
989 for(i=index1;i<index2;i++)
990 {
991 Node *nodep=LookupNode(nodes,i,1);
992
993 double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(nodep->latoffset));
994 double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(nodep->lonoffset));
995
996 if(lat>LatMin && lat<LatMax && lon>LonMin && lon<LonMax)
997 (*callback)(i,lat,lon);
998 }
999 }
1000 }

Properties

Name Value
cvs:description Functions for data visualisation.