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

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

useractivity 1.0

  • Property svn:executable set to *
File size: 21.0 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
19use strict ;
20use warnings ;
21
22use OSM::osm ;
23use File::stat;
24use Time::localtime;
25
26my $program = "useractivity.pl" ;
27my $usage = $program . " file1.osm file2.osm out.htm [numTopUsers]" ;
28my $version = "1.0" ;
29
30my $topMax = 10 ;
31
32my $wayId1 ; my $wayUser1 ; my @wayNodes1 ; my @wayTags1 ;
33my $wayId2 ; my $wayUser2 ; my @wayNodes2 ; my @wayTags2 ;
34
35my $nodeId1 ; my $nodeUser1 ; my $nodeLat1 ; my $nodeLon1 ; my @nodeTags1 ; my $nodeVersion1 ; my $nodeTimestamp1 ; my $nodeUid1 ; my $nodeChangeset1 ;
36my $nodeId2 ; my $nodeUser2 ; my $nodeLat2 ; my $nodeLon2 ; my @nodeTags2 ; my $nodeVersion2 ; my $nodeTimestamp2 ; my $nodeUid2 ; my $nodeChangeset2 ;
37my $aRef1 ; my $aRef2 ;
38
39my $time0 = time() ; 
40
41my $html ; my $htmlName ;
42my $osm1Name ; my $osm2Name ;
43
44my $file1 ; my $file2 ; my $bz1 ; my $bz2 ; my $isBz21 ; my $isBz22 ; my $line1 ; my $line2 ; my $bzerrno ;
45my $file1Name ; my $file2Name ;
46
47my %minLon ; my %minLat ; my %maxLon ; my %maxLat ; # per user
48my $deletedNodes = 0 ; my $deletedNodesWithTags = 0 ;
49my %nodesAdded ; my %nodesMovedNumber ; my %nodesMovedDistance ; my %nodesMovedMax ;
50my %tagsAdded ; my %tagsDeleted ; my %tagsRenamed ; my %tagsReclassified ;
51my %tagsDeletedName ;
52my %renames ; 
53my @deletedNodesIds = () ; my %deletedNodesTags = () ;
54my %versionJumpsNodes = () ;
55
56###############
57# get parameter
58###############
59$osm1Name = shift||'';
60if (!$osm1Name) { die (print $usage, "\n") ; }
61
62$osm2Name = shift||'';
63if (!$osm2Name) { die (print $usage, "\n") ; }
64
65$htmlName = shift||'';
66if (!$htmlName) { die (print $usage, "\n") ; }
67
68$topMax = shift||'';
69if (!$topMax) { $topMax = 10 ; }
70
71print "\n$program $version for files:\n\n" ;
72print stringFileInfo ($osm1Name), "\n"  ;
73print stringFileInfo ($osm2Name), "\n\n"  ;
74
75# test ways 1
76# expand way fields
77# test ways
78# copy ways file 2
79# test ways file 2
80# picture?
81
82#------------------------------------------------------------------------------------
83# Main
84#------------------------------------------------------------------------------------
85
86openOsm1File ($osm1Name) ;
87($nodeId1, $nodeVersion1, $nodeTimestamp1, $nodeUid1, $nodeUser1, $nodeChangeset1, $nodeLat1, $nodeLon1, $aRef1) = getNode1 () ;
88if ($nodeId1 != -1) {
89        @nodeTags1 = @$aRef1 ;
90}
91openOsm2File ($osm2Name) ;
92($nodeId2, $nodeVersion2, $nodeTimestamp2, $nodeUid2, $nodeUser2, $nodeChangeset2, $nodeLat2, $nodeLon2, $aRef1) = getNodeFile2 () ;
93if ($nodeId2 != -1) {
94        @nodeTags2 = @$aRef1 ;
95}
96processNodes() ;
97
98# TODO get first ways
99processWays() ;
100
101closeOsm1File () ;
102closeOsm2File () ;
103
104output() ;
105
106#-------
107# FINISH
108#-------
109
110print "\n$program finished after ", stringTimeSpent (time()-$time0), "\n\n" ;
111
112
113#------------------------------------------------------------------------------------
114# Node procesing
115#------------------------------------------------------------------------------------
116
117sub processNodes {
118        print "processing nodes...\n" ;
119        while ( ($nodeId1 > -1) or ($nodeId2 > -1) ) {
120                # print "while $nodeId1     $nodeId2\n" ;
121                if ($nodeId1 == -1) {
122                        # get rest from file 2, new nodes
123                        while ( $nodeId2 != -1 ) {
124                                # print "$nodeId1     $nodeId2   2-NEW\n" ;
125                                $nodesAdded{$nodeUser2}++ ;
126                                userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
127                                ($nodeId2, $nodeVersion2, $nodeTimestamp2, $nodeUid2, $nodeUser2, $nodeChangeset2, $nodeLat2, $nodeLon2, $aRef1) = getNodeFile2 () ;
128                                if ($nodeId2 != -1) {
129                                        @nodeTags2 = @$aRef1 ;
130                                }
131                        }
132                }
133
134                if ($nodeId2 == -1) {
135                        # get rest from file 1, deleted nodes
136                        while ( $nodeId1 != -1 ) {
137                                $deletedNodes++ ;
138                                if (scalar @nodeTags1 > 0) { 
139                                        $deletedNodesWithTags++ ; 
140                                        push @deletedNodesIds, $nodeId1 ;
141                                        @{$deletedNodesTags{$nodeId1}} = @nodeTags1 ;
142                                }
143                                ($nodeId1, $nodeVersion1, $nodeTimestamp1, $nodeUid1, $nodeUser1, $nodeChangeset1, $nodeLat1, $nodeLon1, $aRef1) = getNode1 () ;
144                                if ($nodeId1 != -1) {
145                                        @nodeTags1 = @$aRef1 ;
146                                }
147                        }
148                }
149
150                if ( ($nodeId1 == $nodeId2) and ($nodeId1 != -1) ) {
151                        # print "equal $nodeId1     $nodeId2\n" ;
152                        # position...
153                        if ( ($nodeLon1 != $nodeLon2) or ($nodeLat1 != $nodeLat2) ) {
154                                $nodesMovedNumber{$nodeUser2}++ ;
155                                my ($d) = distance ($nodeLon1, $nodeLat1, $nodeLon2, $nodeLat2) ;
156                                $nodesMovedDistance{$nodeUser2} += $d ;
157                                if (defined $nodesMovedMax{$nodeUser2}) {
158                                        if ($nodesMovedMax{$nodeUser2} < $d) { $nodesMovedMax{$nodeUser2} = $d ; }
159                                }
160                                else {
161                                        $nodesMovedMax{$nodeUser2} = $d ;
162                                }
163                                userArea ($nodeUser2, $nodeLon1, $nodeLat1) ;
164                                userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
165                        } # moved
166
167                        if ($nodeVersion2 - $nodeVersion1 > 2) { 
168                                push @{$versionJumpsNodes{$nodeUser2}}, [$nodeId2, $nodeVersion2 - $nodeVersion1] ;
169                        }
170
171                        # process tags
172                        my ($added, $deleted, $renamed, $reclassified) = compareTags (\@nodeTags1, \@nodeTags2) ; 
173                        if ($added) { $tagsAdded{$nodeUser2} += $added ; }
174                        if ($deleted) { $tagsDeleted{$nodeUser2} += $deleted ; }
175                        if ($renamed) { $tagsRenamed{$nodeUser2} += $renamed ; }
176                        # 2x next
177                        ($nodeId2, $nodeVersion2, $nodeTimestamp2, $nodeUid2, $nodeUser2, $nodeChangeset2, $nodeLat2, $nodeLon2, $aRef1) = getNodeFile2 () ;
178                        if ($nodeId2 != -1) {
179                                @nodeTags2 = @$aRef1 ;
180                        }
181                        ($nodeId1, $nodeVersion1, $nodeTimestamp1, $nodeUid1, $nodeUser1, $nodeChangeset1, $nodeLat1, $nodeLon1, $aRef1) = getNode1 () ;
182                        if ($nodeId1 != -1) {
183                                @nodeTags1 = @$aRef1 ;
184                        }
185                }
186
187                if ( ($nodeId1 > $nodeId2) and ($nodeId2 != -1) ) {
188                        # print "1 > 2 $nodeId1     $nodeId2   2-NEW\n" ;
189                        # id 2 not found in file 1, nodeId2 new
190                        $nodesAdded{$nodeUser2}++ ;
191                        userArea ($nodeUser2, $nodeLon2, $nodeLat2) ;
192                        # move file2 until id2>=id1
193                        while ( ($nodeId2 < $nodeId1) and ($nodeId2 != -1) ) {
194                                ($nodeId2, $nodeVersion2, $nodeTimestamp2, $nodeUid2, $nodeUser2, $nodeChangeset2, $nodeLat2, $nodeLon2, $aRef1) = getNodeFile2 () ;
195                                if ($nodeId2 != -1) {
196                                        @nodeTags2 = @$aRef1 ;
197                                }
198                        }
199                }
200
201                if ( ($nodeId1 < $nodeId2) and ($nodeId1 != -1) ) {
202                        # print "1 < 2 $nodeId1     $nodeId2   1-DELETED\n" ;
203                        # id 1 not found in file 2, nodeId1 deleted
204                        $deletedNodes++ ;
205                        if (scalar @nodeTags1 > 0) { 
206                                $deletedNodesWithTags++ ; 
207                                push @deletedNodesIds, $nodeId1 ;
208                                @{$deletedNodesTags{$nodeId1}} = @nodeTags1 ;
209                        }
210                        # move file1 until id1>=id2
211                        while ( ($nodeId1 < $nodeId2) and ($nodeId1 != -1) ) {
212                                ($nodeId1, $nodeVersion1, $nodeTimestamp1, $nodeUid1, $nodeUser1, $nodeChangeset1, $nodeLat1, $nodeLon1, $aRef1) = getNode1 () ;
213                                if ($nodeId1 != -1) {
214                                        @nodeTags1 = @$aRef1 ;
215                                }
216                        }
217                }
218        }
219        print "finished.\n" ;
220}
221
222#------------------------------------------------------------------------------------
223# Way procesing
224#------------------------------------------------------------------------------------
225
226sub processWays {
227
228}
229
230#------------------------------------------------------------------------------------
231# Output functions
232#------------------------------------------------------------------------------------
233
234sub output {
235        open ($html, ">", $htmlName) or die ("can't open html output file") ;
236        printHTMLHeader ($html, "UserActvity by Gary68") ;
237        print $html "<H1>UserActvity by gary68</H1>" ;
238        print $html "<p>", stringFileInfo ($osm1Name), "</p>\n"  ;
239        print $html "<p>", stringFileInfo ($osm2Name), "</p>\n"  ;
240        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>" ;
241        print $html "<H1>Results</H1>" ;
242        print $html "<p>DELETED NODES: $deletedNodes</p>\n" ;
243        print $html "<p>DELETED NODES WITH TAGS: $deletedNodesWithTags (details see further down)</p>\n" ;
244
245        my @a = () ;
246        foreach my $e (keys %nodesMovedNumber) { push @a, [$e, $nodesMovedNumber{$e}] ; }
247        printTop ("TOP moved nodes number", 0, @a) ;
248        @a = () ;
249        foreach my $e (keys %nodesMovedDistance) { push @a, [$e, $nodesMovedDistance{$e}] ; }
250        printTop ("TOP moved nodes total distance (km)", 1, @a) ;
251        @a = () ;
252        foreach my $e (keys %nodesMovedDistance) { push @a, [$e, $nodesMovedDistance{$e}/$nodesMovedNumber{$e}] ; }
253        printTop ("TOP moved nodes average distance (km)", 1, @a) ;
254        @a = () ;
255        foreach my $e (keys %nodesMovedMax) { push @a, [$e, $nodesMovedMax{$e}] ; }
256        printTop ("TOP moved nodes maximum distance (km)", 1, @a) ;
257
258        @a = () ;
259        foreach my $u (keys %maxLon) {
260                push @a, [$u, distance ($minLon{$u}, $minLat{$u}, $minLon{$u}, $maxLat{$u}) * distance ($minLon{$u}, $minLat{$u}, $maxLon{$u}, $minLat{$u})] ;
261        }
262        printTop ("TOP work areas (km²)", 1, @a) ;
263
264        @a = () ;
265        foreach my $e (keys %tagsAdded) { push @a, [$e, $tagsAdded{$e}] ; }
266        printTop ("TOP tags added", 0, @a) ;
267
268        @a = () ;
269        foreach my $e (keys %tagsRenamed) { push @a, [$e, $tagsRenamed{$e}] ; }
270        printTop ("TOP objects renamed", 0, @a) ;
271
272        my (@list) = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
273        # if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
274        print $html "<h2>Renames by ALL users</h2>\n" ;
275        printHTMLTableHead ($html) ;
276        printHTMLTableHeadings ($html, "User", "Tag", "Number") ; 
277        foreach my $e (@list) {
278                foreach my $t (keys %{$renames{$e->[0]}}) {
279                        # printf $html "%-25s %-80s %5i<br>\n" , $e->[0], $t, $renames{$e->[0]}{$t} ;
280                        printHTMLRowStart ($html) ;
281                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
282                        printHTMLCellLeft ($html, $t) ;                 
283                        printHTMLCellRight ($html, $renames{$e->[0]}{$t}) ;                     
284                        printHTMLRowEnd ($html) ;
285                }
286        }
287        printHTMLTableFoot ($html) ;
288
289        print $html "<h2>Version jumps nodes by ALL users</h2>\n" ;
290        printHTMLTableHead ($html) ;
291        printHTMLTableHeadings ($html, "User", "Nodes") ; 
292        foreach my $u (keys %versionJumpsNodes) {
293                printHTMLRowStart ($html) ;
294                printHTMLCellLeft ($html, userLink ($u)) ;                     
295                my $jumps = "" ;
296                foreach my $v (@{$versionJumpsNodes{$u}}) {
297                        $jumps = $jumps . historyLink ("node", $v->[0]) . " (" . $v->[1] . ") " ;
298                }
299                printHTMLCellLeft ($html, $jumps) ;                     
300                printHTMLRowEnd ($html) ;
301        }
302        printHTMLTableFoot ($html) ;
303
304        @a = () ;
305        foreach my $e (keys %tagsDeleted) { push @a, [$e, $tagsDeleted{$e}] ; }
306        printTop ("TOP tags deleted", 0, @a) ;
307
308        @list = @a ; @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
309        if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
310        print $html "<h2>Tags removed by TOP users</h2>\n" ;
311        printHTMLTableHead ($html) ;
312        printHTMLTableHeadings ($html, "User", "Removed", "Number") ; 
313        foreach my $e (@list) {
314                foreach my $t (keys %{$tagsDeletedName{$e->[0]}}) {
315                        # printf $html "%-25s %-50s %5i<br>\n" , $e->[0], $t, $tagsDeletedName{$e->[0]}{$t} ;
316                        printHTMLRowStart ($html) ;
317                        printHTMLCellLeft ($html, userLink ($e->[0])) ;                 
318                        printHTMLCellLeft ($html, $t) ;                 
319                        printHTMLCellRight ($html, $tagsDeletedName{$e->[0]}{$t}) ;                     
320                        printHTMLRowEnd ($html) ;
321                }
322        }
323        printHTMLTableFoot ($html) ;
324
325        print $html "<h2>ALL deleted Nodes with tags (details)</h2>\n" ;
326        printHTMLTableHead ($html) ;
327        printHTMLTableHeadings ($html, "NodeId", "Tags") ; 
328        foreach my $n (@deletedNodesIds) {
329                printHTMLRowStart ($html) ;
330                printHTMLCellLeft ($html, historyLink ("node", $n) ) ;                 
331                my $tagText = "" ;
332                foreach my $t (@{$deletedNodesTags{$n}}) { $tagText = $tagText . $t->[0] . ":" . $t->[1] . "<br>\n" ; }
333                printHTMLCellLeft ($html, $tagText) ;   
334                printHTMLRowEnd ($html) ;
335        }
336        printHTMLTableFoot ($html) ;
337
338        printHTMLFoot ($html) ;
339        print $html "<p>$program finished after ", stringTimeSpent (time()-$time0), "</p>\n" ;
340        close ($html) ;
341
342        # TODO
343        #@a = () ;
344        #foreach my $e (keys %tagsReclassified) { push @a, [$e, $tagsReclassified{$e}] ; }
345        #printTop ("Highways reclassified", @a) ;
346
347
348        # TODO reclassification list
349}
350
351sub printTop {
352        my ($heading, $decimal, @list) = @_ ;
353        print $html "<h2>$heading</h2>\n" ;
354        printHTMLTableHead ($html) ;
355        printHTMLTableHeadings ($html, "User", "Data") ; 
356        @list = reverse (sort {$a->[1]<=>$b->[1]} @list) ;
357        if (scalar @list > $topMax) { @list = @list[0..$topMax-1] ; }
358        foreach my $e (@list) {
359                printHTMLRowStart ($html) ;
360                my $s ;
361                if ($decimal) { 
362                        $s = sprintf "%8.3f", $e->[1] ;
363                }
364                else {
365                        $s = sprintf "%8i", $e->[1] ;
366                }
367                printHTMLCellLeft ($html, userLink ($e->[0]) ) ;                       
368                printHTMLCellRight ($html, $s) ;                       
369                printHTMLRowEnd ($html) ;
370        } 
371        printHTMLTableFoot ($html) ;
372}
373
374
375#------------------------------------------------------------------------------------
376# some functions
377#------------------------------------------------------------------------------------
378
379sub userArea {
380        my ($u, $lon, $lat) = @_ ;
381        if (! defined $maxLon{$u}) {
382                $minLon{$u} = $lon ;
383                $minLat{$u} = $lat ;
384                $maxLon{$u} = $lon ;
385                $maxLat{$u} = $lat ;
386        }
387        else {
388                if ($lon > $maxLon{$u}) { $maxLon{$u} = $lon ; }
389                if ($lon < $minLon{$u}) { $minLon{$u} = $lon ; }
390                if ($lat > $maxLat{$u}) { $maxLat{$u} = $lat ; }
391                if ($lat < $minLat{$u}) { $minLat{$u} = $lat ; }
392        }
393}
394
395sub compareTags {
396        my ($aRef1, $aRef2) = @_ ;
397        my $added = 0 ; my $deleted = 0 ; my $renamed = 0 ; my $reclassified = 0 ;
398        my (@tags1) = @$aRef1 ; my (@tags2) = @$aRef2 ;
399
400        # RENAMED?
401        my $nameGiven = 0 ;
402        my $nameOld = "" ; 
403        my $nameNew = "" ;
404        foreach my $t (@tags1) { 
405                if ($t->[0] eq "name") { $nameGiven = 1 ; $nameOld = $t->[1] ; }
406        }
407        foreach my $t (@tags2) { 
408                if ($t->[0] eq "name") { $nameNew = $t->[1] ; }
409        }
410        if ( ($nameGiven == 1) and ($nameNew ne $nameOld) ) { 
411                $renamed = 1 ; 
412                $renames{$nodeUser2}{$nameOld . " -> " . $nameNew} ++ ;
413        }
414       
415        # RECLASSIFIED?
416        my $highwayGiven = 0 ;
417        my $highwayOld = "" ;
418        my $highwayNew = "" ;
419        foreach my $t (@tags1) { 
420                if ($t->[0] eq "highway") { $highwayGiven = 1 ; $highwayOld = $t->[1] ; }
421        }
422        foreach my $t (@tags2) { 
423                if ($t->[0] eq "highway") { $highwayNew = $t->[1] ; }
424        }
425        if ( ($highwayGiven == 1) and ($highwayNew ne $highwayOld) ) { $reclassified = 1 ; }
426
427        # ADDED?
428        foreach my $t2 (@tags2) {
429                my $found = 0 ;
430                foreach my $t1 (@tags1) {
431                        if ( ($t1->[0] eq $t2->[0]) and ($t1->[1] eq $t2->[1]) ) { $found = 1 ; }
432                }
433                if ($found == 0) { $added++ ; }
434        }
435
436        # DELETED?
437        foreach my $t1 (@tags1) {
438                my $found = 0 ;
439                foreach my $t2 (@tags2) {
440                        if ( ($t1->[0] eq $t2->[0]) and ($t1->[1] eq $t2->[1]) ) { $found = 1 ; }
441                }
442                # if ($found == 0) {
443                if ( ($found == 0) and ($t1->[0] ne "created_by") ) { 
444                        $deleted++ ; 
445                        $tagsDeletedName{$nodeUser2}{$t1->[0].":".$t1->[1]}++ ;
446                }
447        }
448
449        return ($added, $deleted, $renamed, $reclassified) ;
450} # compareTags
451
452sub userLink {
453        my ($user) = shift ;
454        return "<a href=\"http://www.openstreetmap.org/user/" . $user . "\">" . $user . "</a>" ;
455}
456
457
458
459#------------------------------------------------------------------------------------
460# Basic object operations
461#------------------------------------------------------------------------------------
462
463sub getNode1 {
464        my ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) ;
465        my @gTags = () ;
466        if($line1 =~ /^\s*\<node/) {
467                if ( (grep /user=/, $line1) and (grep /uid=/, $line1) ) {
468                        ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) = 
469                        ($line1 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](.+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
470                }
471                else {
472                        ($id, $version, $timestamp, $changeset, $lat, $lon) = 
473                        ($line1 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
474                        $user = "unknown" ; $uid = 0 ;
475                }
476                if (!defined $user) { $user = "unknown" ; }
477                if (!defined $uid) { $uid = 0 ; }
478
479                if (!$id or (! (defined ($lat))) or ( ! (defined ($lon))) ) {
480                        print "WARNING reading osm file, line follows (expecting id, lon, lat and user for node):\n", $line1, "\n" ; 
481                }
482                else {
483                        if ( (grep (/">/, $line1)) or (grep (/'>/, $line1)) ) {                  # more lines, get tags
484                                nextLine1() ;
485                                while (!grep(/<\/node>/, $line1)) {
486                                        my ($k, $v) = ($line1 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
487                                        if ( (defined ($k)) and (defined ($v)) ) {
488                                                my $tag = [$k, $v] ; push @gTags, $tag ;
489                                        }
490                                        else { 
491                                                #print "WARNING tag not recognized: ", $line1, "\n" ;
492                                        }
493                                        nextLine1() ;
494                                }
495                                nextLine1() ;
496                        }
497                        else {
498                                nextLine1() ;
499                        }
500                }
501        }
502        else {
503                return (-1, -1, -1, -1, -1) ; 
504        } # node
505        return ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon, \@gTags) ; # in main @array = @$ref
506} # getNode1
507
508sub getNodeFile2 {
509        my ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) ;
510        my @gTags = () ;
511        if($line2 =~ /^\s*\<node/) {
512                if ( (grep /user=/, $line2) and (grep /uid=/, $line2) ) {
513                        ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon) = 
514                        ($line2 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+uid=[\'\"](.+)[\'\"].+user=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
515                }
516                else {
517                        ($id, $version, $timestamp, $changeset, $lat, $lon) = 
518                        ($line2 =~ /^\s*\<node id=[\'\"](\d+)[\'\"].+version=[\'\"](\d+)[\'\"].+timestamp=[\'\"](.+)[\'\"].+changeset=[\'\"](\d+)[\'\"].+lat=[\'\"](.+)[\'\"].+lon=[\'\"](.+)[\'\"]/) ;
519                        $user = "unknown" ; $uid = 0 ;
520                }
521                if (!defined $user) { $user = "unknown" ; }
522                if (!defined $uid) { $uid = 0 ; }
523
524                if (!$id or (! (defined ($lat))) or ( ! (defined ($lon))) ) {
525                        print "WARNING reading osm file 2, line follows (expecting id, lon, lat and user for node):\n", $line2, "\n" ; 
526                }
527                else {
528                        if ( (grep (/">/, $line2)) or (grep (/'>/, $line2)) ) {                  # more lines, get tags
529                                nextLine2() ;
530                                while (!grep(/<\/node>/, $line2)) {
531                                        my ($k, $v) = ($line2 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
532                                        if ( (defined ($k)) and (defined ($v)) ) {
533                                                my $tag = [$k, $v] ; push @gTags, $tag ;
534                                        }
535                                        else { 
536                                                #print "WARNING tag not recognized file 2: ", $line2, "\n" ;
537                                        }
538                                        nextLine2() ;
539                                }
540                                nextLine2() ;
541                        }
542                        else {
543                                nextLine2() ;
544                        }
545                }
546        }
547        else {
548                return (-1, -1, -1, -1, -1) ; 
549        } # node
550        return ($id, $version, $timestamp, $uid, $user, $changeset, $lat, $lon, \@gTags) ; # in main @array = @$ref
551} # getNodeFile2
552
553
554
555# TODO copy 1->2
556sub getWay1 {
557        my $gId ; my $gU ; my @gTags ; my @gNodes ;
558        if($line1 =~ /^\s*\<way/) {
559                my ($id)   = ($line1 =~ /^\s*\<way id=[\'\"](\d+)[\'\"]/); # get way id
560                my ($u) = ($line1 =~ /^.+user=[\'\"](.*)[\'\"]/);       # get value // REGEX???
561                if (!$u) { $u = "unknown" ; }
562                if (!$id) { print "ERROR reading osm file, line follows (expecting way id):\n", $line1, "\n" ; }
563                unless ($id) { next; }
564                nextLine1() ;
565                while (not($line1 =~ /\/way>/)) { # more way data
566                        my ($node) = ($line1 =~ /^\s*\<nd ref=[\'\"](\d+)[\'\"]/); # get node id
567                        my ($k, $v) = ($line1 =~ /^\s*\<tag k=[\'\"](.+)[\'\"]\s*v=[\'\"](.+)[\'\"]/) ;
568                        if ($node) {
569                                push @gNodes, $node ;
570                        }
571                        if ($k and defined($v)) { my $tag = [$k, $v] ; push @gTags, $tag ; }
572                        nextLine1() ;
573                }
574                nextLine1() ;
575                $gId = $id ; $gU = $u ;
576        }
577        else {
578                return (-1, -1, -1, -1) ;
579        }
580        return ($gId, $gU, \@gNodes, \@gTags) ;
581} # getWay1
582
583
584
585
586#------------------------------------------------------------------------------------
587# Basic file operations
588#------------------------------------------------------------------------------------
589
590sub openOsm1File {
591        $file1Name = shift ;
592        if (grep /.bz2/, $file1Name) { $isBz21 = 1 ; } else { $isBz21 = 0 ; }
593        if ($isBz21) {
594                $bz1 = bzopen($file1Name, "rb") or die "Cannot open $file1Name: $bzerrno\n" ;
595        }
596        else {
597                open ($file1, "<", $file1Name) || die "can't open osm file1" ;
598        }
599        nextLine1() ;           
600        while ( ! (grep /\<node/, $line1) ) {
601                nextLine1() ;
602        }
603        return 1 ;
604}
605
606sub closeOsm1File {
607        if ($isBz21) { $bz1->bzclose() ; }
608        else { close ($file1) ; }
609}
610
611sub nextLine1 {
612        if ($isBz21) { $bz1->bzreadline($line1) ; }
613        else { $line1 = <$file1> ; }
614}
615
616sub openOsm2File {
617        $file2Name = shift ;
618        if (grep /.bz2/, $file2Name) { $isBz22 = 1 ; } else { $isBz22 = 0 ; }
619        if ($isBz22) {
620                $bz2 = bzopen($file2Name, "rb") or die "Cannot open $file2Name: $bzerrno\n" ;
621        }
622        else {
623                open ($file2, "<", $file2Name) || die "can't open osm file2" ;
624        }
625        nextLine2() ;           
626        while ( ! (grep /\<node/, $line2) ) {
627                nextLine2() ;
628        }
629        return 1 ;
630}
631
632sub closeOsm2File {
633        if ($isBz22) { $bz2->bzclose() ; }
634        else { close ($file2) ; }
635}
636
637sub nextLine2 {
638        if ($isBz22) { $bz2->bzreadline($line2) ; }
639        else { $line2 = <$file2> ; }
640}
641
Note: See TracBrowser for help on using the repository browser.