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

Last change on this file since 21494 was 16562, checked in by gary68, 10 years ago

initial upload of several programs

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