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

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

new mapweaver version 0.06

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