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

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

initial upload of several programs

File size: 33.4 KB
Line 
1#
2# osmdiff.pl by Gary68
3#
4# osmdiff takes two .osm files and compares them. It will list changes of node and way data. It also draws a map
5# of the area and highlights changes. Changes are distinguished between:
6# - new nodes and ways
7# - changed nodes and ways (position, length)
8# - deleted nodes and ways
9# - changes in tags
10#
11# size and thickness are optional and will default to 1024 pixels and 1 pixel // deleted ways will be drawn at a minimum of 2 pixels though
12# size given is the size of longitude in pixels. If C is specified background will be colored lightly.
13#
14# Version 2
15# - German Umlaute (DONE - OK)
16# - history links for ways (DONE - OK)
17# - history links for nodes (DONE - OK)
18# - limit html table width to 100% (DONE - OK)
19# - exclude "created_by" tags (DONE)
20# - optional different background colors (DONE - OK)
21#
22# Version 3.0
23# - implement osmgraph.pm [X]
24# - implement street names [ ]
25#
26
27
28
29use strict ;
30use warnings ;
31
32use File::stat;
33use Time::localtime;
34use GD ;
35use Encode ;
36
37use OSM::osmgraph 2.0 ;
38
39##########
40#constants
41##########
42my $version = "V3.0" ;
43my $usage   = "osmdiff.pl file1.osm file2.osm output.htm pic.png [size [thickness [C]]]" ;
44my $delimiter = ":" ;   # for tag/value pair
45
46my $background = "gray" ;
47my $black = "black" ;
48my $new = "black" ;
49my $deleted = "red" ;
50my $changed = "blue" ;
51my $changedtags = "orange" ;
52my $bg_bab = "lightblue" ;
53my $bg_primary = "tomato" ;
54my $bg_water = "lightblue" ;
55
56
57##################
58# OSM data storage
59##################
60my %node0_lon ;
61my %node0_lat ;
62my %node0_tags ;
63my %node0_user ;
64my %way0_nodes ;
65my %way0_tags ;
66my %way0_user ;
67my %node1_lon ;
68my %node1_lat ;
69my %node1_tags ;
70my %node1_user ;
71my %way1_nodes ;
72my %way1_tags ;
73my %way1_user ;
74my %place_name ;
75my %place_lon ;
76my %place_lat ;
77my %user_lon ;
78my %user_lat ;
79my %user_num ;
80
81
82##################
83# difference lists
84##################
85my @nodes_new = () ;
86my @nodes_deleted = () ;
87my @nodes_changed_pos = () ;
88my @nodes_changed_tags = () ;
89my @ways_new = () ;
90my @ways_deleted = () ;
91my @ways_changed_num_nodes = () ;
92my @ways_changed_tags = () ;
93my @ways_changed_nodepos = () ;
94
95my $nodetags0 = 0 ;
96my $waytags0 = 0 ;
97my $nodetags1 = 0 ;
98my $waytags1 = 0 ;
99my $waynodecount0 = 0 ;
100my $waynodecount1 = 0 ;
101
102
103######################
104# definition variables
105######################
106my $bottom = "" ;
107my $top = "" ;
108my $left = "" ;
109my $right = "" ;
110
111################
112# file variables
113################
114my $basefile_name = "" ;
115my $file2_name = "" ;
116my $html_name ;
117my $html_file ;
118my $pic_name ;
119my $svg_name ;
120my $pic_file ;
121
122
123##########
124# graphics
125##########
126my $pic_size_x ; # lon
127my $pic_size_y ; # lat
128my $node_diameter = 4 ;
129my $thickness ;
130my $colors = "N" ;
131
132
133#################
134# other variables
135#################
136my $key ;
137my $time0 ;
138my $time1 ;
139my $timespent ;
140my $temp ;
141my $i ;
142my $j ;
143my $n ;
144my $a ;
145my $b ;
146my $c ;
147
148
149$time0 = time() ;
150
151#########################
152# get cmd line parameters
153#########################
154
155$basefile_name = shift||'';
156if (!$basefile_name)
157{
158        die (print $usage, "\n");
159}
160
161$file2_name = shift||'';
162if (!$file2_name)
163{
164        die (print $usage, "\n");
165}
166
167$html_name = shift||'';
168if (!$html_name)
169{
170        die (print $usage, "\n");
171}
172
173$pic_name = shift||'';
174if (!$pic_name)
175{
176        die (print $usage, "\n");
177}
178
179$pic_size_x = shift||'';
180if (!$pic_size_x)
181{
182        $pic_size_x = 1024 ;
183}
184
185$thickness = shift||'';
186if (!$thickness)
187{
188        $thickness = 1 ;
189}
190
191$colors = shift||'';
192if (!$colors)
193{
194        $colors = "N" ;
195}
196
197print "\n" ;
198
199$svg_name = $pic_name ;
200$svg_name =~ s/\.png/\.svg/ ;
201
202read_file ($basefile_name, 0) ;
203read_file ($file2_name, 1) ;
204
205
206####################
207# calc maxs and mins
208####################
209$top = -99 ;
210$left = 999 ;
211$bottom = 99 ;
212$right = -999 ;
213
214print "calculating area...\n" ;
215foreach $key (keys %node0_lat) {
216        if ($node0_lat{$key} > $top ) { $top = $node0_lat{$key} ; }
217        if ($node0_lat{$key} < $bottom ) { $bottom = $node0_lat{$key} ; }
218        if ($node0_lon{$key} < $left ) { $left = $node0_lon{$key} ; }
219        if ($node0_lon{$key} > $right ) { $right = $node0_lon{$key} ; }
220}
221
222foreach $key (keys %node1_lat) {
223        if ($node1_lat{$key} > $top ) { $top = $node1_lat{$key} ; }
224        if ($node1_lat{$key} < $bottom ) { $bottom = $node1_lat{$key} ; }
225        if ($node1_lon{$key} < $left ) { $left = $node1_lon{$key} ; }
226        if ($node1_lon{$key} > $right ) { $right = $node1_lon{$key} ; }
227}
228
229print "Left: $left " ;
230print "Right: $right " ;
231print "Bottom: $bottom " ;
232print "Top: $top\n" ;
233
234open ($html_file, ">", $html_name) ;
235
236print_html_header () ;
237
238#############
239# comparisons
240#############
241
242print "start comparison and write html...\n" ;
243
244#####################
245# general information
246#####################
247print $html_file "<h1>osmdiff by Gary68</h1>\n" ;
248print $html_file "<p>\n" ;
249print $html_file "<a href=\"#General Information\">General Information</a><br>\n" ;
250print $html_file "<a href=\"#User Information\">User Information</a><br>\n" ;
251print $html_file "<a href=\"#Deleted ways\">Deleted ways</a><br>\n" ;
252print $html_file "<a href=\"#New ways\">New ways</a><br>\n" ;
253print $html_file "<a href=\"#Ways with altered node count\">Ways with altered node count</a><br>\n" ;
254print $html_file "<a href=\"#Ways with at least one node with changed position\">Ways with at least one node with changed position</a><br>\n" ;
255print $html_file "<a href=\"#Ways with changed tags\">Ways with changed tags</a><br>\n" ;
256print $html_file "<a href=\"#Deleted nodes\">Deleted nodes</a><br>\n" ;
257print $html_file "<a href=\"#New nodes\">New nodes</a><br>\n" ;
258print $html_file "<a href=\"#Nodes with changed position\">Nodes with changed position</a><br>\n" ;
259print $html_file "<a href=\"#Nodes with changed tags\">Nodes with changed tags</a><br>\n" ;
260print $html_file "</p>\n" ;
261
262print $html_file "<a name=\"General Information\">" ;
263print $html_file "<h2>General information</h2>\n" ;
264print $html_file "</a>\n" ;
265
266
267print $html_file "<p>Bounding Box: $left - $right // $bottom - $top</p>\n" ;
268
269print $html_file "<table border=\"1\" width=\"100%\">\n" ;
270print $html_file " <tr>\n" ;
271print $html_file "  <th></th>\n" ;
272print $html_file "  <th>Old</th>\n" ;
273print $html_file "  <th>New</th>\n" ;
274print $html_file "  <th>Difference</th>\n" ;
275print $html_file " </tr>\n" ;
276
277print $html_file "<tr><td>Files</td>\n" ;
278print $html_file "<td>".$basefile_name." date: ".ctime(stat($basefile_name)->mtime)."</td>\n" ;
279print $html_file "<td>".$file2_name." date: ".ctime(stat($file2_name)->mtime)."</td>\n" ;
280print $html_file "<td></td>\n" ;
281print $html_file "</tr>\n" ;
282
283$a = scalar (keys %node0_lon) ;
284$b = scalar (keys %node1_lon) ;
285$c = $b - $a ;
286print $html_file "<tr><td>Number nodes</td>\n" ;
287print $html_file "<td>$a</td>\n" ;
288print $html_file "<td>$b</td>\n" ;
289print $html_file "<td>$c</td>\n" ;
290print $html_file "</tr>\n" ;
291
292$a = scalar (keys %way0_nodes) ;
293$b = scalar (keys %way1_nodes) ;
294$c = $b - $a ;
295print $html_file "<tr><td>Number ways</td>\n" ;
296print $html_file "<td>$a</td>\n" ;
297print $html_file "<td>$b</td>\n" ;
298print $html_file "<td>$c</td>\n" ;
299print $html_file "</tr>\n" ;
300
301$a = $nodetags0 ;
302$b = $nodetags1 ;
303$c = $b - $a ;
304print $html_file "<tr><td>Number node tags</td>\n" ;
305print $html_file "<td>$a</td>\n" ;
306print $html_file "<td>$b</td>\n" ;
307print $html_file "<td>$c</td>\n" ;
308print $html_file "</tr>\n" ;
309
310$a = $waytags0 ;
311$b = $waytags1 ;
312$c = $b - $a ;
313print $html_file "<tr><td>Number way tags</td>\n" ;
314print $html_file "<td>$a</td>\n" ;
315print $html_file "<td>$b</td>\n" ;
316print $html_file "<td>$c</td>\n" ;
317print $html_file "</tr>\n" ;
318
319$a = $waynodecount0 ;
320$b = $waynodecount1 ;
321$c = $b - $a ;
322print $html_file "<tr><td>Waynode count</td>\n" ;
323print $html_file "<td>$a</td>\n" ;
324print $html_file "<td>$b</td>\n" ;
325print $html_file "<td>$c</td>\n" ;
326print $html_file "</tr>\n" ;
327
328
329print $html_file "</table>\n" ;
330
331
332#######################
333# user stats / new node
334#######################
335foreach $key (keys %node1_lon) {
336        if (!exists $node0_lon{$key}) {
337                # check if user is new to list! init.
338                if (!exists $user_num{ $node1_user{$key} } ) {
339                        $user_lon{ $node1_user{$key} } = 0 ;
340                        $user_lat{ $node1_user{$key} } = 0 ;
341                        $user_num{ $node1_user{$key} } = 0 ;
342                }
343                $user_lon{ $node1_user{$key} } += $node1_lon{$key} ;
344                $user_lat{ $node1_user{$key} } += $node1_lat{$key} ;
345                $user_num{ $node1_user{$key} } ++ ;
346        }
347}
348
349###############################
350# user stats / changed pos node
351###############################
352foreach $key (keys %node0_lon) {
353        if ( (exists $node1_lon{$key}) and 
354        ( ($node0_lon{$key} != $node1_lon{$key}) or 
355        ($node0_lat{$key} != $node1_lat{$key}) ) ) {
356                # check if user is new to list! init.
357                if (!exists $user_num{ $node1_user{$key} } ) {
358                        $user_lon{ $node1_user{$key} } = 0 ;
359                        $user_lat{ $node1_user{$key} } = 0 ;
360                        $user_num{ $node1_user{$key} } = 0 ;
361                }
362                $user_lon{ $node1_user{$key} } += $node1_lon{$key} ;
363                $user_lat{ $node1_user{$key} } += $node1_lat{$key} ;
364                $user_num{ $node1_user{$key} } ++ ;
365        }
366}
367
368
369########################
370# print user information
371########################
372print $html_file "<hr />\n" ;
373print $html_file "<a name=\"User Information\">" ;
374print $html_file "<h2>User statistics</h2>\n" ;
375print $html_file "</a>\n" ;
376print $html_file "<p>Number active users: ", scalar (keys %user_num), "</p>\n" ;
377print $html_file "<h3>Number new and changed nodes per user</h3>\n" ;
378
379
380print $html_file "<table border=\"1\" width=\"100%\">\n" ;
381print $html_file " <tr>\n" ;
382print $html_file "  <th>User</th>\n" ;
383print $html_file "  <th>Nodes added/changed</th>\n" ;
384print $html_file " </tr>\n" ;
385
386foreach $key (keys %user_num) {
387        print $html_file "<tr><td>".$key."</td><td>".$user_num{$key}."</td></tr>\n" ;
388}
389print $html_file "</table>\n" ;
390
391
392#################
393#################
394# Way information
395#################
396#################
397
398print $html_file "<hr />\n" ;
399print $html_file "<h2>Way information</h2>\n" ;
400
401##############
402# deleted ways
403##############
404print $html_file "<a name=\"Deleted ways\">" ;
405print $html_file "<h3>Deleted ways</h3>\n" ;
406print $html_file "</a>\n" ;
407print $html_file "<p><span style=\"color:red\">" ;
408foreach $key (keys %way0_user) {
409        if (!exists $way1_user{$key}) {
410                print $html_file "<strong>", weblink("way", $key), "</strong> - ", $#{$way0_nodes{$key}}, " nodes. Tags: " ;
411                if (defined $way0_tags{$key}[0]) {
412                        for ($n=0; $n <= $#{$way0_tags{$key}}; $n++) {             
413                                print $html_file $way0_tags{$key}[$n], "  " ;
414                        }
415                }
416                else {
417                        print $html_file "no tags" ;
418                }
419                print $html_file "<br>\n" ;
420                push (@ways_deleted, $key) ;
421        }
422}
423print $html_file "</span></p>\n" ;
424
425##########
426# new ways
427##########
428print $html_file "<a name=\"New ways\">" ;
429print $html_file "<h3>New ways</h3>\n" ;
430print $html_file "</a>\n" ;
431print $html_file "<p><span style=\"color:black\">" ;
432foreach $key (keys %way1_user) {
433        if (!exists $way0_user{$key}) {
434                print $html_file "<strong>" ;
435                print $html_file weblink("way", $key), " by user ", $way1_user{$key}, "</strong>: " ;
436                if (defined $way1_tags{$key}[0]) {
437                        for ($n=0; $n <= $#{$way1_tags{$key}}; $n++) {             
438                                print $html_file $way1_tags{$key}[$n], "  " ;
439                        }
440                }
441                else {
442                        print $html_file "no tags" ;
443                }
444                print $html_file "<br>\n" ;
445                push (@ways_new, $key) ;
446        }
447}
448print $html_file "</span></p>\n" ;
449
450
451##########################
452# ways node number changed
453##########################
454print $html_file "<a name=\"Ways with altered node count\">" ;
455print $html_file "<h3>Ways with altered number of nodes</h3>\n" ;
456print $html_file "</a>\n" ;
457print $html_file "<p>Tags and user listed from new way.</p>\n" ;
458print $html_file "<p><span style=\"color:blue\">" ;
459foreach $key (keys %way0_user) {
460        if (exists $way1_user{$key}) {
461                if ($#{$way0_nodes{$key}} != $#{$way1_nodes{$key}}) {
462                        print $html_file "<strong>", weblink("way", $key), " by user ", $way1_user{$key}, "</strong> - " ;
463                        print $html_file " Nodes: ", $#{$way0_nodes{$key}}, "/", $#{$way1_nodes{$key}}, " Tags: " ;
464                        if (defined $way1_tags{$key}[0]) {
465                                for ($n=0; $n <= $#{$way1_tags{$key}}; $n++) {             
466                                        print $html_file $way1_tags{$key}[$n], "  " ;
467                                }
468                        }
469                        else {
470                                print $html_file "no tags" ;
471                        }
472                        print $html_file "<br>\n" ;
473                        push (@ways_changed_num_nodes, $key) ;
474                }
475        }
476
477}
478print $html_file "</span></p>\n" ;
479
480#######################
481# ways node pos changed
482#######################
483print $html_file "<a name=\"Ways with at least one node with changed position\">" ;
484print $html_file "<h3>Ways where at least one node changed position</h3>\n" ;
485print $html_file "</a>\n" ;
486print $html_file "<p><span style=\"color:blue\">" ;
487foreach $key (keys %way1_user) {
488        if (exists $way0_user{$key}) {   # ONLY IF OLD WAY EXISTS !!!
489                my $changed = 0 ;
490                for ($i = 0; $i <= $#{$way1_nodes{$key}}; $i++) {
491                        if ( defined ( $node0_lon{$way1_nodes{$key}[$i]} ) ) {
492                                if ( ( $node0_lon{$way1_nodes{$key}[$i]} != $node1_lon{$way1_nodes{$key}[$i]} ) or   
493                                        ( $node0_lat{$way1_nodes{$key}[$i]} != $node1_lat{$way1_nodes{$key}[$i]} ) ) {
494                                        $changed = 1 ;
495                                }
496                        }
497                        else {
498                                $changed = 1 ;
499                        }
500                }
501                if ($changed) {
502                        print $html_file "<strong>", weblink("way", $key), "</strong> - \n" ;
503                        if (defined $way1_tags{$key}[0]) {
504                                for ($n=0; $n <= $#{$way1_tags{$key}}; $n++) {             
505                                        print $html_file $way1_tags{$key}[$n], "  " ;
506                                }
507                        }
508                        else {
509                                print $html_file "no tags" ;
510                        }
511                        print $html_file "<br>\n" ;
512                        push @ways_changed_nodepos, $key ;
513                }
514        }
515}
516print $html_file "</span></p>\n" ;
517print $html_file "<p>Number ways: ", $#ways_changed_nodepos + 1, "</p>\n" ;
518
519
520################################
521# check for changed tags in ways
522################################
523print $html_file "<a name=\"Ways with changed tags\">" ;
524print $html_file "<h3>Ways with changed tags</h3>\n" ;
525print $html_file "</a>\n" ;
526print $html_file "<table border=\"1\" width=\"100%\">\n" ;
527print $html_file " <tr>\n" ;
528print $html_file "  <th>Way</th>\n" ;
529print $html_file "  <th>Last user</th>\n" ;
530print $html_file "  <th>Deleted tags</th>\n" ;
531print $html_file "  <th>New tags</th>\n" ;
532print $html_file "  <th>All tags (new file)</th>\n" ;
533print $html_file " </tr>\n" ;
534
535foreach $key (keys %way0_nodes) {
536        if (defined $way1_nodes{$key}) {
537                my @tags_new ;
538                my @tags_deleted ;
539                my $changed = 0 ;
540                my $found ;
541                if ( $#{$way0_tags{$key}} > 0 ) {
542                        if ( $#{$way1_tags{$key}} > 0 ) {
543
544                                # check each tag in way0
545                                for ( $i=0; $i<=$#{$way0_tags{$key}}; $i++ ) {
546                                        $found = 0  ;
547                                        for ( $j=0; $j<=$#{$way1_tags{$key}}; $j++) {
548                                                if ( $way0_tags{$key}[$i] eq $way1_tags{$key}[$j] ) {
549                                                        $found = 1 ;
550                                                }
551                                        }
552                                        if ( $found == 0 ) {
553                                                push @tags_deleted, $way0_tags{$key}[$i] ;
554                                                $changed = 1 ;
555                                        }
556                                }                               
557
558                                # check each tag in way0
559                                for ( $i=0; $i<=$#{$way1_tags{$key}}; $i++ ) {
560                                        $found = 0  ;
561                                        for ( $j=0; $j<=$#{$way0_tags{$key}}; $j++) {
562                                                if ( $way1_tags{$key}[$i] eq $way0_tags{$key}[$j] ) {
563                                                        $found = 1 ;
564                                                }
565                                        }
566                                        if ( $found == 0 ) {
567                                                push @tags_new, $way1_tags{$key}[$i] ;
568                                                $changed = 1 ;
569                                        }
570                                }                               
571
572                        }
573                        else { # way0 = 0
574
575                                # all tags from 0 deleted
576                                for ( $i=0; $i<= $#{$way0_tags{$key}}; $i++ ) {
577                                        push @tags_deleted, $way0_tags{$key}[$i] ;
578                                        $changed = 1 ;
579                                }
580                        }
581                }
582                else { # way0 = 0
583                        if ( $#{$way1_tags{$key}} > 0 ) {
584
585                                # all tags from way1 new
586                                for ( $i=0; $i<= $#{$way1_tags{$key}}; $i++ ) {
587                                        push @tags_new, $way1_tags{$key}[$i] ;
588                                        $changed = 1 ;
589                                }
590                        }
591                        else # way1 = 0
592                        {
593                                # no changes
594                        }
595                }
596                if ($changed) {
597
598                        push @ways_changed_tags, $key ;
599
600                        # print row to html
601                        print $html_file "<tr>\n" ;
602                        print $html_file "<td>" . weblink("way", $key) . "</td>\n" ;
603                        print $html_file "<td>$way1_user{$key}</td>\n" ;
604
605
606                        # print deleted tags
607                        print $html_file "<td><p>" ;
608                        foreach $temp (@tags_deleted) {
609                                print $html_file $temp, "<br>\n" ;
610                        }
611                        print $html_file "</p></td>\n" ;
612
613                        # print new tags
614                        print $html_file "<td><p>" ;
615                        foreach $temp (@tags_new) {
616                                print $html_file $temp, "<br>\n" ;
617                        }
618                        print $html_file "</p></td>\n" ;
619
620                        # all tags as in new way
621                        print $html_file "<td><p>" ;
622                        for ( $i = 0; $i <= $#{$way1_tags{$key}}; $i++ ) {
623                                print $html_file $way1_tags{$key}[$i], "<br>\n" ;
624                        }
625                        print $html_file "</p></td>\n" ;
626
627                        print $html_file "</tr>\n" ;
628                }
629        }
630}
631print $html_file "</table>\n" ;
632$i = $#ways_changed_tags + 1 ;
633print $html_file "<p>", $i, " ways with changed tags.</p>\n" ; 
634
635
636##################
637##################
638# node information
639##################
640##################
641
642print $html_file "<hr />\n" ;
643print $html_file "<h2>Node information</h2>\n" ;
644
645###############
646# deleted nodes
647###############
648print $html_file "<a name=\"Deleted nodes\">" ;
649print $html_file "<h3>Deleted nodes</h3>\n" ;
650print $html_file "</a>\n" ;
651print $html_file "<p><span style=\"color:red\">" ;
652foreach $key (keys %node0_lon) {
653        if (!exists $node1_lon{$key}) {
654                print $html_file "<strong>" ;
655                print $html_file weblink("node", $key), "</strong>: " ;
656                if (defined $node0_tags{$key}[0]) {
657                        for ($n=0; $n <= $#{$node0_tags{$key}}; $n++) {             
658                                print $html_file $node0_tags{$key}[$n], "  " ;
659                        }
660                }
661                else {
662                        print $html_file "no tags" ;
663                }
664                print $html_file "<br>\n" ;
665                push (@nodes_deleted, $key) ;
666        }
667}
668print $html_file "</span></p>\n" ;
669
670###########
671# new nodes
672###########
673print $html_file "<a name=\"New nodes\">" ;
674print $html_file "<h3>New nodes</h3>\n" ;
675print $html_file "</a>\n" ;
676print $html_file "<p><span style=\"color:black\">" ;
677foreach $key (keys %node1_lon) {
678        if (!exists $node0_lon{$key}) {
679                print $html_file "<strong>" ;
680                print $html_file weblink("node", $key), " by user ", $node1_user{$key}, "</strong>: " ;
681                if (defined $node1_tags{$key}[0]) {
682                        for ($n=0; $n <= $#{$node1_tags{$key}}; $n++) {             
683                                print $html_file $node1_tags{$key}[$n], "  " ;
684                        }
685                }
686                else {
687                        print $html_file "no tags" ;
688                }
689                print $html_file "<br>\n" ;
690                push (@nodes_new, $key) ;
691        }
692}
693print $html_file "</span></p>\n" ;
694
695
696#############################
697# nodes with position changed
698#############################
699print $html_file "<a name=\"Nodes with changed position\">" ;
700print $html_file "<h3>Nodes with new position</h3>\n" ;
701print $html_file "</a>\n" ;
702print $html_file "<p><span style=\"color:blue\">" ;
703foreach $key (keys %node0_lon) {
704        if ( (exists $node1_lon{$key}) and 
705        ( ($node0_lon{$key} != $node1_lon{$key}) or 
706        ($node0_lat{$key} != $node1_lat{$key}) ) ) {
707                my ($dist) = sqrt ( ($node0_lon{$key}-$node1_lon{$key})**2 + ($node0_lat{$key}-$node1_lat{$key})**2 ) * 111.11 * 1000 ;
708                print $html_file "<strong>" ;
709                printf $html_file "%s distance = ~%.1i (m)</strong> (tags from old data): ", weblink("node", $key), $dist ;
710                if (defined $node0_tags{$key}[0]) {
711                        for ($n=0; $n <= $#{$node0_tags{$key}}; $n++) {             
712                                print $html_file $node0_tags{$key}[$n], "  " ;
713                        }
714                }
715                else {
716                        print $html_file "no tags" ;
717                }
718                print $html_file "<br>\n" ;
719                push (@nodes_changed_pos, $key) ;
720        }
721}
722print $html_file "</span></p>\n" ;
723
724
725#################################
726# check for changed tags in nodes
727#################################
728print $html_file "<a name=\"Nodes with changed tags\">" ;
729print $html_file "<h3>Nodes with changed tags</h3>\n" ;
730print $html_file "</a>\n" ;
731print $html_file "<table border=\"1\" width=\"100%\">\n" ;
732print $html_file " <tr>\n" ;
733print $html_file "  <th>Node</th>\n" ;
734print $html_file "  <th>Last user</th>\n" ;
735print $html_file "  <th>Deleted tags</th>\n" ;
736print $html_file "  <th>New tags</th>\n" ;
737print $html_file "  <th>All tags (new file)</th>\n" ;
738print $html_file " </tr>\n" ;
739
740foreach $key (keys %node0_lon) {
741        if (defined $node1_lon{$key}) {
742                my @tags_new ;
743                my @tags_deleted ;
744                my $changed = 0 ;
745                my $found ;
746                if ( $#{$node0_tags{$key}} > 0 ) {
747                        if ( $#{$node1_tags{$key}} > 0 ) {
748
749                                # check each tag in node0
750                                for ( $i=0; $i<=$#{$node0_tags{$key}}; $i++ ) {
751                                        $found = 0  ;
752                                        for ( $j=0; $j<=$#{$node1_tags{$key}}; $j++) {
753                                                if ( $node0_tags{$key}[$i] eq $node1_tags{$key}[$j] ) {
754                                                        $found = 1 ;
755                                                }
756                                        }
757                                        if ( $found == 0 ) {
758                                                push @tags_deleted, $node0_tags{$key}[$i] ;
759                                                $changed = 1 ;
760                                        }
761                                }                               
762
763                                # check each tag in node1
764                                for ( $i=0; $i<=$#{$node1_tags{$key}}; $i++ ) {
765                                        $found = 0  ;
766                                        for ( $j=0; $j<=$#{$node0_tags{$key}}; $j++) {
767                                                if ( $node1_tags{$key}[$i] eq $node0_tags{$key}[$j] ) {
768                                                        $found = 1 ;
769                                                }
770                                        }
771                                        if ( $found == 0 ) {
772                                                push @tags_new, $node1_tags{$key}[$i] ;
773                                                $changed = 1 ;
774                                        }
775                                }                               
776
777                        }
778                        else { # node0 = 0
779
780                                # all tags from 0 deleted
781                                for ( $i=0; $i<= $#{$node0_tags{$key}}; $i++ ) {
782                                        push @tags_deleted, $node0_tags{$key}[$i] ;
783                                        $changed = 1 ;
784                                }
785                        }
786                }
787                else { # node0 = 0
788                        if ( $#{$node1_tags{$key}} > 0 ) {
789
790                                # all tags from node1 new
791                                for ( $i=0; $i<= $#{$node1_tags{$key}}; $i++ ) {
792                                        push @tags_new, $node1_tags{$key}[$i] ;
793                                        $changed = 1 ;
794                                }
795                        }
796                        else # node1 = 0
797                        {
798                                # no changes
799                        }
800                }
801                if ($changed) {
802
803                        push @nodes_changed_tags, $key ;
804
805                        # print row to html
806                        print $html_file "<tr>\n" ;
807                        print $html_file "<td>" . weblink("node", $key) . "</td>\n" ;
808                        print $html_file "<td>$node1_user{$key}</td>\n" ;
809
810                        # print deleted tags
811                        print $html_file "<td><p>" ;
812                        foreach $temp (@tags_deleted) {
813                                print $html_file $temp, "<br>\n" ;
814                        }
815                        print $html_file "</p></td>\n" ;
816
817                        # print new tags
818                        print $html_file "<td><p>" ;
819                        foreach $temp (@tags_new) {
820                                print $html_file $temp, "<br>\n" ;
821                        }
822                        print $html_file "</p></td>\n" ;
823
824                        # all tags as in new node
825                        print $html_file "<td><p>" ;
826                        for ( $i = 0; $i <= $#{$node1_tags{$key}}; $i++ ) {
827                                print $html_file $node1_tags{$key}[$i], "<br>\n" ;
828                        }
829                        print $html_file "</p></td>\n" ;
830
831                        print $html_file "</tr>\n" ;
832                }
833        }
834}
835print $html_file "</table>\n" ;
836$i = $#nodes_changed_tags + 1 ;
837print $html_file "<p>", $i, " nodes with changed tags.</p>\n" ; 
838
839
840
841
842
843print_html_foot () ;
844close $html_file ;
845
846print "finished.\n\n" ;
847
848draw_pic () ;
849
850$time1 = time() ;
851$timespent = ($time1 - $time0);
852print "Time spent: ", ($timespent/(60*60))%99, " hours, ", ($timespent/60)%60, " minutes and ", $timespent%60, " seconds\n" ;
853
854
855
856
857##########################################################################################################################
858##########################################################################################################################
859# sub routines
860##########################################################################################################################
861##########################################################################################################################
862
863
864############
865# READ FILES
866############
867
868sub read_file {
869        my ($name, $position) = @_;
870        my $file ;
871
872        print "reading file $name...\n" ;
873        open ($file, , "<", $name) ;
874
875        while(my $line = <$file>) {
876                if($line =~ /^\s*\<way/) {
877                        my $n = 0 ; # way nodes count
878                        my $m = 0 ; # way k/v count
879       
880                        # get all needed information
881                        my ($id)   = ($line =~ /^\s*\<way id=[\'\"](\d+)[\'\"]/); # get way id
882                        my ($u) = ($line =~ /^.+user=[\'\"]([-\w\d\s]+)[\'\"]/);       # get value // REGEX???
883
884                        if (!$u) {
885                                $u = "unknown" ;
886                        }
887                       
888                        if (!$id) {
889                                print "ERROR reading osm file ", $name, ", line follows (expecting way id):\n", $line, "\n" ; 
890                        }
891       
892                        unless ($id) { next; }
893
894                        if ($id and $u) {
895                                if ($position ==0) {
896                                        ${way0_nodes{$id}} = () ;
897                                        $way0_user{$id} = $u ;
898                                }
899                                else {
900                                        ${way1_nodes{$id}} = () ;
901                                        $way1_user{$id} = $u ;
902                                }
903                        }
904
905                        $line = <$file> ;
906                        while (not($line =~ /\/way/)) { # more way data
907
908                                #get nodes and type
909                                my ($node) = ($line =~ /^\s*\<nd ref=[\'\"](\d+)[\'\"]/); # get node id
910                                my ($k)   = ($line =~ /^\s*\<tag k=[\'\"]([\w_:]+)[\'\"]/); # get key
911                                #my ($v) = ($line =~ /^.+v=[\'\"]([-\w\d\s\.\-]+)[\'\"]/);       # get value // REGEX???
912                                my ($v) = ($line =~ /v=[\'\"](.*)[\'\"]/) ;
913
914                                if (!(($node) or ($k and defined($v) ))) {
915                                        print "WARNING reading osm file ", $name, ", line follows (expecting node or k/v for way):\n", $line, "\n" ; 
916                                }
917                       
918                                if ($node) {
919                                        #add node to way data
920                                        if ($position ==0) {
921                                                $way0_nodes{$id}[$n] = $node ;
922                                                $way0_user{$id} = $u ;
923                                                $waynodecount0++ ;
924                                        }
925                                        else {
926                                                $way1_nodes{$id}[$n] = $node ;
927                                                $way1_user{$id} = $u ;
928                                                $waynodecount1++ ;
929                                        }
930                                        $n++ ;
931                                }
932
933                                #get tags but not CREATED_BY
934                                if ($k and defined($v)) {
935                                        if ($k ne "created_by") {
936                                                #print "k/v; ", $k, " ", $v, "\n" ;
937                                                if ($position == 0) {
938                                                        $way0_tags{$id}[$m] = $k . $delimiter . $v ;
939                                                        $waytags0++ ;
940                                                }
941                                                else {
942                                                        $way1_tags{$id}[$m] = $k . $delimiter . $v ;
943                                                        $waytags1++ ;
944                                                }
945                                                $m++ ;
946                                        }
947                                }
948                                $line = <$file> ;
949                        }
950                }
951
952                if($line =~ /^\s*\<node/) {
953                        # get all needed information
954                        my ($id)   = ($line =~ /^\s*\<node id=[\'\"](\d+)[\'\"]/); # get node id
955                        my ($lon) = ($line =~ /^.+lon=[\'\"]([-\d,\.]+)[\'\"]/);    # get position
956                        my ($lat) = ($line =~ /^.+lat=[\'\"]([-\d,\.]+)[\'\"]/);    # get position
957                        my ($u) = ($line =~ /^.+user=[\'\"]([-\w\d\s]+)[\'\"]/);       # get value // REGEX???
958
959                        my ($i) = 0 ;
960                        my $place = 0 ;
961                        my $name = "" ;
962
963                        if (!$u) {
964                                $u = "unknown" ;
965                        }
966
967                        if (!$id or !$lat or !$lon) {
968                                print "WARNING reading osm file ", $name, ", line follows (expecting id, lon, lat and user for node):\n", $line, "\n" ; 
969                        }
970
971                        unless ($id) { next; }
972                        unless ($lat) { next; }
973                        unless ($lon) { next; }
974                        #unless ($u) { next; }
975
976                        #store node
977                        if ($position == 0) {
978                                $node0_lon {$id} = $lon ;
979                                $node0_lat {$id} = $lat ;
980                                $node0_user {$id} = $u ;
981                        }
982                        else {
983                                $node1_lon {$id} = $lon ;
984                                $node1_lat {$id} = $lat ;
985                                $node1_user {$id} = $u ;
986                        }
987                       
988                        if (grep (/">/, $line)) {                  # more lines, get tags
989                                $line = <$file> ;
990                                while (!grep(/<\/node>/, $line)) {
991                                        my ($k) = ($line =~ /^\s*\<tag k=[\'\"]([\w_:]+)[\'\"]/);   # get key
992                                        #my ($v) = ($line =~ /^.+v=[\'\"]([\/\w\d\s\.:,\(\)]+)[\'\"]/);   # get value REGEX???
993                                        my ($v) = ($line =~ /v=[\'\"](.*)[\'\"]/) ;
994
995
996                                        #get tags but not CREATED_BY
997                                        if ($k and defined($v) ) {
998                                                if ($k ne "created_by") {
999                                                        if ($position == 0) {
1000                                                                $node0_tags{$id}[$i] = $k . $delimiter . $v ;
1001                                                                $nodetags0++ ;
1002                                                                if ( ($k eq "place") and (($v eq "city") or ($v eq "town") or ($v eq "suburb") or ($v eq "village")) ) {
1003                                                                        $place = 1 ;
1004                                                                }
1005                                                                if ($k eq "name") {
1006
1007                                                                        # REPLACE UMLAUTE
1008                                                                        #print $v, " " ;
1009                                                                        #utf8::decode ($v) ;
1010                                                                        #$v =~ s/ä/ae/g ;
1011                                                                        #$v =~ s/\148/oe/g ;
1012                                                                        #$v =~ s/ü/ue/g ;
1013                                                                        #$v =~ s/ß/ss/g ;
1014                                                                        #$v =~ s/ä/ae/g;
1015                                                                        #$v =~ s/Ä/Ae/g;
1016                                                                        #$v =~ s/ö/oe/g;
1017                                                                        #$v =~ s/ü/ue/g;
1018                                                                        #$v =~ s/Ãœ/Ue/g;
1019                                                                        #$v =~ s/ß/ss/g;
1020                                                                        #$v =~ s/Ã/Oe/g;
1021                                                                        $name = $v ;
1022                                                                        #print $name, "\n" ;
1023                                                                }
1024                                                        }
1025                                                        else {
1026                                                                $node1_tags{$id}[$i] = $k . $delimiter . $v ;
1027                                                                $nodetags1++ ;
1028                                                        }
1029                                                        $i++ ;
1030                                                }
1031                                        }
1032                                        else {
1033                                                print "WARNING reading osm file ", $name, ", line follows (expecting k/v for node):\n", $line, "\n" ; 
1034                                        }
1035                                        $line = <$file> ;
1036                                }
1037                        }
1038                        if ( ($place == 1) and ($name ne "") ) {
1039                                #print "place found: $id $name $lon $lat\n" ;
1040                                $place_name{$id} = $name ;
1041                                $place_lat{$id} = $lat ;
1042                                $place_lon{$id} = $lon ;
1043                        }
1044                }
1045        }
1046        close $file ;
1047        print "finished.\n" ;
1048} #sub
1049
1050
1051######
1052# HTML
1053######
1054
1055sub print_html_header {
1056        print $html_file "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"";
1057        print $html_file "  \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
1058        print $html_file "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">\n";
1059        print $html_file "<head><title>osmdiff by Gary68</title>\n";
1060        print $html_file "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n";
1061        print $html_file "</head>\n<body>\n";
1062}
1063sub print_html_foot {
1064        print $html_file "</body>\n</html>\n" ;
1065}
1066
1067
1068##############
1069# draw picture
1070##############
1071
1072sub draw_pic {
1073
1074        my $color ;
1075
1076        # init pic
1077        initGraph ($pic_size_x, $left, $bottom, $right, $top) ;
1078        enableSVG ;
1079
1080        print "drawing picture...\n" ;
1081#       printf "pic size: %i by %i\n", $pic_size_x, $pic_size_y ;
1082
1083#       $image->filledRectangle(0,0,$pic_size_x-1,$pic_size_y-1,$white) ;
1084
1085        # draw old ways
1086        foreach $key (keys %way0_nodes) {
1087                if ( $#{$way0_nodes{$key}} > 0 ) {
1088                        $color = $background ;
1089                        if ($colors eq "C") {
1090                                if ( defined ($way0_tags{$key}) ) {
1091                                        for ($i=0; $i<= $#{$way0_tags{$key}}; $i++ ) {
1092                                                if ( grep (/trunk/, $way0_tags{$key}[$i]) ) { $color = $bg_bab ; } 
1093                                                if ( grep (/motorway/, $way0_tags{$key}[$i]) ) { $color = $bg_bab ; } 
1094                                                if ( grep (/waterway/, $way0_tags{$key}[$i]) ) { $color = $bg_water ; } 
1095                                                if ( grep (/primary/, $way0_tags{$key}[$i]) ) { $color = $bg_primary ; } 
1096                                        }
1097                                }
1098                        }
1099                        drawWay ($color, 1, nodes02Coordinates ( @{$way0_nodes{$key}} ) ) ; 
1100                }
1101        }
1102        print "background drawn.\n" ;
1103
1104        # draw deleted ways
1105        my $thick2 = $thickness ;
1106        if ($thick2 < 2) { $thick2 = 2 ; }
1107       
1108        foreach $key (@ways_deleted) {
1109
1110                if ( $#{$way0_nodes{$key}} > 0 ) {
1111                        drawWay ($deleted, $thick2, nodes02Coordinates ( @{$way0_nodes{$key}} ) ) ; 
1112                }
1113        }
1114        print "deleted ways drawn.\n" ;
1115
1116        # draw new ways
1117        foreach $key (@ways_new) {
1118                if ( $#{$way1_nodes{$key}} > 0 ) {
1119                        drawWay ($new, $thickness, nodes12Coordinates ( @{$way1_nodes{$key}} ) ) ; 
1120                }
1121        }
1122        print "new ways drawn.\n" ;
1123
1124
1125        # draw changed ways / tags
1126        foreach $key (@ways_changed_tags) {
1127                if ( $#{$way1_nodes{$key}} > 0 ) {
1128                        drawWay ($changedtags, $thickness, nodes12Coordinates ( @{$way1_nodes{$key}} ) ) ; 
1129                }
1130        }
1131        print "ways with changed tags drawn.\n" ;
1132
1133        # draw changed ways / number nodes
1134        foreach $key (@ways_changed_num_nodes) {
1135                if ( $#{$way1_nodes{$key}} > 0 ) {
1136                        drawWay ($changed, $thickness, nodes12Coordinates ( @{$way1_nodes{$key}} ) ) ; 
1137                }
1138        }
1139        print "ways with different nodecount drawn.\n" ;
1140
1141        # draw changed ways / position node changed
1142        foreach $key (@ways_changed_nodepos) {
1143                if ( $#{$way1_nodes{$key}} > 0 ) {
1144                        drawWay ($changed, $thickness, nodes12Coordinates ( @{$way1_nodes{$key}} ) ) ; 
1145                }
1146        }
1147        print "ways with nodes with changed position drawn.\n" ;
1148
1149
1150        # draw new nodes (only those with tags)
1151        foreach $key (@nodes_new) {
1152                if ($#{$node1_tags{$key}} > 0) {
1153                        drawNodeDot ($node1_lon{$key}, $node1_lat{$key}, $new, $node_diameter) ; 
1154                }
1155        }
1156        print "new nodes drawn (only those with tags).\n" ;
1157
1158
1159        # draw deleted nodes
1160        foreach $key (@nodes_deleted) {
1161                drawNodeDot ($node0_lon{$key}, $node0_lat{$key}, $deleted, $node_diameter) ; 
1162        }
1163        print "deleted nodes drawn.\n" ;
1164
1165        # draw changed nodes pos
1166        foreach $key (@nodes_changed_pos) {
1167                drawNodeDot ($node0_lon{$key}, $node0_lat{$key}, $changed, $node_diameter) ; 
1168        }
1169        print "nodes with changed position drawn.\n" ;
1170
1171        # draw changed nodes tags
1172        foreach $key (@nodes_changed_tags) {
1173                drawNodeCircle ($node0_lon{$key}, $node0_lat{$key}, $changedtags, $node_diameter) ; 
1174        }
1175        print "nodes with changed tags drawn.\n" ;
1176
1177        # draw places
1178        foreach $key (keys %place_name) {
1179                drawTextPos ($place_lon{$key}, $place_lat{$key}, 0, 0, $place_name{$key}, $black, 3) ;
1180#               drawTextPos ($place_lon{$key}, $place_lat{$key}, 0, 0, encode("iso-8859-1", decode("utf8", $place_name{$key})), $black, 3) ;
1181        }
1182        print "places drawn.\n" ;
1183
1184
1185        # draw user positions
1186        foreach $key (keys %user_lat) {
1187                my ($x) = $user_lon{$key} / $user_num{$key} ;
1188                my ($y) = $user_lat{$key} / $user_num{$key} ;
1189                drawTextPos ($x, $y, 0, 0, $key, $changed, 2) ;
1190        }
1191
1192        drawHead ("data by www.openstreetmap.org", $black, 2) ;
1193
1194        drawLegend (3, "Changed Tags", $changedtags, "Changed Position", $changed, "Deleted", $deleted, "New", $new) ; 
1195
1196        drawFoot ("Gary68's osmdiff "   . $version . 
1197                " - ".$basefile_name." ".ctime(stat($basefile_name)->mtime)." // ".$file2_name." ".ctime(stat($file2_name)->mtime), $black, 2) ; 
1198
1199        drawRuler ("black") ;
1200
1201        writeGraph ($pic_name) ;
1202        writeSVG ($svg_name) ;
1203        print "finished.\n\n" ;
1204} # draw_pic
1205
1206
1207##############
1208# history link
1209##############
1210
1211sub weblink {
1212        my ($type, $key) = @_;
1213        return "<a href=\"http://www.openstreetmap.org/browse/$type/$key/history\">$key</a>";
1214}
1215
1216
1217sub nodes02Coordinates {
1218#
1219# transform list of node1Ids to list of lons/lats
1220#
1221        my @nodes = @_ ;
1222        my $i ;
1223        my @result = () ;
1224
1225        #print "in @nodes\n" ;
1226
1227        for ($i=0; $i<=$#nodes; $i++) {
1228                push @result, $node0_lon{$nodes[$i]} ;
1229                push @result, $node0_lat{$nodes[$i]} ;
1230        }
1231        return @result ;
1232}
1233
1234sub nodes12Coordinates {
1235#
1236# transform list of node1Ids to list of lons/lats
1237#
1238        my @nodes = @_ ;
1239        my $i ;
1240        my @result = () ;
1241
1242        #print "in @nodes\n" ;
1243
1244        for ($i=0; $i<=$#nodes; $i++) {
1245                push @result, $node1_lon{$nodes[$i]} ;
1246                push @result, $node1_lat{$nodes[$i]} ;
1247        }
1248        return @result ;
1249}
Note: See TracBrowser for help on using the repository browser.