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

Last change on this file was 26778, checked in by gary68, 8 years ago

gpl added to some files

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