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

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

mapweaver version 0.04

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