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

Revision 14625, 9.2 KB checked in by hardaker, 5 years ago (diff)

calculate the Y grid number based on a ratio (which needs improvement

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