mapweaver/mwWays.pm

285 lines
9.6 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 mwWays;
use strict;
use warnings;
use OSM::osm 8.3;
use mwConfig;
use mwFile;
use mwRules;
use mwMap;
use mwMisc;
use mwWayLabel;
use mwCoastLines;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(processWays
getCoastWays
createDirectory
);
my $areasOmitted = 0;
my $areasDrawn = 0;
my $areaLabels = 0;
my $areaLabelsOmitted = 0;
my @coastWays =();
sub processWays{
print "drawing ways/areas...\n";
my $nodesRef; my $tagRef;
($nodesRef, $tagRef)= getWayPointers();
my($lonRef, $latRef, $nodeTagRef)= getNodePointers();
foreach my $wayId(keys %$nodesRef){ my @tags = @{$$tagRef{$wayId}};
my $tagsString = "";
# coast
my $v = getValue("natural", \@tags);
if((defined $v)and($v eq "coastline")){ push @coastWays, $wayId;
}
# WAYS
my $ruleRef = getWayRule(\@tags);
if(defined $ruleRef){ my @nodes = @{$$nodesRef{$wayId}};
my $layer = getValue("layer", $$tagRef{$wayId});
if(! defined $layer){$layer = 0;}
# TODO check for numeric!!!
my $direction = 0;
my $ow = getValue("oneway", $$tagRef{$wayId});
if(defined $ow){ if(($ow eq "yes")or($ow eq "true")or($ow eq "1")){$direction = 1;} if($ow eq "-1"){$direction = -1;} }
my $bridge = getValue("bridge", $$tagRef{$wayId});
if(defined $bridge){ if(($bridge eq "yes")or($bridge eq "true")){$bridge = 1;}else{$bridge = 0;} } else{$bridge = 0;}
my $tunnel = getValue("tunnel", $$tagRef{$wayId});
if(defined $tunnel){ if(($tunnel eq "yes")or($tunnel eq "true")){$tunnel = 1;}else{$tunnel = 0;} } else{$tunnel = 0;}
my($svg1, $layer1, $svg2, $layer2)= createWayParameters($ruleRef, $layer, $bridge, $tunnel);
drawWay(\@nodes, 1, $svg1, undef, $layer1);
if($svg2 ne ""){ drawWay(\@nodes, 1, $svg2, undef, $layer2);
}
my $size = $$ruleRef{'size'};
if((cv('oneways')eq "1")and($direction != 0)){ addOnewayArrows(\@nodes, $direction, $size, $layer);
}
# LABEL WAY
if(cv('ignorelabels')eq "0"){ if($$ruleRef{'label'}ne "none"){
my $name = ""; my $ref1; my @names;
if(grep /shield/i, $$ruleRef{'label'}){ ($name, $ref1)= createLabel(\@tags, "ref",0, 0);
my $ref = $name;
if(grep /;/, $ref){ my @a = split /;/, $ref;
$ref = $a[0];
}
if($ref ne ""){ @names =($ref);
$name = $$ruleRef{'label'}. ":$ref";
# print "DRAW WAY: name set to $name\n";
} else{ @names =();
$name = "";
}
# print "WAY: name for shield >$name<\n";
} else{ ($name, $ref1)= createLabel(\@tags, $$ruleRef{'label'}, 0, 0);
@names = @$ref1;
$name = labelTransform($name, $$ruleRef{'labeltransform'});
}
if((cv('nolabel')eq "1")and($name eq "")){$name = "NO LABEL";}
if($name ne ""){
addWayLabel($wayId, $name, $ruleRef);
} if((cv('dir')eq "1")and($$ruleRef{'direxclude'}eq "no")){ if(cv('grid')> 0){ foreach my $node(@nodes){ foreach my $name(@names){ my $sq = gridSquare($$lonRef{$node}, $$latRef{$node}, cv('grid'));
if(defined $sq){ addToDirectory($name, $sq);
} } } } else{ foreach my $name(@names){ addToDirectory($name, undef);
} } } } # label
}# ignorelabels
}
# AREAS
$ruleRef = getAreaRule(\@tags);
my @nodes = @{$$nodesRef{$wayId}};
if((defined $ruleRef)and($nodes[0] == $nodes[-1])){ my $color = $$ruleRef{'color'};
my $icon = $$ruleRef{'icon'};
my $base = $$ruleRef{'base'};
my $svgString = $$ruleRef{'svgstring'};
my $size = areaSize(\@nodes);
my @ways = [@nodes];
if(($svgString eq "")and($icon eq "none")){ $svgString = "fill=\"$color\" ";
}
if($size > cv('minareasize')){ if($base eq "yes"){ drawArea($svgString, $icon, \@ways, 1, "base");
} else{ drawArea($svgString, $icon, \@ways, 1, "area");
} $areasDrawn++;
# DRAW label
if($$ruleRef{'label'}ne "none"){ $areaLabels++;
if($size > cv('minarealabelsize')){ # text
my($name, $ref1)= createLabel(\@tags, $$ruleRef{'label'},0, 0);
$name = labelTransform($name, $$ruleRef{'labeltransform'});
# pos
my($lon, $lat)= areaCenter($$nodesRef{$wayId});
# draw
my $labelFont = $$ruleRef{'labelfont'};
my $labelFontFamily = $$ruleRef{'labelfontfamily'};
my $labelSize = $$ruleRef{'labelsize'};
my $color = $$ruleRef{'labelcolor'};
my $labelBold = $$ruleRef{'labelbold'};
my $labelItalic = $$ruleRef{'labelitalic'};
my $labelHalo = $$ruleRef{'labelhalo'};
my $labelHaloColor = $$ruleRef{'labelhalocolor'};
my $svgText = createTextSVG($labelFontFamily, $labelFont, $labelBold, $labelItalic, $labelSize, $color, $labelHalo, $labelHaloColor);
mwLabel::placeLabelAndIcon($lon, $lat, 0, 0, $name, $svgText, "none", 0, 0, "arealabels");
} else{ $areaLabelsOmitted++;
} }
} else{ $areasOmitted++;
}
}# Area
}
print "$areasDrawn areas drawn, $areasOmitted omitted because they are too small\n";
print "$areaLabels area labels total, $areaLabelsOmitted omitted because belonging areas were too small\n";
my $cw = scalar @coastWays;
if(cv('verbose')){print "$cw coast line ways found.\n";}
preprocessWayLabels();
createWayLabels();
if($cw > 0){ processCoastLines(\@coastWays);
}}
# ----------------------------------------------------------------------------
sub createWayParameters{ my($ruleRef, $layer, $bridge, $tunnel)= @_;
my $svg1 = ""; my $layer1 = 0;
my $svg2 = ""; my $layer2 = 0;
my %dashDefinition =();
@{$dashDefinition{1}}=("round", "20,20");
@{$dashDefinition{2}}=("round", "44,20");
@{$dashDefinition{3}}=("round", "28,20");
@{$dashDefinition{4}}=("round", "12,20");
@{$dashDefinition{10}}=("round", "8,8");
@{$dashDefinition{11}}=("round", "16,16");
@{$dashDefinition{12}}=("round", "24,24");
@{$dashDefinition{13}}=("round", "32,32");
@{$dashDefinition{14}}=("round", "40,40");
@{$dashDefinition{20}}=("round", "0,8,0,16");
@{$dashDefinition{21}}=("round", "0,16,0,32");
@{$dashDefinition{22}}=("round", "0,24,0,48");
@{$dashDefinition{23}}=("round", "0,32,0,48");
@{$dashDefinition{30}}=("butt", "4,4");
@{$dashDefinition{31}}=("butt", "8,8");
@{$dashDefinition{32}}=("butt", "12,12");
@{$dashDefinition{33}}=("butt", "4,12");
@{$dashDefinition{34}}=("butt", "4,20");
@{$dashDefinition{35}}=("butt", "8,20");
if(cv('autobridge')eq "0"){ $layer = 0;
}
if(($$ruleRef{'svgstringtop'}ne "")or($$ruleRef{'svgstringbottom'}ne "")){
$svg1 = $$ruleRef{'svgstringtop'};
$svg2 = $$ruleRef{'svgstringbottom'};
# TODO layer
$layer1 = $layer;
$layer2 = $layer;
} else{
my $size = $$ruleRef{'size'};
my $color = $$ruleRef{'color'};
my $lc = "round";
my $lj = "round";
my $dash = "";
if($$ruleRef{'dash'}ne ""){ if(! grep /,/, $$ruleRef{'dash'}){ my @ds = @{$dashDefinition{$$ruleRef{'dash'}}};
$lc = $ds[0];
my $style = $ds[1];
$dash = "stroke-dasharray=\"$style\" ";
} else{ $lc = $$ruleRef{'dashcap'};
my $style = $$ruleRef{'dash'};
$dash = "stroke-dasharray=\"$style\"";
} }
# top(actual way) $svg1 = "stroke=\"$color\" stroke-width=\"$size\" stroke-linecap=\"$lc\" fill=\"none\" stroke-linejoin=\"$lj\" " . $dash;
$layer1 = $layer + $size / 100;
my $bs = $$ruleRef{'bordersize'};
$lc = "round";
$dash = "";
if(cv('autobridge')eq "1"){ # TODO bridge/tunnel
if($bridge == 1){ $lc = "butt";
$bs += 3; # TODO config value
} elsif($tunnel == 1){ $lc = "butt";
$dash = "stroke-dasharray=\"10,10\" ";
$bs += 3;
} }
# bottom(border) if($bs > 0){ $size = 2 * $bs + $$ruleRef{'size'};
$color = $$ruleRef{'bordercolor'};
$svg2 = "stroke=\"$color\" stroke-width=\"$size\" stroke-linecap=\"$lc\" fill=\"none\" stroke-linejoin=\"$lj\" " . $dash;
$layer2 = $layer - 0.3 + $size / 100;
} else{ $svg2 = "";
$layer2 = 0;
}
}
return($svg1, $layer1, $svg2, $layer2);
}
# ---------------------------------------------------------------------------------
sub createDirectory{ my $directoryName;
my $dirFile;
$directoryName = cv('out');
$directoryName =~ s/\.svg/\_streets.txt/;
setConfigValue("directoryname", $directoryName);
print "creating dir file $directoryName ...\n";
open($dirFile, ">", $directoryName)or die("can't open dir file $directoryName\n");
my $ref = getDirectory();
my %directory = %$ref;
if(cv('grid')eq "0"){ foreach my $street(sort keys %directory){ $street = replaceHTMLCode($street);
print $dirFile "$street\n";
}} else{ foreach my $street(sort keys %directory){ my $streetSanitized = replaceHTMLCode($street);
print $dirFile "$streetSanitized\t";
foreach my $square(sort keys %{$directory{$street}}){ print $dirFile "$square ";
} print $dirFile "\n";
}} close($dirFile);
}
1;