source: subversion/applications/rendering/osmbook/trunk/osmbook @ 14906

Revision 14906, 10.4 KB checked in by hardaker, 5 years ago (diff)

specify min/max lats for orp.pl

  • Property svn:executable set to *
Line 
1#!/usr/bin/perl
2
3use Getopt::GUI::Long;
4use GD;
5use POSIX qw(ceil floor);
6
7my %opts = (
8            'D' => 'mapdata',
9            'X' => "osm-map-features-z14.xml",
10            'O' => "osm-map-features-z06.xml",
11           );
12
13Getopt::GUI::Long::Configure(qw(display_help no_ignore_case));
14GetOptions(\%opts,
15           ["mx|min-x=s", "Minimum Longitude"],
16           ["Mx|max-x=s", "Maximum Longitude"],
17           ["my|min-y=s", "Minimum Latitude"],
18           ["My|may-x=s", "Maximum Latitude"],
19           ["n|number-steps=i", "Number of steps on a side"],
20           ["D|map-data=s", "Map data directory"],
21
22           ["M|maximum-squares=i", "limit the number of squares to actually perform to M"],
23           ["X|xml-master=s", "XML Master Grid Rule File"],
24           ["O|overview=s", "XML Master Overview Rule File"],
25           ["l|latex-file=s", "Save Figure commands to a latex file"],
26           ["force-fetch",    "Force fetching of new data"],
27           ["ps",             "Expect a postscript generation instead"],
28          ) || exit;
29
30die "need at least -mx -Mx -my -My and -n\n"
31  if (!$opts{'mx'} || !$opts{'Mx'} || !$opts{'my'} || !$opts{'My'} || !$opts{'n'});
32
33my $diffx = $opts{'Mx'} - $opts{'mx'};
34my $diffy = $opts{'My'} - $opts{'my'};
35
36# for the number of Y grid squares, use n*P*y/x
37# n = num x, P = paper aspect ratio (height/width), y/x = map area aspect ration
38# XXX: should round not int; requires a math package
39# XXX: or not...  need to default to fitting on the page, which is ceil()
40# (more squares)
41my $ygridnum = ceil($opts{'n'}*(17/20)*$diffy/$diffx);
42print "Y grid squares: $ygridnum  ($opts{'n'}*1.3*$diffy/$diffx)\n";
43
44
45my $segx = $diffx/$opts{'n'};
46my $segy = $diffy/$ygridnum;
47
48my @osmfiles;
49
50mkdir ($opts{'D'}) if (! -d $opts{'D'});
51
52my $count;
53
54my $combinedosm  = "$opts{'D'}/combined.osm";
55my $combinedsvg  = "$opts{'D'}/combined.svg";
56my $combinedpng  = "$opts{'D'}/combined.png";
57my $overviewsvg = "$opts{'D'}/overview.svg";
58my $overvieweps = "$opts{'D'}/overview.eps";
59my $overviewpng = "$opts{'D'}/overview.png";
60if ($opts{'l'}) {
61    open(L,">$opts{'l'}");
62    if ($opts{'ps'}) {
63        printf L ("\\Overview{$overvieweps}{%s}{%s}{%s}{%s}\n",
64                  $opts{'mx'},$opts{'My'},$opts{'Mx'},$opts{'my'});
65    } else {
66        printf L ("\\Overview{$overviewpng}{%s}{%s}{%s}{%s}\n",
67                  $opts{'mx'},$opts{'My'},$opts{'Mx'},$opts{'my'});
68    }
69}
70
71my $needoverview = 0;
72
73sub get_grid_num {
74    my ($x, $y) = @_;
75    return "X" if ($y < 1 || $y > $ygridnum);
76    return "X" if ($x < 1 || $x > $opts{'n'});
77
78    return (($ygridnum - $y) * $opts{'n'} + $x);
79}
80
81
82foreach my $y (reverse(1..$ygridnum)) {
83    foreach my $x (1..$opts{'n'}) {
84
85        my $gridsquare = get_grid_num($x, $y);
86
87        print "----------------------------------------------------------------------\n";
88        print "Starting grid $gridsquare\n";
89        print "----------------------------------------------------------------------\n";
90
91        # calculate the bounding box (BB)
92        my $minx = $opts{'mx'} + ($x-1)*$segx;
93        my $miny = $opts{'my'} + ($y-1)*$segy;
94
95        my $maxx = $opts{'mx'} + ($x)*$segx;
96        my $maxy = $opts{'my'} + ($y)*$segy;
97       
98        my $smosmfile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.osm";
99        my $osmfile = $smosmfile;
100        my $xmlfile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.xml";
101
102        if (!$opts{'force-fetch'} && -f $combinedosm) {
103            $osmfile = $combinedosm;
104        } else {
105            if (! -f $osmfile) {
106                System("wget --no-proxy -O $osmfile http://www.openstreetmap.org/api/0.5/map?bbox=$minx,$miny,$maxx,$maxy");
107                $needoverview = 1;
108            }
109
110            push @osmfiles, $osmfile;
111        }
112
113
114        # render the page
115        if (! -f $xmlfile || Stat($opts{'X'}, $xmlfile)) {
116            print STDERR "creating $xmlfile\n";
117
118            # sigh...  xmlstarlet already assumes the subdir for some reason
119            my $starfile = $osmfile;
120            $starfile =~ s/$opts{'D'}\///;
121
122            open(I, $opts{'X'});
123            open(O,">$xmlfile");
124            while (<I>) {
125                s/data.osm/$osmfile/;
126#               s/data.osm/$starfile/;
127                print O;
128            }
129            close(I);
130            close(O);
131        }
132
133        # render the map as a svg
134        my $svgfile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.svg";
135        if (! -f $svgfile || Stat($xmlfile, $svgfile)) {
136            #System("xmlstarlet tr osmarender.xsl $xmlfile > $svgfile");
137            System("perl orp.svn/orp.pl --minlat $miny --maxlat $maxy --minlon $minx --maxlon $maxx -r $xmlfile $osmfile");
138            if ($osmfile ne $smosmfile) {
139                my $combinedsvg = $osmfile;
140                $combinedsvg =~ s/osm$/svg/;
141                rename($combinedsvg, $svgfile);
142            }
143        }
144
145        # convert to png
146        # inkscape -f map.svg -e map.png
147        my $pngfile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.png";
148        if (! -f $pngfile || Stat($svgfile, $pngfile)) {
149            System("inkscape -f $svgfile -e $pngfile");
150        }
151
152        # convert to eps
153        # inkscape -f map.svg -E map.eps
154        my $outfile;
155        if ($opts{'ps'}) {
156            my $epsfile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.eps";
157            if (! -f $epsfile || Stat($svgfile, $epsfile)) {
158                System("inkscape -f $svgfile -E $epsfile");
159            }
160            $outfile = $epsfile;
161        } else {
162            my $pdffile = "$opts{'D'}/mapdata-$minx-$maxx-$miny-$maxy.pdf";
163            if (! -f $pdffile || Stat($svgfile, $pdffile)) {
164                System("inkscape -f $svgfile -E $pdffile");
165            }
166            $outfile = $pdffile;
167        }
168
169        $count++;
170       
171        if (defined($opts{'l'})) {
172            # note: y numbers are functionally backwards (bottom to top)
173            my $nw = get_grid_num($x-1, $y+1);
174            my $n  = get_grid_num($x,   $y+1);
175            my $ne = get_grid_num($x+1, $y+1);
176
177            my $w  = get_grid_num($x-1, $y);
178            my $e  = get_grid_num($x+1, $y);
179
180            my $sw = get_grid_num($x-1, $y-1);
181            my $s  = get_grid_num($x,   $y-1);
182            my $se = get_grid_num($x+1, $y-1);
183
184            my $gridstring = "\\Grid{$nw}{$n}{$ne}{$w}{$e}{$sw}{$s}{$se}";
185
186            if ($opts{'ps'}) {
187                print L "\\Map{$outfile}{$gridsquare}{$minx}{$maxy}{$maxx}{$miny}{$gridstring}\n";
188            } else {
189                print L "\\Map{$outfile}{$gridsquare}{$minx}{$maxy}{$maxx}{$miny}{$gridstring}\n";
190            }
191        }
192
193        if (defined($opts{'M'}) && $count >= $opts{'M'}) {
194            print STDERR "reached maximum\n";
195            exit;
196        }
197    }
198}
199
200#System("osmmerge all.osm ",join(" ",@osmfiles));
201# combine all the exsting OSM files into a single combined OSM file
202if ($needoverview || ! -f $combinedosm) {
203
204    # create the overview OSM file
205    my $cmd = "osmosis/bin/osmosis --read-xml " . 
206      join(" --s --merge --read-xml ", @osmfiles) . " --s --merge --write-xml $combinedosm";
207    $cmd =~ s/--merge//;
208    System($cmd);
209}
210
211
212# build the combined OSM file into a SVG (without the grid)
213if (! -f $combinedsvg || Stat($combinedosm, $combinedsvg) ||
214    Stat($opts{'O'}, $combinedsvg)) {
215
216    System("perl orp.svn/orp.pl --minlat $opts{'my'} --maxlat $opts{'My'} --minlon $opts{'mx'} --maxlon $opts{'Mx'} -r $opts{'O'} $combinedosm");
217}
218
219# build the overview SVG that contains the grid over the combined OSM
220if (! -f $overviewsvg || Stat($combinedsvg, $overviewsvg)) {
221    make_overview($overviewsvg, $opts{'n'}, $ygridnum,
222                  $opts{'n'} * 10, $ygridnum * 10, $combinedsvg);
223}
224
225# render the overview SVG as EPS for later inclusion into latex
226if (! -f $combindepng  ||
227    Stat($combinedsvg, $combinedpng)) {
228    System("inkscape -d 45 -f $combinedsvg -e $combinedpng");
229#    Stat($overviewsvg, $overvieweps)) {
230#    System("inkscape -f $overviewsvg -E $overvieweps");
231}
232
233if (! -f $overviewpng  ||
234    Stat($combinedpng, $overviewpng)) {
235    make_overviewpng($combinedpng, $overviewpng, $opts{'n'}, $ygridnum);
236}
237
238if ($opts{'ps'}) {
239    if (! -f $overvieweps  ||
240        Stat($overviewpng, $overvieweps)) {
241        System("convert $overviewpng $overvieweps");
242    }
243}
244
245
246sub System {
247    print join(" ",@_),"\n";
248    system(@_);
249}
250
251sub make_overview {
252    my ($out, $numx, $numy, $width, $height, $img) = @_;
253
254    use SVG;
255
256    print "Creating $out\n";
257
258    my $gridw = $width/$numx;
259    my $gridh = $height/$numy;
260
261    $svg = SVG->new(width => $width, height => $height);
262
263    $svg->image(x => 0, y => 0, width => $width, height => $height,
264                '-href' => $img, id => 'undermap');
265
266    # vertical grid lines
267    for my $x (0..($numx-1)) {
268        my $tag1 = $svg->line(
269                              id => "vert_$x",
270                              x1 => $x*$gridw, x2 => $x*$gridw,
271                              y1 => 0,  y2 => $height,
272                              style => {'stroke' => 'rgb(0,0,0)'}
273                             );
274    }
275    my $tag1 = $svg->line(
276                          id => "vert_last",
277                          x1 => $gridw-1, x2 => $gridw,
278                          y1 => 0,  y2 => $height,
279                          style => {'stroke' => 'rgb(0,0,0)'}
280                         );
281
282    # vertical grid lines
283    for my $y (0..($numy-1)) {
284        my $tag1 = $svg->line(
285                              id => "horz_$y",
286                              x1 => 0,  x2 => $width,
287                              y1 => $y*$gridh, y2 => $y*$gridh,
288                              style => {'stroke' => 'rgb(0,0,0)'}
289                             );
290    }
291    my $tag1 = $svg->line(
292                          id => "horz_max",
293                          x1 => 0,  x2 => $width,
294                          y1 => $gridh, y2 => $gridh,
295                          style => {'stroke' => 'rgb(0,0,0)'}
296                         );
297
298
299    # grid square labels
300    for my $x (0..($numx-1)) {
301        for my $y (0..($numy-1)) {
302            $svg->text(x => $x*$gridw + $gridw/2,
303                       y => $y*$gridh + $gridh/2)
304              ->cdata($y*$numx + $x + 1);
305        }
306    }
307
308    open(OVERVIEW,">$out");
309    print OVERVIEW $svg->xmlify,"\n";
310    close(OVERVIEW);
311}
312
313sub make_overviewpng {
314    my ($inpng, $outpng, $numx, $numy) = @_;
315
316    print "Creating $outpng\n";
317
318    my $overviewimg = GD::Image->newFromPng($inpng, 1);
319    die ("couldn't open/create $combinedpng") if (!$overviewimg);
320    my ($width, $height) = $overviewimg->getBounds();
321
322
323    my $black = $overviewimg->colorAllocate(32,32,32);
324    my $gridw = $width/$numx;
325    my $gridh = $height/$numy;
326
327    my $linewidth = int($width/400) || 1;
328
329    # vertical grid lines
330    for my $x (0..$numx) {
331        $overviewimg->filledRectangle(int($x*$gridw)-$linewidth, 0,
332                                      int($x*$gridw)+$linewidth, $height,
333                                      $black);
334    }
335
336    # horizontal grid lines
337    for my $y (0..$numy) {
338        $overviewimg->filledRectangle(0,      int($y*$gridh)-$linewidth,
339                                      $width, int($y*$gridh)+$linewidth,
340                                      $black);
341    }
342
343    # grid square labels
344    for my $x (0..($numx-1)) {
345        for my $y (0..($numy-1)) {
346#           $overviewimg->string(gdGiantFont,
347#                                int($x*$gridw + $gridw/2),
348#                                int($y*$gridh + $gridh/2),
349#                                $y*$numx + $x + 1,
350#                                $black);
351            $overviewimg->stringFT($black, '/home/hardaker/docs/ham/maps/LiberationMono-Bold.ttf',
352                                   int($width/30), 0,
353                                   int($x*$gridw + $gridw/2),
354                                   int($y*$gridh + $gridh/2),
355                                   $y*$numx + $x + 1);
356        }
357    }
358
359    # save the results
360    open(OPNG, ">$outpng");
361    print OPNG $overviewimg->png;
362    close(OPNG);
363}
364
365
366# returns true if the timestamp from file ARG1 is newer than file ARG2
367sub Stat {
368    my ($file1, $file2) = @_;
369    my @attr1 = stat $file1;
370    my @attr2 = stat $file2;
371#    print STDERR "newer: $file1\n" if ($attr1[9] > $attr2[9]);
372#    print STDERR "newer: $file2\n" if ($attr1[9] <= $attr2[9]);
373    return $attr1[9] > $attr2[9];
374}
375
Note: See TracBrowser for help on using the repository browser.