1 /***************************************
2 $Header: /home/amb/routino/src/RCS/visualiser.c,v 1.10 2010/07/26 18:17:20 amb Exp $
4 Extract data from Routino.
6 Part of the Routino routing software.
7 ******************/ /******************
8 This file Copyright 2008-2010 Andrew M. Bishop
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.
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.
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 ***************************************/
30 #include "visualiser.h"
37 #define WEIGHT_LIMIT 2
38 #define HEIGHT_LIMIT 3
40 #define LENGTH_LIMIT 5
44 typedef void (*callback_t)(index_t node,double latitude,double longitude);
48 static Nodes *OSMNodes;
49 static Segments *OSMSegments;
57 static int limit_type=0;
61 static void find_all_nodes(Nodes *nodes,callback_t callback);
62 static void output_junctions(index_t node,double latitude,double longitude);
63 static void output_super(index_t node,double latitude,double longitude);
64 static void output_oneway(index_t node,double latitude,double longitude);
65 static void output_limits(index_t node,double latitude,double longitude);
68 /*++++++++++++++++++++++++++++++++++++++
69 Output the data for junctions.
71 Nodes *nodes The set of nodes to use.
73 Segments *segments The set of segments to use.
75 Ways *ways The set of ways to use.
77 double latmin The minimum latitude.
79 double latmax The maximum latitude.
81 double lonmin The minimum longitude.
83 double lonmax The maximum longitude.
84 ++++++++++++++++++++++++++++++++++++++*/
86 void OutputJunctions(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
88 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
99 /* Iterate through the nodes and process them */
101 find_all_nodes(nodes,(callback_t)output_junctions);
105 /*++++++++++++++++++++++++++++++++++++++
106 Process a single node (called as a callback).
108 index_t node The node to output.
110 double latitude The latitude of the node.
112 double longitude The longitude of the node.
113 ++++++++++++++++++++++++++++++++++++++*/
115 static void output_junctions(index_t node,double latitude,double longitude)
119 int count=0,difference=0;
121 segment=FirstSegment(OSMSegments,OSMNodes,node);
122 firstway=LookupWay(OSMWays,segment->way,1);
126 Way *way=LookupWay(OSMWays,segment->way,2);
128 if(IsNormalSegment(segment))
131 if(WaysCompare(firstway,way))
134 segment=NextSegment(OSMSegments,segment,node);
138 if(count!=2 || difference)
139 printf("%.6f %.6f %d\n",radians_to_degrees(latitude),radians_to_degrees(longitude),count);
143 /*++++++++++++++++++++++++++++++++++++++
144 Output the data for super-nodes and super-segments.
146 Nodes *nodes The set of nodes to use.
148 Segments *segments The set of segments to use.
150 Ways *ways The set of ways to use.
152 double latmin The minimum latitude.
154 double latmax The maximum latitude.
156 double lonmin The minimum longitude.
158 double lonmax The maximum longitude.
159 ++++++++++++++++++++++++++++++++++++++*/
161 void OutputSuper(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
163 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
166 OSMSegments=segments;
174 /* Iterate through the nodes and process them */
176 find_all_nodes(nodes,(callback_t)output_super);
180 /*++++++++++++++++++++++++++++++++++++++
181 Process a single node (called as a callback).
183 index_t node The node to output.
185 double latitude The latitude of the node.
187 double longitude The longitude of the node.
188 ++++++++++++++++++++++++++++++++++++++*/
190 static void output_super(index_t node,double latitude,double longitude)
194 if(!IsSuperNode(OSMNodes,node))
197 printf("%.6f %.6f n\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
199 segment=FirstSegment(OSMSegments,OSMNodes,node);
203 if(IsSuperSegment(segment))
205 index_t othernode=OtherNode(segment,node);
208 GetLatLong(OSMNodes,othernode,&lat,&lon);
210 if(node>othernode || (lat<LatMin || lat>LatMax || lon<LonMin || lon>LonMax))
211 printf("%.6f %.6f s\n",radians_to_degrees(lat),radians_to_degrees(lon));
214 segment=NextSegment(OSMSegments,segment,node);
220 /*++++++++++++++++++++++++++++++++++++++
221 Output the data for one-way segments.
223 Nodes *nodes The set of nodes to use.
225 Segments *segments The set of segments to use.
227 Ways *ways The set of ways to use.
229 double latmin The minimum latitude.
231 double latmax The maximum latitude.
233 double lonmin The minimum longitude.
235 double lonmax The maximum longitude.
236 ++++++++++++++++++++++++++++++++++++++*/
238 void OutputOneway(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
240 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
243 OSMSegments=segments;
251 /* Iterate through the nodes and process them */
253 find_all_nodes(nodes,(callback_t)output_oneway);
257 /*++++++++++++++++++++++++++++++++++++++
258 Process a single node (called as a callback).
260 index_t node The node to output.
262 double latitude The latitude of the node.
264 double longitude The longitude of the node.
265 ++++++++++++++++++++++++++++++++++++++*/
267 static void output_oneway(index_t node,double latitude,double longitude)
271 segment=FirstSegment(OSMSegments,OSMNodes,node);
275 if(IsNormalSegment(segment))
277 index_t othernode=OtherNode(segment,node);
283 GetLatLong(OSMNodes,othernode,&lat,&lon);
285 if(IsOnewayFrom(segment,node))
286 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude),radians_to_degrees(lat),radians_to_degrees(lon));
287 else if(IsOnewayFrom(segment,othernode))
288 printf("%.6f %.6f %.6f %.6f\n",radians_to_degrees(lat),radians_to_degrees(lon),radians_to_degrees(latitude),radians_to_degrees(longitude));
292 segment=NextSegment(OSMSegments,segment,node);
298 /*++++++++++++++++++++++++++++++++++++++
299 Output the data for speed limits.
301 Nodes *nodes The set of nodes to use.
303 Segments *segments The set of segments to use.
305 Ways *ways The set of ways to use.
307 double latmin The minimum latitude.
309 double latmax The maximum latitude.
311 double lonmin The minimum longitude.
313 double lonmax The maximum longitude.
314 ++++++++++++++++++++++++++++++++++++++*/
316 void OutputSpeedLimits(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
318 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
321 OSMSegments=segments;
329 /* Iterate through the nodes and process them */
331 limit_type=SPEED_LIMIT;
333 find_all_nodes(nodes,(callback_t)output_limits);
337 /*++++++++++++++++++++++++++++++++++++++
338 Output the data for weight limits.
340 Nodes *nodes The set of nodes to use.
342 Segments *segments The set of segments to use.
344 Ways *ways The set of ways to use.
346 double latmin The minimum latitude.
348 double latmax The maximum latitude.
350 double lonmin The minimum longitude.
352 double lonmax The maximum longitude.
353 ++++++++++++++++++++++++++++++++++++++*/
355 void OutputWeightLimits(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
357 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
360 OSMSegments=segments;
368 /* Iterate through the nodes and process them */
370 limit_type=WEIGHT_LIMIT;
372 find_all_nodes(nodes,(callback_t)output_limits);
376 /*++++++++++++++++++++++++++++++++++++++
377 Output the data for height limits.
379 Nodes *nodes The set of nodes to use.
381 Segments *segments The set of segments to use.
383 Ways *ways The set of ways to use.
385 double latmin The minimum latitude.
387 double latmax The maximum latitude.
389 double lonmin The minimum longitude.
391 double lonmax The maximum longitude.
392 ++++++++++++++++++++++++++++++++++++++*/
394 void OutputHeightLimits(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
396 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
399 OSMSegments=segments;
407 /* Iterate through the nodes and process them */
409 limit_type=HEIGHT_LIMIT;
411 find_all_nodes(nodes,(callback_t)output_limits);
415 /*++++++++++++++++++++++++++++++++++++++
416 Output the data for width limits.
418 Nodes *nodes The set of nodes to use.
420 Segments *segments The set of segments to use.
422 Ways *ways The set of ways to use.
424 double latmin The minimum latitude.
426 double latmax The maximum latitude.
428 double lonmin The minimum longitude.
430 double lonmax The maximum longitude.
431 ++++++++++++++++++++++++++++++++++++++*/
433 void OutputWidthLimits(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
435 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
438 OSMSegments=segments;
446 /* Iterate through the nodes and process them */
448 limit_type=WIDTH_LIMIT;
450 find_all_nodes(nodes,(callback_t)output_limits);
454 /*++++++++++++++++++++++++++++++++++++++
455 Output the data for length limits.
457 Nodes *nodes The set of nodes to use.
459 Segments *segments The set of segments to use.
461 Ways *ways The set of ways to use.
463 double latmin The minimum latitude.
465 double latmax The maximum latitude.
467 double lonmin The minimum longitude.
469 double lonmax The maximum longitude.
470 ++++++++++++++++++++++++++++++++++++++*/
472 void OutputLengthLimits(Nodes *nodes,Segments *segments,Ways *ways,double latmin,double latmax,double lonmin,double lonmax)
474 /* Use local variables so that the callback doesn't need to pass them backwards and forwards */
477 OSMSegments=segments;
485 /* Iterate through the nodes and process them */
487 limit_type=LENGTH_LIMIT;
489 find_all_nodes(nodes,(callback_t)output_limits);
493 /*++++++++++++++++++++++++++++++++++++++
494 Process a single node (called as a callback).
496 index_t node The node to output.
498 double latitude The latitude of the node.
500 double longitude The longitude of the node.
501 ++++++++++++++++++++++++++++++++++++++*/
503 static void output_limits(index_t node,double latitude,double longitude)
505 Segment *segment,*segments[16];
511 segment=FirstSegment(OSMSegments,OSMNodes,node);
515 if(IsNormalSegment(segment) && count<16)
517 ways [count]=LookupWay(OSMWays,segment->way,1);
518 segments[count]=segment;
522 case SPEED_LIMIT: limits[count]=ways[count]->speed; break;
523 case WEIGHT_LIMIT: limits[count]=ways[count]->weight; break;
524 case HEIGHT_LIMIT: limits[count]=ways[count]->height; break;
525 case WIDTH_LIMIT: limits[count]=ways[count]->width; break;
526 case LENGTH_LIMIT: limits[count]=ways[count]->length; break;
529 if(limits[count] || ways[count]->type<Way_Track)
533 segment=NextSegment(OSMSegments,segment,node);
537 /* Nodes with only one limit are not interesting */
542 /* Nodes with all segments the same limit is not interesting */
546 if(limits[0]==limits[j])
552 /* Display the interesting speed limits */
554 printf("%.6f %.6f\n",radians_to_degrees(latitude),radians_to_degrees(longitude));
560 if(limits[i]==limits[j])
563 if(count==2 || same!=(count-1))
567 GetLatLong(OSMNodes,OtherNode(segments[i],node),&lat,&lon);
572 printf("%.6f %.6f %d\n",radians_to_degrees(lat),radians_to_degrees(lon),speed_to_kph(limits[i]));
575 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),weight_to_tonnes(limits[i]));
578 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),height_to_metres(limits[i]));
581 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),width_to_metres(limits[i]));
584 printf("%.6f %.6f %.1f\n",radians_to_degrees(lat),radians_to_degrees(lon),length_to_metres(limits[i]));
592 /*++++++++++++++++++++++++++++++++++++++
593 A function to iterate through all nodes and call a callback function for each one.
595 Nodes *nodes The list of nodes to process.
597 callback_t callback The callback function for each node.
598 ++++++++++++++++++++++++++++++++++++++*/
600 static void find_all_nodes(Nodes *nodes,callback_t callback)
602 int32_t latminbin=latlong_to_bin(radians_to_latlong(LatMin))-nodes->file.latzero;
603 int32_t latmaxbin=latlong_to_bin(radians_to_latlong(LatMax))-nodes->file.latzero;
604 int32_t lonminbin=latlong_to_bin(radians_to_latlong(LonMin))-nodes->file.lonzero;
605 int32_t lonmaxbin=latlong_to_bin(radians_to_latlong(LonMax))-nodes->file.lonzero;
607 index_t i,index1,index2;
609 /* Loop through all of the nodes. */
611 for(latb=latminbin;latb<=latmaxbin;latb++)
612 for(lonb=lonminbin;lonb<=lonmaxbin;lonb++)
614 llbin=lonb*nodes->file.latbins+latb;
616 if(llbin<0 || llbin>(nodes->file.latbins*nodes->file.lonbins))
619 index1=LookupNodeOffset(nodes,llbin);
620 index2=LookupNodeOffset(nodes,llbin+1);
622 for(i=index1;i<index2;i++)
624 Node *node=LookupNode(nodes,i,1);
626 double lat=latlong_to_radians(bin_to_latlong(nodes->file.latzero+latb)+off_to_latlong(node->latoffset));
627 double lon=latlong_to_radians(bin_to_latlong(nodes->file.lonzero+lonb)+off_to_latlong(node->lonoffset));
629 if(lat>LatMin && lat<LatMax && lon>LonMin && lon<LonMax)
630 (*callback)(i,lat,lon);