Check out the latest version of Routino: svn co http://routino.org/svn/trunk routino
Contents of /trunk/src/visualiser.c
Parent Directory
|
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)
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. |