source: subversion/applications/utils/gary68/useractivity.pl @ 17683

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

ua version 2.1 privacy for time slot reports

  • Property svn:executable set to *
File size: 40.4 KB
Line 
1#
2#
3# useractivity.pl by gary68
4#
5#
6#
7# Copyright (C) 2009, Gerhard Schwanz
8#
9# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the
10# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
16#
17#
18# Version 2
19# - map support added
20# - way support added
21#
22# Version 2.1
23# - separate files for time slots (privacy)
24#
25
26use strict ;
27use warnings ;
28
29use OSM::osm ;
30use OSM::osmgraph ;
31use File::stat;
32use Time::localtime;
33
34my $program = "useractivity.pl" ;
35my $usage = $program . " file1.osm file2.osm out.htm Mode numTopUsers picSize (Mode = [N|P|D|S|PD], picSize x in pixels)" ;
36my $version = "2.1" ;
37
38my $topMax = 10 ;
39
40my %lon1 ; my %lat1 ; my %lon2 ; my %lat2 ;
41my $wayId1 ; my $wayVersion1 ; my $wayTimestamp1 ; my $wayUid1 ; my $wayUser1 ; my $wayChangeset1 ; my @wayNodes1 ; my @wayTags1 ;
42my $wayId2 ; my $wayVersion2 ; my $wayTimestamp2 ; my $wayUid2 ; my $wayUser2 ; my $wayChangeset2 ; my @wayNodes2 ; my @wayTags2 ;
43
44my $nodeId1 ; my $nodeUser1 ; my $nodeLat1 ; my $nodeLon1 ; my @nodeTags1 ; my $nodeVersion1 ; my $nodeTimestamp1 ; my $nodeUid1 ; my $nodeChangeset1 ;
45my $nodeId2 ; my $nodeUser2 ; my $nodeLat2 ; my $nodeLon2 ; my @nodeTags2 ; my $nodeVersion2 ; my $nodeTimestamp2 ; my $nodeUid2 ; my $nodeChangeset2 ;
46my $aRef1 ; my $aRef2 ;
47
48my $time0 = time() ; 
49
50my $mode = "" ; my $sizeX = 1024 ;
51my $html ; my $htmlName ;
52my $osm1Name ; my $osm2Name ;
53
54my $file1 ; my $file2 ; my $bz1 ; my $bz2 ; my $isBz21 ; my $isBz22 ; my $line1 ; my $line2 ; my $bzerrno ;
55my $file1Name ; my $file2Name ;
56
57my %minLon ; my %minLat ; my %maxLon ; my %maxLat ; # per user
58my $deletedNodes = 0 ; my $deletedNodesWithTags = 0 ;
59my $deletedWays = 0 ; my $deletedWaysWithTags = 0 ;
60my %nodesAdded ; my %nodesMovedNumber ; my %nodesMovedDistance ; my %nodesMovedMax ;
61my %waysAdded ;
62my %tagsAdded ; my %tagsDeleted ; my %tagsRenamed ; my %tagsReclassified ; my %tagsRereffed ;
63my %tagsDeletedName ;
64my %renames ; my %reclassifications ; my %rerefs ;
65my @deletedNodesIds = () ; my %deletedNodesTags = () ;
66my @deletedWaysIds = () ; my %deletedWaysTags = () ;
67my %versionJumpsNodes = () ;
68my %versionJumpsWays = () ;
69my %opTime ;
70my %neededNodes = () ;
71
72my $reName ; my $reClass ; my $reRef ;
73my $name1 ; my $name2 ; my $ref1 ; my $ref2 ; my $class1 ; my $class2 ;
74
75my $objectProcessed = 0 ; # 0=node, 1=way
76
77###############
78# get parameter
79###############
80$osm1Name = shift||'';
81if (!$osm1Name) { die (print $usage, "\n") ; }
82
83$osm2Name = shift||'';
84if (!$osm2Name) { die (print $usage, "\n") ; }
85
86$htmlName = shift||'';
87if (!$htmlName) { die (print $usage, "\n") ; }
88
89$mode = shift||'';
90if (!$mode) {   $mode = "N" ; }
91
92$topMax = shift||'';
93if (!$topMax) { $topMax = 10 ; }
94
95$sizeX = shift||'';
96if (!$sizeX) {  $sizeX = 1024 ; }
97
98print "\n$program $version for files:\n\n" ;
99print stringFileInfo ($osm1Name), "\n"  ;
100print stringFileInfo ($osm2Name), "\n\n"  ;
101
102#------------------------------------------------------------------------------------
103# Main
104#------------------------------------------------------------------------------------
105
106if (grep /P/, $mode) { initializeMap() ; }
107
108openOsm1File ($osm1Name) ;
109moveNodeFile1() ;
110
111openOsm2File ($osm2Name) ;
112moveNodeFile2() ;
113
114processNodes() ;
115
116moveWayFile1() ;
117moveWayFile2() ;
118
119processWays() ;
120
121closeOsm1File () ;
122closeOsm2File () ;
123
124if ( ! (grep /P/, $mode) )  { 
125        processNeededWayNodes() ; 
126}
127
128if (grep /P/, $mode) { print "paint areas and save map...\n" ; }
129if (grep /P/, $mode) { paintAreas() ; }
130if (grep /P/, $mode) { saveMap() ; }
131if (grep /P/, $mode) { print "done.\n" ; }
132
133
134output() ;
135
136#-------
137# FINISH
138#-------
139
140print "\n$program finished after ", stringTimeSpent (time()-$time0), "\n\n" ;
141
142
143#------------------------------------------------------------------------------------
144# Node procesing
145#------------------------------------------------------------------------------------
146
147sub processNodes {
148        print "processing nodes...\n" ;
149        while ( ($nodeId1 > -1) or ($nodeId2 > -1) ) {
150                # print "while $nodeId1     $nodeId2\n" ;
151                if ($nodeId1 == -1) {
152                        # get rest from file 2, new nodes
153                        while ( $nodeId2 != -1 ) {
154                                # print "$nodeId1     $nodeId2   2-NEW\n" ;
155                                $nodesAdded{$nodeUser2}++ ;
156                                addOperationTime ($nodeUser2, $nodeTimestamp2) ;
157                                if (grep /P/, $mode) { paintNewNode() ; }
158                                userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
159                                moveNodeFile2() ;
160                        }
161                }
162
163                if ($nodeId2 == -1) {
164                        # get rest from file 1, deleted nodes
165                        while ( $nodeId1 != -1 ) {
166                                $deletedNodes++ ;
167                                if (scalar @nodeTags1 > 0) { 
168                                        $deletedNodesWithTags++ ; 
169                                        if (grep /P/, $mode) { paintDeletedNodeWithTag() ; }
170                                        push @deletedNodesIds, $nodeId1 ;
171                                        @{$deletedNodesTags{$nodeId1}} = @nodeTags1 ;
172                                }
173                                else {
174                                        if (grep /P/, $mode) { paintDeletedNode() ; }
175                                }
176                                moveNodeFile1() ;
177                        }
178                }
179
180                if ( ($nodeId1 == $nodeId2) and ($nodeId1 != -1) ) {
181                        # print "equal $nodeId1     $nodeId2\n" ;
182
183                        # place?
184                        if (grep /P/, $mode) {
185                                my $place = 0 ; my $placeName = "" ; my $placeNameGiven = 0 ;
186                                foreach my $t (@nodeTags1) {
187                                        if ($t->[0] eq "place") { $place = 1 ; }
188                                        if ($t->[0] eq "name") { $placeNameGiven = 1 ; $placeName = $t->[1] ; }
189                                }
190                                if ( ($place == 1) and ($placeNameGiven == 1) ) { paintPlace ($nodeLon1, $nodeLat1, $placeName) ; } 
191                        }
192
193                        # position...
194                        if ( ($nodeLon1 != $nodeLon2) or ($nodeLat1 != $nodeLat2) ) {
195                                $nodesMovedNumber{$nodeUser2}++ ;
196                                addOperationTime ($nodeUser2, $nodeTimestamp2) ;
197                                if (grep /P/, $mode) { paintMovedNode() ; }
198                                my ($d) = distance ($nodeLon1, $nodeLat1, $nodeLon2, $nodeLat2) ;
199                                $nodesMovedDistance{$nodeUser2} += $d ;
200                                if (defined $nodesMovedMax{$nodeUser2}) {
201                                        if ($nodesMovedMax{$nodeUser2} < $d) { $nodesMovedMax{$nodeUser2} = $d ; }
202                                }
203                                else {
204                                        $nodesMovedMax{$nodeUser2} = $d ;
205                                }
206                                userArea ($nodeUser2, $nodeLon1, $nodeLat1) ;
207                                userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
208                        } # moved
209
210                        if ($nodeVersion2 - $nodeVersion1 > 2) { 
211                                push @{$versionJumpsNodes{$nodeUser2}}, [$nodeId2, $nodeVersion2 - $nodeVersion1] ;
212                        }
213
214                        # process tags
215                        my ($added, $deleted, $renamed, $reclassified) = compareTags (\@nodeTags1, \@nodeTags2) ; 
216                        if ($added) { $tagsAdded{$nodeUser2} += $added ; }
217                        if ($deleted) { $tagsDeleted{$nodeUser2} += $deleted ; }
218                        if ($renamed) { 
219                                $tagsRenamed{$nodeUser2} += $renamed ; 
220                                if (grep /P/, $mode) { paintRenamedNode() ; }
221                        }
222                        if ($added or $deleted or $renamed or $reclassified) {
223                                addOperationTime ($nodeUser2, $nodeTimestamp2) ;
224                        }
225                        moveNodeFile1() ;
226                        moveNodeFile2() ;
227                }
228
229                if ( ($nodeId1 > $nodeId2) and ($nodeId2 != -1) ) {
230                        # print "1 > 2 $nodeId1     $nodeId2   2-NEW\n" ;
231                        # id 2 not found in file 1, nodeId2 new
232                        $nodesAdded{$nodeUser2}++ ;
233                        addOperationTime ($nodeUser2, $nodeTimestamp2) ;
234                        if (grep /P/, $mode) { paintNewNode() ; }
235                        userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
236                        # move file2 until id2>=id1
237                        while ( ($nodeId2 < $nodeId1) and ($nodeId2 != -1) ) {
238                                moveNodeFile2() ;
239                        }
240                }
241
242                if ( ($nodeId1 < $nodeId2) and ($nodeId1 != -1) ) {
243                        # print "1 < 2 $nodeId1     $nodeId2   1-DELETED\n" ;
244                        # id 1 not found in file 2, nodeId1 deleted
245                        $deletedNodes++ ;
246                        if (scalar @nodeTags1 > 0) { 
247                                $deletedNodesWithTags++ ; 
248                                if (grep /P/, $mode) { paintDeletedNodeWithTag() ; }
249                                push @deletedNodesIds, $nodeId1 ;
250                                @{$deletedNodesTags{$nodeId1}} = @nodeTags1 ;
251                        }
252                        else {
253                                if (grep /P/, $mode) { paintDeletedNode() ; }
254                        }
255                        # move file1 until id1>=id2
256                        while ( ($nodeId1 < $nodeId2) and ($nodeId1 != -1) ) {
257                                moveNodeFile1() ;
258                        }
259                }
260        }
261        print "finished.\n" ;
262}
263
264#------------------------------------------------------------------------------------
265# Way procesing
266#------------------------------------------------------------------------------------
267
268sub processWays {
269        $objectProcessed = 1 ;
270        print "processing ways...\n" ;
271        while ( ($wayId1 > -1) or ($wayId2 > -1) ) {
272                if ($wayId1 == -1) {
273                        # get rest from file 2, new ways
274                        while ( $wayId2 != -1 ) {
275                                # print "$wayId1     $wayId2   2-NEW\n" ;
276                                $waysAdded{$wayUser2}++ ;
277                                addOperationTime ($wayUser2, $wayTimestamp2) ;
278                                if (scalar @wayNodes2 >= 2) {
279                                        #userArea ($wayUser2, $lon2{$wayNodes2[0]}, $lat2{$wayNodes2[0]}) ;
280                                        #userArea ($wayUser2, $lon2{$wayNodes2[-1]}, $lat2{$wayNodes2[-1]}) ;
281                                        userAreaWay ($wayUser2, $wayNodes2[0]) ;
282                                        userAreaWay ($wayUser2, $wayNodes2[-1]) ;
283                                        if (grep /P/, $mode) { paintNewWay() ; }
284                                }
285                                #next
286                                moveWayFile2() ;
287                        }
288                }
289
290                if ($wayId2 == -1) {
291                        # get rest from file 1, deleted ways
292                        while ( $wayId1 != -1 ) {
293                                $deletedWays++ ;
294                                if (scalar @wayTags1 > 0) { 
295                                        $deletedWaysWithTags++ ; 
296                                        if (scalar @wayNodes1 >= 2) {
297                                                if (grep /P/, $mode) { paintDeletedWayWithTag() ; }
298                                        }
299                                        push @deletedWaysIds, $wayId1 ;
300                                        @{$deletedWaysTags{$wayId1}} = @wayTags1 ;
301                                }
302                                else {
303                                        if (scalar @wayNodes1 >= 2) {
304                                                if (grep /P/, $mode) { paintDeletedWay() ; }
305                                        }
306                                }
307                                #next
308                                moveWayFile1() ;
309                        }
310                }
311
312                if ( ($wayId1 == $wayId2) and ($wayId1 != -1) ) {
313                        # print "equal $wayId1     $wayId2\n" ;
314                        # TODO position
315                        # TODO nodes number
316
317                        if ($wayVersion2 - $wayVersion1 > 2) { 
318                                push @{$versionJumpsWays{$wayUser2}}, [$wayId2, $wayVersion2 - $wayVersion1] ;
319                        }
320
321                        # process tags
322                        my ($added, $deleted, $renamed, $reclassified, $rereffed) = compareTags (\@wayTags1, \@wayTags2) ; 
323                        if ($added) { $tagsAdded{$wayUser2} += $added ; }
324                        if ($deleted) { $tagsDeleted{$wayUser2} += $deleted ; }
325                        if ($renamed) { 
326                                $tagsRenamed{$wayUser2} += $renamed ; 
327                                # TODO draw
328                        }
329                        if ($reclassified) { 
330                                $tagsReclassified{$wayUser2} += $reclassified ; 
331                                if (scalar @wayNodes1 >= 2) {
332                                        if (grep /P/, $mode) { paintReclassifiedWay() ; }
333                                }
334                        } 
335                        if ($rereffed) { 
336                                $tagsRereffed{$wayUser2} += $rereffed ; 
337                                if (scalar @wayNodes1 >= 2) {
338                                        if (grep /P/, $mode) { paintRereffedWay() ; }
339                                }
340                        } 
341                        if ($added or $deleted or $renamed or $reclassified or $rereffed) { 
342                                addOperationTime ($wayUser2, $wayTimestamp2) ; 
343                                if ( (scalar @wayNodes1 >= 2) and (scalar @wayNodes2 >= 2) ) {
344                                        # userArea ($wayUser2, $lon2{$wayNodes2[0]}, $lat2{$wayNodes2[0]}) ;
345                                        # userArea ($wayUser2, $lon2{$wayNodes2[-1]}, $lat2{$wayNodes2[-1]}) ;
346                                        userAreaWay ($wayUser2, $wayNodes2[0]) ;
347                                        userAreaWay ($wayUser2, $wayNodes2[-1]) ;
348                                }
349                        }
350                        moveWayFile1() ;
351                        moveWayFile2() ;
352                }
353
354                if ( ($wayId1 > $wayId2) and ($wayId2 != -1) ) {
355                        # print "1 > 2 $wayId1     $wayId2   2-NEW\n" ;
356                        # id 2 not found in file 1, wayId2 new
357                        $waysAdded{$wayUser2}++ ;
358                        addOperationTime ($wayUser2, $wayTimestamp2) ; 
359                        if (scalar @wayNodes2 >= 2) {
360                                # userArea ($wayUser2, $lon2{$wayNodes2[0]}, $lat2{$wayNodes2[0]}) ;
361                                # userArea ($wayUser2, $lon2{$wayNodes2[-1]}, $lat2{$wayNodes2[-1]}) ;
362                                userAreaWay ($wayUser2, $wayNodes2[0]) ;
363                                userAreaWay ($wayUser2, $wayNodes2[-1]) ;
364                                if (grep /P/, $mode) { paintNewWay() ; }
365                        }
366                        # move file2 until id2>=id1
367                        while ( ($wayId2 < $wayId1) and ($wayId2 != -1) ) {
368                                moveWayFile2() ;
369                        }
370                }
371
372                if ( ($wayId1 < $wayId2) and ($wayId1 != -1) ) {
373                        # print "1 < 2 $wayId1     $wayId2   1-DELETED\n" ;
374                        # id 1 not found in file 2, wayId1 deleted
375                        $deletedWays++ ;
376                        if (scalar @wayTags1 > 0) { 
377                                $deletedWaysWithTags++ ; 
378                                if (scalar @wayNodes1 >= 2) {
379                                        if (grep /P/, $mode) { paintDeletedWayWithTag() ; }
380                                }
381                                push @deletedWaysIds, $wayId1 ;
382                                @{$deletedWaysTags{$wayId1}} = @wayTags1 ;
383                        }
384                        else {
385                                if (scalar @wayNodes1 >= 2) {
386                                        if (grep /P/, $mode) { paintDeletedWay() ; }
387                                }
388                        }
389                        # move file1 until id1>=id2
390                        while ( ($wayId1 < $wayId2) and ($wayId1 != -1) ) {
391                                moveWayFile1() ;
392                        }
393                }
394        }
395        print "finished.\n" ;
396}
397
398
399#------------------------------------------------------------------------------------
400# Output functions
401#------------------------------------------------------------------------------------
402
403sub output {
404        print "outputting html...\n" ;
405        my @a ; my @list ;
406        open ($html, ">", $htmlName) or die ("can't open html output file") ;
407        printHTMLHeader ($html, "UserActvity by Gary68") ;
408        print $html "<H1>UserActvity by gary68</H1>" ;
409        print $html "<p>", stringFileInfo ($osm1Name), "</p>\n"  ;
410        print $html "<p>", stringFileInfo ($osm2Name), "</p>\n"  ;
411        print $html "<p>A deleted tag can result out of a change of a tag. The same is true for the addition of a tag. Real changes are not counted.</p>" ;
412        print $html "<H1>Results</H1>" ;
413        print $html "<p>DELETED NODES: $deletedNodes</p>\n" ;
414        print $html "<p>DELETED NODES WITH TAGS: $deletedNodesWithTags (details see further down)</p>\n" ;
415       
416        @a = () ;
417        foreach my $e (keys %nodesMovedNumber) { push @a, [$e, $nodesMovedNumber{$e}] ; }
418        printTop ("TOP moved nodes number", 0, @a) ;
419        @a = () ;
420        foreach my $e (keys %nodesMovedDistance) { push @a, [$e, $nodesMovedDistance{$e}] ; }
421        printTop ("TOP moved nodes total distance (km)", 1, @a) ;
422        @a = () ;
423        foreach my $e (keys %nodesMovedDistance) { push @a, [$e, $nodesMovedDistance{$e}/$nodesMovedNumber{$e}] ; }
424        printTop ("TOP moved nodes average distance (km)", 1, @a) ;
425        @a = () ;
426        foreach my $e (keys %nodesMovedMax) { push @a, [$e, $nodesMovedMax{$e}] ; }
427        printTop ("TOP moved nodes maximum distance (km)", 1, @a) ;
428
429        @a = () ;
430        foreach my $u (keys %maxLon) {
431                # print "calc area for user: $u\n" ;
432                push @a, [$u, distance ($minLon{$u}, $minLat{$u}, $minLon{$u}, $maxLat{$u}) * distance ($minLon{$u}, $minLat{$u}, $maxLon{$u}, $minLat{$u})] ;
433        }
434        printTop ("TOP work areas (km²)", 1, @a) ;
435
436        @a = () ;
437        foreach my $e (keys %tagsAdded) { push @a, [$e, $tagsAdded{$e}] ; }
438        printTop ("TOP tags added", 0, @a) ;
439
440        @a = () ;
441        foreach my $e (keys %tagsRenamed) { push @a, [$e, $tagsRenamed{$e}] ; }
442        printTop ("TOP objects renamed", 0, @a) ;
443
444        @list = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
445        # if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
446        print $html "<h2>Renames by ALL users</h2>\n" ;
447        printHTMLTableHead ($html) ;
448        printHTMLTableHeadings ($html, "User", "Tag", "Number") ; 
449        foreach my $e (@list) {
450                foreach my $t (keys %{$renames{$e->[0]}}) {
451                        # printf $html "%-25s %-80s %5i<br>\n" , $e->[0], $t, $renames{$e->[0]}{$t} ;
452                        printHTMLRowStart ($html) ;
453                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
454                        printHTMLCellLeft ($html, $t) ;                 
455                        printHTMLCellRight ($html, $renames{$e->[0]}{$t}) ;                     
456                        printHTMLRowEnd ($html) ;
457                }
458        }
459        printHTMLTableFoot ($html) ;
460
461        @a = () ;
462        foreach my $e (keys %tagsRereffed) { push @a, [$e, $tagsRereffed{$e}] ; }
463        printTop ("TOP objects rereffed", 0, @a) ;
464
465        @list = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
466        # if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
467        print $html "<h2>Rerefs by ALL users</h2>\n" ;
468        printHTMLTableHead ($html) ;
469        printHTMLTableHeadings ($html, "User", "Tag", "Number") ; 
470        foreach my $e (@list) {
471                foreach my $t (keys %{$rerefs{$e->[0]}}) {
472                        # printf $html "%-25s %-80s %5i<br>\n" , $e->[0], $t, $rerefs{$e->[0]}{$t} ;
473                        printHTMLRowStart ($html) ;
474                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
475                        printHTMLCellLeft ($html, $t) ;                 
476                        printHTMLCellRight ($html, $rerefs{$e->[0]}{$t}) ;                     
477                        printHTMLRowEnd ($html) ;
478                }
479        }
480        printHTMLTableFoot ($html) ;
481
482        @a = () ;
483        foreach my $e (keys %tagsReclassified) { push @a, [$e, $tagsReclassified{$e}] ; }
484        printTop ("TOP ways reclassified", 0, @a) ;
485
486        @list = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
487        # if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
488        print $html "<h2>Reclassifications by ALL users</h2>\n" ;
489        printHTMLTableHead ($html) ;
490        printHTMLTableHeadings ($html, "User", "Tag", "Number") ; 
491        foreach my $e (@list) {
492                foreach my $t (keys %{$reclassifications{$e->[0]}}) {
493                        # printf $html "%-25s %-80s %5i<br>\n" , $e->[0], $t, $reclassifications{$e->[0]}{$t} ;
494                        printHTMLRowStart ($html) ;
495                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
496                        printHTMLCellLeft ($html, $t) ;                 
497                        printHTMLCellRight ($html, $reclassifications{$e->[0]}{$t}) ;                   
498                        printHTMLRowEnd ($html) ;
499                }
500        }
501        printHTMLTableFoot ($html) ;
502
503#       print $html "<h2>Version jumps nodes by ALL users</h2>\n" ;
504#       printHTMLTableHead ($html) ;
505#       printHTMLTableHeadings ($html, "User", "Nodes") ;
506#       foreach my $u (keys %versionJumpsNodes) {
507#               printHTMLRowStart ($html) ;
508#               printHTMLCellLeft ($html, userLink ($u)) ;                     
509#               my $jumps = "" ;
510#               foreach my $v (@{$versionJumpsNodes{$u}}) {
511#                       $jumps = $jumps . historyLink ("node", $v->[0]) . " (" . $v->[1] . ") " ;
512#               }
513#               printHTMLCellLeft ($html, $jumps) ;                     
514#               printHTMLRowEnd ($html) ;
515#       }
516#       printHTMLTableFoot ($html) ;
517
518#       print $html "<h2>Version jumps ways by ALL users</h2>\n" ;
519#       printHTMLTableHead ($html) ;
520#       printHTMLTableHeadings ($html, "User", "Ways") ;
521#       foreach my $u (keys %versionJumpsWays) {
522#               printHTMLRowStart ($html) ;
523#               printHTMLCellLeft ($html, userLink ($u)) ;                     
524#               my $jumps = "" ;
525#               foreach my $v (@{$versionJumpsWays{$u}}) {
526#                       $jumps = $jumps . historyLink ("node", $v->[0]) . " (" . $v->[1] . ") " ;
527#               }
528#               printHTMLCellLeft ($html, $jumps) ;                     
529#               printHTMLRowEnd ($html) ;
530#       }
531#       printHTMLTableFoot ($html) ;
532
533        @a = () ;
534        foreach my $e (keys %tagsDeleted) { push @a, [$e, $tagsDeleted{$e}] ; }
535        printTop ("TOP tags deleted", 0, @a) ;
536
537        @list = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
538        if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
539        print $html "<h2>Tags removed by TOP users</h2>\n" ;
540        printHTMLTableHead ($html) ;
541        printHTMLTableHeadings ($html, "User", "Removed", "Number") ; 
542        foreach my $e (@list) {
543                foreach my $t (keys %{$tagsDeletedName{$e->[0]}}) {
544                        # printf $html "%-25s %-50s %5i<br>\n" , $e->[0], $t, $tagsDeletedName{$e->[0]}{$t} ;
545                        printHTMLRowStart ($html) ;
546                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
547                        printHTMLCellLeft ($html, $t) ;                 
548                        printHTMLCellRight ($html, $tagsDeletedName{$e->[0]}{$t}) ;                     
549                        printHTMLRowEnd ($html) ;
550                }
551        }
552        printHTMLTableFoot ($html) ;
553
554        print $html "<h2>ALL deleted Nodes with tags (details)</h2>\n" ;
555        printHTMLTableHead ($html) ;
556        printHTMLTableHeadings ($html, "NodeId", "Tags") ; 
557        foreach my $n (@deletedNodesIds) {
558                printHTMLRowStart ($html) ;
559                printHTMLCellLeft ($html, historyLink ("node", $n) ) ;                 
560                my $tagText = "" ;
561                foreach my $t (@{$deletedNodesTags{$n}}) { $tagText = $tagText . $t->[0] . ":" . $t->[1] . "<br>\n" ; }
562                printHTMLCellLeft ($html, $tagText) ;   
563                printHTMLRowEnd ($html) ;
564        }
565        printHTMLTableFoot ($html) ;
566
567        print $html "<h2>ALL deleted ways with tags (details)</h2>\n" ;
568        printHTMLTableHead ($html) ;
569        printHTMLTableHeadings ($html, "WayId", "Tags") ; 
570        foreach my $n (@deletedWaysIds) {
571                printHTMLRowStart ($html) ;
572                printHTMLCellLeft ($html, historyLink ("way", $n) ) ;                   
573                my $tagText = "" ;
574                foreach my $t (@{$deletedWaysTags{$n}}) { $tagText = $tagText . $t->[0] . ":" . $t->[1] . "<br>\n" ; }
575                printHTMLCellLeft ($html, $tagText) ;   
576                printHTMLRowEnd ($html) ;
577        }
578        printHTMLTableFoot ($html) ;
579
580        print $html "<p>$program finished after ", stringTimeSpent (time()-$time0), "</p>\n" ;
581        printHTMLFoot ($html) ;
582        close ($html) ;
583
584        my ($html2Name) = $htmlName ;
585        $html2Name =~ s/.htm/.time.htm/ ;
586        open ($html, ">", $html2Name) or die ("can't open html2 output file") ;
587        printHTMLHeader ($html, "UserActvity (TIME) by Gary68") ;
588        print $html "<H1>UserActvity (TIME) by gary68</H1>" ;
589        print $html "<p>", stringFileInfo ($osm1Name), "</p>\n"  ;
590        print $html "<p>", stringFileInfo ($osm2Name), "</p>\n"  ;
591
592        @a = () ;
593        foreach my $u (keys %opTime) { push @a, [$u, numOpHours ($u)] ; }
594        printTop ("TOP operation hour slots", 0, @a) ;
595
596        @list = reverse (sort {$a->[1]<=>$b->[1]} @a) ;
597        if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
598        print $html "<h2>Operation time slots TOP users</h2>\n" ;
599        printHTMLTableHead ($html) ;
600        printHTMLTableHeadings ($html, "User", "00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23") ; 
601        foreach my $e (@list) {
602                printHTMLRowStart ($html) ;
603                printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
604                my $max = 0 ;
605                foreach my $h ("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23") {
606                        if ( (defined $opTime{$e->[0]}{$h}) and ($opTime{$e->[0]}{$h} > $max) )  { $max = $opTime{$e->[0]}{$h} ; } 
607                }
608                # print "$e->[0] $max\n" ;
609                my $value = 0 ;
610                foreach my $h ("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23") {
611                        if (defined $opTime{$e->[0]}{$h}) { $value = $opTime{$e->[0]}{$h} ; } else { $value = 0 ; }
612                        my ($colorValue) = 255 - ( int ($value / $max * 255) / 2) ; my ($colorString) = sprintf "%02x", $colorValue ;
613                        # print "$value $colorValue $colorString\n" ;
614                        my ($htmlString) = "<td align=\"right\" bgcolor=\"#" . $colorString . $colorString . $colorString . "\">" . $value . "</td>" ;
615                        print $html $htmlString ;
616                }
617                printHTMLRowEnd ($html) ;
618        }
619        printHTMLTableFoot ($html) ;
620
621
622        printHTMLFoot ($html) ;
623        close ($html) ;
624
625
626        print "done.\n" ;
627}
628
629sub printTop {
630        my ($heading, $decimal, @list) = @_ ;
631        print $html "<h2>$heading</h2>\n" ;
632        printHTMLTableHead ($html) ;
633        printHTMLTableHeadings ($html, "User", "Data") ; 
634        @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
635        if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
636        foreach my $e (@list) {
637                printHTMLRowStart ($html) ;
638                my $s ;
639                if ($decimal) { 
640                        $s = sprintf "%8.3f", $e->[1] ;
641                }
642                else {
643                        $s = sprintf "%8i", $e->[1] ;
644                }
645                printHTMLCellLeft ($html, userLink ($e->[0]) ) ;                       
646                printHTMLCellRight ($html, $s) ;                       
647                printHTMLRowEnd ($html) ;
648        } 
649        printHTMLTableFoot ($html) ;
650}
651
652
653#------------------------------------------------------------------------------------
654# some functions
655#------------------------------------------------------------------------------------
656
657sub addOperationTime {
658        my ($user, $timestamp) = @_ ;
659        # timestamp="2008-04-13T13:23:55+01:00"
660        my ($hour) = substr ($timestamp, 11, 2) ;
661        $opTime{$user}{$hour}++ ;
662}
663
664sub numOpHours {
665        my ($user) = shift ;
666        my $hours = 0 ;
667        foreach my $hour ("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23") {
668                if (defined $opTime{$user}{$hour}) { $hours++ ; }
669        }
670        return ($hours) ;
671}
672
673sub userAreaWay {
674        my ($u, $n) = @_ ;
675        if (grep /P/, $mode) {
676                userArea ($u, $lon2{$n}, $lat2{$n}) ;
677        }
678        else {
679                $neededNodes{$n} = $u ;
680        }
681}
682
683sub processNeededWayNodes {
684        print "get needed nodes for touched ways...\n" ;
685        openOsm2File ($osm2Name) ;
686        moveNodeFile2() ;
687        while ( $nodeId2 != -1 ) {
688                if (defined $neededNodes{$nodeId2}) {
689                        userArea ($neededNodes{$nodeId2}, $nodeLon2, $nodeLat2) ;
690                }
691                moveNodeFile2() ;
692        }
693        closeOsm2File () ;
694        print "done.\n" ;
695}
696
697sub userArea {
698        my ($u, $lon, $lat) = @_ ;
699
700        if ( (!defined $lon) or (! defined $lat) ) {
701                print "userArea ERROR user $u nodes $nodeId1 $nodeId2 ways $wayId1 $wayId2\n" ;
702        }
703
704        if (! defined $maxLon{$u}) {
705                $minLon{$u} = $lon ;
706                $minLat{$u} = $lat ;
707                $maxLon{$u} = $lon ;
708                $maxLat{$u} = $lat ;
709        }
710        else {
711                if ($lon > $maxLon{$u}) { $maxLon{$u} = $lon ; }
712                if ($lon < $minLon{$u}) { $minLon{$u} = $lon ; }
713                if ($lat > $maxLat{$u}) { $maxLat{$u} = $lat ; }
714                if ($lat < $minLat{$u}) { $minLat{$u} = $lat ; }
715        }
716}
717
718sub compareTags {
719        my ($aRef1, $aRef2) = @_ ;
720        my $added = 0 ; my $deleted = 0 ; my $renamed = 0 ; my $reclassified = 0 ; my $rereffed = 0 ;
721        my (@tags1) = @$aRef1 ; my (@tags2) = @$aRef2 ;
722
723        $reName = 0 ; $reClass = 0 ; $reRef = 0 ;
724
725        # RENAMED?
726        my $nameGiven = 0 ;
727        my $nameOld = "" ; 
728        my $nameNew = "" ;
729        foreach my $t (@tags1) { 
730                if ($t->[0] eq "name") { $nameGiven = 1 ; $nameOld = $t->[1] ; }
731        }
732        foreach my $t (@tags2) { 
733                if ($t->[0] eq "name") { $nameNew = $t->[1] ; }
734        }
735        if ( ($nameGiven == 1) and ($nameNew ne $nameOld) ) { 
736                $renamed = 1 ; 
737                $renames{$nodeUser2}{$nameOld . " > " . $nameNew} ++ ;
738                $reName = 1 ; $name1 = $nameOld ; $name2 = $nameNew ;
739        }
740       
741        if ($objectProcessed == 1 ) {
742                # REREF?
743                my $refGiven = 0 ;
744                my $refOld = "" ; 
745                my $refNew = "" ;
746                foreach my $t (@tags1) { 
747                        if ($t->[0] eq "ref") { $refGiven = 1 ; $refOld = $t->[1] ; }
748                }
749                foreach my $t (@tags2) { 
750                        if ($t->[0] eq "ref") { $refNew = $t->[1] ; }
751                }
752                if ( ($refGiven == 1) and ($refNew ne $refOld) ) { 
753                        $rereffed = 1 ; 
754                        $rerefs{$wayUser2}{$refOld . " > " . $refNew} ++ ;
755                        $reRef = 1 ; $ref1 = $refOld ; $name2 = $refNew ;
756                }
757                # RECLASSIFIED?
758                my $highwayGiven = 0 ;
759                my $highwayOld = "" ;
760                my $highwayNew = "" ;
761                foreach my $t (@tags1) { 
762                        if ($t->[0] eq "highway") { $highwayGiven = 1 ; $highwayOld = $t->[1] ; }
763                }
764                foreach my $t (@tags2) { 
765                        if ($t->[0] eq "highway") { $highwayNew = $t->[1] ; }
766                }
767                if ( ($highwayGiven == 1) and ($highwayNew ne $highwayOld) ) { 
768                        $reclassified = 1 ; 
769                        $reclassifications{$wayUser2}{$highwayOld . " > " . $highwayNew} ++ ;
770                        $reClass = 1 ; $class1 = $highwayOld ; $class2 = $highwayNew ;
771                }
772        } # objectProcessed
773
774        # ADDED?
775        foreach my $t2 (@tags2) {
776                my $found = 0 ;
777                foreach my $t1 (@tags1) {
778                        if ( ($t1->[0] eq $t2->[0]) and ($t1->[1] eq $t2->[1]) ) { $found = 1 ; }
779                }
780                if ($found == 0) { $added++ ; }
781        }
782
783        # DELETED?
784        foreach my $t1 (@tags1) {
785                my $found = 0 ;
786                foreach my $t2 (@tags2) {
787                        if ( ($t1->[0] eq $t2->[0]) and ($t1->[1] eq $t2->[1]) ) { $found = 1 ; }
788                }
789                # if ($found == 0) {
790                if ( ($found == 0) and ($t1->[0] ne "created_by") ) { 
791                        $deleted++ ; 
792                        $tagsDeletedName{$nodeUser2}{$t1->[0].":".$t1->[1]}++ ;
793                }
794        }
795
796        return ($added, $deleted, $renamed, $reclassified, $rereffed) ;
797} # compareTags
798
799sub userLink {
800        my ($user) = shift ;
801        return "<a href=\"http://www.openstreetmap.org/user/" . $user . "\">" . $user . "</a>" ;
802}
803
804
805
806#------------------------------------------------------------------------------------
807# Map functions
808#------------------------------------------------------------------------------------
809
810sub paintNewWay {
811        drawWay ("black", 2, nodes2Coordinates2 (@wayNodes2) ) ;
812        if (grep /D/, $mode) { drawTextPos ($lon2{$wayNodes2[0]}, $lat2{$wayNodes2[0]}, 0, 0, $wayUser2, "black", 2) ; }
813}
814
815sub paintDeletedWay {
816        drawWay ("red", 2, nodes2Coordinates1 (@wayNodes1) ) ;
817}
818
819sub paintDeletedWayWithTag {
820        drawWay ("red", 3, nodes2Coordinates1 (@wayNodes1) ) ;
821}
822
823sub paintRenamedWay {
824        drawWay ("orange", 3, nodes2Coordinates1 (@wayNodes1) ) ;
825        if (grep /D/, $mode) { 
826                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, 0, $wayUser2, "orange", 2) ; 
827                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, -8, $name1 . "->" . $name2, "black", 2) ; 
828        }
829}
830
831sub paintRereffedWay {
832        drawWay ("orange", 3, nodes2Coordinates1 (@wayNodes1) ) ;
833        if (grep /D/, $mode) { 
834                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, 0, $wayUser2, "orange", 2) ; 
835                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, -8, $ref1 . "->" . $ref2, "black", 2) ; 
836        }
837}
838
839sub paintReclassifiedWay {
840        drawWay ("pink", 3, nodes2Coordinates1 (@wayNodes1) ) ;
841        if (grep /D/, $mode) { 
842                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, 0, $wayUser2, "pink", 2) ; 
843                drawTextPos ($lon1{$wayNodes1[0]}, $lat1{$wayNodes1[0]}, 0, -8, $class1 . "->" . $class2, "black", 2) ; 
844        }
845}
846
847sub paintMovedWay {
848}
849
850
851sub paintNewNode {
852        drawNodeDot ($nodeLon2, $nodeLat2, "black", 4) ;
853        if (grep /D/, $mode) { drawTextPos ($nodeLon2, $nodeLat2, 0, 0, $nodeUser2, "black", 2) ; }
854}
855
856sub paintDeletedNode {
857        drawNodeDot ($nodeLon1, $nodeLat1, "red", 4) ;
858}
859
860sub paintDeletedNodeWithTag {
861        drawNodeDot ($nodeLon1, $nodeLat1, "red", 5) ;
862}
863
864sub paintRenamedNode {
865        drawNodeDot ($nodeLon1, $nodeLat1, "orange", 4) ;
866        if (grep /D/, $mode) { 
867                drawTextPos ($nodeLon1, $nodeLat1, 0, 0, $nodeUser2, "orange", 2) ; 
868                drawTextPos ($nodeLon1, $nodeLat1, 0, -8, $name1 . "->" . $name2, "black", 2) ; 
869        }
870}
871
872sub paintMovedNode {
873        # blue
874        drawNodeDot ($nodeLon1, $nodeLat1, "lightblue", 4) ;
875        drawWay ("lightblue", 1, ($nodeLon1, $nodeLat1, $nodeLon2, $nodeLat2) ) ;
876        drawNodeDot ($nodeLon2, $nodeLat2, "blue", 4) ;
877        if (grep /D/, $mode) { drawTextPos ($nodeLon1, $nodeLat1, 0, 0, $nodeUser2, "blue", 2) ; }
878}
879
880sub paintAreas {
881        foreach my $user (keys %minLon) {
882                drawWay ("tomato", 1, $minLon{$user}, $minLat{$user}, $minLon{$user}, $maxLat{$user}, $maxLon{$user}, $maxLat{$user}, $maxLon{$user}, $minLat{$user}, $minLon{$user}, $minLat{$user} ) ;
883                drawTextPos ($minLon{$user}, $minLat{$user}, 0, 0, $user, "black", 2) ;
884        }
885}
886
887sub paintPlace {
888        my ($lon, $lat, $name) = @_ ;
889        drawTextPos ($lon, $lat, 0, 0, $name, "black", 4) ;     
890        drawNodeDot ($lon, $lat, "black", 2) ;
891}
892
893sub initializeMap {
894        print "initializing map...\n" ;
895        print "- parsing nodes file1...\n" ;
896        my $lonMax = -999 ; my $lonMin = 999 ; my $latMax = -999 ; my $latMin = 999 ;
897        openOsm1File ($osm1Name) ;
898        moveNodeFile1() ;       
899
900        # get all node information from file 1         
901        while ($nodeId1 != -1) {
902                $lon1{$nodeId1} = $nodeLon1 ; $lat1{$nodeId1} = $nodeLat1 ;
903                if ($nodeLon1 > $lonMax) { $lonMax = $nodeLon1 ; }
904                if ($nodeLat1 > $latMax) { $latMax = $nodeLat1 ; }
905                if ($nodeLon1 < $lonMin) { $lonMin = $nodeLon1 ; }
906                if ($nodeLat1 < $latMin) { $latMin = $nodeLat1 ; }
907                # next
908                moveNodeFile1() ;       
909        }
910        initGraph ($sizeX, $lonMin, $latMin, $lonMax, $latMax) ;
911        if (grep /S/, $mode) {
912                enableSVG() ;
913        }
914
915        # ways
916        print "- parsing ways file1...\n" ;
917        moveWayFile1() ;
918        while ($wayId1 != -1) {
919                drawWay ("lightgray", 1, nodes2Coordinates1 (@wayNodes1) ) ;
920                moveWayFile1() ;
921        }
922        closeOsm1File() ;
923
924        print "- parsing nodes file2...\n" ;
925        openOsm2File ($osm2Name) ;
926        moveNodeFile2() ;
927
928        # get all node information from file 2
929        while ($nodeId2 != -1) {
930                $lon2{$nodeId2} = $nodeLon2 ; $lat2{$nodeId2} = $nodeLat2 ;
931                # next
932                moveNodeFile2() ;
933        }
934        closeOsm2File() ;
935
936        print "done.\n" ;
937}
938
939sub saveMap {
940        print "saving map...\n" ;
941        drawHead ($program . " ". $version . " by Gary68", "black", 3) ;
942        drawFoot ("data by openstreetmap.org" . " " . $osm1Name . " " .ctime(stat($osm1Name)->mtime) . $osm2Name . " " .ctime(stat($osm2Name)->mtime), "black", 3) ;
943        drawLegend (3, "New", "black", "Deleted", "red", "Moved", "blue", "Renamed", "orange", "Reclassified", "pink", "User Area", "tomato") ;
944        drawRuler ("black") ;
945        my ($pngName) = $htmlName ;
946        $pngName =~ s/.htm/.png/ ;
947        writeGraph ($pngName) ; 
948        if (grep /S/, $mode) {
949                my ($svgName) = $htmlName ;
950                $svgName =~ s/.htm/.svg/ ;
951                writeSVG ($svgName) ; 
952        }
953        print "done.\n" ;
954}
955
956sub nodes2Coordinates1 {
957        my @nodes = @_ ;
958        my $i ;
959        my @result = () ;
960        for ($i=0; $i<=$#nodes; $i++) {
961                push @result, $lon1{$nodes[$i]} ;
962                push @result, $lat1{$nodes[$i]} ;
963        }
964        return @result ;
965}
966
967sub nodes2Coordinates2 {
968        my @nodes = @_ ;
969        my $i ;
970        my @result = () ;
971        for ($i=0; $i<=$#nodes; $i++) {
972                push @result, $lon2{$nodes[$i]} ;
973                push @result, $lat2{$nodes[$i]} ;
974        }
975        return @result ;
976}
977
978
979
980#------------------------------------------------------------------------------------
981# Basic object operations
982#------------------------------------------------------------------------------------
983
984sub getNode1 {
985        my ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) ;
986        my @gTags = () ;
987        if($line1 =~ /^\s*\<node/) {
988                if (! grep /changeset/, $line1) { $line1 =~ s/lat=/changeset=\"0\" lat=/ ; }
989                if ( (grep /user=/, $line1) and (grep /uid=/, $line1) ) {
990                        ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) = 
991                        ($line1 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](.+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
992                }
993                else {
994                        ($id, $version, $timestamp, $changeset, $lat, $lon) = 
995                        ($line1 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
996                        $user = "unknown" ; $uid = 0 ;
997                }
998                if (!defined $user) { $user = "unknown" ; }
999                if (!defined $uid) { $uid = 0 ; }
1000
1001                if (!$id or (! (defined ($lat))) or ( ! (defined ($lon))) ) {
1002                        print "WARNING reading osm file1, line follows (expecting id, lon, lat and user for node):\n", $line1, "\n" ; 
1003                }
1004                else {
1005                        if ( (grep (/">/, $line1)) or (grep (/'>/, $line1)) ) {                  # more lines, get tags
1006                                nextLine1() ;
1007                                while (!grep(/<\/node>/, $line1)) {
1008                                        my ($k, $v) = ($line1 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
1009                                        if ( (defined ($k)) and (defined ($v)) ) {
1010                                                my $tag = [$k, $v] ; push @gTags, $tag ;
1011                                        }
1012                                        else { 
1013                                                #print "WARNING tag not recognized file1: ", $line1, "\n" ;
1014                                        }
1015                                        nextLine1() ;
1016                                }
1017                                nextLine1() ;
1018                        }
1019                        else {
1020                                nextLine1() ;
1021                        }
1022                }
1023        }
1024        else {
1025                return (-1, -1, -1, -1, -1) ; 
1026        } # node
1027        return ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon, \@gTags) ; # in main @array = @$ref
1028} # getNode1
1029
1030sub getNodeFile2 {
1031        my ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) ;
1032        my @gTags = () ;
1033        if($line2 =~ /^\s*\<node/) {
1034                if (! grep /changeset/, $line2) { $line2 =~ s/lat=/changeset=\"0\" lat=/ ; }
1035                if ( (grep /user=/, $line2) and (grep /uid=/, $line2) ) {
1036                        ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) = 
1037                        ($line2 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](.+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
1038                }
1039                else {
1040                        ($id, $version, $timestamp, $changeset, $lat, $lon) = 
1041                        ($line2 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
1042                        $user = "unknown" ; $uid = 0 ;
1043                }
1044                if (!defined $user) { $user = "unknown" ; }
1045                if (!defined $uid) { $uid = 0 ; }
1046
1047                if (!$id or (! (defined ($lat))) or ( ! (defined ($lon))) ) {
1048                        print "WARNING reading osm file 2, line follows (expecting id, lon, lat and user for node):\n", $line2, "\n" ; 
1049                }
1050                else {
1051                        if ( (grep (/">/, $line2)) or (grep (/'>/, $line2)) ) {                  # more lines, get tags
1052                                nextLine2() ;
1053                                while (!grep(/<\/node>/, $line2)) {
1054                                        my ($k, $v) = ($line2 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
1055                                        if ( (defined ($k)) and (defined ($v)) ) {
1056                                                my $tag = [$k, $v] ; push @gTags, $tag ;
1057                                        }
1058                                        else { 
1059                                                #print "WARNING tag not recognized file 2: ", $line2, "\n" ;
1060                                        }
1061                                        nextLine2() ;
1062                                }
1063                                nextLine2() ;
1064                        }
1065                        else {
1066                                nextLine2() ;
1067                        }
1068                }
1069        }
1070        else {
1071                return (-1, -1, -1, -1, -1) ; 
1072        } # node
1073        return ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon, \@gTags) ; # in main @array = @$ref
1074} # getNodeFile2
1075
1076
1077
1078sub getWay1 {
1079        my $id ; my $u ; my @tags ; my @nodes ; my $version ; my $timestamp ; my $uid ; my $changeset ;
1080        if($line1 =~ /^\s*\<way/) {
1081
1082                if (! grep /changeset/, $line1) { $line1 =~ s/\">/\" changeset=\"0\">/ ; }
1083                if ( (grep /user=/, $line1) and (grep /uid=/, $line1) ) {
1084                        ($id, $version, $timestamp, $uid, $u, $changeset) = ($line1 =~ /^\s*\<way id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](\d+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"]>/) ;
1085                }
1086                else {
1087                        ($id, $version, $timestamp, $changeset) = ($line1 =~ /^\s*\<way id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"]>/) ;
1088                        $uid = 0 ; $u = "unknown" ;
1089                }
1090
1091                if (!$u) { $u = "unknown" ; }
1092                if (!$id) { print "ERROR reading osm file1, line follows (expecting way id):\n", $line1, "\n" ; }
1093                unless ($id) { next; }
1094                nextLine1() ;
1095                while (not($line1 =~ /\/way>/)) { # more way data
1096                        my ($node) = ($line1 =~ /^\s*\<nd ref=[\'\"](\d+)[\'\"]/); # get node id
1097                        my ($k, $v) = ($line1 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
1098                        if ($node) {
1099                                push @nodes, $node ;
1100                        }
1101                        if ($k and defined($v)) { my $tag = [$k, $v] ; push @tags, $tag ; }
1102                        nextLine1() ;
1103                }
1104                nextLine1() ;
1105        }
1106        else {
1107                return (-1, -1, -1, -1, -1, -1, -1, -1) ;
1108        }
1109        return ($id, $version, $timestamp, $uid, $u, $changeset, \@nodes, \@tags) ;
1110} # getWay1
1111
1112sub getWayFile2 {
1113        my $id ; my $u ; my @tags ; my @nodes ; my $version ; my $timestamp ; my $uid ; my $changeset ;
1114        if($line2 =~ /^\s*\<way/) {
1115
1116                if (! grep /changeset/, $line2) { $line2 =~ s/\">/\" changeset=\"0\">/ ; }
1117                if ( (grep /user=/, $line2) and (grep /uid=/, $line2) ) {
1118                        ($id, $version, $timestamp, $uid, $u, $changeset) = ($line2 =~ /^\s*\<way id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](\d+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"]>/) ;
1119                }
1120                else {
1121                        ($id, $version, $timestamp, $changeset) = ($line2 =~ /^\s*\<way id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"]>/) ;
1122                        $uid = 0 ; $u = "unknown" ;
1123                }
1124                if (!$u) { $u = "unknown" ; }
1125                if (!$id) { print "ERROR reading osm file2, line follows (expecting way id):\n", $line1, "\n" ; }
1126                unless ($id) { next; }
1127                nextLine2() ;
1128                while (not($line2 =~ /\/way>/)) { # more way data
1129                        my ($node) = ($line2 =~ /^\s*\<nd ref=[\'\"](\d+)[\'\"]/); # get node id
1130                        my ($k, $v) = ($line2 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
1131                        if ($node) {
1132                                push @nodes, $node ;
1133                        }
1134                        if ($k and defined($v)) { my $tag = [$k, $v] ; push @tags, $tag ; }
1135                        nextLine2() ;
1136                }
1137                nextLine2() ;
1138        }
1139        else {
1140                return (-1, -1, -1, -1, -1, -1, -1, -1) ;
1141        }
1142        return ($id, $version, $timestamp, $uid, $u, $changeset, \@nodes, \@tags) ;
1143} # getWayFile2
1144
1145
1146sub moveNodeFile1 {
1147        ($nodeId1, $nodeVersion1, $nodeTimestamp1, $nodeUid1, $nodeUser1, $nodeChangeset1, $nodeLat1, $nodeLon1, $aRef1) = getNode1 () ;
1148        if ($nodeId1 != -1) {
1149                @nodeTags1 = @$aRef1 ;
1150        }
1151}
1152
1153sub moveNodeFile2 {
1154        ($nodeId2, $nodeVersion2, $nodeTimestamp2, $nodeUid2, $nodeUser2, $nodeChangeset2, $nodeLat2, $nodeLon2, $aRef1) = getNodeFile2 () ;
1155        if ($nodeId2 != -1) {
1156                @nodeTags2 = @$aRef1 ;
1157        }
1158}
1159
1160sub moveWayFile1 {
1161        ($wayId1, $wayVersion1, $wayTimestamp1, $wayUid1, $wayUser1, $wayChangeset1, $aRef1, $aRef2) = getWay1() ;
1162        if ($wayId1 != -1) {
1163                @wayNodes1 = @$aRef1 ;
1164                @wayTags1 = @$aRef2 ;
1165        }
1166}
1167
1168sub moveWayFile2 {
1169        ($wayId2, $wayVersion2, $wayTimestamp2, $wayUid2, $wayUser2, $wayChangeset2, $aRef1, $aRef2) = getWayFile2() ;
1170        if ($wayId2 != -1) {
1171                @wayNodes2 = @$aRef1 ;
1172                @wayTags2 = @$aRef2 ;
1173        }
1174}
1175
1176
1177#------------------------------------------------------------------------------------
1178# Basic file operations
1179#------------------------------------------------------------------------------------
1180
1181sub openOsm1File {
1182        $file1Name = shift ;
1183        if (grep /.bz2/, $file1Name) { $isBz21 = 1 ; } else { $isBz21 = 0 ; }
1184        if ($isBz21) {
1185                $bz1 = bzopen($file1Name, "rb") or die "Cannot open $file1Name: $bzerrno\n" ;
1186        }
1187        else {
1188                open ($file1, "<", $file1Name) || die "can't open osm file1" ;
1189        }
1190        nextLine1() ;           
1191        while ( ! (grep /\<node/, $line1) ) {
1192                nextLine1() ;
1193        }
1194        return 1 ;
1195}
1196
1197sub closeOsm1File {
1198        if ($isBz21) { $bz1->bzclose() ; }
1199        else { close ($file1) ; }
1200}
1201
1202sub nextLine1 {
1203        if ($isBz21) { $bz1->bzreadline($line1) ; }
1204        else { $line1 = <$file1> ; }
1205}
1206
1207sub openOsm2File {
1208        $file2Name = shift ;
1209        if (grep /.bz2/, $file2Name) { $isBz22 = 1 ; } else { $isBz22 = 0 ; }
1210        if ($isBz22) {
1211                $bz2 = bzopen($file2Name, "rb") or die "Cannot open $file2Name: $bzerrno\n" ;
1212        }
1213        else {
1214                open ($file2, "<", $file2Name) || die "can't open osm file2" ;
1215        }
1216        nextLine2() ;           
1217        while ( ! (grep /\<node/, $line2) ) {
1218                nextLine2() ;
1219        }
1220        return 1 ;
1221}
1222
1223sub closeOsm2File {
1224        if ($isBz22) { $bz2->bzclose() ; }
1225        else { close ($file2) ; }
1226}
1227
1228sub nextLine2 {
1229        if ($isBz22) { $bz2->bzreadline($line2) ; }
1230        else { $line2 = <$file2> ; }
1231}
1232
Note: See TracBrowser for help on using the repository browser.