source: subversion/applications/utils/gary68/mwRules.pm @ 30595

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

mapweaver: label halo; pbf support; bold and italic fonts

File size: 28.3 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 mwRules ; 
20
21use strict ;
22use warnings ;
23
24use mwConfig ;
25use mwMap ;
26use mwMisc ;
27
28use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
29
30require Exporter ;
31
32@ISA = qw ( Exporter AutoLoader ) ;
33
34@EXPORT = qw (  readRules
35                        getNodeRule
36                        printNodeRules
37                        getWayRule
38                        printWayRules
39                        getAreaRule
40                        printAreaRules
41                        printValidObjectProperties
42                        getRouteColors
43                        getRouteRule
44                        printRouteRules
45                        adaptRuleSizes
46                        createLegend
47                 ) ;
48
49my @validNodeProperties = (     
50                        ["keyValue","key and value like [amenity=hospital]"],
51                        ["color","color of node i.e. [black]"],
52                        ["size","size of node i.e. [50]"],
53                        ["shape","shape of node [circle|disc|triangle|diamond|rectangle]"],
54                        ["svgString","svg format of shape [valid svg string]"],
55                        ["circle","add a circle to the node [yes|no]"],
56                        ["circleColor","color of the circle i.e. [blue]"],
57                        ["circleRadius","circle radius in meters i.e. [1000]"],
58                        ["circleThickness","thickness of the circle i.e. [5]"],
59                        ["circleSVGString","format of the circle []"],
60                        ["disc","add a disc to the node [yes|no]"],
61                        ["discColor","color of the disc i.e. [green]"],
62                        ["discOpacity","opacity of the disc [0..100]"],
63                        ["discRadius","radius of disc in meters i.e. [5000]"],
64                        ["discSVGString","format of the disc []"],
65                        ["label","label for the node like [name|ref]"],
66                        ["labelColor","color for label text i.e. [white]"],
67                        ["labelSize","size of label text i.e. [20]"],
68                        ["labelFont","font for label"],
69                        ["labelFontFamily","font family for label"],
70                        ["labelOffset","distance of label to node i.e. [10]"],
71                        ["labelBold","bold font for label"],
72                        ["labelItalic","italic font for label"],
73                        ["labelHalo","halo for label, width in pixels"],
74                        ["labelHaloColor","color for halo"],
75                        ["labelTransform","perl code for label name transformation"],
76                        ["legend","is this object to be listed in map legend? [yes|no]"],
77                        ["legendLabel","label text of object in legend i.e. [city]"],
78                        ["icon","icon to use for node, overrides shape i.e. [icondir/icon.svg]"],
79                        ["iconSize","size of the icon i.e. [40]"],
80                        ["shieldName","NOT YET IMPLEMENTED"],
81                        ["shieldSize","NOT YET IMPLEMENTED"],
82                        ["shieldLabel","NOT YET IMPLEMENTED"],
83                        ["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
84                        ["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"],
85                        ["direxclude","should these objects be excluded from directory? [yes|no]"]
86                                        ) ;
87
88my @validWayProperties =  (     
89                        ["keyValue","key and value like [highway=residential]"],
90                        ["color","color for the way i.e. [gray]"],
91                        ["size","size of the way i.e. [15]"],
92                        ["dash","svg dash array for the way i.e. [20,20]; old mapgen values are also possible"],
93                        ["dashCap","linecap shape for dashes like [butt|round|square]"],
94                        ["borderColor","color of the border of the way i.e. [black]"],
95                        ["borderSize","thickness os the border i.e. [2]"],
96                        ["label","label to be used i.e. [name|ref]"],
97                        ["labelColor","color of label text i.e. [blue]"],
98                        ["labelSize","size of the label i.e. [20]"],
99                        ["labelFont","font for label"],
100                        ["labelFontFamily","font family for label"],
101                        ["labelOffset","distance of label to middle of way i.e. [5]"],
102                        ["labelBold","bold font for label"],
103                        ["labelItalic","italic font for label"],
104                        ["labelHalo","halo for label, width in pixels"],
105                        ["labelHaloColor","color for halo"],
106                        ["labelTransform","perl code for label name transformation"],
107                        ["legend","is this object to be listed in map legend? [yes|no]"],
108                        ["legendLabel","label text of object in legend i.e. [Highway]"],
109
110                        ["svgStringBottom","format of lower way part (i.e. border) []"],
111                        ["svgStringTop","format of upper way part []"],
112                        ["bottomBorder","NOT YET IMPLEMENTED"],
113                       
114                        ["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
115                        ["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"],
116
117                        ["direxclude","should these objects be excluded from directory? [yes|no]"]
118                                        ) ;
119
120my @validAreaProperties = (     
121                        ["keyValue","key and value of object i.e. [amenity=parking]"],
122                        ["color","color of area i.e. [lightgrey]"],
123                        ["icon","icon for fill pattern to be used i.e. [icondir/parking.svg]"],
124                        ["label", "label text to be rendered i.e. [name]"] ,
125                        ["labelFont","font for label"],
126                        ["labelFontFamily","font family for label"],
127                        ["labelColor", "color of label i.e. [green]"] ,
128                        ["labelSize", "size of label text i.e. [20]"] ,
129                        ["labelBold","bold font for label"],
130                        ["labelItalic","italic font for label"],
131                        ["labelHalo","halo for label, width in pixels"],
132                        ["labelHaloColor","color for halo"],
133                        ["labelTransform","perl code for label name transformation"],
134                        ["base","should this object be drawn underneath other objects? (applies for landuse residential i.e.) [yes|no]"],
135                        ["svgString","format of area []"],
136                        ["legend","is this object to be listed in map legend? [yes|no]"],
137                        ["legendLabel","label text of object in legend i.e. [Parking]"],
138                        ["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
139                        ["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"]
140                                        ) ;
141
142
143my @validRouteProperties =  (   
144                        ["type","type of route like [bus|hiking]"],
145                        ["color","color of route like [red]"],
146                        ["size","size of route i.e. [10]"],
147                        ["dash","svg dash array style like [20,20]"],
148                        ["linecap","linecap style [butt|round|square]"],
149                        ["opacity","opacity of the route [0..100]"],
150                        ["label","label to be used like [ref]"],
151                        ["labelFont","font for label"],
152                        ["labelFontFamily","font family for label"],
153                        ["labelSize","size of the label i.e. [15]"],
154                        ["nodeSize","size of nodes belonging to route i.e. [20]"],
155                        ["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
156                        ["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"]
157                                        ) ;
158
159
160my %nodeRules = () ;
161my %areaRules = () ;
162my %wayRules = () ;
163my %routeRules = () ;
164my $nodeNr = 0 ;
165my $areaNr = 0 ;
166my $wayNr = 0 ;
167my $routeNr = 0 ;
168
169my $line ;
170my $ruleFile ;
171
172# ---------------------------------------------------------------------------------------
173
174sub printValidObjectProperties {
175
176        print "\nValid Object Properties\n" ;
177
178        print "\nNodes\n-----\n" ;
179        foreach my $p (sort {$a->[0] cmp $b->[0]} @validNodeProperties) {
180                printf "%-20s %s\n", $p->[0], $p->[1] ;
181        }
182        print "\nWays\n----\n" ;
183        foreach my $p (sort {$a->[0] cmp $b->[0]} @validWayProperties) {
184                printf "%-20s %s\n", $p->[0], $p->[1] ;
185        }
186        print "\nAreas\n-----\n" ;
187        foreach my $p (sort {$a->[0] cmp $b->[0]} @validAreaProperties) {
188                printf "%-20s %s\n", $p->[0], $p->[1] ;
189        }
190        print "\nRoutes\n-----\n" ;
191        foreach my $p (sort {$a->[0] cmp $b->[0]} @validRouteProperties) {
192                printf "%-20s %s\n", $p->[0], $p->[1] ;
193        }
194        print "\n" ;
195}
196
197
198# ---------------------------------------------------------------------------------------
199
200
201sub readRules {
202
203        my $fileName = cv('style') ;
204        my $nrr = 0 ; my $wrr = 0 ; my $arr = 0 ; my $rrr = 0 ; my $crr = 0 ;
205
206        print "reading rule file $fileName\n" ;
207
208        my %vnp = () ;
209        foreach my $p ( @validNodeProperties ) { $vnp{ lc ( $p->[0] ) } = 1 ; }
210
211        my %vwp = () ;
212        foreach my $p ( @validWayProperties ) { $vwp{ lc ( $p->[0] ) } = 1 ; }
213
214        my %vap = () ;
215        foreach my $p ( @validAreaProperties ) { $vap{ lc ( $p->[0] ) } = 1 ; }
216
217        my %vrp = () ;
218        foreach my $p ( @validRouteProperties ) { $vrp{ lc ( $p->[0] ) } = 1 ; }
219
220        openRuleFile($fileName) ;
221        while (defined $line) {
222                if ( grep /^rule node/i, $line ) {
223                        $nodeNr++ ;
224                        $nrr++ ;
225                        getRuleLine() ;
226
227                        # set defaults first
228                        $nodeRules{ $nodeNr }{ 'size' } = cv( 'ruleDefaultNodeSize' ) ;
229                        $nodeRules{ $nodeNr }{ 'color' } = cv( 'ruleDefaultNodeColor' ) ;
230                        $nodeRules{ $nodeNr }{ 'shape' } = cv( 'ruleDefaultNodeShape' ) ;
231
232                        $nodeRules{ $nodeNr }{ 'label' } = cv( 'ruleDefaultNodeLabel' ) ;
233                        $nodeRules{ $nodeNr }{ 'labelfont' } = cv( 'ruleDefaultNodeLabelFont' ) ;
234                        $nodeRules{ $nodeNr }{ 'labelfontfamily' } = cv( 'ruleDefaultNodeLabelFontFamily' ) ;
235                        $nodeRules{ $nodeNr }{ 'labelsize' } = cv( 'ruleDefaultNodeLabelSize' ) ;
236                        $nodeRules{ $nodeNr }{ 'labelitalic' } = "no" ;
237                        $nodeRules{ $nodeNr }{ 'labelbold' } = "no" ;
238                        $nodeRules{ $nodeNr }{ 'labelhalo' } = 0 ;
239                        $nodeRules{ $nodeNr }{ 'labelhalocolor' } = "white" ;
240                        $nodeRules{ $nodeNr }{ 'labeltransform' } = "" ;
241                        $nodeRules{ $nodeNr }{ 'icon' } = "none" ;
242                        $nodeRules{ $nodeNr }{ 'iconsize' } = cv( 'ruleDefaultNodeIconSize' ) ;
243                        $nodeRules{ $nodeNr }{ 'legend' } = "no" ;
244                        $nodeRules{ $nodeNr }{ 'shieldname' } = "none" ;
245                        $nodeRules{ $nodeNr }{ 'svgstring' } = "" ;
246                        $nodeRules{ $nodeNr }{ 'legend' } = "no" ;
247                        $nodeRules{ $nodeNr }{ 'legendlabel' } = "" ;
248
249                        $nodeRules{ $nodeNr }{ 'circle' } = 'no' ;
250                        $nodeRules{ $nodeNr }{ 'circlecolor' } = 'black' ;
251                        $nodeRules{ $nodeNr }{ 'circleradius' } = 1000 ;
252                        $nodeRules{ $nodeNr }{ 'circlethickness' } = 10 ;
253                        $nodeRules{ $nodeNr }{ 'circlesvgstring' } = "" ;
254
255                        $nodeRules{ $nodeNr }{ 'disc' } = 'no' ;
256                        $nodeRules{ $nodeNr }{ 'disccolor' } = 'red' ;
257                        $nodeRules{ $nodeNr }{ 'discopacity' } = 50 ;
258                        $nodeRules{ $nodeNr }{ 'discradius' } = 1000 ;
259                        $nodeRules{ $nodeNr }{ 'discradius' } = 1000 ;
260                        $nodeRules{ $nodeNr }{ 'discsvgstring' } = '' ;
261
262                        $nodeRules{ $nodeNr }{ 'fromscale' } = cv ('ruledefaultnodefromscale') ;
263                        $nodeRules{ $nodeNr }{ 'toscale' } =  cv ('ruledefaultnodetoscale') ;
264
265                        $nodeRules{ $nodeNr }{ 'direxclude' } = cv('direxcludedefault') ;
266
267                        while ( ( defined $line) and ( ! grep /^rule/i, $line) ) {
268                                my ($k, $v) = ( $line =~ /(.+?)=(.+)/ ) ;
269                                if ( ( ! defined $k ) or ( ! defined $v ) ) {
270                                        print "WARNING: could not parse rule line: $line" ;
271                                }
272                                else {
273                                        $k = lc ( $k ) ;
274                                        $nodeRules{ $nodeNr }{ $k } = $v ;
275                                        if ( ! defined $vnp{$k} ) { print "WARNING: $k is not a valid node property!\n" ; }
276                                }
277                                getRuleLine() ;
278                        }
279                        if ( ! defined $nodeRules{ $nodeNr }{ 'keyvalue' } ) { die "ERROR: rule without keyValue detected!\n" ; }
280
281                } # node
282
283                elsif ( grep /^rule way/i, $line ) {
284
285                        $wayNr++ ;
286                        $wrr++ ;
287                        getRuleLine() ;
288
289                        # set defaults first
290                        $wayRules{ $wayNr }{ 'label' } = cv( 'ruleDefaultWayLabel' ) ;
291                        $wayRules{ $wayNr }{ 'labelfont' } = cv( 'ruleDefaultWayLabelFont' ) ;
292                        $wayRules{ $wayNr }{ 'labelfontfamily' } = cv( 'ruleDefaultWayLabelFontFamily' ) ;
293                        $wayRules{ $wayNr }{ 'labelsize' } = cv( 'ruleDefaultWayLabelSize' ) ;
294                        $wayRules{ $wayNr }{ 'labelcolor' } = cv( 'ruleDefaultWayLabelColor' ) ;
295                        $wayRules{ $wayNr }{ 'labelfont' } = cv( 'ruleDefaultWayLabelFont' ) ;
296                        $wayRules{ $wayNr }{ 'labeloffset' } = cv( 'ruleDefaultWayLabelOffset' ) ;
297                        $wayRules{ $wayNr }{ 'labelitalic' } = "no" ;
298                        $wayRules{ $wayNr }{ 'labelbold' } = "no" ;
299                        $wayRules{ $wayNr }{ 'labelhalo' } = 0 ;
300                        $wayRules{ $wayNr }{ 'labelhalocolor' } = "white" ;
301                        $wayRules{ $wayNr }{ 'labeltransform' } = "" ;
302                        $wayRules{ $wayNr }{ 'legend' } = "no" ;
303                        $wayRules{ $wayNr }{ 'legendlabel' } = "" ;
304                        $wayRules{ $wayNr }{ 'color' } = cv( 'ruleDefaultWayColor' ) ;
305                        $wayRules{ $wayNr }{ 'size' } = cv( 'ruleDefaultWaySize' ) ;
306                        $wayRules{ $wayNr }{ 'bordercolor' } = cv( 'ruleDefaultWayBorderColor' ) ;
307                        $wayRules{ $wayNr }{ 'bordersize' } = cv( 'ruleDefaultWayBorderSize' ) ;
308                        $wayRules{ $wayNr }{ 'dash' } = cv( 'ruleDefaultWayDash' ) ;
309                        $wayRules{ $wayNr }{ 'dashcap' } = cv( 'ruleDefaultWayDashCap' ) ;
310
311                        $wayRules{ $wayNr }{ 'svgstringtop' } = "" ;
312                        $wayRules{ $wayNr }{ 'svgstringbottom' } = "" ;
313
314                        $wayRules{ $wayNr }{ 'fromscale' } = cv ('ruledefaultwayfromscale') ;
315                        $wayRules{ $wayNr }{ 'toscale' } =  cv ('ruledefaultwaytoscale') ;
316
317                        $wayRules{ $wayNr }{ 'direxclude' } = cv('direxcludedefault') ;
318
319                        while ( ( defined $line) and ( ! grep /^rule/i, $line) ) {
320                                my ($k, $v) = ( $line =~ /(.+?)=(.+)/ ) ;
321                                if ( ( ! defined $k ) or ( ! defined $v ) ) {
322                                        print "WARNING: could not parse rule line: $line" ;
323                                }
324                                else {
325                                        $k = lc ( $k ) ;
326                                        $wayRules{ $wayNr }{ $k } = $v ;
327                                        if ( ! defined $vwp{$k} ) { print "WARNING: $k is not a valid way property!\n" ; }
328                                }
329                                getRuleLine() ;
330                        }
331                        if ( ! defined $wayRules{ $wayNr }{ 'keyvalue' } ) { die "ERROR: rule without keyValue detected!\n" ; }
332
333                } # way
334
335                elsif ( grep /^rule area/i, $line ) {
336                        $areaNr++ ;
337                        $arr++ ;
338                        getRuleLine() ;
339
340                        # set defaults first
341                        $areaRules{ $areaNr }{ 'label' } = "none" ;
342                        $areaRules{ $areaNr }{ 'labelfont' } = cv( 'ruleDefaultAreaLabelFont' ) ;
343                        $areaRules{ $areaNr }{ 'labelfontfamily' } = cv( 'ruleDefaultAreaLabelFontFamily' ) ;
344                        $areaRules{ $areaNr }{ 'labelcolor' } = "black" ;
345                        $areaRules{ $areaNr }{ 'labelsize' } = 30 ;
346                        $areaRules{ $areaNr }{ 'labelitalic' } = "no" ;
347                        $areaRules{ $areaNr }{ 'labelbold' } = "no" ;
348                        $areaRules{ $areaNr }{ 'labelhalo' } = 0 ;
349                        $areaRules{ $areaNr }{ 'labelhalocolor' } = "white" ;
350                        $areaRules{ $areaNr }{ 'labeltransform' } = "" ;
351                        $areaRules{ $areaNr }{ 'color' } = cv( 'ruleDefaultAreaColor') ;
352                        $areaRules{ $areaNr }{ 'icon' } = "none" ;
353                        $areaRules{ $areaNr }{ 'base' } = "no"  ;
354                        $areaRules{ $areaNr }{ 'svgstring' } = ""  ;
355                        $areaRules{ $areaNr }{ 'minsize' } = cv ('ruledefaultareaminsize')  ;
356                        $areaRules{ $areaNr }{ 'legend' } = "no" ;
357                        $areaRules{ $areaNr }{ 'legendlabel' } = "" ;
358                        $areaRules{ $areaNr }{ 'fromscale' } = cv ('ruledefaultareafromscale') ;
359                        $areaRules{ $areaNr }{ 'toscale' } =  cv ('ruledefaultareatoscale') ;
360
361                        while ( ( defined $line) and ( ! grep /^rule/i, $line) ) {
362                                my ($k, $v) = ( $line =~ /(.+?)=(.+)/ ) ;
363                                if ( ( ! defined $k ) or ( ! defined $v ) ) {
364                                        print "WARNING: could not parse rule line: $line" ;
365                                }
366                                else {
367                                        $k = lc ( $k ) ;
368                                        $areaRules{ $areaNr }{ $k } = $v ;
369                                        if ( ! defined $vap{$k} ) { print "WARNING: $k is not a valid area property!\n" ; }
370
371                                        if ($k eq "icon") { mwMap::addAreaIcon ($v) ; }
372                                }
373                                getRuleLine() ;
374                        }
375                        if ( ! defined $areaRules{ $areaNr }{ 'keyvalue' } ) { die "ERROR: rule without keyValue detected!\n" ; }
376
377                } # area
378
379                elsif ( grep /^rule route/i, $line ) {
380                        $routeNr++ ;
381                        $rrr++ ;
382                        getRuleLine() ;
383
384                        # set defaults first
385                        $routeRules{ $routeNr }{ 'color' } = cv( 'ruleDefaultRouteColor' ) ;
386                        $routeRules{ $routeNr }{ 'size' } = cv( 'ruleDefaultRouteSize' ) ;
387                        $routeRules{ $routeNr }{ 'dash' } = cv( 'ruleDefaultRouteDash' ) ;
388                        $routeRules{ $routeNr }{ 'linecap' } = cv( 'ruleDefaultRouteLinecap' ) ;
389                        $routeRules{ $routeNr }{ 'opacity' } = cv( 'ruleDefaultRouteOpacity' ) ;
390                        $routeRules{ $routeNr }{ 'label' } = cv( 'ruleDefaultRouteLabel' ) ;
391                        # $routeRules{ $routeNr }{ 'labelfont' } = cv( 'ruleDefaultRouteLabelFont' ) ;
392                        # $routeRules{ $routeNr }{ 'labelfontfamily' } = cv( 'ruleDefaultRouteLabelFontFamily' ) ;
393                        # $routeRules{ $routeNr }{ 'labelsize' } = cv( 'ruleDefaultRouteLabelSize' ) ;
394                        $routeRules{ $routeNr }{ 'nodesize' } = cv( 'ruleDefaultRouteNodeSize' ) ;
395                        $routeRules{ $routeNr }{ 'fromscale' } = cv( 'ruleDefaultRouteFromScale' ) ;
396                        $routeRules{ $routeNr }{ 'toscale' } = cv( 'ruleDefaultRouteToScale' ) ;
397
398                        while ( ( defined $line) and ( ! grep /^rule/i, $line) ) {
399                                my ($k, $v) = ( $line =~ /(.+?)=(.+)/ ) ;
400                                if ( ( ! defined $k ) or ( ! defined $v ) ) {
401                                        print "WARNING: could not parse rule line: $line" ;
402                                }
403                                else {
404                                        $k = lc ( $k ) ;
405                                        $routeRules{ $routeNr }{ $k } = $v ;
406                                        if ( ! defined $vrp{$k} ) { print "WARNING: $k is not a valid route property!\n" ; }
407                                }
408                                getRuleLine() ;
409                        }
410                        if ( ! defined $routeRules{ $routeNr }{ 'type' } ) { die "ERROR: route rule without type detected!\n" ; }
411
412                } # route
413
414                elsif ( grep /^rule config/i, $line ) {
415                        $crr++ ;
416                        my ($key, $value) = ( $line =~ /^rule config\s+(.+)=(.+)/i ) ;
417                        if ( (defined $key) and (defined $value) ) {
418                                setConfigValue ($key, $value) ;
419                                if ( cv('debug') eq "1" ) {
420                                        print "RULES: config changed $key=$value\n" ;
421                                }
422                        }
423                        getRuleLine() ;
424                } # config
425
426                else {
427                        getRuleLine() ;
428                }
429
430        }
431
432
433        close ($ruleFile) ;
434
435        print "rules read: $nrr nodes, $wrr ways, $arr areas, $rrr routes and $crr configs\n\n" ;
436
437}
438
439sub getNodeRule {
440
441        # takes tagref and returns hashref to rule properties
442
443        my $tagRef = shift ;
444
445        my $scale = getScale() ;
446        if ( cv('rulescaleset') != 0 ) { $scale = cv('rulescaleset') ; }
447        # print "GNR: scale: $scale\n" ;
448
449        my $ruleFound ; undef $ruleFound ;
450
451        # print "\n" ;
452
453        RUL2: foreach my $rule ( sort { $a <=> $b } keys %nodeRules) {
454                # print "rule $rule\n" ;
455                if ( ( $nodeRules{$rule}{'fromscale'} <= $scale) and ( $nodeRules{$rule}{'toscale'} >= $scale) ) {
456
457                        my @kvs = split /;/, $nodeRules{$rule}{'keyvalue'} ;
458                        my $allValid = 1 ;
459                        RUL1: foreach my $kv1 ( @kvs ) { # for each needed
460                                my ($k, $v) = ( $kv1 =~ /(.+)=(.+)/ ) ;
461                                # print "  looking for $k=$v\n" ;
462                                my $found = 0 ;
463                                RUL3: foreach my $tag ( @$tagRef) {
464                                        # print "    actual kvs: $tag->[0]=$tag->[1]\n" ;
465                                        if ( ( $tag->[0] eq $k) and ( ( $tag->[1] eq $v) or ( $v eq "*") ) ) {
466                                                $found = 1 ;
467                                                # print "    FOUND\n" ;
468                                                last RUL3 ;
469                                        }
470                                } # tags
471                                if ( ! $found ) { 
472                                        $allValid = 0 ;
473                                        last RUL1 ; 
474                                }
475                        } # kv1
476
477                        if ( $allValid ) {
478                                # print "ALL VALID\n" ;
479                                # return the first rule found
480                                $ruleFound = \%{ $nodeRules{ $rule } } ;
481                                last RUL2 ;
482                        }
483
484                } # scale
485
486        } # all rules
487
488        return ($ruleFound) ;
489
490}
491
492sub printNodeRules {
493        foreach my $n ( sort { $a <=> $b }  keys %nodeRules) {
494                print "node rule $n\n" ;
495                foreach my $v (sort keys %{$nodeRules{$n}}) {
496                        print "  $v=$nodeRules{$n}{$v}\n" ;
497                } 
498                print "\n" ;
499        }
500}
501
502# ---------------------------------------------------------------------------------------
503
504
505
506sub getWayRule {
507
508        # takes tagref and returns hashref to rule properties
509
510        my $tagRef = shift ;
511
512        my $scale = getScale() ;
513        if ( cv('rulescaleset') != 0 ) { $scale = cv('rulescaleset') ; }
514
515        my $ruleFound ; undef $ruleFound ;
516
517        RUL5: foreach my $rule ( sort { $a <=> $b } keys %wayRules) {
518                # print "rule $rule\n" ;
519                if ( ( $wayRules{$rule}{'fromscale'} <= $scale) and ( $wayRules{$rule}{'toscale'} >= $scale) ) {
520
521                        my @kvs = split /;/, $wayRules{$rule}{'keyvalue'} ;
522                        my $allValid = 1 ;
523                        RUL4: foreach my $kv1 ( @kvs ) { # for each needed
524                                my ($k, $v) = ( $kv1 =~ /(.+)=(.+)/ ) ;
525                                # print "  looking for $k=$v\n" ;
526                                my $found = 0 ;
527                                RUL6: foreach my $tag ( @$tagRef) {
528                                        # print "    actual kvs: $tag->[0]=$tag->[1]\n" ;
529                                        if ( ( $tag->[0] eq $k) and ( ( $tag->[1] eq $v) or ( $v eq "*") ) ) {
530                                                $found = 1 ;
531                                                # print "    FOUND\n" ;
532                                                last RUL6 ;
533                                        }
534                                } # tags
535                                if ( ! $found ) { 
536                                        $allValid = 0 ;
537                                        last RUL4 ; 
538                                }
539                        } # kv1
540
541                        if ( $allValid ) {
542                                # print "ALL VALID\n" ;
543                                # return the first rule found
544                                $ruleFound = \%{ $wayRules{ $rule } } ;
545                                last RUL5 ;
546                        }
547
548                } # scale
549
550        } # all rules
551
552        return ($ruleFound) ;
553
554}
555
556
557sub printWayRules {
558        foreach my $n ( sort { $a <=> $b }  keys %wayRules) {
559                print "way rule $n\n" ;
560                foreach my $v (sort keys %{$wayRules{$n}}) {
561                        print "  $v=$wayRules{$n}{$v}\n" ;
562                } 
563                print "\n" ;
564        }
565}
566
567
568# ---------------------------------------------------------------------------------------
569
570
571
572sub getAreaRule {
573
574        # takes tagref and returns hashref to rule properties
575
576        my $tagRef = shift ;
577
578        my $scale = getScale() ;
579        if ( cv('rulescaleset') != 0 ) { $scale = cv('rulescaleset') ; }
580
581        my $ruleFound ; undef $ruleFound ;
582
583        RUL8: foreach my $rule ( sort { $a <=> $b } keys %areaRules) {
584                # print "rule $rule\n" ;
585                if ( ( $areaRules{$rule}{'fromscale'} <= $scale) and ( $areaRules{$rule}{'toscale'} >= $scale) ) {
586
587                        my @kvs = split /;/, $areaRules{$rule}{'keyvalue'} ;
588                        my $allValid = 1 ;
589                        RUL7: foreach my $kv1 ( @kvs ) { # for each needed
590                                my ($k, $v) = ( $kv1 =~ /(.+)=(.+)/ ) ;
591                                # print "  looking for $k=$v\n" ;
592                                my $found = 0 ;
593                                RUL9: foreach my $tag ( @$tagRef) {
594                                        # print "    actual kvs: $tag->[0]=$tag->[1]\n" ;
595                                        if ( ( $tag->[0] eq $k) and ( ( $tag->[1] eq $v) or ( $v eq "*") ) ) {
596                                                $found = 1 ;
597                                                # print "    FOUND\n" ;
598                                                last RUL9 ;
599                                        }
600                                } # tags
601                                if ( ! $found ) { 
602                                        $allValid = 0 ;
603                                        last RUL7 ; 
604                                }
605                        } # kv1
606
607                        if ( $allValid ) {
608                                # print "ALL VALID\n" ;
609                                # return the first rule found
610                                $ruleFound = \%{ $areaRules{ $rule } } ;
611                                last RUL8 ;
612                        }
613
614                } # scale
615
616        } # all rules
617
618        return ($ruleFound) ;
619
620}
621
622
623sub printAreaRules {
624        foreach my $n ( sort { $a <=> $b }  keys %areaRules) {
625                print "area rule $n\n" ;
626                foreach my $v (sort keys %{$areaRules{$n}}) {
627                        print "  $v=$areaRules{$n}{$v}\n" ;
628                } 
629                print "\n" ;
630        }
631}
632
633# --------------------------------------------------------------------------------
634
635sub getRouteRule {
636        my $tagRef = shift ;
637
638        my $scale = getScale() ;
639        if ( cv('rulescaleset') != 0 ) { $scale = cv('rulescaleset') ; }
640
641        my $ruleFound ; undef $ruleFound ;
642
643        my $type = getValue ("route", $tagRef) ;
644
645        if (defined $type) {
646                # print "      GRR: $type \n" ;
647                RULA: foreach my $r ( sort { $a <=> $b }  keys %routeRules) {
648                        # print "        GRR: $routeRules{$r}{'type'}\n" ;
649                        if ($routeRules{$r}{'type'} eq $type) {
650                                if ( ( $routeRules{$r}{'fromscale'} <= $scale) and ( $routeRules{$r}{'toscale'} >= $scale) ) {
651                                        $ruleFound = \%{ $routeRules{ $r } } ;
652                                        last RULA ;
653                                }
654                        }
655                }
656
657        }
658
659        return $ruleFound ;
660}
661
662sub getRouteColors {
663        my %routeColors = () ;
664        foreach my $n (keys %routeRules) {
665                my $type = $routeRules{$n}{'type'} ;
666                my $color = $routeRules{$n}{'color'} ;
667                @{$routeColors{$type}} = split ( /;/, $color ) ;
668        }
669        return \%routeColors ;
670}
671
672sub printRouteRules {
673        foreach my $n ( sort { $a <=> $b }  keys %routeRules) {
674                print "route rule $n\n" ;
675                foreach my $v (sort keys %{$routeRules{$n}}) {
676                        print "  $v=$routeRules{$n}{$v}\n" ;
677                } 
678                print "\n" ;
679        }
680}
681
682# --------------------------------------------------------------------------------
683
684
685sub openRuleFile {
686        my $fileName = shift ;
687        open ($ruleFile, "<", $fileName) or die ("ERROR: could not open rule file $fileName\n") ;
688        getRuleLine() ;
689}
690
691sub getRuleLine {
692        $line = <$ruleFile> ;
693        if (defined $line) {   
694                $line =~ s/\r//g ; # remove dos/win char at line end
695        }
696        while ( (defined $line) and ( (length $line < 2) or ( grep /^comment/i, $line) or ( grep /^\#/i, $line) ) ) {
697                $line = <$ruleFile> ;
698        }
699        return $line ;
700}
701
702sub adaptRuleSizes {
703        foreach my $r ( keys %nodeRules ) {
704                foreach my $p ( qw (iconSize labelOffset labelSize shieldSize size) ) {
705                        if ( defined $nodeRules{ $r }{ $p } ) {
706                                if ( grep /:/, $nodeRules{ $r }{ $p } ) {
707                                        my $old = $nodeRules{ $r }{ $p } ;
708                                        my $new = scaleSize ($nodeRules{ $r }{ $p }, $nodeRules{ $r }{ 'fromscale' }, $nodeRules{ $r }{ 'toscale' }) ;
709                                        $nodeRules{ $r }{ $p } = $new ;
710                                        if ( cv('debug') eq "1" ) {
711                                                print "RULES/scale/node: $old -> $new\n" ;
712                                        }
713                                }
714                        }
715                }
716        }
717        foreach my $r ( keys %wayRules ) {
718                foreach my $p ( qw (bordersize labelsize labeloffset size ) ) {
719                        if ( defined $wayRules{ $r }{ $p } ) {
720                                if ( grep /:/, $wayRules{ $r }{ $p } ) {
721                                        my $kv = $wayRules{ $r }{ 'keyvalue' } ;
722                                        my $old = $wayRules{ $r }{ $p } ;
723                                        my $new = 0 ;
724                                        $new = scaleSize ($wayRules{ $r }{ $p }, $wayRules{ $r }{ 'fromscale' }, $wayRules{ $r }{ 'toscale' }) ;
725                                        $wayRules{ $r }{ $p } = $new ;
726                                        if ( cv('debug') eq "1" ) {
727                                                print "RULES/scale/way: $kv $p $old to $new\n" ;
728                                        }
729                                }
730                        }
731                }
732        }
733}
734
735sub scaleSize {
736        my ($str, $fromScale, $toScale) = @_ ;
737        my @tmp = split /:/, $str ;
738        my $lower = $tmp[0] ;
739        my $upper = $tmp[1] ;
740        my $newSize = 0 ;
741
742        my $scale = getScale() ;
743        if ( cv('rulescaleset') ne "0" ) { $scale = cv('rulescaleset') } ;
744
745        if ( $scale < $fromScale) {
746                $newSize = $upper ;
747        }
748        elsif ( $scale > $toScale ) {
749                $newSize = $lower ;
750        }
751        else {
752                my $percent = ( $scale - $fromScale ) / ($toScale - $fromScale) ;
753                $newSize = $upper - $percent * ($upper - $lower) ;
754        }
755        $newSize = int ( $newSize * 10 ) / 10 ;
756        return $newSize ;
757}
758
759sub createLegend {
760
761        # TODO Auto size
762
763        my $nx = 80 ;
764        my $ny = 80 ;
765        my $ey = 1.5 * $ny ;
766        my $sx = 700 ;
767        my $tx = 200 ;
768        my $ty = $ey / 2 ;
769        my $fs = 40 ;
770        my $actualLine = 0 ;
771
772        my $preCount = 0 ;
773        foreach my $n (keys %nodeRules) {
774                if ( $nodeRules{$n}{"legend"} eq "yes" ) { $preCount++ ; }
775        }
776        foreach my $n (keys %wayRules) {
777                if ( $wayRules{$n}{"legend"} eq "yes" ) { $preCount++ ; }
778        }
779        foreach my $n (keys %areaRules) {
780                if ( $areaRules{$n}{"legend"} eq "yes" ) { $preCount++ ; }
781        }
782        if ( cv('debug') eq "1" ) { print "LEGEND: $preCount elements found\n" ; }
783
784        my $sy = $preCount * $ey ;
785        addToLayer ("definitions", "<g id=\"legenddef\" width=\"$sx\" height=\"$sy\" >") ;
786
787        my $color = "white" ;
788        my $svgString = "fill=\"$color\"" ;
789        drawRect (0, 0, $sx, $sy, 0, $svgString, "definitions") ;
790
791        foreach my $n (keys %nodeRules) {
792                if ( $nodeRules{$n}{"legend"} eq "yes" ) {
793                        my $x = $nx ;
794                        my $y = $actualLine * $ey + $ny ;
795                       
796                        if ( ($nodeRules{$n}{'size'} > 0) and ($nodeRules{$n}{'icon'} eq "none") )  {
797                                my $svgString = "" ;
798                                if ( $nodeRules{$n}{'svgstring'} ne "" ) {
799                                        $svgString = $nodeRules{$n}{'svgstring'} ;
800                                }
801                                else {
802                                        $svgString = "fill=\"$nodeRules{$n}{'color'}\"" ;
803                                }
804
805                                if ( $nodeRules{$n}{'shape'} eq "circle") {
806                                        drawCircle ($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions') ;
807                                }
808                                elsif ( $nodeRules{$n}{'shape'} eq "square") {
809                                        drawSquare ($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions') ;
810                                }
811                                elsif ( $nodeRules{$n}{'shape'} eq "triangle") {
812                                        drawTriangle ($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions') ;
813                                }
814                                elsif ( $nodeRules{$n}{'shape'} eq "diamond") {
815                                        drawDiamond ($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions') ;
816                                }
817
818                                my $textSvgString = createTextSVG ( cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef ) ;
819                                drawText ($tx, ($actualLine+0.5) * $ey + $fs/2, 0, $nodeRules{$n}{'legendlabel'}, $textSvgString, "definitions") ;
820                        }
821                        else {
822                                # TODO icon
823                        }
824                $actualLine ++ ;
825                }
826        }
827
828        foreach my $w (keys %wayRules) {
829                if ( $wayRules{$w}{"legend"} eq "yes" ) {
830                        my ($x1, $x2) ;
831                        $x1 = 0.5 * $nx ;
832                        $x2 = 1.5 * $nx ;
833                        my $y = $actualLine * $ey + $ny ;
834                        my ($svg1, $layer1, $svg2, $layer2) = mwWays::createWayParameters ($wayRules{$w}, 0, 0, 0) ;
835                        my @coords = ($x1, $y, $x2, $y) ;
836                        if ($svg2 ne "") {
837                                drawWay ( \@coords, 0, $svg2, "definitions", undef ) ;
838                        }
839                        drawWay ( \@coords, 0, $svg1, "definitions", undef ) ;
840
841                        my $textSvgString = createTextSVG ( cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef ) ;
842                        drawText ($tx, ($actualLine+0.5)*$ey + $fs/2, 0, $wayRules{$w}{'legendlabel'}, $textSvgString, "definitions") ;
843
844                        $actualLine++ ;
845
846                }
847        }
848
849        foreach my $a (keys %areaRules) {
850                if ( $areaRules{$a}{"legend"} eq "yes" ) {
851                        my ($x1, $x2) ;
852                        my ($y1, $y2) ;
853                        $x1 = 0.7 * $nx ;
854                        $x2 = 1.3 * $nx ;
855                        $y1 = $actualLine * $ey + 0.7 * $ny ;
856                        $y2 = $actualLine * $ey + 1.3 * $ny ;
857
858                        my $color = $areaRules{$a}{'color'} ;
859                        my $icon = $areaRules{$a}{'icon'} ;
860                        my $base = $areaRules{$a}{'base'} ;
861                        my $svgString = $areaRules{$a}{'svgstring'} ;
862
863                        if ( ($svgString eq "") and ($icon eq "none") ) {
864                                $svgString = "fill=\"$color\" " ;
865                        }
866
867                        my @coords = ([$x1, $y1, $x2, $y1, $x2, $y2, $x1, $y2, $x1, $y1]) ;
868                        drawArea ($svgString, $icon, \@coords, 0, "definitions") ;
869
870                        my $textSvgString = createTextSVG ( cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef ) ;
871                        drawText ($tx, ($actualLine+0.5)*$ey + $fs/2, 0, $areaRules{$a}{'legendlabel'}, $textSvgString, "definitions") ;
872                        $actualLine++ ;
873                }
874        }
875
876
877        addToLayer ("definitions", "</g>") ;
878
879        my $posX = 0 ;
880        my $posY = 0 ;
881
882        my ($sizeX, $sizeY) = getDimensions() ;
883
884        if ( cv('legend') eq "2") {
885                $posX = $sizeX - $sx ;
886                $posY = 0 ;
887        }
888
889        if ( cv('legend') eq "3") {
890                $posX = 0 ;
891                $posY = $sizeY - $sy ;
892        }
893
894        if ( cv('legend') eq "4") {
895                $posX = $sizeX - $sx ;
896                $posY = $sizeY - $sy ;
897        }
898
899        if ( (cv('legend') >=1) and (cv('legend')<=4) ) {
900                addToLayer ("legend", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#legenddef\" />") ;
901        }
902        elsif (cv('legend') == 5) {
903                # separate file
904                createLegendFile($sx, $sy, "_legend", "#legenddef") ;
905        }
906
907}
908
9091 ;
Note: See TracBrowser for help on using the repository browser.