mapweaver/mwRules.pm

685 lines
26 KiB
Perl

#
# PERL mapweaver module by gary68
#
#
#
#
# Copyright(C)2011, Gerhard Schwanz
#
# 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
# Free Software Foundation; either version 3 of the License, or(at your option)any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program; if not, see <http://www.gnu.org/licenses/>
#
package mwRules;
use strict;
use warnings;
use mwConfig;
use mwMap;
use mwMisc;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(readRules
getNodeRule
printNodeRules
getWayRule
printWayRules
getAreaRule
printAreaRules
printValidObjectProperties
getRouteColors
getRouteRule
printRouteRules
adaptRuleSizes
createLegend
);
my @validNodeProperties =( ["keyValue","key and value like [amenity=hospital]"],
["color","color of node i.e. [black]"],
["size","size of node i.e. [50]"],
["shape","shape of node [circle|disc|triangle|diamond|rectangle]"],
["svgString","svg format of shape [valid svg string]"],
["circle","add a circle to the node [yes|no]"],
["circleColor","color of the circle i.e. [blue]"],
["circleRadius","circle radius in meters i.e. [1000]"],
["circleThickness","thickness of the circle i.e. [5]"],
["circleSVGString","format of the circle []"],
["disc","add a disc to the node [yes|no]"],
["discColor","color of the disc i.e. [green]"],
["discOpacity","opacity of the disc [0..100]"],
["discRadius","radius of disc in meters i.e. [5000]"],
["discSVGString","format of the disc []"],
["label","label for the node like [name|ref]"],
["labelColor","color for label text i.e. [white]"],
["labelSize","size of label text i.e. [20]"],
["labelFont","font for label"],
["labelFontFamily","font family for label"],
["labelOffset","distance of label to node i.e. [10]"],
["labelBold","bold font for label"],
["labelItalic","italic font for label"],
["labelHalo","halo for label, width in pixels"],
["labelHaloColor","color for halo"],
["labelTransform","perl code for label name transformation"],
["legend","is this object to be listed in map legend? [yes|no]"],
["legendLabel","label text of object in legend i.e. [city]"],
["icon","icon to use for node, overrides shape i.e. [icondir/icon.svg]"],
["iconSize","size of the icon i.e. [40]"],
["shieldName","NOT YET IMPLEMENTED"],
["shieldSize","NOT YET IMPLEMENTED"],
["shieldLabel","NOT YET IMPLEMENTED"],
["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"],
["direxclude","should these objects be excluded from directory? [yes|no]"]
);
my @validWayProperties =( ["keyValue","key and value like [highway=residential]"],
["color","color for the way i.e. [gray]"],
["size","size of the way i.e. [15]"],
["dash","svg dash array for the way i.e. [20,20]; old mapgen values are also possible"],
["dashCap","linecap shape for dashes like [butt|round|square]"],
["borderColor","color of the border of the way i.e. [black]"],
["borderSize","thickness os the border i.e. [2]"],
["label","label to be used i.e. [name|ref]"],
["labelColor","color of label text i.e. [blue]"],
["labelSize","size of the label i.e. [20]"],
["labelFont","font for label"],
["labelFontFamily","font family for label"],
["labelOffset","distance of label to middle of way i.e. [5]"],
["labelBold","bold font for label"],
["labelItalic","italic font for label"],
["labelHalo","halo for label, width in pixels"],
["labelHaloColor","color for halo"],
["labelTransform","perl code for label name transformation"],
["legend","is this object to be listed in map legend? [yes|no]"],
["legendLabel","label text of object in legend i.e. [Highway]"],
["svgStringBottom","format of lower way part(i.e. border)[]"],
["svgStringTop","format of upper way part []"],
["bottomBorder","NOT YET IMPLEMENTED"],
["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"],
["direxclude","should these objects be excluded from directory? [yes|no]"]
);
my @validAreaProperties =( ["keyValue","key and value of object i.e. [amenity=parking]"],
["color","color of area i.e. [lightgrey]"],
["icon","icon for fill pattern to be used i.e. [icondir/parking.svg]"],
["label", "label text to be rendered i.e. [name]"] ,
["labelFont","font for label"],
["labelFontFamily","font family for label"],
["labelColor", "color of label i.e. [green]"] ,
["labelSize", "size of label text i.e. [20]"] ,
["labelBold","bold font for label"],
["labelItalic","italic font for label"],
["labelHalo","halo for label, width in pixels"],
["labelHaloColor","color for halo"],
["labelTransform","perl code for label name transformation"],
["base","should this object be drawn underneath other objects?(applies for landuse residential i.e.)[yes|no]"],
["svgString","format of area []"],
["legend","is this object to be listed in map legend? [yes|no]"],
["legendLabel","label text of object in legend i.e. [Parking]"],
["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"]
);
my @validRouteProperties =( ["type","type of route like [bus|hiking]"],
["color","color of route like [red]"],
["size","size of route i.e. [10]"],
["dash","svg dash array style like [20,20]"],
["linecap","linecap style [butt|round|square]"],
["opacity","opacity of the route [0..100]"],
["label","label to be used like [ref]"],
["labelFont","font for label"],
["labelFontFamily","font family for label"],
["labelSize","size of the label i.e. [15]"],
["nodeSize","size of nodes belonging to route i.e. [20]"],
["fromScale","rule will only applied if scale is bigger than fromScale i.e. [5000]"],
["toScale","rule will only applied if scale is lower than fromScale i.e. [25000]"]
);
my %nodeRules =();
my %areaRules =();
my %wayRules =();
my %routeRules =();
my $nodeNr = 0;
my $areaNr = 0;
my $wayNr = 0;
my $routeNr = 0;
my $line;
my $ruleFile;
# ---------------------------------------------------------------------------------------
sub printValidObjectProperties{
print "\nValid Object Properties\n";
print "\nNodes\n-----\n";
foreach my $p(sort{$a->[0] cmp $b->[0]}@validNodeProperties){ printf "%-20s %s\n", $p->[0], $p->[1];
} print "\nWays\n----\n";
foreach my $p(sort{$a->[0] cmp $b->[0]}@validWayProperties){ printf "%-20s %s\n", $p->[0], $p->[1];
} print "\nAreas\n-----\n";
foreach my $p(sort{$a->[0] cmp $b->[0]}@validAreaProperties){ printf "%-20s %s\n", $p->[0], $p->[1];
} print "\nRoutes\n-----\n";
foreach my $p(sort{$a->[0] cmp $b->[0]}@validRouteProperties){ printf "%-20s %s\n", $p->[0], $p->[1];
} print "\n";
}
# ---------------------------------------------------------------------------------------
sub readRules{
my $fileName = cv('style');
my $nrr = 0; my $wrr = 0; my $arr = 0; my $rrr = 0; my $crr = 0;
print "reading rule file $fileName\n";
my %vnp =();
foreach my $p(@validNodeProperties){$vnp{lc($p->[0])}= 1;}
my %vwp =();
foreach my $p(@validWayProperties){$vwp{lc($p->[0])}= 1;}
my %vap =();
foreach my $p(@validAreaProperties){$vap{lc($p->[0])}= 1;}
my %vrp =();
foreach my $p(@validRouteProperties){$vrp{lc($p->[0])}= 1;}
openRuleFile($fileName);
while(defined $line){ if(grep /^rule node/i, $line){ $nodeNr++;
$nrr++;
getRuleLine();
# set defaults first
$nodeRules{$nodeNr}{'size'}= cv('ruleDefaultNodeSize');
$nodeRules{$nodeNr}{'color'}= cv('ruleDefaultNodeColor');
$nodeRules{$nodeNr}{'shape'}= cv('ruleDefaultNodeShape');
$nodeRules{$nodeNr}{'label'}= cv('ruleDefaultNodeLabel');
$nodeRules{$nodeNr}{'labelfont'}= cv('ruleDefaultNodeLabelFont');
$nodeRules{$nodeNr}{'labelfontfamily'}= cv('ruleDefaultNodeLabelFontFamily');
$nodeRules{$nodeNr}{'labelsize'}= cv('ruleDefaultNodeLabelSize');
$nodeRules{$nodeNr}{'labelitalic'}= "no";
$nodeRules{$nodeNr}{'labelbold'}= "no";
$nodeRules{$nodeNr}{'labelhalo'}= 0;
$nodeRules{$nodeNr}{'labelhalocolor'}= "white";
$nodeRules{$nodeNr}{'labeltransform'}= "";
$nodeRules{$nodeNr}{'icon'}= "none";
$nodeRules{$nodeNr}{'iconsize'}= cv('ruleDefaultNodeIconSize');
$nodeRules{$nodeNr}{'legend'}= "no";
$nodeRules{$nodeNr}{'shieldname'}= "none";
$nodeRules{$nodeNr}{'svgstring'}= "";
$nodeRules{$nodeNr}{'legend'}= "no";
$nodeRules{$nodeNr}{'legendlabel'}= "";
$nodeRules{$nodeNr}{'circle'}= 'no';
$nodeRules{$nodeNr}{'circlecolor'}= 'black';
$nodeRules{$nodeNr}{'circleradius'}= 1000;
$nodeRules{$nodeNr}{'circlethickness'}= 10;
$nodeRules{$nodeNr}{'circlesvgstring'}= "";
$nodeRules{$nodeNr}{'disc'}= 'no';
$nodeRules{$nodeNr}{'disccolor'}= 'red';
$nodeRules{$nodeNr}{'discopacity'}= 50;
$nodeRules{$nodeNr}{'discradius'}= 1000;
$nodeRules{$nodeNr}{'discradius'}= 1000;
$nodeRules{$nodeNr}{'discsvgstring'}= '';
$nodeRules{$nodeNr}{'fromscale'}= cv('ruledefaultnodefromscale');
$nodeRules{$nodeNr}{'toscale'}= cv('ruledefaultnodetoscale');
$nodeRules{$nodeNr}{'direxclude'}= cv('direxcludedefault');
while((defined $line)and(! grep /^rule/i, $line)){ my($k, $v)=($line =~ /(.+?)=(.+)/);
if((! defined $k)or(! defined $v)){ print "WARNING: could not parse rule line: $line";
} else{ $k = lc($k);
$nodeRules{$nodeNr}{$k}= $v;
if(! defined $vnp{$k}){print "WARNING: $k is not a valid node property!\n";} } getRuleLine();
} if(! defined $nodeRules{$nodeNr}{'keyvalue'}){die "ERROR: rule without keyValue detected!\n";}
}# node
elsif(grep /^rule way/i, $line){
$wayNr++;
$wrr++;
getRuleLine();
# set defaults first
$wayRules{$wayNr}{'label'}= cv('ruleDefaultWayLabel');
$wayRules{$wayNr}{'labelfont'}= cv('ruleDefaultWayLabelFont');
$wayRules{$wayNr}{'labelfontfamily'}= cv('ruleDefaultWayLabelFontFamily');
$wayRules{$wayNr}{'labelsize'}= cv('ruleDefaultWayLabelSize');
$wayRules{$wayNr}{'labelcolor'}= cv('ruleDefaultWayLabelColor');
$wayRules{$wayNr}{'labelfont'}= cv('ruleDefaultWayLabelFont');
$wayRules{$wayNr}{'labeloffset'}= cv('ruleDefaultWayLabelOffset');
$wayRules{$wayNr}{'labelitalic'}= "no";
$wayRules{$wayNr}{'labelbold'}= "no";
$wayRules{$wayNr}{'labelhalo'}= 0;
$wayRules{$wayNr}{'labelhalocolor'}= "white";
$wayRules{$wayNr}{'labeltransform'}= "";
$wayRules{$wayNr}{'legend'}= "no";
$wayRules{$wayNr}{'legendlabel'}= "";
$wayRules{$wayNr}{'color'}= cv('ruleDefaultWayColor');
$wayRules{$wayNr}{'size'}= cv('ruleDefaultWaySize');
$wayRules{$wayNr}{'bordercolor'}= cv('ruleDefaultWayBorderColor');
$wayRules{$wayNr}{'bordersize'}= cv('ruleDefaultWayBorderSize');
$wayRules{$wayNr}{'dash'}= cv('ruleDefaultWayDash');
$wayRules{$wayNr}{'dashcap'}= cv('ruleDefaultWayDashCap');
$wayRules{$wayNr}{'svgstringtop'}= "";
$wayRules{$wayNr}{'svgstringbottom'}= "";
$wayRules{$wayNr}{'fromscale'}= cv('ruledefaultwayfromscale');
$wayRules{$wayNr}{'toscale'}= cv('ruledefaultwaytoscale');
$wayRules{$wayNr}{'direxclude'}= cv('direxcludedefault');
while((defined $line)and(! grep /^rule/i, $line)){ my($k, $v)=($line =~ /(.+?)=(.+)/);
if((! defined $k)or(! defined $v)){ print "WARNING: could not parse rule line: $line";
} else{ $k = lc($k);
$wayRules{$wayNr}{$k}= $v;
if(! defined $vwp{$k}){print "WARNING: $k is not a valid way property!\n";} } getRuleLine();
} if(! defined $wayRules{$wayNr}{'keyvalue'}){die "ERROR: rule without keyValue detected!\n";}
}# way
elsif(grep /^rule area/i, $line){ $areaNr++;
$arr++;
getRuleLine();
# set defaults first
$areaRules{$areaNr}{'label'}= "none";
$areaRules{$areaNr}{'labelfont'}= cv('ruleDefaultAreaLabelFont');
$areaRules{$areaNr}{'labelfontfamily'}= cv('ruleDefaultAreaLabelFontFamily');
$areaRules{$areaNr}{'labelcolor'}= "black";
$areaRules{$areaNr}{'labelsize'}= 30;
$areaRules{$areaNr}{'labelitalic'}= "no";
$areaRules{$areaNr}{'labelbold'}= "no";
$areaRules{$areaNr}{'labelhalo'}= 0;
$areaRules{$areaNr}{'labelhalocolor'}= "white";
$areaRules{$areaNr}{'labeltransform'}= "";
$areaRules{$areaNr}{'color'}= cv('ruleDefaultAreaColor');
$areaRules{$areaNr}{'icon'}= "none";
$areaRules{$areaNr}{'base'}= "no";
$areaRules{$areaNr}{'svgstring'}= "";
$areaRules{$areaNr}{'minsize'}= cv('ruledefaultareaminsize');
$areaRules{$areaNr}{'legend'}= "no";
$areaRules{$areaNr}{'legendlabel'}= "";
$areaRules{$areaNr}{'fromscale'}= cv('ruledefaultareafromscale');
$areaRules{$areaNr}{'toscale'}= cv('ruledefaultareatoscale');
while((defined $line)and(! grep /^rule/i, $line)){ my($k, $v)=($line =~ /(.+?)=(.+)/);
if((! defined $k)or(! defined $v)){ print "WARNING: could not parse rule line: $line";
} else{ $k = lc($k);
$areaRules{$areaNr}{$k}= $v;
if(! defined $vap{$k}){print "WARNING: $k is not a valid area property!\n";}
if($k eq "icon"){mwMap::addAreaIcon($v);} } getRuleLine();
} if(! defined $areaRules{$areaNr}{'keyvalue'}){die "ERROR: rule without keyValue detected!\n";}
}# area
elsif(grep /^rule route/i, $line){ $routeNr++;
$rrr++;
getRuleLine();
# set defaults first
$routeRules{$routeNr}{'color'}= cv('ruleDefaultRouteColor');
$routeRules{$routeNr}{'size'}= cv('ruleDefaultRouteSize');
$routeRules{$routeNr}{'dash'}= cv('ruleDefaultRouteDash');
$routeRules{$routeNr}{'linecap'}= cv('ruleDefaultRouteLinecap');
$routeRules{$routeNr}{'opacity'}= cv('ruleDefaultRouteOpacity');
$routeRules{$routeNr}{'label'}= cv('ruleDefaultRouteLabel');
# $routeRules{$routeNr}{'labelfont'}= cv('ruleDefaultRouteLabelFont');
# $routeRules{$routeNr}{'labelfontfamily'}= cv('ruleDefaultRouteLabelFontFamily');
# $routeRules{$routeNr}{'labelsize'}= cv('ruleDefaultRouteLabelSize');
$routeRules{$routeNr}{'nodesize'}= cv('ruleDefaultRouteNodeSize');
$routeRules{$routeNr}{'fromscale'}= cv('ruleDefaultRouteFromScale');
$routeRules{$routeNr}{'toscale'}= cv('ruleDefaultRouteToScale');
while((defined $line)and(! grep /^rule/i, $line)){ my($k, $v)=($line =~ /(.+?)=(.+)/);
if((! defined $k)or(! defined $v)){ print "WARNING: could not parse rule line: $line";
} else{ $k = lc($k);
$routeRules{$routeNr}{$k}= $v;
if(! defined $vrp{$k}){print "WARNING: $k is not a valid route property!\n";} } getRuleLine();
} if(! defined $routeRules{$routeNr}{'type'}){die "ERROR: route rule without type detected!\n";}
}# route
elsif(grep /^rule config/i, $line){ $crr++;
my($key, $value)=($line =~ /^rule config\s+(.+)=(.+)/i);
if((defined $key)and(defined $value)){ setConfigValue($key, $value);
if(cv('debug')eq "1"){ print "RULES: config changed $key=$value\n";
} } getRuleLine();
}# config
else{ getRuleLine();
}
}
close($ruleFile);
print "rules read: $nrr nodes, $wrr ways, $arr areas, $rrr routes and $crr configs\n\n";
}
sub getNodeRule{
# takes tagref and returns hashref to rule properties
my $tagRef = shift;
my $scale = getScale();
if(cv('rulescaleset')!= 0){$scale = cv('rulescaleset');} # print "GNR: scale: $scale\n";
my $ruleFound; undef $ruleFound;
# print "\n";
RUL2: foreach my $rule(sort{$a <=> $b}keys %nodeRules){ # print "rule $rule\n";
if(($nodeRules{$rule}{'fromscale'}<= $scale)and($nodeRules{$rule}{'toscale'}>= $scale)){
my @kvs = split /;/, $nodeRules{$rule}{'keyvalue'};
my $allValid = 1;
RUL1: foreach my $kv1(@kvs){# for each needed
my($k, $v)=($kv1 =~ /(.+)=(.+)/);
# print " looking for $k=$v\n";
my $found = 0;
RUL3: foreach my $tag(@$tagRef){ # print " actual kvs: $tag->[0]=$tag->[1]\n";
if(($tag->[0] eq $k)and(($tag->[1] eq $v)or($v eq "*"))){ $found = 1;
# print " FOUND\n";
last RUL3;
} }# tags
if(! $found){
$allValid = 0;
last RUL1;
} }# kv1
if($allValid){ # print "ALL VALID\n";
# return the first rule found
$ruleFound = \%{$nodeRules{$rule}};
last RUL2;
}
}# scale
}# all rules
return($ruleFound);
}
sub printNodeRules{ foreach my $n(sort{$a <=> $b} keys %nodeRules){ print "node rule $n\n";
foreach my $v(sort keys %{$nodeRules{$n}}){ print " $v=$nodeRules{$n}{$v}\n";
}
print "\n";
}}
# ---------------------------------------------------------------------------------------
sub getWayRule{
# takes tagref and returns hashref to rule properties
my $tagRef = shift;
my $scale = getScale();
if(cv('rulescaleset')!= 0){$scale = cv('rulescaleset');}
my $ruleFound; undef $ruleFound;
RUL5: foreach my $rule(sort{$a <=> $b}keys %wayRules){ # print "rule $rule\n";
if(($wayRules{$rule}{'fromscale'}<= $scale)and($wayRules{$rule}{'toscale'}>= $scale)){
my @kvs = split /;/, $wayRules{$rule}{'keyvalue'};
my $allValid = 1;
RUL4: foreach my $kv1(@kvs){# for each needed
my($k, $v)=($kv1 =~ /(.+)=(.+)/);
# print " looking for $k=$v\n";
my $found = 0;
RUL6: foreach my $tag(@$tagRef){ # print " actual kvs: $tag->[0]=$tag->[1]\n";
if(($tag->[0] eq $k)and(($tag->[1] eq $v)or($v eq "*"))){ $found = 1;
# print " FOUND\n";
last RUL6;
} }# tags
if(! $found){
$allValid = 0;
last RUL4;
} }# kv1
if($allValid){ # print "ALL VALID\n";
# return the first rule found
$ruleFound = \%{$wayRules{$rule}};
last RUL5;
}
}# scale
}# all rules
return($ruleFound);
}
sub printWayRules{ foreach my $n(sort{$a <=> $b} keys %wayRules){ print "way rule $n\n";
foreach my $v(sort keys %{$wayRules{$n}}){ print " $v=$wayRules{$n}{$v}\n";
}
print "\n";
}}
# ---------------------------------------------------------------------------------------
sub getAreaRule{
# takes tagref and returns hashref to rule properties
my $tagRef = shift;
my $scale = getScale();
if(cv('rulescaleset')!= 0){$scale = cv('rulescaleset');}
my $ruleFound; undef $ruleFound;
RUL8: foreach my $rule(sort{$a <=> $b}keys %areaRules){ # print "rule $rule\n";
if(($areaRules{$rule}{'fromscale'}<= $scale)and($areaRules{$rule}{'toscale'}>= $scale)){
my @kvs = split /;/, $areaRules{$rule}{'keyvalue'};
my $allValid = 1;
RUL7: foreach my $kv1(@kvs){# for each needed
my($k, $v)=($kv1 =~ /(.+)=(.+)/);
# print " looking for $k=$v\n";
my $found = 0;
RUL9: foreach my $tag(@$tagRef){ # print " actual kvs: $tag->[0]=$tag->[1]\n";
if(($tag->[0] eq $k)and(($tag->[1] eq $v)or($v eq "*"))){ $found = 1;
# print " FOUND\n";
last RUL9;
} }# tags
if(! $found){
$allValid = 0;
last RUL7;
} }# kv1
if($allValid){ # print "ALL VALID\n";
# return the first rule found
$ruleFound = \%{$areaRules{$rule}};
last RUL8;
}
}# scale
}# all rules
return($ruleFound);
}
sub printAreaRules{ foreach my $n(sort{$a <=> $b} keys %areaRules){ print "area rule $n\n";
foreach my $v(sort keys %{$areaRules{$n}}){ print " $v=$areaRules{$n}{$v}\n";
}
print "\n";
}}
# --------------------------------------------------------------------------------
sub getRouteRule{ my $tagRef = shift;
my $scale = getScale();
if(cv('rulescaleset')!= 0){$scale = cv('rulescaleset');}
my $ruleFound; undef $ruleFound;
my $type = getValue("route", $tagRef);
if(defined $type){ # print " GRR: $type \n";
RULA: foreach my $r(sort{$a <=> $b} keys %routeRules){ # print " GRR: $routeRules{$r}{'type'}\n";
if($routeRules{$r}{'type'}eq $type){ if(($routeRules{$r}{'fromscale'}<= $scale)and($routeRules{$r}{'toscale'}>= $scale)){ $ruleFound = \%{$routeRules{$r}};
last RULA;
} } }
}
return $ruleFound;
}
sub getRouteColors{ my %routeColors =();
foreach my $n(keys %routeRules){ my $type = $routeRules{$n}{'type'};
my $color = $routeRules{$n}{'color'};
@{$routeColors{$type}}= split(/;/, $color);
} return \%routeColors;
}
sub printRouteRules{ foreach my $n(sort{$a <=> $b} keys %routeRules){ print "route rule $n\n";
foreach my $v(sort keys %{$routeRules{$n}}){ print " $v=$routeRules{$n}{$v}\n";
}
print "\n";
}}
# --------------------------------------------------------------------------------
sub openRuleFile{ my $fileName = shift;
open($ruleFile, "<", $fileName)or die("ERROR: could not open rule file $fileName\n");
getRuleLine();
}
sub getRuleLine{ $line = <$ruleFile>;
if(defined $line){
$line =~ s/\r//g; # remove dos/win char at line end
} while((defined $line)and((length $line < 2)or(grep /^comment/i, $line)or(grep /^\#/i, $line))){ $line = <$ruleFile>;
} return $line;
}
sub adaptRuleSizes{ foreach my $r(keys %nodeRules){ foreach my $p(qw(iconSize labelOffset labelSize shieldSize size)){ if(defined $nodeRules{$r}{$p}){ if(grep /:/, $nodeRules{$r}{$p}){ my $old = $nodeRules{$r}{$p};
my $new = scaleSize($nodeRules{$r}{$p}, $nodeRules{$r}{'fromscale'}, $nodeRules{$r}{'toscale'});
$nodeRules{$r}{$p}= $new;
if(cv('debug')eq "1"){ print "RULES/scale/node: $old -> $new\n";
} } } }} foreach my $r(keys %wayRules){ foreach my $p(qw(bordersize labelsize labeloffset size)){ if(defined $wayRules{$r}{$p}){ if(grep /:/, $wayRules{$r}{$p}){ my $kv = $wayRules{$r}{'keyvalue'};
my $old = $wayRules{$r}{$p};
my $new = 0;
$new = scaleSize($wayRules{$r}{$p}, $wayRules{$r}{'fromscale'}, $wayRules{$r}{'toscale'});
$wayRules{$r}{$p}= $new;
if(cv('debug')eq "1"){ print "RULES/scale/way: $kv $p $old to $new\n";
} } } }}}
sub scaleSize{ my($str, $fromScale, $toScale)= @_;
my @tmp = split /:/, $str;
my $lower = $tmp[0];
my $upper = $tmp[1];
my $newSize = 0;
my $scale = getScale();
if(cv('rulescaleset')ne "0"){$scale = cv('rulescaleset')};
if($scale < $fromScale){ $newSize = $upper;
} elsif($scale > $toScale){ $newSize = $lower;
} else{ my $percent =($scale - $fromScale)/($toScale - $fromScale);
$newSize = $upper - $percent *($upper - $lower);
} $newSize = int($newSize * 10)/ 10;
return $newSize;
}
sub createLegend{
# TODO Auto size
my $nx = 80;
my $ny = 80;
my $ey = 1.5 * $ny;
my $sx = 700;
my $tx = 200;
my $ty = $ey / 2;
my $fs = 40;
my $actualLine = 0;
my $preCount = 0;
foreach my $n(keys %nodeRules){ if($nodeRules{$n}{"legend"}eq "yes"){$preCount++;}} foreach my $n(keys %wayRules){ if($wayRules{$n}{"legend"}eq "yes"){$preCount++;}} foreach my $n(keys %areaRules){ if($areaRules{$n}{"legend"}eq "yes"){$preCount++;}} if(cv('debug')eq "1"){print "LEGEND: $preCount elements found\n";}
my $sy = $preCount * $ey;
addToLayer("definitions", "<g id=\"legenddef\" width=\"$sx\" height=\"$sy\" >");
my $color = "white";
my $svgString = "fill=\"$color\"";
drawRect(0, 0, $sx, $sy, 0, $svgString, "definitions");
foreach my $n(keys %nodeRules){ if($nodeRules{$n}{"legend"}eq "yes"){ my $x = $nx;
my $y = $actualLine * $ey + $ny;
if(($nodeRules{$n}{'size'}> 0)and($nodeRules{$n}{'icon'}eq "none")){ my $svgString = "";
if($nodeRules{$n}{'svgstring'}ne ""){ $svgString = $nodeRules{$n}{'svgstring'};
} else{ $svgString = "fill=\"$nodeRules{$n}{'color'}\"";
}
if($nodeRules{$n}{'shape'}eq "circle"){ drawCircle($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions');
} elsif($nodeRules{$n}{'shape'}eq "square"){ drawSquare($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions');
} elsif($nodeRules{$n}{'shape'}eq "triangle"){ drawTriangle($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions');
} elsif($nodeRules{$n}{'shape'}eq "diamond"){ drawDiamond($x, $y, 0, $nodeRules{$n}{'size'}, 0, $svgString, 'definitions');
}
my $textSvgString = createTextSVG(cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef);
drawText($tx,($actualLine+0.5)* $ey + $fs/2, 0, $nodeRules{$n}{'legendlabel'}, $textSvgString, "definitions");
} else{ # TODO icon
} $actualLine ++;
}}
foreach my $w(keys %wayRules){ if($wayRules{$w}{"legend"}eq "yes"){ my($x1, $x2);
$x1 = 0.5 * $nx;
$x2 = 1.5 * $nx;
my $y = $actualLine * $ey + $ny;
my($svg1, $layer1, $svg2, $layer2)= mwWays::createWayParameters($wayRules{$w}, 0, 0, 0);
my @coords =($x1, $y, $x2, $y);
if($svg2 ne ""){ drawWay(\@coords, 0, $svg2, "definitions", undef);
} drawWay(\@coords, 0, $svg1, "definitions", undef);
my $textSvgString = createTextSVG(cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef);
drawText($tx,($actualLine+0.5)*$ey + $fs/2, 0, $wayRules{$w}{'legendlabel'}, $textSvgString, "definitions");
$actualLine++;
}}
foreach my $a(keys %areaRules){ if($areaRules{$a}{"legend"}eq "yes"){ my($x1, $x2);
my($y1, $y2);
$x1 = 0.7 * $nx;
$x2 = 1.3 * $nx;
$y1 = $actualLine * $ey + 0.7 * $ny;
$y2 = $actualLine * $ey + 1.3 * $ny;
my $color = $areaRules{$a}{'color'};
my $icon = $areaRules{$a}{'icon'};
my $base = $areaRules{$a}{'base'};
my $svgString = $areaRules{$a}{'svgstring'};
if(($svgString eq "")and($icon eq "none")){ $svgString = "fill=\"$color\" ";
}
my @coords =([$x1, $y1, $x2, $y1, $x2, $y2, $x1, $y2, $x1, $y1]);
drawArea($svgString, $icon, \@coords, 0, "definitions");
my $textSvgString = createTextSVG(cv('elementFontFamily'), cv('elementFont'), $fs, "black", undef, undef);
drawText($tx,($actualLine+0.5)*$ey + $fs/2, 0, $areaRules{$a}{'legendlabel'}, $textSvgString, "definitions");
$actualLine++;
}}
addToLayer("definitions", "</g>");
my $posX = 0;
my $posY = 0;
my($sizeX, $sizeY)= getDimensions();
if(cv('legend')eq "2"){ $posX = $sizeX - $sx;
$posY = 0;
}
if(cv('legend')eq "3"){ $posX = 0;
$posY = $sizeY - $sy;
}
if(cv('legend')eq "4"){ $posX = $sizeX - $sx;
$posY = $sizeY - $sy;
}
if((cv('legend')>=1)and(cv('legend')<=4)){ addToLayer("legend", "<use x=\"$posX\" y=\"$posY\" xlink:href=\"#legenddef\" />");
} elsif(cv('legend')== 5){ # separate file
createLegendFile($sx, $sy, "_legend", "#legenddef");
}
}
1;