source: subversion/applications/utils/filter/oscgrep/oscgrep.pl @ 34385

Last change on this file since 34385 was 18168, checked in by frederik, 10 years ago

always pass through <osmChange>

File size: 3.9 KB
Line 
1#!/usr/bin/perl
2
3# Written by Frederik Ramm <frederik@remote.org>, public domain.
4sub HELP_MESSAGE { print <<EOF;
5$0 is a simple script that helps you find certain objects in .osc files.
6
7It is called like this:
8
9perl $0 [-a action] [-t type] [-s shapename] [-q] [-v] [-r regex] [file] [file...]
10
11where
12  "action" is either create, modify, or delete;
13  "type" is either way, node, or relation;
14  "regex" is any regular expression
15  "file" is an .osc file (also supports .osc.gz or .osc.bz2)
16
17It lists all elements from the .osc file that match the given action, type, and
18regex (regex is applied against full XML content of the object). The switch
19-v inverts the regex match (prints records that do NOT match the regex).
20If -a, -t or -r are omitted, dumps all actions/all types/all content;
21if file is omitted, reads from stdin.
22
23If the -s parameter is specified, then $0 will, in addition to its normal
24output, also write a shape file under the given name which contains all
25nodes found. For example, the parameters "-a delete -s myshape user=.fred"
26will create a shapefile in myshape.shp that contains all nodes deleted
27by users whose name begins with "fred".
28
29Add -q to suppress normal output.
30EOF
31exit;
32}
33sub VERSION_MESSAGE {};
34
35use strict;
36use Time::Local;
37use Getopt::Std;
38
39my $options = {};
40getopts("a:t:s:r:vq", $options);
41my $grep = $options->{"r"};
42
43my $shp;
44if (defined($options->{"s"}))
45{
46    eval "use Geo::Shapelib qw/:all/; 1; " or die("-s option requires perl module Geo::Shapelib - stopped");
47    $shp = new Geo::Shapelib {
48        Name => $options->{"s"}, 
49        Shapetype => 1,
50        FieldNames => ['File','Unixtime','Action','User'],
51        FieldTypes => ['String:50','Integer:10','String:10','String:50']
52    };
53
54}
55
56push(@ARGV, "-") if (scalar(@ARGV) == 0);
57
58while(my $current_file = shift(@ARGV))
59{
60    if (($current_file ne "-") && ($current_file !~ /\.osc(\.gz|\.bz2)?$/))
61    {
62        warn ("file $current_file has unrecognized name (expected: .osc, .osc.gz, .osc.bz2) - ignored");
63        next;
64    }
65
66    unless (open(F, ($1 eq ".bz2") ? "bzcat $current_file|" : ($1 eq ".gz") ? "zcat $current_file|" : $current_file))
67    {
68        warn ("cannot read from $current_file - ignored");
69        next;
70    }
71
72    my $seek;
73    my $buffer;
74    my $action;
75    while(<F>)
76    {
77        if (/<\/?osmChange/)
78        {
79            print;
80        }
81        elsif (/<(modify|create|delete)/)
82        {
83            $action = $1;
84        }
85        elsif (/<(node|way|relation).*?(\/)?>/)
86        {
87            if ($2 eq "/")
88            {
89                out($1, $action, $current_file, $_);
90            }
91            else
92            {
93                $seek = $1;
94                $buffer = $_;
95            }
96        }
97        elsif (/<\/$seek>/)
98        {
99            out($seek, $action, $current_file, $buffer . $_);
100        }
101        else
102        {
103            $buffer .= $_;
104        }
105    }
106    close(F);
107}
108$shp->save() if (defined($shp));
109
110sub out
111{
112    my ($type, $action, $file, $content) = @_;
113    return if (defined($options->{"a"}) && $options->{"a"} ne $action);
114    return if (defined($options->{"t"}) && $options->{"t"} ne $type);
115    if (defined($grep))
116    {
117        if ($options->{"v"})
118        {
119            return if ($content =~ /$grep/);
120        }
121        else
122        {
123            return unless ($content =~ /$grep/);
124        }
125    }
126    print "<$action>\n$content</$action>\n" unless($options->{"q"});
127
128    if (defined($shp) && ($type eq "node"))
129    {
130        $content =~ /lat=["']([0-9.-]+)["']/;
131        my $lat=$1;
132        $content =~ /lon=["']([0-9.-]+)["']/;
133        my $lon=$1;
134        $content =~ /timestamp=["'](\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z["']/;
135        my $uts = timelocal($6,$5,$4,$3,$2-1,$1-1900);
136        $content =~ /user=["']([^"']+)["']/;
137        my $user=$1;
138        push @{$shp->{Shapes}},{ Vertices => [[$lon,$lat,0,0]] };
139        $file =~ /.*\/(.{1,50})/;
140        push @{$shp->{ShapeRecords}}, [$1, $uts, $action, $user];
141    }
142}
Note: See TracBrowser for help on using the repository browser.