source: subversion/applications/utils/gary68/areacheck.pl @ 30595

Last change on this file since 30595 was 17897, checked in by gary68, 10 years ago

areacheck now ignores ways that are part of a relation

  • Property svn:executable set to *
File size: 11.6 KB
Line 
1#
2# areacheck by gary68
3#
4#
5#
6#
7# Copyright (C) 2008, 2009, Gerhard Schwanz
8#
9# 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
10# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
16#
17#
18# 1.0 B 003
19# - added lots of tags
20#
21# 1.0 B 004
22#
23# 1.0 B 005
24# - hash get node info
25# - additional gpx output
26#
27# 1.1
28# - add more links to HTML
29#
30# 3.0
31# - online api support
32#
33# 3.2
34# - check if way is part of relation, then omit
35#
36
37use strict ;
38use warnings ;
39
40use OSM::osm 4.9 ;
41
42my @areas = qw (area:yes waterway:riverbank aeroway:terminal aeroway:apron man_made:surveillance building:yes leisure:park leisure:playground
43        amenity:bus_station amenity:college
44        amenity:ferry_terminal amenity:hospital amenity:parking amenity:school amenity:university tourism:attraction tourism:zoo tourism:museum
45        landuse:forest landuse:residential landuse:industrial landuse:cemetery natural:glacier natural:wood natural:water ) ;
46
47#my @areas = qw (area:yes waterway:riverbank waterway:dock railway:turntable landuse:railway aeroway:terminal aeroway:apron
48#       aerialway:station power:station power:sub_station man_made:reservoir_covered man_made:surveillance
49#       man_made:wastewater_plant man_made:watermill man_made:water_works building:yes
50#       leisure:golf_course leisure:sports_center leisure:stadium leisure:track leisure:pitch leisure:water_park leisure:marina
51#       leisure:fishing leisure:nature_reserve leisure:park leisure:playground leisure:garden leisure:common
52#       amenity:bicycle_parking amenity:bus_station amenity:car_rental amenity:car_sharing amenity:college
53#       amenity:ferry_terminal amenity:fountain amenity:hospital amenity:kindergarten amenity:parking amenity:place_of_worship
54#       amenity:public_building amenity:school amenity:taxi amenity:townhall amenity:university amenity:verterinary
55#       shop:kiosk shop:supermarket tourism:chalet tourism:camp_site tourism:caravan_site tourism:picnic_site tourism:theme_park
56#       tourism:attraction tourism:zoo tourism:museum historic:archeological_site historic:ruins historic:battlefield historic:wreck
57#       landuse:farm landuse:farm_yard landuse:quarry landuse:landfill landuse:basin landuse:reservoir landuse:forest
58#       landuse:allotments landuse:residential landuse:retail landuse:commercial landuse:industrial landuse:brownfield landuse:greenfield
59#       landuse:railway landuse:construction landuse:military landuse:cemetery landuse:meadow landuse:village_green
60#       landuse:recreation_ground military:airfield military:barracks military:danger_area military:range military:naval_base
61#       natural:glacier natural:scree natural:scrub natural:fell natural:heath natural:wood natural:marsh natural:wetland
62#       natural:water natural:mud natural:beach natural:bay natural:land natural:cave_entrance
63#       boundary:administrative boundary:civil boundary:political boundary:national_park
64#       place:region place:county place:city place:town place:village place:hamlet place:suburb place:locality place:island) ;
65
66
67my $program = "areacheck.pl" ;
68my $version = "3.2" ;
69my $usage = $program . " file.osm out.htm out.gpx" ;
70
71my $wayId ;
72my $wayId2 ;
73my $wayUser ;
74my @wayNodes ;
75my @wayTags ;
76my $nodeId ;
77my $nodeId2 ;
78my $nodeUser ;
79my $nodeLat ;
80my $nodeLon ;
81my @nodeTags ;
82my $aRef1 ;
83my $aRef2 ;
84my $relationId ;
85my $relationUser ;
86my @relationMembers ;
87my @relationTags ;
88
89my $wayCount = 0 ;
90my $areaCount = 0 ;
91my $areaOpenCount = 0 ;
92
93my $time0 = time() ; my $time1 ;
94my $i ;
95my $key ;
96my $num ;
97my $tag1 ; my $tag2 ;
98
99my $APIcount = 0 ;
100my $APIerrors = 0 ;
101my $APIrejected = 0 ;
102
103my $html ;
104my $gpx ;
105my $osmName ;
106my $htmlName ;
107my $gpxName ;
108
109
110my @open ;
111my @neededNodes ;
112my %neededNodesHash ;
113my %lon ;
114my %lat ;
115my %wayStart ;
116my %wayEnd ;
117my %openWayTags ;
118my %openWayNodes ;
119my %usedInRelation = () ;
120
121###############
122# get parameter
123###############
124$osmName = shift||'';
125if (!$osmName)
126{
127        die (print $usage, "\n");
128}
129
130$htmlName = shift||'';
131if (!$htmlName)
132{
133        die (print $usage, "\n");
134}
135
136$gpxName = shift||'';
137if (!$gpxName)
138{
139        die (print $usage, "\n");
140}
141
142print "\n$program $version for file $osmName\n\n" ;
143print "\n" ;
144print "ATTENTION!\n" ;
145print "----------\n" ;
146print "This program uses API calls.\n" ;
147print "Although generally running this program once on a relatively small planet-excerpt\n" ;
148print "file poses no threat to the API you might be able to disturb the API\n" ;
149print "by running it often or in parallel and on big files.\n" ;
150print "Calls are made at max. 1/sec. (can be coded)\n" ;
151print "\n" ;
152
153foreach (@areas) {
154        print $_, " " ;
155}
156print "\n\n" ;
157
158
159
160
161#################################
162# find all relation members first
163#################################
164openOsmFile ($osmName) ;
165print "INFO: pass1: skipping nodes...\n" ;
166skipNodes () ;
167print "INFO: pass1: skipping ways...\n" ;
168skipWays () ;
169print "INFO: pass1: parsing relations...\n" ;
170
171($relationId, $relationUser, $aRef1, $aRef2) = getRelation () ;
172if ($relationId != -1) {
173        @relationMembers = @$aRef1 ;
174        @relationTags = @$aRef2 ;
175}
176
177while ($relationId != -1) {
178
179        foreach my $m (@relationMembers) {
180                if ($m->[0] eq "way") { $usedInRelation{$m->[1]} = 1 ; }
181        }
182
183        #next
184        ($relationId, $relationUser, $aRef1, $aRef2) = getRelation () ;
185        if ($relationId != -1) {
186                @relationMembers = @$aRef1 ;
187                @relationTags = @$aRef2 ;
188        }
189}
190
191closeOsmFile () ;
192print "INFO: done.\n" ;
193
194
195
196######################
197# skip all nodes first
198######################
199openOsmFile ($osmName) ;
200print "INFO: pass2: skipping nodes...\n" ;
201skipNodes () ;
202
203
204#####################
205# identify open areas
206#####################
207print "INFO: pass2: find open areas...\n" ;
208($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
209if ($wayId != -1) {
210        @wayNodes = @$aRef1 ;
211        @wayTags = @$aRef2 ;
212}
213while ($wayId != -1) { 
214        $wayCount++ ;
215
216        my $found = 0 ;
217        foreach $tag1 (@wayTags) {
218                foreach $tag2 (@areas) {
219                        if ($tag1 eq $tag2) { $found = 1 ; }
220                }
221        }
222
223        if ($found) { 
224                $areaCount++ ;
225                if ( ($wayNodes[0] != $wayNodes[-1]) and (! defined $usedInRelation{$wayId}) ) {
226                        # check API way data
227                        #print "request API data for way $wayId...\n" ;
228                        sleep (1) ; # don't stress API
229                        $APIcount++ ;
230                        my ($id, $u, @nds, @tags, $ndsRef, $tagRef) ;
231                        ($id, $u, $ndsRef, $tagRef) = APIgetWay ($wayId) ;
232                        #print "API request finished.\n" ;
233                        @nds = @$ndsRef ; 
234                        @tags = @$tagRef ;
235
236                        if ($id == 0) { $APIerrors++ ; }
237
238                        #print "nodes: @nds\n" ;
239                        #print "WayId=$wayId Id=$id wayNodes:", scalar (@wayNodes), " nds:", scalar (@nds), "\n" ;
240
241                        if ( ( scalar (@wayNodes) != scalar (@nds)) and ($wayId == $id) ) { 
242                                print "WARNING: way $wayId has different node count in API call. Ignoring...\n" ;
243                                $APIrejected++ ;
244                        }
245                        else {
246                                $areaOpenCount ++ ;
247                                push @open, $wayId ;
248                                $wayStart{$wayId} = $wayNodes[0] ; 
249                                $wayEnd{$wayId} = $wayNodes[-1] ; 
250                                @{$openWayTags{$wayId}} = @wayTags ;
251                                @{$openWayNodes{$wayId}} = @wayNodes ;
252                        }
253                }
254        }
255
256        # next way
257        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
258        if ($wayId != -1) {
259                @wayNodes = @$aRef1 ;
260                @wayTags = @$aRef2 ;
261        }
262}
263
264closeOsmFile () ;
265
266print "INFO: number total ways: $wayCount\n" ;
267print "INFO: number areas: $areaCount\n" ;
268print "INFO: number open areas: $areaOpenCount\n" ;
269print "INFO: API calls: $APIcount\n" ;
270print "INFO: API errors: $APIerrors\n" ;
271print "INFO: API rejections: $APIrejected\n" ;
272
273
274
275######################
276# collect needed nodes
277######################
278print "INFO: pass3: collect needed nodes...\n" ;
279foreach $wayId (@open) {
280        push @neededNodes, $wayStart{$wayId} ;
281        push @neededNodes, $wayEnd{$wayId} ;
282}
283
284
285######################
286# get node information
287######################
288print "INFO: pass3: get node information...\n" ;
289openOsmFile ($osmName) ;
290
291foreach (@neededNodes) { $neededNodesHash{$_} = 1 ; }
292
293($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
294if ($nodeId != -1) {
295        #@nodeTags = @$aRef1 ;
296}
297
298while ($nodeId != -1) {
299
300        if (exists ($neededNodesHash{$nodeId}) ) { 
301                $lon{$nodeId} = $nodeLon ; $lat{$nodeId} = $nodeLat
302        }
303
304        # next
305        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
306        if ($nodeId != -1) {
307                #@nodeTags = @$aRef1 ;
308        }
309}
310
311closeOsmFile () ;
312
313$time1 = time () ;
314
315
316######################
317# PRINT HTML/GPX INFOS
318######################
319print "\nINFO: write HTML tables...\n" ;
320
321open ($html, ">", $htmlName) || die ("Can't open html output file") ;
322open ($gpx, ">", $gpxName) || die ("Can't open gpx output file") ;
323
324printHTMLHeader ($html, "$program by Gary68") ;
325printGPXHeader ($gpx) ;
326
327print $html "<H1>$program by Gary68</H1>\n" ;
328print $html "<p>Version ", $version, "</p>\n" ;
329
330print $html "<p>Check ways with following tags:</p>\n" ;
331print $html "<p>" ;
332foreach (@areas) {
333        print $html $_, " " ;
334}
335print $html "</p>" ;
336
337
338
339print $html "<H2>Statistics</H2>\n" ;
340print $html "<p>", stringFileInfo ($osmName), "<br>\n" ;
341print $html "number ways total: $wayCount<br>\n" ;
342print $html "number areas: $areaCount</p>\n" ;
343print $html "number open areas: $areaOpenCount</p>\n" ;
344print $html "number API errors: $APIerrors</p>\n" ;
345
346
347print $html "<H2>Open Areas</H2>\n" ;
348print $html "<p>These ways have to be closed areas according to map features but the first node is not the same as the last. So area is probably not closed or not properly so. It is possible that parts of the way are drawn doubly (thus closing the area in a way).</p>" ;
349print $html "<table border=\"1\" width=\"100%\">\n";
350print $html "<tr>\n" ;
351print $html "<th>Line</th>\n" ;
352print $html "<th>WayId</th>\n" ;
353print $html "<th>Tags</th>\n" ;
354print $html "<th>Nodes</th>\n" ;
355print $html "<th>Distance start/end</th>\n" ;
356print $html "<th>start/end node id</th>\n" ;
357print $html "<th>OSM start/end</th>\n" ;
358print $html "<th>OSB start/end</th>\n" ;
359print $html "<th>JOSM start/end</th>\n" ;
360print $html "</tr>\n" ;
361$i = 0 ;
362foreach $wayId (@open) {
363        $i++ ;
364
365        print $html "<tr>\n" ;
366        print $html "<td>", $i , "</td>\n" ;
367        print $html "<td>", historyLink ("way", $wayId) , "</td>\n" ;
368
369        print $html "<td>" ;
370        foreach (@{$openWayTags{$wayId}}) { print $html $_, " - " ; }
371        print $html "</td>\n" ;
372
373        print $html "<td>" ;
374        foreach (@{$openWayNodes{$wayId}}) { print $html $_, " - " ; }
375        print $html "</td>\n" ;
376
377        my $dist = distance ($lon{$wayStart{$wayId}},$lat{$wayStart{$wayId}},$lon{$wayEnd{$wayId}},$lat{$wayEnd{$wayId}}) * 1000 ;
378        printf $html "<td>%.0f m</td>\n", $dist ;
379
380        print $html "<td>", $wayStart{$wayId}, " / ", $wayEnd{$wayId}, "</td>\n" ;
381        print $html "<td>", osmLink ($lon{$wayStart{$wayId}}, $lat{$wayStart{$wayId}}, 16) , " ", osmLink ($lon{$wayEnd{$wayId}}, $lat{$wayEnd{$wayId}}, 16), "</td>\n" ;
382        print $html "<td>", osbLink ($lon{$wayStart{$wayId}}, $lat{$wayStart{$wayId}}, 16) , " ", osbLink ($lon{$wayEnd{$wayId}}, $lat{$wayEnd{$wayId}}, 16), "</td>\n" ;
383        print $html "<td>", josmLink ($lon{$wayStart{$wayId}}, $lat{$wayStart{$wayId}}, 0.01, $wayId), " ", josmLink ($lon{$wayEnd{$wayId}}, $lat{$wayEnd{$wayId}}, 0.01, $wayId), "</td>\n" ;
384
385        print $html "</tr>\n" ;
386
387        # GPX
388        my $text = $wayId . " - area way not closed or doubly drawn segments" ;
389        printGPXWaypoint ($gpx, $lon{$wayStart{$wayId}}, $lat{$wayStart{$wayId}}, $text) ;
390}
391
392print $html "</table>\n" ;
393print $html "<p>$i lines total</p>\n" ;
394
395
396
397########
398# FINISH
399########
400print $html "<p>", stringTimeSpent ($time1-$time0), "</p>\n" ;
401printHTMLFoot ($html) ;
402printGPXFoot ($gpx) ;
403
404close ($html) ;
405close ($gpx) ;
406
407print "\nINFO: finished after ", stringTimeSpent ($time1-$time0), "\n\n" ;
408
409
Note: See TracBrowser for help on using the repository browser.