source: subversion/applications/utils/gary68/mwMap.pm @ 26159

Last change on this file since 26159 was 26159, checked in by gary68, 8 years ago

v0.05 of mapweaver

File size: 20.2 KB
Line 
1#
2# PERL mapweaver module by gary68
3#
4#
5#
6#
7# Copyright (C) 2011, Gerhard Schwanz
8#
9# This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the
10# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
16#
17
18
19package mwMap ; 
20
21use strict ;
22use warnings ;
23
24use mwConfig ;
25# use mwFile ;
26# use mwLabel ;
27
28use OSM::osm ;
29
30use Geo::Proj4 ;
31
32
33use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
34
35require Exporter ;
36
37@ISA = qw ( Exporter AutoLoader ) ;
38
39@EXPORT = qw (  initGraph
40                        drawCircle
41                        drawSquare
42                        drawTriangle
43                        drawDiamond
44                        drawRect
45                        writeMap
46                        drawWay
47                        fitsPaper
48                        getScale
49                        createPath
50                        pathText
51                        placeIcon
52                        convert
53                 ) ;
54
55
56my @belowWays = ("background", "base", "area", "multi") ;
57
58my @aboveWays = ( "wayLabels", "shields", "routes", "routeStops", "nodes", "icons", "text", "additional") ;
59
60my @elements = ("scale", "ruler", "legend", "header", "footer", "title") ;
61
62my %svgLayer = () ;
63my %wayLayer = () ;
64
65my $proj ;
66
67my ($bottom, $left, $right, $top) ;
68my ($sizeX, $sizeY) ;
69my ($projLeft, $projBottom, $projRight, $projTop) ;
70my ($projSizeX, $projSizeY) ;
71
72sub initGraph {
73
74        # function initializes the picture and projection
75
76        my ($x, $l, $b, $r, $t) = @_ ; 
77
78        # my $l0 = int($l) - 1 ;
79        my $l0 = int(($r+$l) / 2 ) ;
80
81        $proj = Geo::Proj4->new(
82                proj => cv('projection'), 
83                ellps => cv('ellipsoid'), 
84                lon_0 => $l0 
85                ) or die "parameter error: ".Geo::Proj4->error. "\n"; 
86
87
88        ($projLeft, $projBottom) = $proj->forward($b, $l) ; # lat/lon!!!
89        ($projRight, $projTop) = $proj->forward($t, $r) ; # lat/lon!!!
90
91        $projSizeX = $projRight - $projLeft ;
92        $projSizeY = $projTop - $projBottom ;
93
94        my $factor = $projSizeY / $projSizeX ;
95
96        $sizeX = int ($x) ;
97        $sizeY = int ($x * $factor) ;
98
99        mwLabel::initQuadTrees ($sizeX, $sizeY) ;
100
101        $top = $t ;
102        $left = $l ;
103        $right = $r ;
104        $bottom = $b ;
105
106        if ( cv('ruler') ne "0" ) {
107                drawRuler() ;
108        }
109
110        if ( cv('scale') ne "0" ) {
111                drawScale() ;
112        }
113
114        if ( cv('grid') != 0) {
115                drawGrid() ;
116        }
117        if ( cv('coords') eq "1") {
118                drawCoords() ;
119        }
120        if ( length cv('foot') > 0 ) {
121                drawFoot() ;
122        }
123        if ( length cv('head') > 0 ) {
124                drawHead() ;
125        }
126}
127
128sub addToLayer {
129        my ($layer, $text) = @_ ;
130        push @{$svgLayer{$layer}}, $text ;
131}
132
133sub drawWay {
134
135        # accepts list of nodes (plus convert=1)  or list of x,y,x,y (convert=0) and draws way/polygon to layerNr if defined or to layerName
136
137        my ($nodesRef, $convert, $svgString, $layerName, $layerNumber) = @_ ;
138        my @points = () ;
139
140        # convert? and expand.
141        if ($convert) {
142                my ($lonRef, $latRef, $tagRef) = mwFile::getNodePointers() ;
143                foreach my $node (@$nodesRef) {
144                        my ($x, $y) = convert ( $$lonRef{$node}, $$latRef{$node}) ;
145                        push @points, $x, $y ;
146                }
147        }
148        else {
149                @points = @$nodesRef ;
150        }
151
152        my $refp = simplifyPoints (\@points) ;
153        @points = @$refp ;
154
155
156        my $svg = "<polyline points=\"" ;
157        for (my$i=0; $i<scalar(@points)-1; $i+=2) {
158                $svg = $svg . $points[$i] . "," . $points[$i+1] . " " ;
159        }
160
161        $svg = $svg . "\" $svgString />" ;
162
163        if (defined $layerNumber) {
164                push @{ $wayLayer{ $layerNumber } }, $svg ;
165        }
166        else {
167                push @{ $svgLayer { $layerName } }, $svg ;
168        }
169}
170
171
172
173sub drawText {
174
175        my ($x, $y, $convert, $text, $svgString, $layerName) = @_ ;
176
177        if ($convert) {
178                ($x, $y) = convert ($x, $y) ;
179        }
180
181        my $svg = "<text x=\"$x\" y=\"$y\" $svgString>" . $text . "</text>" ;
182
183        push @{ $svgLayer { $layerName } }, $svg ;
184
185}
186
187
188
189
190sub drawCircle {
191
192        # draws circle element to svgLayer given; if convertCoords then lon / lat is converted to x / y
193        # circleradius either in pixel or in meters (convert=1)
194
195        my ($x, $y, $convertCoords, $radius, $convertRadius, $format, $layerName) = @_ ;
196
197        if ($convertCoords) {
198                ($x, $y) = convert ($x, $y) ;
199        }
200        if ($convertRadius) {
201                $radius = $radius / (1000 * distance ($left, $bottom, $right, $bottom) ) * $sizeX ;
202        }
203        my $svg = "<circle cx=\"$x\" cy=\"$y\" r=\"$radius\" " ;
204        $svg .= $format . " />" ;
205
206        push @{ $svgLayer { $layerName } }, $svg ;
207}
208
209sub drawSquare {
210
211        # draws square element to svgLayer given; if convertCoords then lon / lat is converted to x / y
212        # square size either in pixel or in meters (convert=1)
213
214        my ($x, $y, $convertCoords, $size, $convertSize, $format, $layerName) = @_ ;
215
216        if ($convertCoords) {
217                ($x, $y) = convert ($x, $y) ;
218        }
219        if ($convertSize) {
220                $size = $size / (1000 * distance ($left, $bottom, $right, $bottom) ) * $sizeX ;
221        }
222
223        my $x1 = $x - $size ;
224        my $y1 = $y - $size ;
225        my $dSize = 2 * $size ;
226
227        my $svg = "<rect x=\"$x1\" y=\"$y1\" width=\"$dSize\" height=\"$dSize\" " ;
228        $svg .= $format . " />" ;
229
230        push @{ $svgLayer { $layerName } }, $svg ;
231}
232
233sub drawTriangle {
234
235        # draws triangle element to svgLayer given; if convertCoords then lon / lat is converted to x / y
236        # square size either in pixel or in meters (convert=1)
237
238        my ($x, $y, $convertCoords, $size, $convertSize, $format, $layerName) = @_ ;
239
240        if ($convertCoords) {
241                ($x, $y) = convert ($x, $y) ;
242        }
243        if ($convertSize) {
244                $size = $size / (1000 * distance ($left, $bottom, $right, $bottom) ) * $sizeX ;
245        }
246
247        my $h = int ( sqrt ($size * $size / 2) ) ;
248
249        my $x1 = $x ;
250        my $y1 = $y - $size ;
251        my $x2 = $x - $h ;
252        my $y2 = $y + $h ;
253        my $x3 = $x + $h ;
254        my $y3 = $y + $h ;
255
256        my $svg = "<polyline points=\"$x1,$y1 $x2,$y2 $x3,$y3 $x1,$y1\" " ;
257        $svg .= $format . " />" ;
258
259        push @{ $svgLayer { $layerName } }, $svg ;
260}
261
262sub drawDiamond {
263
264        # draws diamond element to svgLayer given; if convertCoords then lon / lat is converted to x / y
265        # square size either in pixel or in meters (convert=1)
266
267        my ($x, $y, $convertCoords, $size, $convertSize, $format, $layerName) = @_ ;
268
269        if ($convertCoords) {
270                ($x, $y) = convert ($x, $y) ;
271        }
272        if ($convertSize) {
273                $size = $size / (1000 * distance ($left, $bottom, $right, $bottom) ) * $sizeX ;
274        }
275
276        my $x1 = $x - $size ; # left
277        my $y1 = $y ;
278        my $x2 = $x ; # top
279        my $y2 = $y - $size ;
280        my $x3 = $x + $size ; #right
281        my $y3 = $y ;
282        my $x4 = $x ; # bottom
283        my $y4 = $y + $size ;
284
285        my $svg = "<polyline points=\"$x1,$y1 $x2,$y2 $x3,$y3 $x4,$y4 $x1,$y1\" " ;
286        $svg .= $format . " />" ;
287
288        push @{ $svgLayer { $layerName } }, $svg ;
289}
290
291sub drawRect {
292
293        # draws square element to svgLayer given; if convertCoords then lon / lat is converted to x / y
294        # square size either in pixel or in meters (convert=1)
295
296        my ($x1, $y1, $x2, $y2, $convertCoords, $format, $layerName) = @_ ;
297
298        if ($convertCoords) {
299                ($x1, $y1) = convert ($x1, $y1) ;
300                ($x2, $y2) = convert ($x2, $y2) ;
301        }
302
303        my $sizeX = $x2 - $x1 ;
304        my $sizeY = $y2 - $y1 ;
305
306        my $svg = "<rect x=\"$x1\" y=\"$y1\" width=\"$sizeX\" height=\"$sizeY\" " ;
307        $svg .= $format . " />" ;
308
309        push @{ $svgLayer { $layerName } }, $svg ;
310}
311
312
313sub createPath {
314#
315# creates path element for later use with textPath
316#
317        my ($pathName, $refp, $layer) = @_ ;
318
319        my $refp2 = simplifyPoints ($refp) ;
320        my @points = @$refp2 ;
321
322        my $svg = "<path id=\"" . $pathName . "\" d=\"M " ;
323        my $i ;
324        my $first = 1 ;
325        for ($i=0; $i<scalar(@points); $i+=2) {
326                if ($first) {
327                        $svg = $svg . $points[$i] . "," . $points[$i+1] . " " ;
328                        $first = 0 ;
329                }
330                else {
331                        $svg = $svg . "L " . $points[$i] . "," . $points[$i+1] . " " ;
332                }
333        }
334        $svg = $svg . "\" />\n" ;
335
336        push @{ $svgLayer{ $layer } }, $svg ;
337}
338
339
340sub pathText {
341#
342# draws text to path element; alignment: start, middle, end
343#
344        my ($svgText, $text, $pathName, $tSpan, $alignment, $layer) = @_ ;
345        my $offset = 0 ;
346        if ($alignment eq "start") { $offset = 0 ; }
347        if ($alignment eq "middle") { $offset = 50 ; }
348        if ($alignment eq "end") { $offset = 100 ; }
349
350        my $svg = "<text $svgText >\n" ;
351        $svg = $svg . "<textPath xlink:href=\"#" . $pathName . "\" text-anchor=\"" . $alignment . "\" startOffset=\"" . $offset . "%\" >\n" ;
352        $svg = $svg . "<tspan dy=\"" . $tSpan . "\" >" . $text . " </tspan>\n" ;
353        $svg = $svg . "</textPath>\n</text>\n" ;
354
355        push @{ $svgLayer{ $layer } }, $svg ;
356}
357
358
359sub placeIcon {
360#
361# create SVG text for icons
362#
363        my ($x, $y, $icon, $sizeX, $sizeY, $layer) = @_ ;
364        my ($out) = "<image x=\"" . $x . "\"" ;
365        $out .= " y=\"" . $y . "\"" ;
366        if ($sizeX > 0) { $out .= " width=\"" . $sizeX . "\"" ; }
367        if ($sizeY > 0) { $out .= " height=\"" . $sizeY . "\"" ; }
368        $out .= " xlink:href=\"" . $icon . "\" />" ;
369
370        push @{ $svgLayer{ $layer } }, $out ;
371}
372
373
374
375
376# ---------------------------------------------------------------------
377
378sub writeMap {
379
380        my $fileName = cv ('out')  ;
381
382        open (my $file, ">", $fileName) || die "can't open svg output file $fileName\n";
383
384        print $file "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n" ;
385        print $file "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" >\n" ;
386
387        my $w = $sizeX / 300 * 2.54 ; # cm
388        my $h = $sizeY / 300 * 2.54 ;
389
390        my ($svg) = "<svg version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\" " ;
391        $svg .= "xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" " ;
392        $svg .= "width=\"$w" . "cm\" height=\"$h" . "cm\" viewBox=\"0 0 $sizeX $sizeY\">\n" ;
393        print $file $svg ;
394
395        # definitions
396        if ( defined @{$svgLayer{'definitions'}} ) {
397                print $file "<defs>\n" ;
398                foreach ( @{$svgLayer{'definitions'}} ) { print $file $_, "\n" ; }
399                print $file "</defs>\n" ;
400        }
401
402        # below ways
403        foreach my $layer (@belowWays) {
404                if ( defined @{$svgLayer{$layer}} ) {
405                        print $file "<g id=\"$layer\">\n" ;
406                        foreach ( @{$svgLayer{$layer}} ) { print $file $_, "\n" ; }
407                        print $file "</g>\n" ;
408                }
409        }
410
411        # ways
412        foreach my $layer (sort {$a <=> $b} keys %wayLayer) {
413                if ( defined @{$wayLayer{$layer}} ) {
414                        print $file "<g id=\"way$layer\">\n" ;
415                        foreach ( @{$wayLayer{$layer}} ) { print $file $_, "\n" ; }
416                        print $file "</g>\n" ;
417                }
418        }
419
420
421        # above of ways
422        foreach my $layer (@aboveWays) {
423                if ( defined @{$svgLayer{$layer}} ) {
424                        print $file "<g id=\"$layer\">\n" ;
425                        foreach ( @{$svgLayer{$layer}} ) { print $file $_, "\n" ; }
426                        print $file "</g>\n" ;
427                }
428        }
429
430
431        # TODO use groups
432
433        foreach my $layer (@elements) {
434                if (defined @{$svgLayer{$layer}}) {
435                        print $file "<g id=\"$layer\">\n" ;
436                        foreach ( @{$svgLayer{$layer}} ) { print $file $_, "\n" ; }
437                        print $file "</g>\n" ;
438                }
439        }
440
441
442        print $file "</svg>\n" ;
443
444        close ($file) ;
445
446        if (cv('pdf') eq "1") {
447                my ($pdfName) = $fileName ;
448                $pdfName =~ s/\.svg/\.pdf/ ;
449                print "creating pdf file $pdfName ...\n" ;
450                `inkscape -A $pdfName $fileName` ;
451        }
452
453        if (cv('png') eq "1") {
454                my ($pngName) = $fileName ;
455                $pngName =~ s/\.svg/\.png/ ;
456                print "creating png file $pngName ...\n" ;
457                `inkscape --export-dpi=300 -e $pngName $fileName` ;
458        }
459
460
461
462}
463
464# -----------------------------------------------------------------------------------
465
466sub drawGrid {
467#
468# draw grid on top of map. receives number of parts in x/lon direction
469#
470
471        my $number = cv ('grid') ;
472        my $color = cv ('gridcolor') ;
473
474        my $part = $sizeX / $number ;
475        my $numY = $sizeY / $part ;
476
477        my $svgStringLine="stroke=\"$color\" stroke-width=\"5\" stroke-dasharray=\"30,30\"" ;
478
479        my $svgStringText="font-family=\"sans-serif\" font-size=\"60\" fill=\"$color\"" ;
480
481        # vertical lines
482        for (my $i = 1; $i <= $number; $i++) {
483                my @coords = ($i*$part, 0, $i*$part, $sizeY) ;
484                drawWay (\@coords, 0, $svgStringLine, "additional", undef) ;
485                drawText ( ($i-1)*$part+$part/2, 160, 0, chr($i+64), $svgStringText, "additional") ;
486
487        }
488
489        # hor. lines
490        for (my $i = 1; $i <= $numY; $i++) {
491                my @coords = (0, $i*$part, $sizeX, $i*$part) ;
492                drawWay (\@coords, 0, $svgStringLine, "additional", undef) ;
493                drawText ( 20, ($i-1)*$part+$part/2, 0, $i, $svgStringText, "additional") ;
494
495        }
496}
497
498sub drawCoords {
499#
500# draws coordinates grid on map
501#
502        my $exp = cv('coordsexp') ; 
503        my $color = cv ('coordscolor');
504        my $step = 10 ** $exp ;
505
506        # vert. lines
507        my $start = int ($left / $step) + 1 ;
508        my $actual = $start * $step ;
509
510        my $svgStringLine="stroke=\"$color\" stroke-width=\"3\"" ;
511        my $svgStringText="font-family=\"sans-serif\" font-size=\"30\" fill=\"$color\"" ;
512
513        while ($actual < $right) {
514                my ($x1, $y1) = convert ($actual, 0) ;
515
516                drawText ( $x1+10, $sizeY-50, 0, $actual, $svgStringText, "additional") ;
517
518                my @coords = ($x1, 0, $x1, $sizeY) ;
519                drawWay (\@coords, 0, $svgStringLine, "additional", undef) ;
520
521                $actual += $step ;
522        }
523
524        # hor lines
525        $start = int ($bottom / $step) + 1 ;
526        $actual = $start * $step ;
527        while ($actual < $top) {
528                # print "actualY: $actual\n" ;
529                my ($x1, $y1) = convert (0, $actual) ;
530
531                drawText ( $sizeX-180, $y1+30, 0, $actual, $svgStringText, "additional") ;
532
533                my @coords = (0, $y1, $sizeX, $y1) ;
534                drawWay (\@coords, 0, $svgStringLine, "additional", undef) ;
535
536                $actual += $step ;
537        }
538}
539
540
541
542
543# -----------------------------------------------------------------------------------
544
545sub convert {
546
547        # converts real world coordinates to system graph pixel coordinates
548
549        my ($x, $y) = @_ ;
550
551        my ($x1, $y1) = $proj->forward($y, $x) ; # lat/lon!!!
552
553        my $x2 = int ( ($x1 - $projLeft) / ($projRight - $projLeft) * $sizeX ) ;
554        my $y2 = $sizeY - int ( ($y1 - $projBottom) / ($projTop - $projBottom) * $sizeY ) ;
555
556        return ($x2, $y2) ;
557}
558
559sub simplifyPoints {
560        my $ref = shift ;
561        my @points = @$ref ;
562        my @newPoints ;
563        my $maxIndex = $#points ;
564
565        if (scalar @points > 4) {
566                # push first
567                push @newPoints, $points[0], $points[1] ;
568
569                # push other
570                for (my $i=2; $i <= $maxIndex; $i+=2) {
571                        # $simplifyTotal++ ;
572                        if ( ($points[$i]==$points[$i-2]) and ($points[$i+1]==$points[$i-1]) ) {
573                                # same
574                                # $simplified++ ;
575                        }
576                        else {
577                                push @newPoints, $points[$i], $points[$i+1] ;
578                        }
579                }
580                return (\@newPoints) ;
581        }
582        else {
583                return ($ref) ;
584        }
585
586}
587
588sub drawRuler {
589#
590# draws ruler
591#
592        my $col = cv('rulercolor') ;   
593
594        my $B ; my $B2 ;
595        my $L ; my $Lpix ;
596        my $x ;
597        my $text ;
598
599        my $lineThickness = 8 ; # at 300dpi
600        my $textSize = 40 ; # at 300 dpi
601        my $textDist = 60 ; # at 300 dpi
602        my $lineLen = 40 ; # at 300 dpi
603
604        my $xOffset = 2 * $lineThickness ;
605        my $yOffset = 2 * $lineThickness ;
606               
607        $B = $right - $left ;                           # in degrees
608        $B2 = $B * cos ($top/360*3.14*2) * 111.1 ;      # in km
609        $text = "50m" ; $x = 0.05 ;                     # default length ruler
610
611        if ($B2 > 0.5) {$text = "100 m" ; $x = 0.1 ; }  # enlarge ruler
612        if ($B2 > 1) {$text = "500 m" ; $x = 0.5 ; }    # enlarge ruler
613        if ($B2 > 5) {$text = "1 km" ; $x = 1 ; }
614        if ($B2 > 10) {$text = "5 km" ; $x = 5 ; }
615        if ($B2 > 50) {$text = "10 km" ; $x = 10 ; }
616        $L = $x / (cos ($top/360*3.14*2) * 111.1 ) ;    # length ruler in km
617        $Lpix = $L / $B * $sizeX ;                      # length ruler in pixels
618
619        my $rSizeX = int ($Lpix + 2 * $xOffset) ;
620        my $rSizeY = int ($lineLen + $textSize + 3 * $yOffset) ;
621        addToLayer ("definitions", "<g id=\"rulerdef\" width=\"$rSizeX\" height=\"$rSizeY\" >") ;
622
623        if ( cv('rulerbackground') ne "none" ) {
624                my $color = cv ('rulerbackground') ;
625                my $svgString = "fill=\"$color\"" ;
626                drawRect (0, 0, $rSizeX, $rSizeY, 0, $svgString, "definitions") ;
627        }
628
629        my $svgString = "stroke=\"$col\" stroke-width=\"$lineThickness\" stroke-linecap=\"round\" " ;
630
631        my @coords = ($xOffset, $yOffset, $xOffset+$Lpix, $yOffset) ;
632        drawWay (\@coords, 0, $svgString, "definitions", undef) ;
633
634        @coords = ($xOffset, $yOffset, $xOffset, $yOffset+$lineLen) ;
635        drawWay (\@coords, 0, $svgString, "definitions", undef) ;
636
637        @coords = ($xOffset+$Lpix, $yOffset, $xOffset+$Lpix, $yOffset+$lineLen) ;
638        drawWay (\@coords, 0, $svgString, "definitions", undef) ;
639
640        @coords = ($xOffset+$Lpix/2, $yOffset, $xOffset+$Lpix/2, $yOffset+$lineLen/2) ;
641        drawWay (\@coords, 0, $svgString, "definitions", undef) ;
642
643        $svgString = "fill=\"$col\" stroke=\"$col\" font-size=\"45\" " ;
644        my $scale= getScale() ;
645        $text .= "(1:$scale)" ;
646        drawText ($xOffset, $yOffset+$textDist+30, 0, $text, $svgString, "definitions") ;
647
648        addToLayer ("definitions", "</g>") ;
649
650        my $posX = 40 ; my $posY = 40 ;
651
652        if ( cv('ruler') eq "2") {
653                $posX = $sizeX - 40 - $rSizeX ;
654                $posY = 40 ;
655        }
656
657        if ( cv('ruler') eq "3") {
658                $posX = 40 ;
659                $posY = $sizeY - 40 - $rSizeY ;
660        }
661
662        if ( cv('ruler') eq "4") {
663                $posX = $sizeX - 40 - $rSizeX ;
664                $posY = $sizeY - 40 - $rSizeY ;
665        }
666
667        addToLayer ("ruler", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#rulerdef\" />") ;
668}
669
670sub drawScale {
671#
672# draws scale value
673#
674        my $col = cv('scalecolor') ;   
675
676        my $xOffset = 20 ;
677        my $yOffset = 20 ;
678        my $fontSize = 70 ;             
679        my $borderDist = 60 ;
680
681        my $rSizeX = int (350 + 2 * $xOffset) ;
682        my $rSizeY = int ($fontSize + 2 * $yOffset) ;
683        addToLayer ("definitions", "<g id=\"scaledef\" width=\"$rSizeX\" height=\"$rSizeY\" >") ;
684
685        if ( cv('scalebackground') ne "none" ) {
686                my $color = cv ('scalebackground') ;
687                my $svgString = "fill=\"$color\"" ;
688                drawRect (0, 0, $rSizeX, $rSizeY, 0, $svgString, "definitions") ;
689        }
690
691        my $scale= getScale() ;
692        my $svgString = "fill=\"$col\" stroke=\"$col\" font-size=\"$fontSize\" " ;
693        drawText ($xOffset, $fontSize + $yOffset, 0, "1:$scale", $svgString, "definitions") ;
694
695        addToLayer ("definitions", "</g>") ;
696
697        my $posX = $borderDist ; my $posY = $borderDist ;
698
699        if ( cv('scale') eq "2") {
700                $posX = $sizeX - $borderDist - $rSizeX ;
701                $posY = $borderDist ;
702        }
703
704        if ( cv('scale') eq "3") {
705                $posX = $borderDist ;
706                $posY = $sizeY - $borderDist - $rSizeY ;
707        }
708
709        if ( cv('scale') eq "4") {
710                $posX = $sizeX - $borderDist - $rSizeX ;
711                $posY = $sizeY - $borderDist - $rSizeY ;
712        }
713
714        addToLayer ("scale", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#scaledef\" />") ;
715}
716
717sub drawFoot {
718#
719# draws footer
720#
721        my $col = cv('footcolor') ;     
722        my $text = cv('foot') ; 
723        my $len = length $text ;
724
725        my $xOffset = 20 ;
726        my $yOffset = 20 ;
727        my $fontSize = cv('footsize') ;         
728        my $borderDistX = 60 ;
729        my $borderDistY = $fontSize + 50 ;
730
731        my $rSizeX = int ($len*cv('ppc')/10*$fontSize + 2 * $xOffset) ;
732        my $rSizeY = int ($fontSize + 2 * $yOffset) ;
733        addToLayer ("definitions", "<g id=\"footdef\" width=\"$rSizeX\" height=\"$rSizeY\" >") ;
734
735        if ( cv('footbackground') ne "none" ) {
736                my $color = cv ('footbackground') ;
737                my $svgString = "fill=\"$color\"" ;
738                drawRect (0, 0, $rSizeX, $rSizeY, 0, $svgString, "definitions") ;
739        }
740
741        my $svgString = "fill=\"$col\" stroke=\"$col\" font-size=\"$fontSize\" " ;
742        drawText ($xOffset, $fontSize + $yOffset, 0, $text, $svgString, "definitions") ;
743
744        addToLayer ("definitions", "</g>") ;
745
746        my $posX = $borderDistX ; my $posY = $sizeY - $borderDistY ;
747
748        addToLayer ("footer", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#footdef\" />") ;
749}
750
751sub drawHead {
752#
753# draws header
754#
755        my $col = cv('headcolor') ;     
756        my $text = cv('head') ; 
757        my $len = length $text ;
758
759        my $xOffset = 20 ;
760        my $yOffset = 20 ;
761        my $fontSize = cv('headsize') ;         
762        my $borderDistX = 60 ;
763        my $borderDistY = 60 ;
764
765        my $rSizeX = int ($len*cv('ppc')/10*$fontSize + 2 * $xOffset) ;
766        my $rSizeY = int ($fontSize + 2 * $yOffset) ;
767        addToLayer ("definitions", "<g id=\"headdef\" width=\"$rSizeX\" height=\"$rSizeY\" >") ;
768
769        if ( cv('headbackground') ne "none" ) {
770                my $color = cv ('headbackground') ;
771                my $svgString = "fill=\"$color\"" ;
772                drawRect (0, 0, $rSizeX, $rSizeY, 0, $svgString, "definitions") ;
773        }
774
775        my $svgString = "fill=\"$col\" stroke=\"$col\" font-size=\"$fontSize\" " ;
776        drawText ($xOffset, $fontSize + $yOffset, 0, $text, $svgString, "definitions") ;
777
778        addToLayer ("definitions", "</g>") ;
779
780        my $posX = $borderDistX ; my $posY = $borderDistY ;
781
782        addToLayer ("header", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#headdef\" />") ;
783}
784
785
786sub fitsPaper {
787#
788# calculates on what paper size the map will fit. sizes are taken from global variables
789#
790
791        my $width = $sizeX / 300 * 2.54 ;
792        my $height = $sizeY / 300 * 2.54 ;
793        my $paper = "" ;
794
795        my @sizes = () ;
796        push @sizes, ["4A0", 168.2, 237.8] ;
797        push @sizes, ["2A0", 118.9, 168.2] ;
798        push @sizes, ["A0", 84.1, 118.9] ;
799        push @sizes, ["A1", 59.4, 84.1] ;
800        push @sizes, ["A2", 42, 59.4] ;
801        push @sizes, ["A3", 29.7, 42] ;
802        push @sizes, ["A4", 21, 29.7] ;
803        push @sizes, ["A5", 14.8, 21] ;
804        push @sizes, ["A6", 10.5, 14.8] ;
805        push @sizes, ["A7", 7.4, 10.5] ;
806        push @sizes, ["none", 0, 0] ;
807
808        foreach my $size (@sizes) {
809                if ( ( ($width<=$size->[1]) and ($height<=$size->[2]) ) or ( ($width<=$size->[2]) and ($height<=$size->[1]) ) ) {
810                        $paper = $size->[0] ;
811                }
812        }
813
814        return ($paper, $width, $height) ;
815}
816
817sub getScale {
818#
819# calcs scale of map
820#
821        my ($dpi) = 300 ;
822
823        my $dist = distance ($left, $bottom, $right, $bottom) ;
824        my $inches = $sizeX / $dpi ;
825        my $cm = $inches * 2.54 ;
826        my $scale = int ( $dist / ($cm/100/1000)  ) ;
827        $scale = int ($scale / 100) * 100 ;
828
829        return ($scale) ;
830}
831
832
8331 ;
834
835
Note: See TracBrowser for help on using the repository browser.