source: subversion/applications/utils/gary68/onewaycheck.pl @ 34621

Last change on this file since 34621 was 19249, checked in by gary68, 10 years ago

onewaycheck 1.3 - only highways for cars will be checked - can be
configured

  • Property svn:executable set to *
File size: 10.4 KB
Line 
1#
2# onewaycheck by gary68
3#
4#
5# Copyright (C) 2009, Gerhard Schwanz
6#
7# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the
8# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
14#
15#
16
17use strict ;
18use warnings ;
19
20use OSM::osm ;
21use File::stat;
22use Time::localtime;
23
24my $programName = "onewaycheck" ; 
25my $usage = "onewaycheck.pl file.osm out.htm" ;
26my $version = "1.3" ;
27my @checkWays = qw (motorway motorway_link trunk trunk_link primary primary_link secondary secondary_link tertiary residential service unclassified road living_street ) ;
28
29
30my $wayId ;
31my $wayUser ;
32my @wayNodes ;
33my @wayTags ;
34my $nodeId ;
35my $nodeUser ;
36my $nodeLat ;
37my $nodeLon ;
38my @nodeTags ;
39my $aRef1 ;
40my $aRef2 ;
41my $wayCount = 0 ;
42
43my $oneway ;
44my $reverse ;
45my $problems = 0 ;
46my $numCritical = 0 ;
47
48my %to = () ;
49my %from = () ;
50my %wayNodeNumber = () ;
51my %nodeWays = () ;
52my %neededWayNodes = () ;
53
54my %criticalNodes = () ;
55my %nodesLon ;
56my %nodesLat ;
57
58my $time0 = time() ;
59my $time1 ;
60my $i ;
61my $key ;
62my $num ;
63my $oneways = 0 ;
64
65my $APIcount = 0 ;
66my $APIerrors = 0 ;
67my $APIrejections = 0 ;
68
69my $html ;
70my $gpx ;
71my $osmName ;
72my $htmlName ;
73
74
75###############
76# get parameter
77###############
78$osmName = shift||'';
79if (!$osmName)
80{
81        die (print $usage, "\n");
82}
83
84$htmlName = shift||'';
85if (!$htmlName)
86{
87        die (print $usage, "\n");
88}
89
90my $gpxName = $htmlName ;
91$gpxName =~ s/htm/gpx/ ;
92
93
94print "\n$programName $version for file $osmName\n" ;
95print "Check ways: @checkWays\n" ;
96
97#####################
98# open and init files
99#####################
100
101openOsmFile ($osmName) ;
102
103
104######################
105# skip all nodes first
106######################
107print $programName, " ", $osmName, " pass0: skipping nodes...\n" ;
108skipNodes () ;
109
110
111#######################################
112#
113#######################################
114print $programName, " ", $osmName, " pass0: processing ways...\n" ;
115($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
116if ($wayId != -1) {
117        @wayNodes = @$aRef1 ;
118        @wayTags = @$aRef2 ;
119}
120
121while ($wayId != -1) {
122        if (scalar (@wayNodes) >= 2) {
123                $oneway = 0 ; my $highway = 0 ;
124                foreach my $wt (@wayTags) {
125                        if ($wt->[0] eq "highway") { 
126                                my $found = 0 ;
127                                foreach my $hw (@checkWays) {
128                                        if ($wt->[1] eq $hw) { $found = 1 ; }
129                                }
130                                if ($found) { $highway = 1 ; }
131                        } 
132                        if ( ($wt->[0] eq "junction") and ($wt->[1] eq "roundabout") ) { $highway = 1 ; } 
133                        if ($wt->[0] eq "oneway") { $oneway = 1 ; }
134                }
135                if (($highway == 1) and ($oneway == 1) ) { 
136                        $oneways++ ;
137                        foreach my $node (@wayNodes) {
138                                $neededWayNodes{$node} = 1 ;
139                        }
140                }
141        }
142        else {
143                #print "invalid way (one node only): ", $wayId, "\n" ;
144        }
145
146        ($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
147        if ($wayId != -1) {
148                @wayNodes = @$aRef1 ;
149                @wayTags = @$aRef2 ;
150        }
151}
152
153closeOsmFile () ;
154
155print "$oneways oneways found.\n" ;
156
157openOsmFile ($osmName) ;
158
159
160######################
161# skip all nodes first
162######################
163print $programName, " ", $osmName, " pass1: skipping nodes...\n" ;
164skipNodes () ;
165
166
167#######################################
168#
169#######################################
170print $programName, " ", $osmName, " pass1: processing ways...\n" ;
171$oneway = 0 ;
172$reverse = 0 ;
173($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
174if ($wayId != -1) {
175        @wayNodes = @$aRef1 ;
176        @wayTags = @$aRef2 ;
177}
178
179while ($wayId != -1) {
180        $wayCount++ ;
181
182        if (scalar (@wayNodes) >= 2) {
183                $oneway = 0 ; $reverse = 0 ; my $highway = 0 ;
184                foreach my $wt (@wayTags) {
185
186                        if ($wt->[0] eq "highway") { 
187                                my $found = 0 ;
188                                foreach my $hw (@checkWays) {
189                                        if ($wt->[1] eq $hw) { $found = 1 ; }
190                                }
191                                if ($found) { $highway = 1 ; }
192                        } 
193
194                        if ($wt->[0] eq "amenity" and $wt->[1] eq "parking" ) { $highway = 1 ; } 
195                        if ($wt->[0] eq "junction" and $wt->[1] eq "roundabout" ) { $highway = 1 ; } 
196
197                        if ($wt->[0] eq "oneway" and $wt->[1] eq "true") { $oneway = 1 ; }
198                        if ($wt->[0] eq "oneway" and $wt->[1] eq "false") { $oneway = 0 ; }
199                        if ($wt->[0] eq "oneway" and $wt->[1] eq "yes") { $oneway = 1 ; }
200                        if ($wt->[0] eq "oneway" and $wt->[1] eq "no") { $oneway = 0 ; }
201                        if ($wt->[0] eq "oneway" and $wt->[1] eq "1") { $oneway = 1 ; }
202                        if ($wt->[0] eq "oneway" and $wt->[1] eq "-1") { $oneway = 1 ; $reverse = 1 ; }
203                }
204                if ($highway) {
205                        if ( ($oneway) and ($reverse)) { @wayNodes = reverse @wayNodes ; } 
206       
207                        for (my $i = 0; $i <= $#wayNodes; $i++) {
208                                if (defined $neededWayNodes{$wayNodes[$i]}) {
209                                        $to{$wayNodes[$i]} ++ ;
210                                        $from{$wayNodes[$i]} ++ ;
211                                        push @{$nodeWays{$wayNodes[$i]}}, $wayId ;
212                                        $wayNodeNumber{$wayId} = scalar (@wayNodes) ;
213                                        if ( ($i == 0) and ($oneway) ) {
214                                                $to{$wayNodes[$i]} -- ;
215                                        }
216                                        if ( ($i == $#wayNodes) and ($oneway) ) {
217                                                $from{$wayNodes[$i]} -- ;
218                                        }
219                                }
220                        }               
221                }
222        }
223        else {
224                #print "invalid way (one node only): ", $wayId, "\n" ;
225        }
226
227        ($wayId, $wayUser, $aRef1, $aRef2) = getWay2 () ;
228        if ($wayId != -1) {
229                @wayNodes = @$aRef1 ;
230                @wayTags = @$aRef2 ;
231        }
232}
233
234closeOsmFile () ;
235
236#####################
237# find critical nodes
238#####################
239print $programName, " ", $osmName, " pass1: find critical nodes (incl. API calls)...\n" ;
240%criticalNodes = () ;
241
242foreach my $key (keys %to) {
243        my $allWaysOK = 1 ;
244        if ( ( ($to{$key} > 0) and ($from{$key} == 0) ) or 
245                ( ($to{$key} == 0) and ($from{$key} > 0) ) ) {
246                foreach my $wayId (@{$nodeWays{$key}}) {
247                        my $APIok = 1 ;
248                        # print "request API data for way $wayId...\n" ;
249                        $APIcount++ ;
250                        sleep (1) ; # don't stress API
251                        my ($id, $u, @nds, @tags, $ndsRef, $tagRef) ;
252                        ($id, $u, $ndsRef, $tagRef) = APIgetWay ($wayId) ;
253                        # print "API request finished.\n" ;
254                        @nds = @$ndsRef ; @tags = @$tagRef ;
255                        if ($id == 0) { $APIerrors++ ; }
256                        if ( ( $wayNodeNumber{$wayId} != scalar @nds) and ($wayId == $id) ) { 
257                                $APIok = 0 ;
258                                $APIrejections++ ;
259                                # print "WARNING: $key ignored because way node count of osm file not equal to API node count\n" ;
260                        }
261                        if ($APIok == 0) { $allWaysOK = 0 ; }
262                }
263
264                if ($allWaysOK == 1) { 
265                        $criticalNodes{$key} = 1 ;
266                }
267        }
268}
269
270
271######################
272# get node information
273######################
274print $programName, " ", $osmName, " pass2: get node information...\n" ;
275openOsmFile ($osmName) ;
276
277($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
278if ($nodeId != -1) {
279        #@nodeTags = @$aRef1 ;
280}
281
282while ($nodeId != -1) {
283        #print "test nodeID $nodeId\n" ;
284        if (defined $criticalNodes{$nodeId}) {
285                $nodesLon{$nodeId} = $nodeLon ;
286                $nodesLat{$nodeId} = $nodeLat ;
287                #print "node info read $nodeLon $nodeLat\n" ;
288        }
289
290        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode2 () ;
291        if ($nodeId != -1) {
292                #@nodeTags = @$aRef1 ;
293        }
294}
295
296closeOsmFile () ;
297print $programName, " ", $osmName, " pass2: nodes read...\n" ;
298
299
300
301
302$time1 = time () ;
303
304
305#######################
306# print info to console
307#######################
308
309print "\n", $programName, " ", $osmName, " number ways: $wayCount\n" ;
310$numCritical = scalar (keys %criticalNodes) ;
311print $programName, " ", $osmName, " critical nodes: ", $numCritical, "\n\n" ;
312print $programName, " ", $osmName, " write HTML tables...\n" ;
313
314
315
316
317##############################
318# PRINT HTML / GPX INFOS NODES
319##############################
320open ($gpx, ">", $gpxName) || die ("Can't open gpx output file") ;
321printGPXHeader ($gpx) ;
322
323
324open ($html, ">", $htmlName) || die ("Can't open html output file") ;
325printHTMLHeader ($html, "OnewayCheck by Gary68") ;
326print $html "<H1>OnewayCheck by Gary68</H1>\n" ;
327print $html "<p>Version ", $version, "</p>\n" ;
328print $html "<p>Check ways: @checkWays</p>\n" ;
329print $html "<H2>Statistics</H2>\n" ;
330print $html "<p>", stringFileInfo ($osmName), "</p>\n" ;
331print $html "<p>number ways: $wayCount<br>\n" ;
332$numCritical = scalar (keys %criticalNodes) ;
333print $html "critical nodes: ", $numCritical, "</p>\n" ;
334print $html "<p>$APIcount API calls</p>" ;
335print $html "<p>$APIerrors API errors</p>" ;
336print $html "<p>$APIrejections API rejections</p>" ;
337
338print $html "<H2>Critical Nodes</H2>\n" ;
339print $html "<table border=\"1\">\n";
340print $html "<tr>\n" ;
341print $html "<th>Line</th>\n" ;
342print $html "<th>NodeId</th>\n" ;
343# print $html "<th>Ways</th>\n" ;
344print $html "<th>OSM</th>\n" ;
345print $html "<th>OSB</th>\n" ;
346print $html "<th>JOSM</th>\n" ;
347print $html "<th>Mapnik</th>\n" ;
348print $html "<th>Osmarender</th>\n" ;
349print $html "</tr>\n" ;
350$i = 0 ;
351#print @criticalNodes, "\n" ;
352foreach $nodeId (keys %criticalNodes) {
353        $i++ ;
354        print $html "<tr>\n" ;
355        print $html "<td>", $i , "</td>\n" ;
356        print $html "<td>", historyLink ("node", $nodeId) , "</td>\n" ;
357
358#       print $html "<td>" ;
359#       foreach (@{$endNodeWays{$nodeId}}) {
360#               print $html historyLink ("way", $_), " " ;
361#       }
362#       print $html "</td>\n" ;
363
364        print $html "<td>", osmLink ($nodesLon{$nodeId}, $nodesLat{$nodeId}, 16) , "</td>\n" ;
365        print $html "<td>", osbLink ($nodesLon{$nodeId}, $nodesLat{$nodeId}, 16) , "</td>\n" ;
366        print $html "<td>", josmLinkSelectNode ($nodesLon{$nodeId}, $nodesLat{$nodeId}, 0.01, $nodeId), "</td>\n" ;
367        print $html "<td>", picLinkMapnik ($nodesLon{$nodeId}, $nodesLat{$nodeId}, 16), "</td>\n" ;
368        print $html "<td>", picLinkOsmarender ($nodesLon{$nodeId}, $nodesLat{$nodeId}, 16), "</td>\n" ;
369        print $html "</tr>\n" ;
370
371        # GPX
372        my $text = "OnewayCheck - " . $nodeId . " problem with oneway road" ;
373        printGPXWaypoint ($gpx, $nodesLon{$nodeId}, $nodesLat{$nodeId}, $text) ;
374
375}
376print $html "</table>\n" ;
377print $html "<p>$i lines total</p>\n" ;
378
379
380
381
382print $html "<p>", stringTimeSpent ($time1-$time0), "</p>\n" ;
383
384
385########
386# FINISH
387########
388
389printHTMLFoot ($html) ;
390close ($html) ;
391
392printGPXFoot ($gpx) ;
393close ($gpx) ;
394
395print "\n$APIcount API calls\n" ;
396print "$APIerrors API errors\n" ;
397print "$APIrejections API rejections\n" ;
398
399print $programName, " ", $osmName, " FINISHED after ", stringTimeSpent ($time1-$time0), "\n\n" ;
400
Note: See TracBrowser for help on using the repository browser.