source: subversion/applications/utils/gary68/osmgraph.pm @ 15298

Last change on this file since 15298 was 15287, checked in by gary68, 10 years ago

-

  • Property svn:executable set to *
File size: 18.8 KB
Line 
1#
2# PERL osmgraph module by gary68
3#
4# !!! store as osmgraph.pm in folder OSM in lib directory !!!
5#
6# This module contains a lot of useful graphic functions for working with osm files and data. This enables you (in conjunction with osm.pm)
7# to easily draw custom maps. Although not as sophisticated as Mapnik, Osmarender and KOSMOS.
8# Have a look at the last (commented) function below. It is useful for your main program!
9#
10#
11#
12#
13# Copyright (C) 2009, Gerhard Schwanz
14#
15# 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
16# Free Software Foundation; either version 3 of the License, or (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
22
23#
24# USAGE
25#
26#
27# drawArea ($color, @nodes)
28# drawChartColumns ($lon, $lat, $offX, $offY, $sizeY, $columnWidthPix, $yMax, $color, @values)
29# drawCircleRadius ($lon, $lat, $radius, $size, $color)
30# drawCircleRadiusText ($lon, $lat, $radius, $size, $color, $text)
31# drawHead ($text, $color, $size) / size (1..5)
32# drawFoot ($text, $color, $size) / size (1..5)
33# drawLegend ($size, @entries) / size (1..5) ("t1", "col1", "t2", "col2")
34# drawNodeDot ($lon, $lat, $color, $size) / size (1..5)
35# drawNodeCircle ($lon, $lat, $color, $size) / size (1..5)
36# drawRuler ($color)
37# drawTextPix ($x, $y, $text, $color, $size) / size (1..5)
38# drawTextPos ($lon, $lat, $offX, $offY, $text, $color, $size) / size (1..5)
39# drawWay ($color, $size, @nodes) / size = thickness
40# enableSVG ()
41# initGraph ($sizeX, $left, $bottom, $right, $top) / real world coordinates, sizeX in pixels, Y automatic
42# labelWay ($col, $size, $font, $text, $tSpan, @nodes) / size can be 0..5 (or bigger...) / $tSpan = offset to line/way
43# writeGraph ($fileName)
44# writeSVG ($fileName)
45#
46#
47# INTERNAL
48#
49# convert ($x, $y)                                              -> ($x1, $y1) pixels in graph
50#
51# INFO
52#
53# graph bottom left coordinates: (0,0)
54# font size (1..5). 1 = smallest, 5 = giant
55# size for lines = pixel width / thickness
56# pass color as string, i.e. "black". list see farther down.
57#
58#
59
60package OSM::osmgraph ; 
61
62use strict ;
63use warnings ;
64
65use Math::Trig;
66use File::stat;
67use Time::localtime;
68use List::Util qw[min max] ;
69use GD ;
70use Encode ;
71
72
73use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
74
75$VERSION = '2.2' ; # PUBLISHED
76
77require Exporter ;
78
79@ISA = qw ( Exporter AutoLoader ) ;
80
81@EXPORT = qw ( drawArea drawCircleRadius drawCircleRadiusText drawChartColumns drawHead drawFoot drawLegend drawNodeDot drawNodeCircle drawRuler drawTextPix drawTextPos drawWay enableSVG initGraph labelWay writeGraph writeSVG) ;
82
83#
84# constants
85#
86
87my %colorHash ;
88
89@{$colorHash{"black"}} = (0, 0, 0) ;
90@{$colorHash{"darkgray"}} = (79,79,79) ;
91@{$colorHash{"gray"}} = (145, 145, 145) ;
92@{$colorHash{"lightgray"}} = (207, 207, 207) ;
93@{$colorHash{"white"}} = (255, 255, 255) ;
94
95@{$colorHash{"red"}} = (255, 0, 0) ;
96@{$colorHash{"orange"}} = (255, 165, 0) ;
97@{$colorHash{"darkorange"}} = (255, 140, 0) ;
98@{$colorHash{"tomato"}} = (255, 140, 0) ;
99@{$colorHash{"yellow"}} = (255, 255, 0) ;
100
101@{$colorHash{"blue"}} = (0, 0, 255) ;
102@{$colorHash{"lightblue"}} = (135, 206, 235) ;
103@{$colorHash{"pink"}} = (255, 105, 180) ;
104@{$colorHash{"green"}} = (0, 255, 0) ;
105@{$colorHash{"darkgreen"}} = (105, 139, 105) ;
106@{$colorHash{"lightgreen"}} = (0, 255, 127) ;
107@{$colorHash{"brown"}} = (139, 69, 19) ;
108@{$colorHash{"lightbrown"}} = (244, 164, 96) ;
109
110my %fonts ;
111$fonts{1} = gdTinyFont ;
112$fonts{2} = gdSmallFont ;
113$fonts{3} = gdMediumBoldFont ;
114$fonts{4} = gdLargeFont ;
115$fonts{5} = gdGiantFont ;
116
117#
118# variables
119#
120my $image ;
121my %color ;
122
123my ($top, $bottom, $left, $right) ; # min and max real world coordinates
124my ($sizeX, $sizeY) ; # pic size in pixels
125
126my $svgEnabled = 0 ;
127
128my @svgOutputWaysNodes = () ;
129my @svgOutputAreas = () ;
130my @svgOutputText = () ;
131my @svgOutputDef = () ;
132my @svgOutputPathText = () ;
133my $pathNumber = 0 ;
134my $svgBaseFontSize = 10 ;
135
136
137sub initGraph {
138#
139# function initializes the picture, the colors and the background (white)
140#
141        my ($x, $l, $b, $r, $t) = @_ ; 
142       
143        $sizeX = $x ;
144        $sizeY = $x * ($t - $b) / ($r - $l) / cos ($t/360*3.14*2) ;
145        $top = $t ;
146        $left = $l ;
147        $right = $r ;
148        $bottom = $b ;
149
150        $image = new GD::Image($sizeX, $sizeY);
151        $image->trueColor() ;
152
153        my $c ;
154        foreach $c (keys %colorHash) {
155                $color{$c} = $image->colorAllocate(@{$colorHash{$c}}) ;
156        }
157
158        $image->filledRectangle(0,0,$sizeX-1,$sizeY-1,$color{"white"}) ;
159       
160}
161
162sub writeGraph {
163#
164# writes the created graph to a file
165#
166        my $fileName = shift ;
167        my $picFile ;
168
169        open ($picFile, ">", $fileName) || die ("error opening graph file") ;
170        binmode $picFile ;
171        print $picFile $image->png ; 
172        close $picFile ;
173}
174
175sub convert {
176#
177# converts real world coordinates to system graph pixel coordinates
178#
179        my ($x, $y) = @_ ;
180
181        my ($x1) = int( ($x - $left) / ($right - $left) * $sizeX ) ;
182        my ($y1) = $sizeY - int( ($y - $bottom) / ($top - $bottom) * $sizeY ) ;
183
184        return ($x1, $y1) ;
185}
186
187sub drawHead {
188#
189# draws text on top left corner of the picture
190#
191        my ($text, $col, $size) = @_ ;
192        $image->string($fonts{$size}, 20, 20, encode("iso-8859-1", decode("utf8", $text)), $color{$col} ) ;
193
194        if ($svgEnabled) {
195                push @svgOutputText, svgElementText (20, 20, $text, $size, $col, "") ;
196        }
197}
198
199sub drawFoot {
200#
201# draws text on bottom left corner of the picture, below legend
202#
203        my ($text, $col, $size) = @_ ;
204        $image->string($fonts{$size}, 20, ($sizeY-20), encode("iso-8859-1", decode("utf8", $text)), $color{$col} ) ;
205
206        if ($svgEnabled) {
207                push @svgOutputText, svgElementText (20, ($sizeY-20), $text, $size, $col, "") ;
208        }
209}
210
211
212sub drawTextPos {
213#
214# draws text at given real world coordinates. however an offset can be given for not to interfere with node dot i.e.
215#
216        my ($lon, $lat, $offX, $offY, $text, $col, $size) = @_ ;
217        my ($x1, $y1) = convert ($lon, $lat) ;
218        $x1 = $x1 + $offX ;
219        $y1 = $y1 - $offY ;
220
221        $image->string($fonts{$size}, $x1, $y1, encode("iso-8859-1", decode("utf8", $text)), $color{$col}) ;
222        if ($svgEnabled) {
223                push @svgOutputText, svgElementText ($x1, $y1, $text, $size, $col, "") ;
224        }
225}
226
227
228sub drawTextPix {
229#
230# draws text at pixel position
231#
232        my ($x1, $y1, $text, $col, $size) = @_ ;
233
234        $image->string($fonts{$size}, $x1, $sizeY-$y1, encode("iso-8859-1", decode("utf8", $text)), $color{$col}) ;
235        if ($svgEnabled) {
236                push @svgOutputText, svgElementText ($x1, $sizeY-$y1, $text, $size, $col, "") ;
237        }
238}
239
240sub drawNodeDot {
241#
242# draws node as a dot at given real world coordinates
243#
244        my ($lon, $lat, $col, $size) = @_ ;
245        my ($x1, $y1) = convert ($lon, $lat) ;
246        $image->filledEllipse($x1, $y1, $size, $size, $color{$col}) ;           
247
248        if ($svgEnabled) {
249                push @svgOutputWaysNodes, svgElementCircleFilled ($x1, $y1, $size, $col) ;
250        }
251}
252
253sub drawNodeCircle {
254#
255# draws node as a circle at given real world coordinates
256#
257        my ($lon, $lat, $col, $size) = @_ ;
258        my ($x1, $y1) = convert ($lon, $lat) ;
259       
260        $image->setThickness(2) ;
261        $image->ellipse($x1, $y1, $size, $size, $color{$col}) ;         
262        $image->setThickness(1) ;
263
264        if ($svgEnabled) {
265                push @svgOutputWaysNodes, svgElementCircle ($x1, $y1, $size, 2, $col) ;
266        }
267}
268
269sub drawCircleRadius {
270#
271# draws circle at real world coordinates with radius in meters
272#
273        my ($lon, $lat, $radius, $size, $col) = @_ ;
274        my $radX ; my $radY ;
275        my ($x1, $y1) = convert ($lon, $lat) ;
276
277        $radX = ($radius/1000) / (($right - $left) * 111.1) / cos ($top/360*3.14*2) * $sizeX ;
278        $radY = $radX ;
279        $image->setThickness($size) ;
280        $image->ellipse($x1, $y1, 2*$radX, 2*$radY, $color{$col}) ;             
281        $image->setThickness(1) ;
282        if ($svgEnabled) {
283                push @svgOutputWaysNodes, svgElementCircle ($x1, $y1, $radX, $size, $col) ;
284        }
285}
286
287sub drawCircleRadiusText {
288#
289# draws circle at real world coordinates with radius in meters
290#
291        my ($lon, $lat, $radius, $size, $col, $text) = @_ ;
292        my $radX ; my $radY ;
293        my ($x1, $y1) = convert ($lon, $lat) ;
294
295        $radX = ($radius/1000) / (($right - $left) * 111.1) / cos ($top/360*3.14*2) * $sizeX ;
296        $radY = $radX ;
297        $image->setThickness($size) ;
298        $image->ellipse($x1, $y1, 2*$radX, 2*$radY, $color{$col}) ;             
299        $image->setThickness(1) ;
300        if ($size > 4 ) { $size = 4 ; }
301        $image->string($fonts{$size+1}, $x1, $y1+$radY+1, $text, $color{$col}) ;
302        if ($svgEnabled) {
303                push @svgOutputWaysNodes, svgElementCircle ($x1, $y1, $radX, $size, $col) ;
304                push @svgOutputText, svgElementText ($x1, $y1+$radY+10, $text, $size, $col, "") ;
305        }
306       
307}
308
309
310sub drawWay {
311#
312# draws way as a line at given real world coordinates. nodes have to be passed as array ($lon, $lat, $lon, $lat...)
313# $size = thickness
314#
315        my ($col, $size, @nodes) = @_ ;
316        my $i ;
317        my @points = () ;
318
319        $image->setThickness($size) ;
320        for ($i=0; $i<$#nodes-2; $i+=2) {
321                my ($x1, $y1) = convert ($nodes[$i], $nodes[$i+1]) ;
322                my ($x2, $y2) = convert ($nodes[$i+2], $nodes[$i+3]) ;
323                $image->line($x1,$y1,$x2,$y2,$color{$col}) ;
324        }
325        if ($svgEnabled) {
326                for ($i=0; $i<$#nodes; $i+=2) {
327                        my ($x, $y) = convert ($nodes[$i], $nodes[$i+1]) ;
328                        push @points, $x ; push @points, $y ; 
329                }
330                push @svgOutputWaysNodes, svgElementPolyline ($col, $size, @points) ;
331        }
332        $image->setThickness(1) ;
333}
334
335
336sub labelWay {
337#
338# labels a way (ONLY SVG!)
339#
340        my ($col, $size, $font, $text, $tSpan, @nodes) = @_ ;
341        my $i ;
342        my @points = () ;
343
344        #print "labelWay: $col, $size, $font, $text\n" ;
345
346        if ($svgEnabled) {
347                for ($i=0; $i<$#nodes; $i+=2) {
348                        my ($x, $y) = convert ($nodes[$i], $nodes[$i+1]) ;
349                        push @points, $x ; push @points, $y ; 
350                }
351                my $pathName = "Path" . $pathNumber ; $pathNumber++ ;
352                push @svgOutputDef, svgElementPath ($pathName, @points) ;
353                push @svgOutputPathText, svgElementPathText ($col, $size, $font, $text, $pathName, $tSpan) ;
354        }
355        $image->setThickness(1) ;
356}
357
358
359sub drawArea {
360#
361# draws an area like waterway=riverbank or landuse=forest.
362# pass color as string and nodes as list (x1, y1, x2, y2...) - real world coordinates
363#
364        my ($col, @nodes) = @_ ;
365        my $i ;
366        my $poly ; my @points = () ;
367        $poly = new GD::Polygon ;
368       
369        for ($i=0; $i<$#nodes; $i+=2) {
370                my ($x1, $y1) = convert ($nodes[$i], $nodes[$i+1]) ;
371                $poly->addPt ($x1, $y1) ;
372                push @points, $x1 ; push @points, $y1 ; 
373        }
374        $image->filledPolygon ($poly, $color{$col}) ;
375        if ($svgEnabled) {
376                push @svgOutputAreas, svgElementPolygonFilled ($col, @points) ;
377        }
378}
379
380
381
382sub drawRuler {
383#
384# draws ruler in top right corner, size is automatic
385#
386        my $col = shift ;
387
388        my $B ;
389        my $B2 ;
390        my $L ;
391        my $Lpix ;
392        my $x ;
393        my $text ;
394        my $rx = $sizeX - 20 ;
395        my $ry = 20 ;
396       
397        $B = $right - $left ;                           # in degrees
398        $B2 = $B * cos ($top/360*3.14*2) * 111.1 ;      # in km
399        $text = "100m" ; $x = 0.1 ;                     # default length ruler
400        if ($B2 > 5) {$text = "500m" ; $x = 0.5 ; }     # enlarge ruler
401        if ($B2 > 10) {$text = "1km" ; $x = 1 ; }
402        if ($B2 > 50) {$text = "5km" ; $x = 5 ; }
403        if ($B2 > 100) {$text = "10km" ; $x = 10 ; }
404        $L = $x / (cos ($top/360*3.14*2) * 111.1 ) ;    # length ruler in km
405        $Lpix = $L / $B * $sizeX ;                      # length ruler in pixels
406
407        $image->setThickness(1) ;
408        $image->line($rx-$Lpix,$ry,$rx,$ry,$color{$col}) ;
409        $image->line($rx-$Lpix,$ry,$rx-$Lpix,$ry+10,$color{$col}) ;
410        $image->line($rx,$ry,$rx,$ry+10,$color{$col}) ;
411        $image->line($rx-$Lpix/2,$ry,$rx-$Lpix/2,$ry+5,$color{$col}) ;
412        $image->string(gdSmallFont, $rx-$Lpix, $ry+15, $text, $color{$col}) ;
413
414        if ($svgEnabled) {
415                push @svgOutputText, svgElementLine ($rx-$Lpix,$ry,$rx,$ry, $col, 1) ;
416                push @svgOutputText, svgElementLine ($rx-$Lpix,$ry,$rx-$Lpix,$ry+10, $col, 1) ;
417                push @svgOutputText, svgElementLine ($rx,$ry,$rx,$ry+10, $col, 1) ;
418                push @svgOutputText, svgElementLine ($rx-$Lpix/2,$ry,$rx-$Lpix/2,$ry+5, $col, 1) ;
419                push @svgOutputText, svgElementText ($rx-$Lpix, $ry+15, $text, 2, $col, "") ;
420        }
421}
422
423
424
425sub drawLegend {
426#
427# draws legend (list of strings with different colors) in lower left corner, above foot. pass ("text", "color", ...)
428#
429        my ($size, @entries) = @_ ;
430        my $i ;
431        my $offset = 40 ;
432       
433        for ($i=0; $i<$#entries; $i+=2) {
434                $image->string($fonts{$size}, 20, ($sizeY-$offset), $entries[$i], $color{$entries[$i+1]}) ;
435                $offset += 20 ;
436                if ($svgEnabled) {
437                        push @svgOutputText, svgElementText (20, ($sizeY-$offset), $entries[$i], $size, $entries[$i+1], "") ;
438                }
439        }
440}
441
442
443
444
445sub drawChartColumns {
446#
447# draws a column chart at given real world coordinates. however, an offset can be given to bring distance between node/position and chart.
448# pass max column size (Y), column width in pixels and YMAX. values below 0 and above YMAX will be truncated.
449# chart will be framed black and gray.
450#
451        my ($lon, $lat, $offX, $offY, $colSizeY, $columnWidthPix, $yMax, $col, @values) = @_ ;
452        my ($x, $y) = convert ($lon, $lat) ;
453        $x = $x + $offX ;
454        $y = $y - $offY ;
455        my $num = scalar (@values) ;
456
457        $image->line($x,$y,$x+$num*$columnWidthPix,$y,$color{$col}) ; #lower
458        $image->line($x,$y,$x,$y-$colSizeY,$color{$col}) ; #left
459        $image->line($x,$y-$colSizeY,$x+$num*$columnWidthPix,$y-$colSizeY,$color{"gray"}) ; #top
460        $image->line($x+$num*$columnWidthPix,$y,$x+$num*$columnWidthPix,$y-$colSizeY,$color{"gray"}) ; #right
461       
462        my $i ;
463        for ($i=0; $i<=$#values; $i++) {
464                if ($values[$i] > $yMax) { $values[$i] = $yMax ; }
465                if ($values[$i] < 0) { $values[$i] = 0 ; }
466                my $yCol = ($values[$i] / $yMax) * $colSizeY ;
467                $image->filledRectangle($x+$i*$columnWidthPix, $y, $x+($i+1)*$columnWidthPix, $y-$yCol, $color{$col}) ;
468        }       
469
470        # TODO SVG output
471
472}
473
474#####
475# SVG
476#####
477
478
479sub enableSVG {
480#
481# only when called will svg elements be collected for later export to file
482#
483        $svgEnabled = 1 ;
484}
485
486sub writeSVG {
487#
488# writes svg elemets collected so far to file
489#
490        my ($fileName) = shift ;
491        my $file ;
492        open ($file, ">", $fileName) || die "can't open svg output file";
493        print $file "<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>\n" ;
494        print $file "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\" >\n" ;
495        print $file "<svg version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:ev=\"http://www.w3.org/2001/xml-events\" width=\"$sizeX\" height=\"$sizeY\" >\n" ;
496        print $file "<rect width=\"$sizeX\" height=\"$sizeY\" y=\"0\" x=\"0\" fill=\"#ffffff\" />\n" ;
497
498        print $file "<defs>\n" ;
499        foreach (@svgOutputDef) { print $file $_, "\n" ; }
500        print $file "</defs>\n" ;
501
502        print $file "<g id=\"Areas\">\n" ;
503        foreach (@svgOutputAreas) { print $file $_, "\n" ; }
504        print $file "</g>\n" ;
505
506        print $file "<g id=\"WaysAndNodes\">\n" ;
507        foreach (@svgOutputWaysNodes) { print $file $_, "\n" ; }
508        print $file "</g>\n" ;
509
510        print $file "<g id=\"Text\">\n" ;
511        foreach (@svgOutputText) { print $file $_, "\n" ; }
512        print $file "</g>\n" ;
513
514        print $file "<g id=\"Labels\">\n" ;
515        foreach (@svgOutputPathText) { print $file $_, "\n" ; }
516        print $file "</g>\n" ;
517
518        print $file "</svg>\n" ;
519        close ($file) ;
520}
521
522sub svgElementText {
523#
524# creates string with svg element incl utf-8 encoding
525# TODO support different fonts
526#
527        my ($x, $y, $text, $size, $col, $font) = @_ ; 
528        my $fontSize = 12 + ($size - 1) * 4 ;
529        my $svg = "<text x=\"" . $x . "\" y=\"" . $y . "\" font-size=\"" . $fontSize . "\" fill=\"#" . colorToHex(@{$colorHash{$col}}) . "\">" . encode("iso-8859-1", decode("utf8", $text)) . "</text>" ;
530        return $svg ;
531}
532
533sub svgElementCircleFilled {
534#
535# draws circle not filled
536#
537        my ($x, $y, $size, $col) = @_ ;
538        my $svg = "<circle cx=\"" . $x . "\" cy=\"" . $y . "\" r=\"" . $size . "\" fill=\"#" . colorToHex(@{$colorHash{$col}})  . "\" />" ;
539        return $svg ;
540}
541
542sub svgElementCircle {
543#
544# draws filled circle / dot
545#
546        my ($x, $y, $radius, $size, $col) = @_ ;
547        my $svg = "<circle cx=\"" . $x . "\" cy=\"" . $y . "\" r=\"" . $radius . "\" fill=\"none\" stroke=\"#" . colorToHex(@{$colorHash{$col}})  . "\" stroke-width=\"2\" />" ;
548        return $svg ;
549}
550
551sub svgElementLine {
552#
553# draws line between two points
554#
555        my ($x1, $y1, $x2, $y2, $col, $size) = @_ ;
556        my $svg = "<polyline points=\"" . $x1 . "," . $y1 . " " . $x2 . "," . $y2 . "\" stroke=\"#" . colorToHex(@{$colorHash{$col}}) . "\" stroke-width=\"" . $size . "\"/>" ;
557        return $svg ;
558}
559
560sub svgElementPolyline {
561#
562# draws way to svg
563#
564        my ($col, $size, @points) = @_ ;
565        my $svg = "<polyline points=\"" ;
566        my $i ;
567        for ($i=0; $i<scalar(@points)-1; $i+=2) {
568                $svg = $svg . $points[$i] . "," . $points[$i+1] . " " ;
569        }
570        $svg = $svg . "\" stroke=\"#" . colorToHex(@{$colorHash{$col}}) . "\" stroke-width=\"" . $size . "\" fill=\"none\" />" ;
571        return $svg ;
572}
573
574sub svgElementPath {
575#
576# creates path element for later use with textPath
577#
578        my ($pathName, @points) = @_ ;
579        my $svg = "<path id=\"" . $pathName . "\" d=\"M " ;
580        my $i ;
581        my $first = 1 ;
582        for ($i=0; $i<scalar(@points); $i+=2) {
583                if ($first) {
584                        $svg = $svg . $points[$i] . "," . $points[$i+1] . " " ;
585                        $first = 0 ;
586                }
587                else {
588                        $svg = $svg . "L " . $points[$i] . "," . $points[$i+1] . " " ;
589                }
590        }
591        $svg = $svg . "\" />\n" ;
592}
593
594sub svgElementPathText {
595#
596# draws text to path element
597#
598        my ($col, $size, $font, $text, $pathName, $tSpan) = @_ ;
599        my $fontSize = 12 + ($size - 1) * 4 ;
600        my $svg = "<text font-family=\"" . $font . "\" " ;
601        $svg = $svg . "font-size=\"" . $fontSize . "\" " ;
602        $svg = $svg . "fill=\"#" . colorToHex(@{$colorHash{$col}}) . "\" >\n" ;
603        $svg = $svg . "<textPath xlink:href=\"#" . $pathName . "\" text-anchor=\"middle\" startOffset=\"50%\" >\n" ;
604        $svg = $svg . "<tspan dy=\"" . $tSpan . "\" >" . $text . " </tspan>\n" ;
605        $svg = $svg . "</textPath>\n</text>\n" ;
606        return $svg ;
607}
608
609sub svgElementPolygonFilled {
610#
611# draws areas in svg, filled with color
612#
613        my ($col, @points) = @_ ;
614        my $i ;
615        my $svg = "<polygon fill=\"#" . colorToHex(@{$colorHash{$col}}) . "\" points=\"" ;
616        for ($i=0; $i<scalar(@points); $i+=2) {
617                $svg = $svg . $points[$i] . "," . $points[$i+1] . " " ;
618        }
619        $svg = $svg . "\" />" ;
620        return $svg ;
621}
622
623sub colorToHex {
624#
625# converts array of integers (rgb) to hex string without hash # (internaly used)
626#
627        my @arr = @_ ;
628        my $string = "" ; 
629        $string = sprintf "%02x", $arr[0] ;
630        $string = $string . sprintf "%02x", $arr[1] ;
631        $string = $string . sprintf "%02x", $arr[2] ;
632        return $string ;
633}
634
6351 ;
636
637#
638# copy this useful function to your main program and uncomment, if needed
639#
640# sub nodes2Coordinates {
641#
642# transform list of nodeIds to list of lons/lats
643#
644#       my @nodes = @_ ;
645#       my $i ;
646#       my @result = () ;
647#
648#       #print "in @nodes\n" ;
649#
650#       for ($i=0; $i<=$#nodes; $i++) {
651#               push @result, $lon{$nodes[$i]} ;
652#               push @result, $lat{$nodes[$i]} ;
653#       }
654#       return @result ;
655#}
656
Note: See TracBrowser for help on using the repository browser.