source: subversion/applications/rendering/tilesAtHome/lib/TahConf.pm @ 12207

Last change on this file since 12207 was 12105, checked in by deelkar, 11 years ago

add a little debug-helper to quickly get bbox and center coordinates for tilenumbers

File size: 14.6 KB
Line 
1# A Config class for t@h.
2#
3# Copyright 2008, by Matthias Julius
4# licensed under the GPL v2 or (at your option) any later version.
5
6package TahConf;
7
8use strict;
9use AppConfig qw(:argcount);
10use Config; #needed to check flock availability
11use File::Path;
12use File::Spec;
13
14my $instance = undef; # Singleton instance of Config class
15
16#-----------------------------------------------------------------------
17# returns the AppConfig object that can be globally used throughout the
18# application and initializes it if called for the first time.
19# This method is called on the class, and not on an instance.
20#-----------------------------------------------------------------------
21sub getConfig 
22{
23    my $class = shift;
24
25    if (defined($instance))
26    {
27        # already initialized, do nothing
28        return $instance;
29    }
30
31    # not yet initialized
32    my $self = {};       # TahConf instance
33
34
35    my $Config = AppConfig->new(
36                 {CREATE => 1,              # Autocreate unknown config variables
37                  GLOBAL => {DEFAULT  => undef, # Create undefined Variables by default
38                  ARGCOUNT => ARGCOUNT_ONE} # Simple Values (no arrays, no hashmaps)
39                 });
40    $Config->define("help|usage!");
41    $Config->define("nodownload=s");
42    $Config->set("nodownload",0);
43    $Config->file("config.defaults", "layers.conf", "tilesAtHome.conf", "authentication.conf");
44    $Config->args();                # overwrite config options with command line options
45    $Config->file("general.conf");  # overwrite with hardcoded values that must not be changed
46
47    $self->{Config} = $Config;
48
49    bless $self, $class;
50    $instance = $self;
51    return $self;
52}
53
54
55#-----------------------------------------------------------------------------
56# retrieve a specific config setting
57#-----------------------------------------------------------------------------
58sub get
59{
60    my $self = shift;
61    return $self->{Config}->get(shift);
62}
63
64
65#-----------------------------------------------------------------------------
66# set a config setting
67#-----------------------------------------------------------------------------
68sub set
69{
70    my $self = shift();
71    return $self->{Config}->set(@_);
72}
73
74#-----------------------------------------------------------------------------
75# get a hash of config settings matching regex
76#-----------------------------------------------------------------------------
77sub varlist
78{
79    my $self = shift();
80    return $self->{Config}->varlist(@_);
81}
82
83#--------------------------------------------------------------------------
84# Checks a tiles@home basic configuration which is needed for uploading
85# also sets some runtime environment information
86#--------------------------------------------------------------------------
87sub CheckBasicConfig
88{
89    my $self = shift();
90    my %EnvironmentInfo;
91    my $cmd;
92
93    #------
94    ## switch on verbose mode if Debug is set
95    if ($self->get("Debug"))
96    {
97        $self->set("Verbose",10);
98    }
99
100    #------
101    ## check and set the WorkingDirectory.
102    #  NOTE: it will contain no trailing slash after we are finished
103    if ($self->get("WorkingDirectory"))
104    {
105        $self->set("WorkingDirectory", 
106                    File::Spec->rel2abs($self->get("WorkingDirectory")));
107    }
108    else
109    {   # no WorkingDir set in config file. Use system default tmp dir
110        $self->set("WorkingDirectory", File::Spec->tmpdir());
111    }
112
113    #------
114    ## Finally create the WorkingDir if necessary.
115    printf "- Using working directory %s\n", $self->get("WorkingDirectory");
116    File::Path::mkpath($self->get("WorkingDirectory"));
117
118    #------
119    printf "- Using process log file %s\n", $self->get("ProcessLogFile") if ($self->get("ProcessLog"));
120
121    #------
122    if ($self->get("Subversion"))
123    {
124        $cmd=$self->get("Subversion");
125        my $SubversionV = `\"$cmd\" --version`;
126        $EnvironmentInfo{"Subversion"}=$SubversionV;
127        # die here if svn executable not found, but before enabling try on windows machines wether --version works.
128    }
129    else
130    {
131        die ("! no subversion command set");
132    }
133
134    #------
135    # LocalSplippymap
136    if ($self->get("LocalSlippymap"))
137    {
138        print "- Writing LOCAL slippy map directory hierarchy, no uploading\n";
139    }
140    else
141    {
142        if($self->get("DeleteZipFilesAfterUpload") == 0){
143            print "- Keeping ZIP files after upload\n";
144        }
145    }
146
147    #------
148    if ($self->get("UploadToDirectory"))
149    {
150        if (! -d $self->get("UploadTargetDirectory")) {
151            # we chose to upload to directory, but it does not exist!
152            print "- Upload Directory does not exist. Trying to create ",
153                   $self->get("UploadTargetDirectory"),"\n";
154            File::Path::mkpath $self->get("UploadTargetDirectory");
155           if (! -d $self->get("UploadTargetDirectory")) {
156               die "! Failed to create Upload directory.";
157           }
158        }
159    }
160
161    #------
162    # Zip version
163    $cmd=$self->get("Zip");
164    my $ZipV = `\"$cmd\" -v`;
165    $EnvironmentInfo{Zip}=$ZipV;
166    if ($EnvironmentInfo{Zip} eq "") 
167    {
168        die("! Can't find zip (using \"".$self->get("Zip")."\")\n");
169    }
170    #------
171    # check if flock is available on this OS
172    # Theoertically the next 2 lines are correct, but Winows seems to cannot lock directories
173    # even if flock exists. So bypass flock there completely
174    #if (($Config{'d_flock'} && $Config{'d_flock'} eq 'define') or
175    #   ($Config{'d_fcntl_can_lock'} && $Config{'d_fcntl_can_lock'} eq 'define'))
176    if ($^O ne "MSWin32")
177    {
178        # it's a sane OS and flock is there
179        $self->set('flock_available',1);
180    } else {
181        print "! 'flock' not available. Do not run concurrent uploads\n";
182        $self->set('flock_available',0);
183    }
184
185    #------
186    # check a correct pngoptimizer is set
187    if ( ! (($self->get("PngOptimizer") eq "pngcrush") or ($self->get("PngOptimizer") eq "optipng")))
188    {
189        die("! Can't find valid PngOptimizer setting, check config");
190    }
191
192    #------
193    # Check pngcrush version
194    if ($self->get("PngOptimizer") eq "pngcrush")
195    {
196        # PNGCrush version
197        $cmd = $self->get("Pngcrush");
198        my $PngcrushV = `\"$cmd\" -version`;
199
200        if ($PngcrushV !~ /[Pp]ngcrush\s+(\d+\.\d+\.?\d*)/)
201        {
202            print "! Can't find pngcrush (using \"".$self->get("Pngcrush")."\")\n";
203        }
204        else
205        {
206            print "- Pngcrush version $1\n";
207        }
208    }
209    #------
210    # check optipng version
211    if ($self->get("PngOptimizer") eq "optipng")
212    {
213        # Optipng version
214        $cmd = $self->get("Optipng");
215        my $OptipngV = `\"$cmd\" -v`;
216
217        if ($OptipngV !~ /[Oo]pti[Pp][Nn][Gg]\s+(\d+\.\d+\.?\d*)/) 
218        {
219            die("! Can't find OptiPNG (using \"".$self->get("Optipng")."\")\n");
220        }
221        else
222        {
223            print "- OptiPNG version $1\n";
224        }
225    }
226    #------
227    # check pngnq version
228    if ( $self->get("PngQuantizer") eq "pngnq" )
229    {
230        $cmd = $self->get("pngnq");
231        my $PngnqV=`\"$cmd\" -V 2>&1`;
232        if ($PngnqV !~ /pngnq.+(\d+(\.\d+)+)/)
233        {
234            print "! Can't find pngnq (using \"".$self->get("pngnq")."\")\n";
235            print "! disabling pngnq\n";
236            $self->set("PngQuantizer", undef);
237        }
238        else
239        {
240            my $minVersion = "0.5";
241            if ($self->CompareVersions($1, $minVersion) == -1) {
242                print "! pngnq version ${1} too low, needs to be at least ${minVersion}\n";
243                print "! disabling pngnq\n";
244                $self->set("PngQuantizer", undef);
245            } else {
246                print "- pngnq version $1\n";
247            }
248        }
249    } else {
250        print "! no valid PngQuantizer specified\n";
251    }
252    #------
253    # check java version and path separator
254    my @javaInfo = split(/\n/,`java -cp java TestJava`);
255    $self->set("JavaAvailable", $javaInfo[0] eq "JAVATEST");
256    if ($self->get("JavaAvailable"))
257    {
258       $self->set("JavaVersion", $javaInfo[1]);
259       $self->set("JavaSeparator", $javaInfo[2]);
260       print "- Java version $javaInfo[1] is available\n";
261    } 
262    else 
263    {
264       $self->set("JavaVersion", 0);
265       $self->set("JavaSeparator", ":");
266       print "- Java is not available\n";
267    }
268    eval
269    {
270        require Image::Magick;
271        if(($Image::Magick::VERSION cmp "6.4.5") < 0)
272        {
273            print "- ImageMagick version $Image::Magick::VERSION (lowzoom disabled)\n";
274        }
275        else
276        {
277            print "- ImageMagick version $Image::Magick::VERSION (lowzoom enabled)\n";
278        }
279    };
280
281    return %EnvironmentInfo;
282
283}
284
285#--------------------------------------------------------------------------
286# Checks a tiles@home configuration which is needed for rendering
287#--------------------------------------------------------------------------
288sub CheckConfig
289{
290    my $self = shift;
291    my $cmd;
292
293    my %EnvironmentInfo = $self->CheckBasicConfig();
294
295    if (!defined($self->get("Layers")))
296    {
297        die("no layers configured");
298    }
299
300    # Rendering through Omsarender/XSLT or or/p
301    if ($self->get("Osmarender") eq "XSLT")
302    {
303        print "- rendering using Osmarender/XSLT\n";
304        die "! Can't find osmarender/xslt/osmarender.xsl" unless (-f "osmarender/xslt/osmarender.xsl");
305
306        # XmlStarlet version
307        $cmd=$self->get("XmlStarlet");
308        my $XmlV = `\"$cmd\" --version`;
309        $EnvironmentInfo{Xml}=$XmlV;
310
311        if($XmlV !~ /(\d+\.\d+\.\d+)/) {
312            die("Can't find xmlstarlet (using \"" . $self->get("XmlStarlet") . "\")\n");
313        }
314        print "- xmlstarlet version $1\n";
315    }
316    elsif ($self->get("Osmarender") eq "orp")
317    {
318        print "- rendering using or/p\n";
319        die "! Can't find osmarender/orp/orp.pl" unless (-f "osmarender/orp/orp.pl");
320    }
321    else
322    {
323        die "! invalid configuration setting for 'Osmarender' - allowed values are 'XSLT', 'orp'";
324    }
325
326    if( ! $self->get('Rasterizer') && $self->get('Batik') ){
327        warn "Deprecated configuration variable Batik found, use Rasterizer instead. For now it will be mapped\n";
328        if( $self->get('Batik') == 1 || $self->get('Batik') == 2 ){
329            $self->set('Rasterizer', 'Batik');
330        } elsif( $self->get('Batik') == 3 ){
331            $self->set('Rasterizer', 'BatikAgent');
332        }
333    }
334
335    my $rasterizer = $self->get("Rasterizer");
336    if ( $rasterizer =~ /inkscape/i )
337    {
338        $cmd = $self->get("inkscape"); # this config parameter is deprecated and not present in newer installations
339                                       # http://trac.openstreetmap.org/ticket/1286
340
341        # Fall back un 'inkscape' if the inkscape variable isn't
342        # defined, in the config. As is the case in some
343        # installations.
344        $cmd = 'inkscape' unless defined $cmd;
345
346        my $InkscapeV=`\"$cmd\" -V 2>&1`;
347        $InkscapeV =~ /Inkscape.(\d+(\.\d+)+)/;
348
349        my $minVersion = "0.46";
350
351        if ( $InkscapeV eq '' )
352        {
353            print "* Could not determine your inkscape version\n";
354            print "* You need at least version ${minVersion} for RenderStripes=0 setting\n" unless $self->get("RenderStripes");
355        }
356        elsif ($self->CompareVersions($1, $minVersion) == -1 and not $self->get("RenderStripes")) 
357        {
358            print "! Inkscape version ${1} too low, needs to be at least ${minVersion} for RenderStripes=0 setting\n";
359        }
360        else 
361        {
362            print "- Inkscape version $1\n";
363        }
364    }
365
366
367    #-------------------------------------------------------------------
368    # check all layers for existing and sane values
369    #------------------------------------------------------------------
370    foreach my $layer(split(/,/, $self->get("LayersCapability")))
371    {
372        if ($self->get($layer."_MaxZoom") < $self->get($layer."_MinZoom"))
373        {
374            die " ! Check MinZoom and MaxZoom for section [".$layer."]\n";
375        } 
376
377        for(my $zoom=$self->get($layer."_MinZoom"); $zoom<=$self->get($layer."_MaxZoom"); $zoom++)
378        {
379            if (!defined($self->get($layer."_Rules.$zoom")))
380            {
381                die " ! config option Rules.".$zoom." is not set for layer".$layer;
382            }
383            if (!-f $self->get($layer."_Rules.".$zoom))
384            {
385                die " ! rules file ".$self->get($layer."_Rules.".$zoom).
386                    " referenced by config option Rules.".$zoom." in section [".$layer."]".
387                    "is not present";
388            }
389        }
390
391        if (!defined($self->get($layer."_Prefix")))
392        {
393            die " ! config option \"Prefix\" is not set for layer ".$layer;
394        }
395
396        if (!defined($self->get($layer."_Transparent")))
397        {
398            die($layer.": Transparent not configured");
399        }
400
401        if (!defined($self->get($layer."_RenderFullTileset")))
402        {
403            die($layer.": RenderFullTileset not configured");
404        }
405
406        if (!defined($self->get($layer."_Preprocessor")))
407        {
408            die(" ! config option \"Preprocessor\" is not set for layer ".$layer);
409        }
410
411        # any combination of comma-separated preprocessor names is allowed
412        die "config option Preprocessor has invalid value in section [".$layer."]" 
413            if (grep { $_ !~ /maplint|close-areas|autocut|noop|area-center/} split(/,/, $self->get($layer."_Preprocessor")));
414
415        foreach my $reqfile(split(/,/, $self->get($layer."_RequiredFiles")))
416        {
417            die " ! file $reqfile required for layer $layer as per config option ".
418                "RequiredFiles in section [".$layer."] not found" unless (-f $reqfile);
419        }
420
421    }
422
423    if($self->get("RequestUrl")){ 
424        ## put back Verbose output to make remote debugging a bit easier
425        print "- Using ".$self->get("RequestUrl")." for Requests\n" if($self->get("Verbose") >=10); 
426    }
427
428    # Misc stuff
429    foreach(qw(NS WE)){
430        if($self->get("Border".$_) > 0.5){
431            printf "Border".$_." looks abnormally large\n";
432        }
433    }
434    return %EnvironmentInfo;
435
436}
437
438#--------------------------------------------------------------------------
439# internal helper function to compare two version numbers
440# works only for dotted numerical numbers like 'x.yy.zz'
441# returns -1 when first is lower, 0 when equal and 1 when first is higher
442#--------------------------------------------------------------------------
443sub CompareVersions {
444    my $self = shift;
445    my ($version1, $version2) = @_;
446    my @v1 = split(/\./, $version1);
447    my @v2 = split(/\./, $version2);
448    for (my $i = 0; ($i <= scalar @v1 - 1) or ($i <= scalar @v2 - 1); $i++) {
449        if ($v1[$i] < $v2[$i]) {
450            return -1;
451        }
452        if ($v1[$i] > $v2[$i]) {
453            return 1;
454        }
455    }
456    return 0;
457}
458
4591;
Note: See TracBrowser for help on using the repository browser.