source: subversion/applications/rendering/imgAtlas/imgAtlas.pl @ 21808

Last change on this file since 21808 was 2805, checked in by hakan, 13 years ago

Option to set tileserver URL

  • Property svn:executable set to *
File size: 8.2 KB
Line 
1#!/usr/bin/perl
2#-----------------------------------------------------------------------------
3# Document-creation system, for PDF output
4# Supports the layout of:
5#  * JPEG photos
6#  * OpenStreetMap maps
7#  * Simple text
8#
9#-----------------------------------------------------------------------------
10# Copyright 2007
11#  * Oliver White
12#  * Hakan Tandogan
13#
14#    (Add your name here if you edit the program)
15#-----------------------------------------------------------------------------
16# This program is free software; you can redistribute it and/or
17# modify it under the terms of the GNU General Public License
18# as published by the Free Software Foundation; either version 2
19# of the License, or (at your option) any later version.
20#
21# This program is distributed in the hope that it will be useful,
22# but WITHOUT ANY WARRANTY; without even the implied warranty of
23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24# GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with this program; if not, write to the Free Software
28# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
29#-----------------------------------------------------------------------------
30use strict;
31use osm::getTileArea;
32use PDF::API2;
33use constant mm => 25.4 / 72;
34my $Usage = "$0 [config file] [output pdf filename]\n";
35my $Config = shift() || "config.txt";
36my $Filename = shift() || "atlas.pdf";
37
38open(COMMANDS, '<', $Config) || die($Usage);
39my $PDF = PDF::API2->new();
40my ($Page, @Attributions);
41my $PageNum = 1;
42# Default options
43my %Option = (dpi=>150); 
44
45newPage();
46my $Font = $PDF->corefont('Helvetica');
47
48 
49while(my $Line = <COMMANDS>)
50{
51    $Line =~ s{     # replace:
52        ^           # at start of line
53        \s*         #
54        \#          # Comment characters
55        .*          # ...
56        $           # to end of line
57    }{}x;           # with nothing
58
59    #---------------------------------------------------------------------------
60    #  New page
61    #---------------------------------------------------------------------------
62    if($Line =~ m{==page==}i)
63    {
64        $Page = $PDF->page;
65        $PageNum++;
66    }
67    #---------------------------------------------------------------------------
68    #  Change an option
69    #---------------------------------------------------------------------------
70    elsif($Line =~ m{
71      option:         # command
72        \s*           #
73        (\w+)         # option name
74        \s* = \s*     #  =
75        (.*)          # value
76    }x)
77    {
78        $Option{$1} = $2;
79        print "Setting option \"$1\" to \"$2\"\n";
80
81        if ($1 eq "tilesource")
82        {
83            getTile::setTileSource($2);
84        }
85    }
86    #---------------------------------------------------------------------------
87    #  Add a line of text
88    #---------------------------------------------------------------------------
89    elsif($Line =~ m{
90      text:                 # command
91        \s*                 #
92        (.*?)               # text
93        \s*                 #
94        \(                  # (
95        (.*?), \s*          #  x
96        (.*?), \s*          #  y
97        (.*?)               #  size
98        \)                  # )
99    }x)
100    {
101        print "Adding \"$1\" at $2, $3, size $4\n";
102        textAt($1,$2,$3,$4);
103    }
104    #---------------------------------------------------------------------------
105    #  Add a list of images used within the document
106    #---------------------------------------------------------------------------
107    elsif($Line =~ m{
108      attribution:          # command
109        \s*                 #
110        \(                  # (
111        (.*?), \s*          #  x
112        (.*?), \s*          #  y
113        (.*?)               #  size
114        \)                  # )
115    }x)
116    {
117        printf "Adding attribution block\n";
118        my $X = $1;
119        my $Y = $2;
120        my $Size = $3;
121
122        # Add a title, just as an extra line of text at the beginning of the textblock
123        unshift(@Attributions, "Image credits:");
124
125        # Draw each line of text (TODO: make a generic "write array of text lines")
126        foreach my $Line (@Attributions)
127        {
128            textAt($Line, $X, $Y, $Size);
129            $Y -= $Size * 1.25;
130        }
131    }
132    #---------------------------------------------------------------------------
133    #  Add a JPEG image to the page
134    #---------------------------------------------------------------------------
135    elsif($Line =~ m{
136      image:               # Command
137        \s*                #
138        (.*?)              # Filename
139        \s*                #
140        \(                 # (
141        (\d+), \s*         #  left
142        (\d+), \s*         #  bottom
143        (\d+), \s*         #  width
144        (\d+), \s*         #  height
145        \"(.*?)\",\s*      #  author
146        \"(.*?)\"          #  description
147        \)                 # )
148    }ix)
149    {
150        print "Adding $1 ($7) by $6 at $2, $3, $4, $5\n";
151        my $PageGfx = $Page->gfx;
152        my $Image = $PDF->image_jpeg($1) || print("Failed to load");
153        $PageGfx->image($Image, $2/mm, $3/mm, $4/mm, $5/mm ); # from left, from bottom, width, height
154   
155        # Add to the list of images
156        # (this text needs to identify which image we're talking about, hence the description)
157        push(@Attributions, "Page $PageNum: Image \"$7\", by $6");
158    }
159    #---------------------------------------------------------------------------
160    #  Add a map to the page
161    #---------------------------------------------------------------------------
162    elsif($Line =~ m{
163      map:                 # Command
164        \s*                #
165        \((.*?)\)          # Map options
166        \s*                #
167        at                 # at
168        \s*                #
169        \((.*?)\)          # Position options
170    }ix)
171    {
172        my ($MapOptions, $PositionOptions) = ($1, $2);
173        my ($Lat, $Long, $SizeKm, $Zoom) = split(/\s*,\s*/, $MapOptions);
174        my ($X,$Y,$W,$H) = split(/\s*,\s*/, $PositionOptions);
175
176        # Process those map options
177        my $Filename = datafile('png');
178        my $AspectRatio = $W / $H;
179        my $ImgW = ($W / 25) * $Option{dpi}; # pixels = width in inches * DPI
180        my $ImgH = $ImgW / $AspectRatio;
181   
182        if (!(defined($Zoom)))
183        {
184            my $DesiredSizeOfTilePx = getTile::size();
185            # print "  .... auto-determiner: DesiredSizeOfTilePx = $DesiredSizeOfTilePx\n";
186
187            my $DesiredWidthInTiles = $ImgW / $DesiredSizeOfTilePx;
188            # print "  .... auto-determiner: ImgW = $ImgW\n";
189            # print "  .... auto-determiner: DesiredWidthInTiles = $DesiredWidthInTiles\n";
190
191            my $DesiredSizeOfTileKm = $SizeKm / $DesiredWidthInTiles;
192            # print "  .... auto-determiner: SizeKm = $SizeKm\n";
193            # print "  .... auto-determiner: DesiredSizeOfTileKm = $DesiredSizeOfTileKm\n";
194
195            my $DesiredZoom = 12 - log($DesiredSizeOfTileKm / 10) / log(2);             
196            # print "  .... auto-determiner: DesiredZoom = $DesiredZoom\n";
197
198            $Zoom = int($DesiredZoom + 0.5);
199            print "Auto-Determined Zoom: $Zoom\n";
200        }
201   
202        my $SizeOfTileKm = 10 * (2 ** (12 - $Zoom));  # Z-12 is about 10km, and each additional zoom halves that
203        my $WidthInTiles = $SizeKm / $SizeOfTileKm;   # How many tiles should fit across the map
204        my $SizeOfTilePx = $ImgW / $WidthInTiles;     # How wide each tile should be made, in pixels
205        print "$SizeKm km across, $SizeOfTileKm km per tile =  $WidthInTiles tiles, so $SizeOfTilePx px per tile\n";
206        my %Area = (lat=>$Lat, long=>$Long, zoom=>$Zoom, width=>$ImgW, height=>$ImgH, size=>$SizeOfTilePx);
207   
208        # Create the map
209        print "Creating map around $Lat, $Long, from zoom $Zoom tiles\nUsing image $ImgW x $ImgH\n";
210        getTileArea::createArea(\%Area, $Filename);
211
212        # Add map to page
213        my $PageGfx = $Page->gfx;
214        my $Image = $PDF->image_png($Filename) || print("Failed to load");
215        $PageGfx->image($Image, $X/mm, $Y/mm, $W/mm, $H/mm ); # from left, from bottom, width, height
216    }
217    #---------------------------------------------------------------------------
218    #  Unrecognized lines of input
219    #---------------------------------------------------------------------------
220    else
221    {
222        #print "Misunderstood $Line\n";
223    }
224}
225
226print "Saving PDF to $Filename\n";
227$PDF->saveas($Filename);
228
229BEGIN
230{
231    my $NextFileNum = 1;
232    sub datafile
233    {
234        my $Suffix = shift();
235        return
236            sprintf("Data/%05d.$Suffix", $NextFileNum++);
237    }
238}
239
240sub textAt
241{
242    my ($Text, $X, $Y, $Size) = @_;
243
244    my $TextHandler = $Page->text;
245    $TextHandler->font($Font, $Size/mm );
246    $TextHandler->fillcolor('black');
247    $TextHandler->translate($X/mm, $Y/mm);
248    $TextHandler->text($Text);
249}
250
251sub newPage
252{
253    # A4 page
254    $Page = $PDF->page;
255    $Page->mediabox(210/mm, 297/mm);
256    $Page->cropbox (10/mm, 10/mm, 200/mm, 287/mm);
257}
Note: See TracBrowser for help on using the repository browser.