source: subversion/applications/utils/gary68/mappingquality.pl @ 23856

Last change on this file since 23856 was 22726, checked in by gary68, 9 years ago

new mq version - minor output change in slippy map file

  • Property svn:executable set to *
File size: 43.0 KB
Line 
1#
2#
3# mappingquality.pl by gary68
4#
5# this program checks an osm file for the quality and quantity of the mapping of places
6#
7# usage: mappingquality.pl file.osm basename [size]
8# prg will create several output names from basename by appending suffixes! size can be omitted and defaults to 2048.
9#
10#
11#
12# Copyright (C) 2009, Gerhard Schwanz
13#
14# 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
15# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
21#
22# Version 1.0
23# Version 1.1
24# - add picture support
25# - add josm and history links
26# - draw highway=service with lightgray
27# - corrected hwy res length error in map
28# Version 1.2
29# - look for radius in osm data, display in pic
30# - faster superior search
31# - streetArray
32# - auto find radius according residentials and nearby places
33# - calc and print counts
34# Version 2
35# - add place areas
36# - headers for csv files
37# - solved two bugs (;:)
38#
39# Version 2.1
40# - bug fixed
41#
42# Version 2.2
43# - population bug fixed
44#
45# Version 2.3
46# - place = X in files for map
47#
48
49
50use strict ;
51use warnings ;
52
53use List::Util qw[min max] ;
54use Math::Polygon ;
55use OSM::osm 3.0 ;
56use OSM::osmgraph 1.0 ;
57
58#
59# CONSTANTS
60#
61#
62my $program = "mappingquality.pl" ;
63my $usage = $program . " file.osm basename size" ;
64my $version = "2.3" ;
65#
66my $iconRed = "unmapped_red.png" ; my $iconYellow = "unmapped_yellow.png" ;
67my $colorRed = "#FF0000" ;
68my $colorGreen = "#9BCD9B" ;
69my $colorOrange = "#FF8C00" ;
70my $colorGrey = "#AAAAAA" ;
71#
72# the next two constants define which places are checked for a node or a way
73my $hashSpanCircle = 0.1 ; # 0.1 means 3 hashes in each dimension will be looked up, 0.2 means 5 each (resulting in 25). this is a performance issue!
74my $hashSpanArea   = 0.1 ; 
75#
76my $minRad = 250 ; # min radius (m) for auto detection. smaller places will default.
77#
78# default distances if no other information is available
79my %dists ; # in km // STAY BELOW 10km !!!
80$dists{"city"} =  4.0 ;
81$dists{"town"} =  1.0 ;
82$dists{"suburb"} =  0.5 ;
83$dists{"village"} =  0.5 ;
84#
85# thresholds for places
86my %sparse ; 
87$sparse{"city"} =  4800 ;
88$sparse{"town"} =  400 ;
89$sparse{"suburb"} =  60 ;
90$sparse{"village"} =  60 ;
91#
92# thresholds for places
93my %unmapped ; 
94$unmapped{"city"} =  2400 ;
95$unmapped{"town"} =  200 ;
96$unmapped{"suburb"} =  30 ;
97$unmapped{"village"} =  30 ;
98
99
100my $place_count ;                       # number places found
101my $assignedAreas = 0 ; # number of places that could be assigned to place nodes
102my %count ;
103my %unmappedCount ; my %sparselyCount ;
104
105# variables for file parsing
106my $wayId ; my $wayId1 ; my $wayId2 ;
107my $wayUser ; my @wayNodes ; my @wayTags ;
108my $nodeId ; my $nodeId2 ;
109my $nodeUser ; my $nodeLat ; my $nodeLon ; my @nodeTags ;
110my $aRef1 ; my $aRef2 ;
111
112my $invalidWays = 0 ;                   # ways with only one node, can not be processed
113
114my $time0 = time() ; my $time1 ; my $timeA ;
115
116# file names and handles
117my $baseName ; my $osmName ; my $htmlName ; my $textName ; my $csvName ; my $pngName ; my $streetName ; 
118my $html ; my $text ; my $csv ; my $png ; my $street ;
119
120# place node information
121# hash value negative if created by area!
122my %placeName ; my %placeType ; my %placeRadius ; my %placeRadiusSource ;
123my %placeNodes ; my %placePopulation ;
124my %placeFixmeNodes ; my %placeFixmeWays ;
125my %placeResidentials ; my %placeResidentialsNoname ; my %placeResidentialLength ;
126my %placeRoads ; my %placeAmenities ; my %placeBuildings ;
127my %placeHash ; my %placeSuperior ; my %placeSuperiorDist ; my %placeDistNext ; 
128my %placeArea ;
129my %placeStreets ; 
130
131my $auto = 0 ;
132my $autoCircle = 0 ;
133
134my %placeStreetArray ;
135
136# place way information
137# hash value negative if created by program automatically (area)
138my %placeWayLon ;
139my %placeWayLat ;
140my %placeWayPolygon ;   # contains polygon
141my %placeWayType ;      # type of place
142my %placeWayName ;      # name of place to compare against place node
143my %placeWayNodeId ;    # nearest place node with same name
144my %placeWayDist ;      # dist to nearest place node
145my %placeWayNodes ;     # nodes of way
146my %placeWayHash ;      # hash of place ways
147my @placeWayNoName ;    # error report
148my @placeWayOpen ;      # error report
149my @unassignedAreas ;
150
151my $areaCount = 0 ; my $areaOpenCount = 0 ; my $areaNoNameCount = 0 ;
152
153my %lon ; my %lat ;
154my %citiesAndTowns ;    # collect for nearest search optimization
155
156#statistic variables
157my %meanNodes ; my %meanHwyRes ; my %meanHwyResLen ; my %meanAmenities ; my %meanBuildings ;
158
159my $wayCount ; my $nodeCount ; my $radCount = 0 ;
160my $key ; my $key1 ; my $key2 ;
161
162my @outArray ;          # sort output before print
163
164# graphics variables
165my $size ; my $lonMin ; my $latMin ; my $lonMax ; my $latMax ;
166
167###############
168# get parameter
169###############
170$osmName = shift||'';
171if (!$osmName)
172{
173        die (print $usage, "\n");
174}
175
176$baseName = shift||'';
177if (!$baseName)
178{
179        die (print $usage, "\n");
180}
181
182$size = shift||'';
183if (!$size)
184{
185        $size = 2048 ; # default size
186}
187
188$htmlName = $baseName . ".htm" ;
189$textName = $baseName . ".txt" ;
190$csvName = $baseName . ".csv" ;
191$pngName = $baseName . ".png" ;
192$streetName = $baseName . "_streets.csv" ;
193
194print "\n$program $version for file $osmName\n\n" ;
195
196foreach (keys %dists) { $count{$_} = 0 ; } # init counts
197
198######################
199# get node information
200######################
201print "get node position information...\n" ;
202openOsmFile ($osmName) ;
203
204($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
205if ($nodeId != -1) {
206        @nodeTags = @$aRef1 ;
207}
208while ($nodeId != -1) {
209        $nodeCount++ ;
210        $lon{$nodeId} = $nodeLon ;      # store position
211        $lat{$nodeId} = $nodeLat ; 
212        my $place = 0 ; my $name = "-" ; my $population = 0 ; my $type = "-" ; my $tag ; my $distance = 0 ;
213        # find node information like name, place, population etc.
214        foreach $tag (@nodeTags) {
215                my $tmp1 = $tag ;
216                my $colon = ($tmp1 =~ s/://g ) ;
217
218                $tmp1 = $tag ;
219                if ( ( grep (/^place:/, $tag) ) and ($colon == 1) ) {
220                        $type = $tag ; $type =~ s/place:// ;
221                        my $t ;
222                        foreach $t (keys %dists) {
223                                if ($t eq $type) { $place = 1 ; }
224                        }
225                }
226                my $tmp = $tag ;
227                if ( (grep /^name:/, $tag) and ($colon == 1) ) { $name = $tag ; $name =~ s/name:// ; }
228                if ( (grep /^place_name:/, $tag) and ($colon == 1) ) { $name = $tag ; $name =~ s/place_name:// ; }
229                if (grep /population:/ , $tag) { 
230                        if (grep /openGeoDB:population:/ , $tag) {
231                                $population = $tag ; $population =~ s/openGeoDB:population:// ; 
232                        }
233                        else {
234                                if ( (grep /^population:/, $tag) and ($colon == 1) ) { $population =~ s/population:// ; }
235                        }
236                }
237                if (grep /^radius:/ , $tag) { 
238                        my $dTmp = $tag ; 
239                        $dTmp =~ s/place_// ;
240                        $dTmp =~ s/radius:// ;
241                        if (grep /km/ , $dTmp) {
242                                $dTmp =~ s/km// ;
243                                # TODO check for numeric
244                                $distance = $dTmp ;
245                                $radCount++ ;
246                        }
247                        else {
248                                if (grep /m/ , $dTmp) {
249                                        $dTmp =~ s/m// ;
250                                        # TODO check for numeric
251                                        $distance = $dTmp / 1000 ;
252                                        $radCount++ ;
253                                }
254                        }
255                }
256                if (grep /^diameter:/ , $tag) { 
257                        my $dTmp = $tag ; 
258                        $dTmp =~ s/place_// ;
259                        $dTmp =~ s/diameter:// ;
260                        if (grep /km/ , $dTmp) {
261                                $dTmp =~ s/km// ;
262                                # TODO check for numeric
263                                $distance = $dTmp / 2 ;
264                                $radCount++ ;
265                        }
266                        else {
267                                if (grep /m/ , $dTmp) {
268                                        $dTmp =~ s/m// ;
269                                        # TODO check for numeric
270                                        $distance = $dTmp / 1000 / 2 ;
271                                        $radCount++ ;
272                                }
273                        }
274                }
275        }
276        $name =~ s/;/-/g ;
277        if ( ($place == 1)  and ($name ne "-") ) {
278                $place_count ++ ;
279                $count{$type} ++ ;
280                $lon{$nodeId} = $nodeLon ;
281                $lat{$nodeId} = $nodeLat ;
282                $placeArea{$nodeId} = 0 ;
283                $placeType{$nodeId} = $type ;
284                $placePopulation{$nodeId} = $population ;
285                $placeName{$nodeId} =  $name ;
286                $placeNodes{$nodeId} = 0 ;
287                $placeFixmeNodes{$nodeId} = 0 ;
288                $placeFixmeWays{$nodeId} = 0 ;
289                $placeResidentials{$nodeId} = 0  ;
290                $placeResidentialsNoname{$nodeId} = 0 ;
291                $placeResidentialLength{$nodeId} = 0 ;
292                $placeRoads{$nodeId} = 0  ;
293                $placeAmenities{$nodeId} = 0 ;
294                $placeBuildings{$nodeId} = 0 ;
295                @{$placeStreetArray{$nodeId}} = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ;
296                $placeDistNext{$nodeId} = 999 ;
297                $placeRadius{$nodeId} = $dists{$type} ; # default dist
298                $placeRadiusSource{$nodeId} = "default" ;
299                if ($distance != 0) {                           # radius from osm data
300                        $placeRadius{$nodeId} = $distance ;
301                        $placeRadiusSource{$nodeId} = "osm" ;
302                }
303                if (($type eq "city") or ($type eq "town") ) {
304                        $citiesAndTowns{$nodeId} = 1 ;
305                }
306                push @{$placeHash{hashValue($nodeLon, $nodeLat)}}, $nodeId ; 
307        }
308        # next
309        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
310        if ($nodeId != -1) {
311                @nodeTags = @$aRef1 ;
312        }
313}
314print "initial place node count: $place_count\n" ;
315#foreach (keys %count) { print "count $_ $count{$_}\n" ; }
316#print "number of nodes with radius information found in osm: $radCount\n" ;
317
318#############
319# place areas
320#############
321print "looking for place areas...\n" ;
322($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
323if ($wayId != -1) {
324        @wayNodes = @$aRef1 ;
325        @wayTags = @$aRef2 ;
326}
327while ($wayId != -1) { 
328        my $name = 0 ; my $wayName ;
329        my $place = 0 ; my $pT ;
330        my $open = 0 ;
331        my $tag ;
332        foreach $tag (@wayTags) {
333                my $tmp1 = $tag ;
334                if  ( ($tmp1 =~ s/://g ) == 1 ) {
335                        if (grep /^name:/, $tag) { $name = 1 ; $wayName = $tag ; $wayName =~ s/name:// ; }
336                        if (grep /^place_name:/, $tag) { $name = 1 ; $wayName = $tag ; $wayName =~ s/place_name:// ; }
337                        if (grep /^place:/, $tag) { $place = 1 ; $pT = $tag ; $pT =~ s/place:// ; }
338                }
339        }
340        my $validPlace = 0 ;
341        if ($place) {
342                foreach $key (keys %dists) {
343                        if ($key eq $pT) { $validPlace = 1 ; }
344                }
345        }
346        if ($place and $validPlace) {
347                if ($wayNodes[0] != $wayNodes[-1]) { $open = 1 ; push @placeWayOpen, $wayId ; $areaOpenCount ++ ; }
348                if ( $name and (!$open) ) {
349                        $areaCount ++ ;
350                        $placeWayName{$wayId} =  $wayName ;
351                        $placeWayType{$wayId} =  $pT ;
352                        $placeWayNodeId{$wayId} = 0 ;
353                        $placeWayDist{$wayId} = 50 ; # dist to nearest place node, init
354                        @{$placeWayNodes{$wayId}} = @wayNodes ;
355                        # put way in wayhash, calc middle first
356                        my $lo = 0 ; my $la = 0 ;
357                        foreach $key (@wayNodes) {
358                                $lo += $lon{$key} ; $la += $lat{$key} ;
359                        }
360                        $lo = $lo / scalar (@wayNodes) ; $la = $la / scalar (@wayNodes) ;
361                        $placeWayLon{$wayId} = $lo ;
362                        $placeWayLat{$wayId} = $la ;
363                        push @{$placeWayHash{hashValue($lo, $la)}}, $wayId ; 
364                        #print "place area found: $wayName $pT $lo $la\n" ;
365                }
366                else {
367                        $areaNoNameCount ++ ;
368                        push @placeWayNoName, $wayId ;
369                }
370        }
371        # next way
372        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
373        if ($wayId != -1) {
374                @wayNodes = @$aRef1 ;
375                @wayTags = @$aRef2 ;
376        }
377}
378print "valid place areas found: $areaCount\n" ;
379print "open areas found: $areaOpenCount\n" ;
380print "areas without name found: $areaNoNameCount\n" ;
381
382closeOsmFile () ;
383
384#####################################################
385# find place nodes for place areas, or create new one
386#####################################################
387print "process found areas...\n" ;
388# try to locate placenodes that match the areas
389my $keyWay ; my $keyNode ;
390foreach $keyWay (keys %placeWayName) {
391        #print "$placeWayName{$keyWay}\n" ;
392        foreach $keyNode (keys %placeName) {
393                #print "  $placeName{$keyNode} " ;
394                my $d = distance ($lon{$keyNode}, $lat{$keyNode}, $placeWayLon{$keyWay}, $placeWayLat{$keyWay}) ;
395                #print "$d\n" ;
396                if ( ( $d < $placeWayDist{$keyWay}) and 
397                        ($placeWayName{$keyWay} eq $placeName{$keyNode}) and 
398                        ($placeWayType{$keyWay} eq $placeType{$keyNode}) ) {
399                        # place node nearer
400                        $placeWayDist{$keyWay} = $d ;
401                        $placeWayNodeId{$keyWay} = $keyNode ;
402                }
403        }
404}
405
406# assign way id to nodes, as back reference
407foreach $keyWay (keys %placeWayName) {
408        if ($placeWayNodeId{$keyWay} != 0) {                            # area with found node
409                $placeArea{$placeWayNodeId{$keyWay}} = $keyWay ;
410                $placeRadius{$placeWayNodeId{$keyWay}} = 0 ;            # radius = 0 !!!
411                $placeRadiusSource{$placeWayNodeId{$keyWay}} = "area" ;
412                #print "*** place area $keyWay assigned to node $placeWayNodeId{$keyWay} / $placeWayName{$keyWay}\n" ;
413                $assignedAreas ++ ;
414        }
415}
416
417print "place areas that could be assigned to nodes: $assignedAreas\n" ;
418
419# create nodes for not assigned areas and fill array
420# these nodes will have a negative number as key and it will be the negative equivalent to the way/area key
421foreach $keyWay (keys %placeWayName) {
422        if ($placeWayNodeId{$keyWay} == 0) {
423                push @unassignedAreas, $keyWay ;
424                $placeWayNodeId{$keyWay} = -$keyWay ;
425                $count{$placeWayType{$keyWay}} ++ ;
426                $lon{-$keyWay} = $placeWayLon{$keyWay} ;
427                $lat{-$keyWay} = $placeWayLat{$keyWay} ;
428                $placeArea{-$keyWay} = $keyWay ;
429                $placeType{-$keyWay} = $placeWayType{$keyWay} ;
430
431                # TODO population
432                $placePopulation{-$keyWay} = 0 ;
433
434                $placeName{-$keyWay} =  $placeWayName{$keyWay} ;
435                $placeNodes{-$keyWay} = 0 ;
436                $placeFixmeNodes{-$keyWay} = 0 ;
437                $placeFixmeWays{-$keyWay} = 0 ;
438                $placeResidentials{-$keyWay} = 0  ;
439                $placeResidentialsNoname{-$keyWay} = 0 ;
440                $placeResidentialLength{-$keyWay} = 0 ;
441                $placeRoads{-$keyWay} = 0  ;
442                $placeAmenities{-$keyWay} = 0 ;
443                $placeBuildings{-$keyWay} = 0 ;
444                @{$placeStreetArray{-$keyWay}} = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ;
445                $placeDistNext{-$keyWay} = 999 ;
446                $placeRadius{-$keyWay} = 0 ;
447                $placeRadiusSource{-$keyWay} = "area" ;
448                if ( ($placeWayType{$keyWay} eq "city") or ($placeWayType{$keyWay} eq "town") ) {
449                        $citiesAndTowns{-$keyWay} = 1 ;
450                }
451        }
452}
453
454# create polygons
455foreach $keyWay (keys %placeWayName) {
456        my @points = () ; my $node ;
457        foreach $node (@{$placeWayNodes{$keyWay}}) {
458                push @points, [$lon{$node}, $lat{$node}] ;
459        }
460        $placeWayPolygon{$keyWay} = Math::Polygon->new(@points) ;
461}
462
463######################
464# calc next place dist
465######################
466print "calc distances to next place...\n" ;
467foreach $key1 (keys %placeName) {
468        foreach $key2 (keys %placeName) {
469                my $d = distance ($lon{$key1}, $lat{$key1}, $lon{$key2}, $lat{$key2}) ;
470                if ( ($key1 != $key2) and ($d < $placeDistNext{$key1}) ) {
471                        $placeDistNext{$key1} = $d ;
472                }
473        }
474}
475       
476
477
478########################
479# calc auto place radius
480########################
481print "calc auto distances...\n" ;
482# build array of street nodes
483openOsmFile ($osmName) ;
484skipNodes() ;
485($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
486if ($wayId != -1) {
487        @wayNodes = @$aRef1 ;
488        @wayTags = @$aRef2 ;
489}
490while ($wayId != -1) { 
491        my $residential = 0 ;
492        if (scalar (@wayNodes) >= 2) {
493                foreach (@wayTags) {
494                        if ($_ eq "highway:residential") { $residential = 1 ; }
495                }
496
497                if ($residential) {
498                        my $resLon = ($lon{$wayNodes[0]} + $lon{$wayNodes[-1]}) / 2 ; 
499                        my $resLat = ($lat{$wayNodes[0]} + $lat{$wayNodes[-1]}) / 2 ; 
500
501                        my $lo ; my $la ;
502                        for ($lo=$resLon-$hashSpanCircle; $lo<=$resLon+$hashSpanCircle; $lo=$lo+0.1) {
503                                for ($la=$resLat-$hashSpanCircle; $la<=$resLat+$hashSpanCircle; $la=$la+0.1) {
504                                        my ($hash_value) = hashValue ($lo, $la) ;
505                                        my $key ;
506                                        foreach $key ( @{$placeHash{$hash_value}} ) {
507                                                my $i ;
508                                                for ($i=0; $i<=$#wayNodes; $i++) {
509                                                        my $d = 1000 * distance ($lon{$wayNodes[$i]}, $lat{$wayNodes[$i]}, $lon{$key}, $lat{$key}) ;
510                                                        if ($d < 1500 ) {
511                                                                ${$placeStreetArray{$key}}[(int($d/50))] ++ ;
512                                                        }
513                                                }
514                                        }
515                                }
516                        }
517                }
518        }
519        else {
520        }
521
522        # next way
523        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
524        if ($wayId != -1) {
525                @wayNodes = @$aRef1 ;
526                @wayTags = @$aRef2 ;
527        }
528}
529closeOsmFile () ;
530
531# parse street array and find place end by "hole" of 150m with no residential streets
532foreach $key (keys %placeName) {
533        my $r = -1 ;
534        my $i ;
535        my $autoCircleDetected = 0 ;
536
537        if ( ($placeRadiusSource{$key} ne "osm") and ($placeRadiusSource{$key} ne "area") ) {
538                for ($i=0; $i < scalar (@{$placeStreetArray{$key}})-2; $i++) {
539                        if (   (${$placeStreetArray{$key}}[$i] == 0) and 
540                               (${$placeStreetArray{$key}}[$i+1] == 0) and 
541                               (${$placeStreetArray{$key}}[$i+2] == 0)   and 
542                               ($r == -1) ){
543                                $r = ($i+1) * 50 ;
544                        }
545                }
546                if  ( ($r >= $minRad) ) { 
547                        if ($r > $placeDistNext{$key}*1000/2) { $r = int ($placeDistNext{$key}*100/2) * 10 ; } # other node nearby, r = rounded to 10
548                        $auto++ ; $autoCircleDetected = 1 ; $autoCircle++ ;
549                        $placeRadius{$key} = $r / 1000 ;
550                        $placeRadiusSource{$key} = "auto circle" ;
551                }
552
553        }
554}
555print "number auto sized places: $auto\n" ;
556print "number auto sized places by circle: $autoCircle\n" ;
557
558#################################################
559# parse nodes for nodeCount and other information
560#################################################
561print "get node distance and tag information...\n" ;
562
563$timeA = time() ;
564openOsmFile ($osmName) ;
565
566($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
567if ($nodeId != -1) {
568        @nodeTags = @$aRef1 ;
569}
570
571while ($nodeId != -1) {
572        # qualify node, parse for fixme etc
573        my $fixme = 0 ;
574        my $amenity = 0 ;
575        my $tag ;
576        foreach $tag (@nodeTags) {
577                if (grep (/FIXME/i, $tag)) { $fixme = 1 ; }
578                if (grep (/TODO/i, $tag)) { $fixme = 1 ; }
579                if (grep (/incomplete/i, $tag)) { $fixme = 1 ; }
580                if (grep (/^amenity:/, $tag)) { $amenity = 1 ; }
581        }
582        # look in vincinity of nodes
583        my $lo ; my $la ;
584        for ($lo=$nodeLon-$hashSpanCircle; $lo<=$nodeLon+$hashSpanCircle; $lo=$lo+0.1) {               
585                for ($la=$nodeLat-$hashSpanCircle; $la<=$nodeLat+$hashSpanCircle; $la=$la+0.1) {
586                        my ($hash_value) = hashValue ($lo, $la) ;
587                        my $key ;
588                        foreach $key ( @{$placeHash{$hash_value}} ) {
589                                if (distance ($lon{$key}, $lat{$key}, $nodeLon, $nodeLat) < $placeRadius{$key}) {
590                                        $placeNodes{$key} = $placeNodes{$key} + 1 ;
591                                        if ($fixme) { $placeFixmeNodes{$key}++ }
592                                        if ($amenity) { $placeAmenities{$key}++ }
593                                }
594                        }
595                }
596        }
597
598        # look inside place areas (WIDER scope than above!!!)
599        for ($lo=$nodeLon-$hashSpanArea; $lo<=$nodeLon+$hashSpanArea; $lo=$lo+0.1) {           
600                for ($la=$nodeLat-$hashSpanArea; $la<=$nodeLat+$hashSpanArea; $la=$la+0.1) {
601                        my ($hash_value) = hashValue ($lo, $la) ;
602                        my $key ;
603                        foreach $key ( @{$placeWayHash{$hash_value}} ) {
604                                if ($placeWayPolygon{$key}->contains([$nodeLon, $nodeLat])) {
605                                        $placeNodes{$placeWayNodeId{$key}} ++ ;
606                                        if ($fixme) { $placeFixmeNodes{$placeWayNodeId{$key}}++ }
607                                        if ($amenity) { $placeAmenities{$placeWayNodeId{$key}}++ }
608                                }
609                        }
610                }
611        }
612
613        # next node
614        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
615        if ($nodeId != -1) {
616                @nodeTags = @$aRef1 ;
617        }
618}
619
620################################
621# parse ways for way information
622################################
623print "get way information...\n" ;
624
625$timeA = time() ;
626my $progress2 ;
627
628($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
629if ($wayId != -1) {
630        @wayNodes = @$aRef1 ;
631        @wayTags = @$aRef2 ;
632}
633while ($wayId != -1) { 
634        $wayCount++ ;
635        my $fixme = 0 ;
636        my $residential = 0 ;
637        my $Length = 0 ;
638        my $road = 0 ;
639        my $connecting = 0 ;
640        my $name = 0 ;
641        my $building = 0 ;
642        my $tmpName = "-" ;
643        if (scalar (@wayNodes) >= 2) {
644                my $tag ; 
645                foreach $tag (@wayTags) {
646                        my $tmp1 = $tag ;
647                        if  ( ($tmp1 =~ s/://g ) == 1 ) {
648                                if ( $tag eq "highway:residential" ) { $residential = 1 ; }
649                                if ( $tag eq "highway:service" ) { $residential = 1 ; }
650                                if ( $tag eq "highway:unclassified" ) { $residential = 1 ; }
651                                if ( $tag eq "highway:living_street" ) { $residential = 1 ; }
652                                if ( $tag eq "highway:primary" ) { $connecting = 1 ; }
653                                if ( $tag eq "highway:secondary" ) { $connecting = 1 ; }
654                                if ( $tag eq "highway:tertiary" ) { $connecting = 1 ; }
655                                if (grep (/^name:/, $tag)) { $name = 1 ; $tmpName = $tag ; $tmpName =~ s/name:// ; $tmpName =~ s/;/-/g ; }
656                                if ( $tag eq "highway:road" ) { $road = 1 ; }
657                                if ( $tag eq "building:yes" ) { $building = 1 ; }
658                                if (grep (/FIXME/i, $tag)) { $fixme = 1 ; }
659                                if (grep (/TODO/i, $tag)) { $fixme = 1 ; }
660                                if (grep (/incomplete/i, $tag)) { $fixme = 1 ; }
661                        }
662                }
663
664                if ($residential or $connecting) {
665                        # calc street length
666                        my $i ;
667                        for ($i = 0; $i<$#wayNodes; $i++) {
668                                $Length += distance ($lon{$wayNodes[$i]}, $lat{$wayNodes[$i]}, $lon{$wayNodes[$i+1]}, $lat{$wayNodes[$i+1]}) ;
669                        }
670                }
671                if ($residential or $connecting or $road or $building or $fixme) {
672                        my $resLon = ($lon{$wayNodes[0]} + $lon{$wayNodes[-1]}) / 2 ; 
673                        my $resLat = ($lat{$wayNodes[0]} + $lat{$wayNodes[-1]}) / 2 ; 
674
675                        # in node of node hash?
676                        my $lo ; my $la ;
677                        for ($lo=$resLon-$hashSpanCircle; $lo<=$resLon+$hashSpanCircle; $lo=$lo+0.1) {
678                                for ($la=$resLat-$hashSpanCircle; $la<=$resLat+$hashSpanCircle; $la=$la+0.1) {
679                                        my ($hash_value) = hashValue ($lo, $la) ;
680                                        my $key ;
681                                        foreach $key ( @{$placeHash{$hash_value}} ) {
682                                                if (distance ($resLon, $resLat, $lon{$key}, $lat{$key}) <  $placeRadius{$key} ) {
683                                                        if ($residential) { 
684                                                                $placeResidentials{$key}++ ; 
685                                                                $placeResidentialLength{$key} = $placeResidentialLength{$key} + $Length ; 
686                                                                if ($name == 0) { 
687                                                                        $placeResidentialsNoname{$key}++ ; 
688                                                                } 
689                                                        } 
690                                                        if (($residential or $connecting) and ($name) ) {
691                                                                if (! defined (${$placeStreets{$key}}{$tmpName}) ) {
692                                                                        ${$placeStreets{$key}}{$tmpName} = $Length ; 
693                                                                }       
694                                                                else {
695                                                                        ${$placeStreets{$key}}{$tmpName} += $Length ;
696                                                                }
697                                                        }
698                                                        if ($road) { $placeRoads{$key}++ ; } 
699                                                        if ($building) { $placeBuildings{$key}++ ; } 
700                                                        if ($fixme) { $placeFixmeWays{$key}++ ; }
701                                                }
702                                        }
703                                }
704                        }
705
706                        # in wayHash area ?
707                        for ($lo=$resLon-$hashSpanArea; $lo<=$resLon+$hashSpanArea; $lo=$lo+0.1) {
708                                for ($la=$resLat-$hashSpanArea; $la<=$resLat+$hashSpanArea; $la=$la+0.1) {
709                                        my ($hash_value) = hashValue ($lo, $la) ;
710                                        my $key ;
711                                        foreach $key ( @{$placeWayHash{$hash_value}} ) {
712                                                if ( $placeWayPolygon{$key}->contains([$resLon, $resLat]) ) {
713                                                        if ($residential) { 
714                                                                $placeResidentials{$placeWayNodeId{$key}}++ ; 
715                                                                $placeResidentialLength{$placeWayNodeId{$key}} = $placeResidentialLength{$placeWayNodeId{$key}} + $Length ; 
716                                                                if ($name == 0) { $placeResidentialsNoname{$placeWayNodeId{$key}}++ ; } 
717                                                        } 
718                                                        if (($residential or $connecting) and ($name) ) {
719                                                                if (! defined (${$placeStreets{$placeWayNodeId{$key}}}{$tmpName}) ) {
720                                                                        ${$placeStreets{$placeWayNodeId{$key}}}{$tmpName} = $Length ; 
721                                                                }       
722                                                                else {
723                                                                        ${$placeStreets{$placeWayNodeId{$key}}}{$tmpName} += $Length ;
724                                                                }
725                                                        }
726                                                        if ($road) { $placeRoads{$placeWayNodeId{$key}}++ ; } 
727                                                        if ($building) { $placeBuildings{$placeWayNodeId{$key}}++ ; } 
728                                                        if ($fixme) { $placeFixmeWays{$placeWayNodeId{$key}}++ ; }
729                                                }
730                                        }
731                                }
732                        }
733                }
734        }
735        else {
736                $invalidWays++ ;
737        }
738        # next way
739        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
740        if ($wayId != -1) {
741                @wayNodes = @$aRef1 ;
742                @wayTags = @$aRef2 ;
743        }
744}
745
746closeOsmFile () ;
747
748print "number ways: $wayCount\n" ;
749print "number invalid ways (1 node only): $invalidWays\n" ;
750
751############
752# calc means
753############
754print "calc means...\n" ;
755# mean nodes
756foreach $key (keys %dists) {
757        my $nodes = 0 ;
758        my $num = 0 ;
759        foreach $key2 (keys %placeType) {
760                if ($placeType{$key2} eq $key) { $num++ ; $nodes += $placeNodes{$key2} ; }
761        }
762        if ($num != 0) {
763                $meanNodes{$key} = $nodes / $num ;
764        }
765        else {
766                $meanNodes{$key} = 99999 ;
767        }
768}
769# mean residentials
770foreach $key (keys %dists) {
771        my $occ = 0 ;
772        my $num = 0 ;
773        foreach $key2 (keys %placeType) {
774                if ($placeType{$key2} eq $key) { $num++ ; $occ += $placeResidentials{$key2} ; }
775        }
776        if ($num != 0) {
777                $meanHwyRes{$key} = $occ / $num ;
778        }
779        else {
780                $meanHwyRes{$key} = 99999 ;
781        }
782}
783# mean res. length
784foreach $key (keys %dists) {
785        my $sum = 0 ;
786        my $num = 0 ;
787        foreach $key2 (keys %placeType) {
788                if ($placeType{$key2} eq $key) { $num++ ; $sum += $placeResidentialLength{$key2} ; }
789        }
790        if ($num != 0) {
791                $meanHwyResLen{$key} = $sum / $num ;
792        }
793        else {
794                $meanHwyResLen{$key} = 99999 ;
795        }
796}
797# mean amenities
798foreach $key (keys %dists) {
799        my $sum = 0 ;
800        my $num = 0 ;
801        foreach $key2 (keys %placeType) {
802                if ($placeType{$key2} eq $key) { $num++ ; $sum += $placeAmenities{$key2} ; }
803        }
804        if ($num != 0) {
805                $meanAmenities{$key} = $sum / $num ;
806        }
807        else {
808                $meanAmenities{$key} = 99999 ;
809        }
810}
811# mean buildings
812foreach $key (keys %dists) {
813        my $sum = 0 ;
814        my $num = 0 ;
815        foreach $key2 (keys %placeType) {
816                if ($placeType{$key2} eq $key) { $num++ ; $sum += $placeBuildings{$key2} ; }
817        }
818        if ($num != 0) {
819                $meanBuildings{$key} = $sum / $num ;
820        }
821        else {
822                $meanBuildings{$key} = 99999 ;
823        }
824}
825
826#########################
827# find superior city/town
828#########################
829print "find nearest city/town for smaller places...\n" ;
830my $placekey1 ; my $placekey2 ; 
831foreach $placekey1 (keys %placeName) {
832        $placeSuperior {$placekey1} = "-" ;
833        $placeSuperiorDist {$placekey1} = 9999 ;
834        if (($placeType {$placekey1} eq "city") or ($placeType {$placekey1} eq "town")) {
835                # do nothing
836        } 
837        else {
838                foreach $placekey2 (keys %citiesAndTowns) {
839                        my $dist = distance ($lon{$placekey1}, $lat{$placekey1}, $lon{$placekey2}, $lat{$placekey2}) ;
840                        if (  ($dist < $placeSuperiorDist {$placekey1})  ) {
841                                $placeSuperior {$placekey1} = $placeName {$placekey2} ;
842                                $placeSuperiorDist {$placekey1} = $dist ;
843                        }
844                }
845        }
846}
847
848################################
849# count unmapped/sparsely mapped
850################################
851foreach (keys %dists) { $unmappedCount{$_} = 0 ; $sparselyCount{$_} = 0 ; } 
852foreach $key (keys %placeName) {
853        if ($placeNodes{$key} < $unmapped{$placeType{$key}}) {
854                $unmappedCount{$placeType{$key}} ++ ;
855        }
856        else {
857                if ($placeNodes{$key} < $sparse{$placeType{$key}}) {
858                        $sparselyCount{$placeType{$key}} ++ ;
859                }       
860        }
861}
862
863##############
864# DRAW PICTURE
865##############
866print "init picture...\n" ;
867# calc boundaries and init
868$lonMin = 999 ; $lonMax = -999 ; $latMin = 999 ; $latMax = -999 ;
869foreach $key (keys %lon) {
870        if ($lon{$key} > $lonMax) { $lonMax = $lon{$key} ; }
871        if ($lon{$key} < $lonMin) { $lonMin = $lon{$key} ; }
872        if ($lat{$key} > $latMax) { $latMax = $lat{$key} ; }
873        if ($lat{$key} < $latMin) { $latMin = $lat{$key} ; }
874}
875initGraph ($size, $lonMin, $latMin, $lonMax, $latMax) ;
876
877openOsmFile ($osmName) ;
878skipNodes () ;
879print "drawing areas...\n" ;
880($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
881if ($wayId != -1) {
882        @wayNodes = @$aRef1 ;
883        @wayTags = @$aRef2 ;
884}
885while ($wayId != -1) {
886        foreach $key (@wayTags) {
887                if ($key eq "waterway:riverbank") {
888                        drawArea ("lightblue", nodes2Coordinates(@wayNodes)) ;
889                }
890                if ($key eq "natural:water") {
891                        drawArea ("lightblue", nodes2Coordinates(@wayNodes)) ;
892                }
893                if ( ($key eq "landuse:forest") or ($key eq "natural:wood") ) {
894                        drawArea ("lightbrown", nodes2Coordinates(@wayNodes)) ;
895                }
896                if ( ($key eq "landuse:farm") or ($key eq "landuse:village_green") ) {
897                        drawArea ("lightgreen", nodes2Coordinates(@wayNodes)) ;
898                }
899                if ($key eq "landuse:residential") {
900                        drawArea ("lightgray", nodes2Coordinates(@wayNodes)) ;
901                }
902        }       
903        # next
904        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
905        if ($wayId != -1) {
906                @wayNodes = @$aRef1 ;
907                @wayTags = @$aRef2 ;
908        }
909}
910
911closeOsmFile () ;
912
913################
914# draw amenities
915################
916openOsmFile ($osmName) ;
917print "drawing amenities...\n" ;
918
919($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
920if ($nodeId != -1) {
921        @nodeTags = @$aRef1 ;
922}
923while ($nodeId != -1) {
924        my $tag ; my $amenity = 0 ;
925        foreach $tag (@nodeTags) {
926                if (grep (/^amenity:/, $tag)) { $amenity = 1 ; }
927        }
928        if ($amenity) {
929                drawNodeDot ($nodeLon, $nodeLat, "orange", 4) ; 
930        }
931        # next node
932        ($nodeId, $nodeLon, $nodeLat, $nodeUser, $aRef1) = getNode () ;
933        if ($nodeId != -1) {
934                @nodeTags = @$aRef1 ;
935        }
936}
937
938###########
939# draw ways
940###########
941print "drawing ways...\n" ;
942($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
943if ($wayId != -1) {
944        @wayNodes = @$aRef1 ;
945        @wayTags = @$aRef2 ;
946}
947while ($wayId != -1) {
948        foreach $key (@wayTags) {
949                if ($key eq "highway:residential") {
950                        drawWay ("darkgray", 2, nodes2Coordinates(@wayNodes)) ;
951                }
952                if ( ($key eq "highway:service") or ($key eq "highway:unclassified") or ($key eq "highway:road")) {
953                        drawWay ("gray", 1, nodes2Coordinates(@wayNodes)) ;
954                }
955                if ( ($key eq "waterway:river") or ($key eq "waterway:stream") ) {
956                        drawWay ("lightblue", 1, nodes2Coordinates(@wayNodes)) ;
957                }
958                if ($key eq "highway:motorway") {
959                        drawWay ("blue", 3, nodes2Coordinates(@wayNodes)) ;
960                }
961                if ($key eq "highway:motorway_link") {
962                        drawWay ("blue", 2, nodes2Coordinates(@wayNodes)) ;
963                }
964                if ($key eq "highway:trunk") {
965                        drawWay ("blue", 3, nodes2Coordinates(@wayNodes)) ;
966                }
967                if ($key eq "highway:trunk_link") {
968                        drawWay ("blue", 2, nodes2Coordinates(@wayNodes)) ;
969                }
970                if ( ($key eq "highway:primary") or ($key eq "highway:primary_link") ) {
971                        drawWay ("red", 2, nodes2Coordinates(@wayNodes)) ;
972                }
973                if ($key eq "highway:secondary") {
974                        drawWay ("red", 2, nodes2Coordinates(@wayNodes)) ;
975                }
976                if ($key eq "highway:tertiary") {
977                        drawWay ("darkgreen", 2, nodes2Coordinates(@wayNodes)) ;
978                }
979        }       
980        # next 
981        ($wayId, $wayUser, $aRef1, $aRef2) = getWay () ;
982        if ($wayId != -1) {
983                @wayNodes = @$aRef1 ;
984                @wayTags = @$aRef2 ;
985        }
986}
987closeOsmFile () ;
988
989####################################
990# draw place names and areas/circles
991####################################
992print "draw places...\n" ;
993foreach $key (keys %placeName) {
994        my $data ;
995        drawTextPos ($lon{$key}, $lat{$key}, 0, 0, $placeName{$key}, "black", 2) ;
996
997        $data = $placeNodes{$key} . "Nds " . $placeResidentials{$key} ."Res " . int ($placeResidentialLength{$key} + 0.5) . "RLen " . $placeAmenities{$key} . "Am " . $placeBuildings{$key} . "Bld" ;
998        drawTextPos ($lon{$key}, $lat{$key}, 0, -15, $data, "blue", 2) ;
999
1000        if ($placeRadiusSource{$key} eq "default") {
1001                drawCircleRadiusText ($lon{$key}, $lat{$key}, $placeRadius{$key}*1000, 1, "darkgray", "default " . $placeRadius{$key}*1000 . "m" ) ;
1002        }
1003        if ($placeRadiusSource{$key} eq "osm") {
1004                drawCircleRadiusText ($lon{$key}, $lat{$key}, $placeRadius{$key}*1000, 1, "blue", "osm " . $placeRadius{$key}*1000 . "m" ) ;
1005        }
1006        if ($placeRadiusSource{$key} eq "auto circle") {
1007                drawCircleRadiusText ($lon{$key}, $lat{$key}, $placeRadius{$key}*1000, 1, "tomato", "auto circle " . $placeRadius{$key}*1000 . "m" ) ;
1008        }
1009        if ($placeRadiusSource{$key} eq "area") {
1010                drawWay ("blue", 2, nodes2Coordinates( @{$placeWayNodes{$placeArea{$key}}} )) ; 
1011        }
1012}
1013
1014########################
1015# draw other information
1016########################
1017print "draw other information and save picture...\n" ;
1018drawLegend (3, "Farm", "lightgreen", "Forest", "lightbrown", "Amenity", "orange", "Water", "lightblue", "Residential", "darkgray", "Tertiary", "darkgreen", "Primary/Secondary", "red", "Motorway", "blue", "Legend", "black") ;
1019drawRuler ("darkgray") ;
1020drawHead ("gary68's mapping quality for " . stringFileInfo ($osmName), "black", 3) ;
1021drawFoot ("data by www.openstreetmap.org", "gray", 2) ;
1022writeGraph ($pngName) ;
1023
1024$time1 = time () ;
1025
1026##################
1027# PRINT HTML INFOS
1028##################
1029print "write output files...\n" ;
1030open ($html, ">", $htmlName) || die ("Can't open html output file") ;
1031open ($text, ">", $textName) || die ("Can't open text output file") ;
1032open ($csv, ">", $csvName) || die ("Can't open csv output file") ;
1033print $csv stringFileInfo ($osmName), "\n\n" ;
1034
1035printHTMLHeader ($html, "Mapping Quality by Gary68") ;
1036print $html "<H1>Mapping Quality by Gary68</H1>\n" ;
1037print $html "<p>Version ", $version, "</p>\n" ;
1038print $html "<H2>Info and statistics</H2>\n" ;
1039print $html "<p>", stringFileInfo ($osmName), "<br>\n" ;
1040
1041# print counts to HTML
1042printHTMLTableHead ($html) ;
1043printHTMLTableHeadings ($html, "Type", "Count", "unmapped", "percent", "sparsely mapped", "percent") ; 
1044printHTMLRowStart ($html) ;
1045my $um = 0 ; my $sm = 0 ; my $ump ; my $smp ;
1046foreach $key (keys %unmapped) {
1047        $um += $unmappedCount{$key} ;
1048        $sm += $sparselyCount{$key} ;
1049} 
1050$ump = int ($um / $place_count *100) ;
1051$smp = int ($sm / $place_count * 100) ;
1052printHTMLCellLeft ($html, "total") ; printHTMLCellRight ($html, $place_count) ;
1053printHTMLCellRight ($html, $um) ; printHTMLCellRight ($html, $ump . "%") ;
1054printHTMLCellRight ($html, $sm) ; printHTMLCellRight ($html, $smp . "%") ;
1055printHTMLRowEnd ($html) ;
1056foreach $key (sort keys %count) { 
1057        if ($count{$key} > 0) {
1058                $ump = int ($unmappedCount{$key} / $count{$key} *100) ;
1059                $smp = int ($sparselyCount{$key} / $count{$key} * 100) ;
1060        }
1061        else {
1062                $ump = "-" ; $smp = "-" ;
1063        }
1064        printHTMLRowStart ($html) ;
1065        printHTMLCellLeft ($html, $key) ; 
1066        printHTMLCellRight ($html, $count{$key}) ; 
1067        printHTMLCellRight ($html, $unmappedCount{$key}) ; 
1068        printHTMLCellRight ($html, $ump . "%") ;
1069        printHTMLCellRight ($html, $sparselyCount{$key}) ; 
1070        printHTMLCellRight ($html, $smp . "%") ;
1071        printHTMLRowEnd ($html) ;
1072} 
1073printHTMLTableFoot ($html) ;
1074
1075my $percent ;
1076if ($assignedAreas >0) { $percent = int ($assignedAreas / $areaCount * 100) ; } else { $percent = 0 ; }
1077print $html "<p>valid place areas found: $areaCount<br>\n" ;
1078print $html "areas that could be assigned to a place node: $assignedAreas, about $percent percent<br>\n" ;
1079print $html "open areas found: $areaOpenCount<br>\n" ;
1080print $html "areas without name found: $areaNoNameCount</p>\n" ;
1081
1082print $html "<H3>Unassigned place areas</H3>\n" ;
1083printHTMLTableHead ($html) ;
1084printHTMLTableHeadings ($html, "way key", "way name", "way type", "JOSM") ; 
1085foreach $key (@unassignedAreas) {
1086        printHTMLTableRowLeft ($html, $key, $placeWayName{$key}, $placeWayType{$key}, josmLinkSelectWay ($placeWayLon{$key}, $placeWayLat{$key}, 0.05, $key)) ;
1087}
1088printHTMLTableFoot ($html) ;
1089
1090print $html "<H3>Unused place ways</H3>\n" ;
1091print $html "<p>Open Areas: " ;
1092foreach $key (@placeWayOpen) {
1093        print $html historyLink ("way", $key), " " ;
1094}
1095print $html "</p>" ;
1096print $html "<p>Areas without name: " ;
1097foreach $key (@placeWayNoName) {
1098        print $html historyLink ("way", $key), " " ;
1099}
1100print $html "</p>" ;
1101
1102print $html "<H3>Auto detected place sizes</H3>\n" ;
1103print $html "<p>total: $auto<br>\n" ;
1104print $html "circle: $autoCircle<br>\n" ;
1105
1106
1107
1108# print parameters
1109print $html "<H3>Parameters</H3>" ;
1110printHTMLTableHead ($html) ;
1111printHTMLTableHeadings ($html, "Place", "Distance", "Sparse Threshold", "Unmapped Threshold") ; 
1112foreach $key2 (sort keys %dists) {
1113        print $html "<tr><td>$key2</td> <td align=\"right\">$dists{$key2}</td> <td align=\"right\">$sparse{$key2}</td> <td align=\"right\">$unmapped{$key2}</td></tr>\n" ;
1114}
1115printHTMLTableFoot ($html) ;
1116
1117# print means
1118print $html "<H3>Mean numbers per place type / DE Mittelwerte</H3>" ;
1119printHTMLTableHead ($html) ;
1120printHTMLTableHeadings ($html, "Place", "Mean Nodes / Knoten", "Mean Hwy Res / Wohnstraßen", "Mean Hwy Res Length / Wohnstr.-Länge", "Mean Amenities / Annehmlichkeiten", "Mean Buildings / Gebäude") ;
1121foreach $key (sort keys %dists) {
1122        print $html "<tr>\n" ;
1123        print $html "<td>$key</td>" ;
1124        printf $html "<td align=\"right\">%i</td>\n", $meanNodes{$key} ;
1125        printf $html "<td align=\"right\">%i</td>\n", $meanHwyRes{$key} ;
1126        printf $html "<td align=\"right\">%i</td>\n", $meanHwyResLen{$key} ;
1127        printf $html "<td align=\"right\">%i</td>\n", $meanAmenities{$key} ;
1128        printf $html "<td align=\"right\">%i</td>\n", $meanBuildings{$key} ;
1129        print $html "</tr>\n" ;
1130}
1131printHTMLTableFoot ($html) ;
1132
1133# print unmapped/sparsely mapped file information
1134print $text "lat\tlon\ttitle\tdescription\ticon\ticonSize\ticonOffset\n" ;
1135
1136print $html "<H2>Details unmapped/sparsely mapped</H2>\n" ;
1137print $html "<p><strong>For details of all places see next section!</strong></p>" ;
1138print $html "<p>To decide whether a place is potentially mapped or sparsely mapped two numbers are used per place type to compare against " ;
1139print $html "the actual node count. Only nodes are counted that are located within a certain distance (per place) from the place node.</p>" ;
1140print $html "<p><strong>DE</strong> Um zu entscheiden, ob ein Ort kartografiert ist oder nicht werden zwei Schwellwerte je Ort-Typ herangezogen, gegen die die tatsächliche Node-Anzahl verglichen wird. Es werden nur Nodes innerhalb eines bestimmten Radius gewertet.</p>" ; 
1141
1142printHTMLTableHead ($html) ;
1143printHTMLTableHeadings ($html, "Place", "Type", "Near", "Attribute", "Node count") ;
1144foreach $key (keys %placeType) {
1145        my $tmp ; my $icon ;
1146        if ($placeNodes{$key} < $sparse{$placeType{$key}}) {
1147                if ($placeNodes{$key} < $unmapped{$placeType{$key}}) {
1148                        $tmp = "unmapped" ;
1149                        $icon = $iconRed ;
1150                }
1151                else {
1152                        $tmp = "sparsely mapped" ;
1153                        $icon = $iconYellow ;
1154                }
1155                my $out =  "<tr>\n" ;
1156                $out = $out . "<td>" . $placeName{$key} . "</td>\n" ;
1157                $out = $out . "<td>" . $placeType{$key} . "</td>\n" ;
1158                $out = $out . "<td>" . $placeSuperior {$key} . "</td>\n" ;
1159                $out = $out . "<td>" . $tmp . "</td>\n" ;
1160                $out = $out . "<td align=\"right\">" . $placeNodes{$key} . "</td>\n" ;
1161                $out = $out . "</tr>\n" ;
1162                push @outArray, $out ;
1163
1164                # slippy file
1165                print $text $lat {$key}, "\t" ;
1166                print $text $lon {$key}, "\t" ;
1167                print $text $placeName {$key}, "\t" ;
1168                print $text "potentially $tmp place=$placeType{$key}\t" ;
1169                print $text "./", $icon, "\t" ;
1170                print $text "24,24", "\t" ;
1171                print $text "-12,-12", "\n" ;
1172        }
1173}
1174@outArray = sort @outArray ;
1175foreach (@outArray) { print $html $_ ; }
1176printHTMLTableFoot ($html) ;
1177
1178close ($text) ;
1179
1180@outArray = () ;
1181
1182print $csv "Place;Type;NodeId;Rad(m);RadiusSource;AreaId;Population;Near;Nodes;FixmeNodes;Residentials;ResLength;ResNoName;Roads;FixmeWays;Amenities;Buildings\n" ;
1183
1184print $html "<H2>Details all information</H2>\n" ;
1185print $html "<H3>Legend</H3>\n" ;
1186printHTMLTableHead ($html) ;
1187printHTMLTableHeadings ($html, "Column", "Meaning/Explanation", "<strong>DE</strong> Bedeutung/Erklärung") ;
1188printHTMLTableRowLeft ($html, "Name", "Place Name", "Ort Name") ;
1189# TODO if time
1190print $html "<tr><td>Type</td><td>Place Type</td><td>Ort Typ</td></tr>\n" ;
1191print $html "<tr><td>Popul.</td><td>Population from same key or OpenGeoDB entry</td><td>Einwohner</td></tr>\n" ;
1192print $html "<tr><td>Near</td><td>Location of place</td><td>Liegt in der Nähe von</td></tr>\n" ;
1193print $html "<tr><td>Nodes</td><td>Number of nodes inside place distance</td><td>Anzahl Knoten</td></tr>\n" ;
1194print $html "<tr><td>Fixme Nds</td><td>number of nodes with FIXME or similar tag</td><td>Anzahl FIXME Knoten</td></tr>\n" ;
1195print $html "<tr><td>Hwy Res</td><td>number of highways=residential inside place distance</td><td>Anzahl Wohnstraßen</td></tr>\n" ;
1196print $html "<tr><td>Res Len</td><td>length of these residentials</td><td>Länge der Wohnstraßen</td></tr>\n" ;
1197print $html "<tr><td>Res w/o n.</td><td>number of residentials without name inside place distance</td><td>Wohnstraßen ohne Name</td></tr>\n" ;
1198print $html "<tr><td>Roads</td><td>number of roads inside place distance</td><td>Anzahl Roads</td></tr>\n" ;
1199print $html "<tr><td>Fixme Ways</td><td>number of ways with FIXME or similar tag inside place distance</td><td>Anzahl FIXME ways</td></tr>\n" ;
1200print $html "<tr><td>Amenit.</td><td>number of amenities inside place distance</td><td>Anzahl Annhemlichkeiten</td></tr>\n" ;
1201print $html "<tr><td>Build.</td><td>number of buildings inside place distance</td><td>Anzahl Gebäude</td></tr>\n" ;
1202printHTMLTableFoot ($html) ;
1203
1204# print data
1205print $html "<H3>Data</H3>\n" ;
1206printHTMLTableHead ($html) ;
1207printHTMLTableHeadings ($html, "Place", "Type", "Rad(km)", "Popul.", "Near", "Nodes", "FIXME Nds", "Hwy Res", "Res Len", "Res w/o n.", "Roads", "FIXME ways", "Ameni.", "Buildings") ;
1208foreach $key (keys %placeType) {
1209        my $out = "<tr>\n" ;
1210        $out = $out . "<td>" . $placeName{$key} . " " . historyLink ("node", $key) . " " . josmLinkSelectNode ($lon{$key}, $lat{$key}, 0.005, $key) . "</td>\n" ;
1211        $out = $out . "<td>" . $placeType{$key} . "</td>\n" ;
1212        $out = $out . "<td align=\"right\">" . $placeRadiusSource{$key} . " " . $placeRadius{$key} . "</td>\n" ;
1213        $out = $out . tableCellZeroRed ($placePopulation{$key}) ;
1214        $out = $out . "<td>" . $placeSuperior{$key} . "</td>\n" ;
1215        $out = $out . tableCellNodes ($placeNodes{$key}, $sparse{$placeType{$key}}, $unmapped{$placeType{$key}} )  ;
1216        $out = $out . tableCellZero ($placeFixmeNodes{$key} ) ;
1217        $out = $out . "<td align=\"right\">" . $placeResidentials{$key} . "</td>\n" ;
1218        my $tmp = int ($placeResidentialLength{$key} + 0.5 )  ;
1219        $out = $out . "<td align=\"right\">" . $tmp . "</td>\n" ;
1220        $out = $out . tableCellZero ($placeResidentialsNoname{$key} ) ;
1221        $out = $out . tableCellZero ($placeRoads{$key} ) ;
1222        $out = $out . tableCellZero ($placeFixmeWays{$key} ) ;
1223        $out = $out . tableCellZeroRed ($placeAmenities{$key} ) ;
1224        $out = $out . tableCellZeroRed ($placeBuildings{$key} ) ;
1225        $out = $out . "</tr>\n" ;
1226        push @outArray, $out ;
1227
1228        $out = $placeName{$key} . ";" ;
1229        $out = $out . $placeType{$key} . ";" ;
1230        $out = $out . $key . ";" ;
1231        $out = $out . $placeRadius{$key}*1000 . ";" ;
1232        $out = $out . $placeRadiusSource{$key} . ";" ;
1233        $out = $out . $placeArea{$key} . ";" ;
1234        $out = $out . $placePopulation{$key} . ";" ;
1235        $out = $out . $placeSuperior {$key} . ";" ;
1236        $out = $out . $placeNodes{$key} . ";" ;
1237        $out = $out . $placeFixmeNodes{$key} . ";" ;
1238        $out = $out . $placeResidentials{$key} . ";" ;
1239        $out = $out . $tmp . ";" ; # RES LENGTH !
1240        $out = $out . $placeResidentialsNoname{$key} . ";" ;
1241        $out = $out . $placeRoads{$key} . ";" ;
1242        $out = $out . $placeFixmeWays{$key} . ";" ;
1243        $out = $out . $placeAmenities{$key} . ";" ;
1244        $out = $out . $placeBuildings{$key} ; # ATTENTION: no colon here!!!
1245        $out = $out . "\n" ;
1246        print $csv $out ;
1247}
1248@outArray = sort @outArray ;
1249foreach (@outArray) { print $html $_ ; }
1250printHTMLTableFoot ($html) ;
1251
1252########
1253# FINISH
1254########
1255print $html "<p>", stringTimeSpent ($time1-$time0), "</p>\n" ;
1256printHTMLFoot ($html) ;
1257close ($html) ;
1258close ($text) ;
1259close ($csv) ;
1260
1261open ($street, ">", $streetName) || die ("Can't open street csv output file") ;
1262print $street stringFileInfo ($osmName), "\n\n" ;
1263print $street "PlaceName;PlaceKey;Street;Length(m)\n" ;
1264my $k1 ; my $k2 ; my @printArray ;
1265foreach $k1 (keys %placeStreets) {
1266        foreach $k2 (sort keys %{$placeStreets{$k1}}) {
1267                my $len = int (${$placeStreets{$k1}}{$k2} * 1000) ;
1268                push @printArray, $placeName{$k1}. ";" . $k1. ";" . $k2. ";" . $len . "\n" ;
1269        }
1270}
1271@printArray = sort @printArray ;
1272foreach (@printArray) {
1273        print $street $_ ;
1274}
1275close ($street) ;
1276
1277
1278print "\n$program finished after ", stringTimeSpent ($time1-$time0), "\n\n" ;
1279
1280#############################################################################################################
1281# sub routines
1282#############################################################################################################
1283
1284sub tableCellMean {
1285        my ($value, $mean) = @_ ;
1286        my $color ;
1287
1288        if ($value >= (1.5 * $mean) ) {
1289                $color = $colorGreen ; 
1290        }
1291        else {
1292                if ($value >= $mean) {
1293                        $color = $colorGrey ;   
1294                }
1295                else {
1296                        if ($value >= 0.5 * $mean) {
1297                                $color = $colorOrange ; 
1298                        }
1299                        else {
1300                                $color = $colorRed ;   
1301                        }
1302                }
1303        }
1304        return ("<td align=\"right\" bgcolor=\"" . $color . "\">" . $value . "</td>") ;
1305}
1306
1307sub tableCellZero {
1308        my $value = shift ;
1309        my $color ;
1310        if ($value == 0 ) {
1311                $color = $colorGreen ; 
1312        }
1313        else
1314        {
1315                $color = $colorRed ;   
1316        }
1317        return ("<td align=\"right\" bgcolor=\"" . $color . "\">" . $value . "</td>") ;
1318}
1319
1320sub tableCellZeroRed {
1321        my $value = shift ;
1322        my $color ;
1323        if ($value == 0 ) {
1324                $color = $colorRed ;   
1325        }
1326        else
1327        {
1328                $color = $colorGreen ; 
1329        }
1330        return ("<td align=\"right\" bgcolor=\"" . $color . "\">" . $value . "</td>") ;
1331}
1332
1333sub tableCellNodes {
1334        my ($value, $sm, $um) = @_ ;
1335        my $color ;
1336        if ($value > $sm ) {
1337                $color = $colorGreen ; 
1338        }
1339        else {
1340                if ($value > $um) {
1341                        $color = $colorOrange ;
1342                }
1343                else {
1344                        $color = $colorRed ;
1345                }
1346        }
1347        return ("<td align=\"right\" bgcolor=\"" . $color . "\">" . $value . "</td>") ;
1348}
1349
1350
1351sub nodes2Coordinates {
1352#
1353# transform list of nodeIds to list of lons/lats
1354#
1355        my @nodes = @_ ;
1356        my $i ;
1357        my @result = () ;
1358
1359        #print "in @nodes\n" ;
1360
1361        for ($i=0; $i<=$#nodes; $i++) {
1362                push @result, $lon{$nodes[$i]} ;
1363                push @result, $lat{$nodes[$i]} ;
1364        }
1365        return @result ;
1366}
1367
1368
Note: See TracBrowser for help on using the repository browser.