source: subversion/applications/utils/planet.osm/perl/unmappedplaces60.pl @ 12038

Revision 12038, 11.7 KB checked in by gary68, 5 years ago (diff)
Line 
1#!/usr/bin/perl
2#
3# program takes osm file and outputs unmapped and potentially unmapped places in html or openlayers poi format
4#
5# written by Gary68
6#
7# v4
8# - new output format
9#
10# v5
11# - places eingeschränkt
12#
13# v6
14# - sorted output
15# - unmapped / sparsely mapped
16# - different parameters for different places
17# - output for slippy map openlayers
18# - much better performance
19# - time spent format changed
20# - count of more places
21# - file date now shown in stats
22# - grouped lists
23#
24
25use strict;
26use warnings;
27
28use File::stat;
29use Time::localtime;
30
31use Exporter ;
32
33# constants
34my $version = "6.0" ;
35my $usage = "usage:  unmappedplaces6.pl <osmfile> <htmlfile> <slippyfile>\n" ;
36my %dists ; # in km // STAY BELOW 10km !!!
37$dists{"city"} =  4.0 ;
38$dists{"town"} =  1.0 ;
39$dists{"suburb"} =  0.5 ;
40$dists{"village"} =  0.5 ;
41
42my %sparse ; # in km
43$sparse{"city"} =  4800 ;
44$sparse{"town"} =  400 ;
45$sparse{"suburb"} =  60 ;
46$sparse{"village"} =  60 ;
47
48my %unmapped ; # in km
49$unmapped{"city"} =  2400 ;
50$unmapped{"town"} =  200 ;
51$unmapped{"suburb"} =  30 ;
52$unmapped{"village"} =  30 ;
53
54my $iconRed = "Ol_icon_red_example.png" ;
55my $iconBlue = "Ol_icon_blue_example.png" ;
56
57# variables
58my $dist ;
59my $node_count = 0 ;
60my $city_count = 0 ;
61my $town_count = 0 ;
62my $village_count = 0 ;
63my $suburb_count = 0 ;
64
65my $place_count = 0 ;
66my $unmapped = 0 ;
67my $sparselyMapped = 0 ;
68
69my $placekey ;
70my $placekey1 ;
71my $placekey2 ;
72my $nodekey ;
73my $progress ;
74my $i ;
75my $key ;
76my $key2 ;
77
78my $place_type_temp ;
79my $place_name_temp ;
80
81my $d_lat ;
82my $d_lon ;
83
84my $time0 ;
85my $time1 ;
86my $time2 ;
87my $timespent ;
88
89my $html_file ;
90my $slippy_file ;
91
92my %node_lon ;
93my %node_lat ;
94
95my %place_name ;
96my %place_type ;
97my %place_lon ;
98my %place_lat ;
99my %place_nodes_inside ;
100my %place_superior ;
101my %place_superior_dist ;
102
103my %node_hash ;
104my $hash_value ;
105
106my @outputData ;
107my @outputDataSorted ;
108my %outputGrouped ;
109
110# get filename from cmd line
111my $xml = shift||'';
112if (!$xml)
113{
114        print STDERR $usage ;
115        die () ;
116}
117
118# file present?
119unless( -f $xml || $xml eq "-" ) {
120        die("input file '$xml' not found\n");
121}
122
123my $html = shift||'';
124if (!$html)
125{
126        print STDERR $usage ;
127        die () ;
128}
129
130my $slippyout = shift||'';
131if (!$slippyout)
132{
133        print STDERR $usage ;
134        die () ;
135}
136
137$time0 = time() ;
138
139# open input file
140open(XML, "<$xml") or die("$!");
141
142# parse data
143while(my $line = <XML>) {
144
145        # node data
146        if($line =~ /^\s*\<node/) {
147                # get all needed information
148                my ($id)   = ($line =~ /^\s*\<node id=[\'\"](\d+)[\'\"]/); # get node id
149                my ($lon) = ($line =~ /^.+lon=[\'\"]([\d,\.]+)[\'\"]/);    # get position
150                my ($lat) = ($line =~ /^.+lat=[\'\"]([\d,\.]+)[\'\"]/);    # get position
151
152                unless ($id) { next; }
153                unless ($lat) { next; }
154                unless ($lon) { next; }
155
156                # print "Node: ", $id, "\n" ;
157                $node_count++ ;
158
159                #store node
160                $node_lon {$id} = $lon ;
161                $node_lat {$id} = $lat ;
162
163                # put in hash
164                $hash_value = hashValue ($lon, $lat) ;
165                #print $hash_value, "\n" ;
166                push @{$node_hash {$hash_value}}, $id ;
167
168                if ($line =~ /\//) {
169                } 
170                else {
171                        # print "processing tags...\n" ;
172                        #get tags
173                        $place_type_temp ="" ;
174                        $place_name_temp = "" ;
175                        while (not($line =~ /\/node/)) {
176                                $line = <XML> ;
177                                # print $line, "\n" ;
178                                my ($key)   = ($line =~ /^\s*\<tag k=[\'\"](\w+)[\'\"]/); # get key
179                                # my ($value)   = ($line =~ /^\s*v=[\'\"](\w+)[\'\"]/); # get value
180                                my ($value) = ($line =~ /^.+v=[\'\"](\w+)[\'\"]/);       # get value // PROBLEM WITH UMLAUTE
181                               
182                                unless ($key) { next; }
183                                unless ($value) { next; }
184
185                                if ($key eq "place") {
186                                        $place_type_temp = $value ;
187                                }                       
188                                if ($key eq "name") {
189                                        $place_name_temp = $value ;
190
191                                }       
192                                # print "K/v: ", $key, "/", $value, "\n" ;
193                        }
194                        if (($place_type_temp ne "") and ($place_name_temp ne "") and 
195                                ( ($place_type_temp eq "city") or ($place_type_temp eq "town") or 
196                                ($place_type_temp eq "village") or ($place_type_temp eq "suburb") ) ) {
197                                $place_name {$id} = $place_name_temp ;
198                                $place_type {$id} = $place_type_temp ;
199                                $place_lat {$id} = $lat ;
200                                $place_lon {$id} = $lon ;
201                                $place_nodes_inside {$id} = 0 ;
202                                $place_count = $place_count + 1 ;
203                                if ($place_type_temp eq "city") { $city_count++ } ;
204                                if ($place_type_temp eq "town") { $town_count++ } ;
205                                if ($place_type_temp eq "village") { $village_count++ } ;
206                                if ($place_type_temp eq "suburb") { $suburb_count++ } ;
207                               
208                        }
209                }               
210        }
211}
212
213#foreach $placekey (keys %node_hash) {
214#       print $placekey, " " ;
215#       foreach (@{$node_hash{$placekey}}) {
216#               print $_, " " ;
217#       }
218#       print "\n" ;
219#}
220
221$time1 = time() ;
222
223$i = 0 ;
224foreach $placekey (keys %place_name) {
225        $i++ ;
226        $progress = int ($i / $place_count * 100) ;
227        if ($i % 10 == 0) { print $xml, " ", $progress, "%\n" ; }
228
229        #print "Name: ", $place_name{$placekey}, "\n" ;
230        #print "Type: ", $place_type{$placekey}, "\n" ;
231        #print "max dist: ", $dists{$place_type{$placekey}}, "\n" ;
232       
233        my $lo ;
234        my $la ;
235        for ($lo=$place_lon{$placekey}-0.1; $lo<=$place_lon{$placekey}+0.1; $lo=$lo+0.1) {
236                for ($la=$place_lat{$placekey}-0.1; $la<=$place_lat{$placekey}+0.1; $la=$la+0.1) {
237                        #print $lo, " ", $la, "\n" ;
238                        $hash_value = hashValue ($lo, $la) ;
239               
240                        #if (defined @{$node_hash{$hash_value}}) {
241                                early1: foreach $nodekey ( @{$node_hash{$hash_value}} ) {
242                                        #print $nodekey, "\n" ;
243                                        my $d_lat = ($node_lat{$nodekey} - $place_lat{$placekey}) * 111.11 ;
244                                        my $d_lon = ($node_lon{$nodekey} - $place_lon{$placekey}) * cos ( $node_lat{$nodekey} / 360 * 3.14 * 2 ) * 111.11;
245                                        $dist = sqrt ($d_lat*$d_lat+$d_lon*$d_lon);
246                                        if ($dist < $dists{$place_type{$placekey}}) {
247                                                $place_nodes_inside {$placekey} = $place_nodes_inside {$placekey} + 1 ;
248                                        }
249                                        if ($place_nodes_inside {$placekey} > $sparse{$place_type{$placekey}}) {
250                                                last early1 ;
251                                        }
252                                }
253                        #}
254                }
255        }
256}
257
258
259# count unmapped/sparsely mapped places
260
261foreach $placekey (keys %place_name) {
262        print "Name: ", $place_name{$placekey}, "\n" ;
263        print "Type: ", $place_type{$placekey}, "\n" ;
264        print "max dist: ", $dists{$place_type{$placekey}}, "\n" ;
265        print "Nodes in: ", $place_nodes_inside {$placekey}, "\n" ;
266        if ($place_nodes_inside {$placekey} < $sparse{$place_type{$placekey}}) {
267                if ($place_nodes_inside {$placekey} < $unmapped{$place_type{$placekey}}) {
268                        $unmapped = $unmapped + 1 ;
269                }
270                else {
271                        $sparselyMapped ++ ;
272                }
273        }
274        print "\n" ;
275}
276
277# find superior city/town
278foreach $placekey1 (keys %place_name) {
279        $place_superior {$placekey1} = "-" ;
280        $place_superior_dist {$placekey1} = 9999 ;
281        if (($place_type {$placekey1} eq "city") or ($place_type {$placekey1} eq "town")) {
282                # do nothing
283        } 
284        else {
285                # look for sup
286                foreach $placekey2 (keys %place_name) {
287                        my $d_lat = $place_lat{$placekey1} - $place_lat{$placekey2} ;
288                        my $d_lon = $place_lon{$placekey1} - $place_lon{$placekey2} ;
289                        $dist = sqrt($d_lat*$d_lat+$d_lon*$d_lon)*111.11;
290                        if (  ($dist < $place_superior_dist {$placekey1}) 
291                                and ( 
292                                        ($place_type {$placekey2} eq "city") or 
293                                        ($place_type {$placekey2} eq "town"))   ) {
294                                $place_superior {$placekey1} = $place_name {$placekey2} ;
295                                $place_superior_dist {$placekey1} = $dist ;
296                        }
297                }
298        }
299}
300
301$time2 = time() ;
302$timespent = $time2 - $time0 ;
303
304# print output files
305
306open ($html_file, , ">", $html) ; 
307open ($slippy_file, ">", $slippyout) ; 
308
309print_html_header() ;
310print $slippy_file "lat\tlon\ttitle\tdescription\ticon\ticonSize\ticonOffset\n" ;
311
312# print stats
313print $html_file "<h1>Unmapped places for ", $xml, "</h1>\n" ;
314print $html_file "<p>by Gary68</p>\n" ;
315print $html_file "<p>Program Version: $version</p>\n" ;
316
317print $html_file "<h2>Stats</h2>\n" ;
318print $html_file "<p>File date: ", ctime(stat($xml)->mtime), "<br>\n" ;
319print $html_file "Node count:      ", $node_count, "<br>\n" ;
320print $html_file "place count:     ", $place_count, "<br>\n" ;
321print $html_file "Cities:          ", $city_count, "<br>\n" ;
322print $html_file "Towns:           ", $town_count, "<br>\n" ;
323print $html_file "Suburbs:         ", $suburb_count, "<br>\n" ;
324print $html_file "Villages:        ", $village_count, "<br>\n" ;
325print $html_file "Unmapped places: ", $unmapped, "<br>\n" ;
326print $html_file "Sparsely mapped: ", $sparselyMapped, "<br>\n" ;
327printf $html_file "Unmapped:        %2d percent<br>\n", ($unmapped*100/$place_count) ;
328printf $html_file "Sparsely mapped: %2d percent<br>\n", ($sparselyMapped*100/$place_count) ;
329print $html_file "runtime1 =       ", $time1-$time0, "secs<br>\n" ;
330print $html_file "<p>Time: ", ($timespent/(60*60))%99, " hours, ", ($timespent/60)%60, " minutes and ", $timespent%60, " seconds</p>" ;
331
332print $html_file "<h2>Definitions</h2>\n" ;
333print $html_file "<p>City: ",  $dists{'city'}, " km radius - sparse/unmapped thresholds ", $sparse{'city'}, "/", $unmapped{'city'}, "<br>\n" ;
334print $html_file "Town: ",  $dists{'town'}, " km radius - sparse/unmapped thresholds ", $sparse{'town'}, "/", $unmapped{'town'}, "<br>\n" ;
335print $html_file "Village: ",  $dists{'village'}, " km radius - sparse/unmapped thresholds ", $sparse{'village'}, "/", $unmapped{'village'}, "<br>\n" ;
336print $html_file "Suburb: ",  $dists{'suburb'}, " km radius - sparse/unmapped thresholds ", $sparse{'suburb'}, "/", $unmapped{'suburb'}, "</p>\n" ;
337
338print $html_file "<h2>Details</h2>\n" ; 
339print $html_file "<p>Grouped list follows below!</p>\n" ;
340foreach $placekey (keys %place_name) { 
341        if ($place_nodes_inside {$placekey} < $sparse{$place_type{$placekey}}) { 
342                my $temp ;
343
344                $temp = "<!--" . $place_name {$placekey} . "-->" ;
345                $temp = $temp . "<A HREF=\"http://www.openstreetmap.org/?lat=" . $place_lat {$placekey} . "&lon=" . $place_lon {$placekey} . "&zoom=13\">" ; 
346                $temp = $temp . $place_name {$placekey} . "</A>" ; 
347                $temp = $temp . " (" . $place_type {$placekey} . " near " . $place_superior {$placekey} . ", " . $place_nodes_inside{$placekey} . ")\n"  ; 
348                if ($place_nodes_inside {$placekey} < $unmapped{$place_type{$placekey}}) { 
349                        $temp = $temp . " - potentially unmapped<br>" ;
350                }
351                else {
352                        $temp = $temp . " - potentially sparsely mapped<br>" ;
353                }
354                $temp = $temp . "\n" ;
355
356                push @outputData, $temp ;
357                push @{$outputGrouped{$place_superior{$placekey}}}, $place_name {$placekey} ;
358
359                print $slippy_file $place_lat {$placekey}, "\t" ;
360                print $slippy_file $place_lon {$placekey}, "\t" ;
361                print $slippy_file $place_name {$placekey}, "\t" ;
362                if ($place_nodes_inside {$placekey} < $unmapped{$place_type{$placekey}}) { 
363                        print $slippy_file "Potentially unmapped place", "\t" ;
364                        print $slippy_file "./", $iconRed, "\t" ;
365                }
366                else {
367                        print $slippy_file "Potentially sparsely mapped place", "\t" ;
368                        print $slippy_file "./", $iconBlue, "\t" ;
369                }
370                print $slippy_file "16,16", "\t" ;
371                print $slippy_file "-8,-8", "\n" ;
372        } 
373} 
374
375
376@outputDataSorted = sort @outputData ;
377
378foreach (@outputDataSorted) {
379        print $html_file $_ ;
380}
381
382print $html_file "<h2>Grouped</h2>\n" ;
383
384foreach $key (sort keys %outputGrouped) {
385        if ($key ne "-") {
386                print $html_file "<h3>$key</h3>\n<p>" ;
387                foreach $key2 (@{$outputGrouped{$key}}) {
388                        print $html_file $key2, "<br>\n" ;
389                }
390                print $html_file "</p>\n" ;
391        }
392}
393
394
395print_html_foot() ;
396
397close $html_file ;
398close $slippy_file ;
399
400print "\nTime: ", ($timespent/(60*60))%99, " hours, ", ($timespent/60)%60, " minutes and ", $timespent%60, " seconds\n" ;
401
402
403######
404# HTML
405######
406
407sub print_html_header {
408        print $html_file "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"";
409        print $html_file "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
410        print $html_file "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n";
411        print $html_file "<head><title>unmapped by Gary68</title>\n";
412        print $html_file "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n";
413        print $html_file "</head>\n<body>\n";
414}
415
416sub print_html_foot {
417        print $html_file "</body>\n</html>\n" ;
418}
419
420
421sub hashValue {
422        my $lon = shift ;
423        my $lat = shift ;
424
425        my $lo = int ($lon*10) * 10000 ;
426        my $la = int ($lat*10) ;
427
428        return ($lo+$la) ;
429}
430
Note: See TracBrowser for help on using the repository browser.