KML-PolyMap
view release on metacpan or search on metacpan
lib/Geo/KML/PolyMap.pm view on Meta::CPAN
hexadecimal number, with 8 bits each for opacity (transparency), blue, green, and red. Note that the ordering of values is
different from usual web color specifications, which are RGB. Examples:
FFFF0000 = pure blue
80FF0000 = blue, 50% transparency
00FF0000 = blue, fully transparent
FF00FF00 = pure green
FF0000FF = pure red
Colors for each bin are constructed by linear interpolation between the optional parameters startcolor and endcolor. The
interpolation is not weighted by bin values; it is just a simple interpolation along the line between start and end in RGB space.
=cut
sub generate_kml_file {
my %args = @_;
return _generate_kml_file($args{entities},$args{placename},$args{data_desc},
$args{nbins},$args{kmlfh},$args{startcolor},$args{endcolor});
}
# _generate_kml_file(entity[]& entities,string placename,string data_desc,
# int nbins,fh filehandle,OPT string startcolor,OPT string endcolor);
# Fills filehandle with the lines of a KML file constituting a display
# for the given entities, split into nbins placemarks.
sub _generate_kml_file($$$$$;$$) {
my ($entities,$placename,$datadesc,$nbins,$fh,$startcolor,$endcolor) = @_;
# Refactored to expose bins and colors for legend generation in KMZ
my $bins_colors = _generate_bins_colors($entities,$nbins,
$startcolor,$endcolor);
# Map data parameter in entities to altitude
altitude_map($entities,"data");
return _generate_kml($entities,$placename,$datadesc,$nbins,
$bins_colors->[0],$bins_colors->[1],$fh);
}
# _generate_kml(entity[]& entities,string placename,string data_desc,
# int nbins,bin[]& bins,string[]& colors,fh file
# OPT string legend_file_name)
# Internal function taking in entities, bins, and colors, and generating
# the associated KML file to the filehandle file
# Return as specified in (user-visible) generate_kml_file
sub _generate_kml($$$$$$$;$) {
my ($entities,$placename,$datadesc,$nbins,$bins,$colors,$fh,$legend_file_name) = @_;
my @kml_file;
push(@kml_file,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
push(@kml_file,"<kml xmlns=\"http://earth.google.com/kml/2.0\">");
push(@kml_file,"<Document>");
if (defined $legend_file_name) {
push(@kml_file,"<ScreenOverlay>");
push(@kml_file,"<description>$placename $datadesc</description>");
push(@kml_file,"<name>Legend</name>");
push(@kml_file,"<Icon>");
push(@kml_file,"<href>$legend_file_name</href>");
push(@kml_file,"</Icon>");
push(@kml_file,"<overlayXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>");
push(@kml_file,"<screenXY x=\"0\" y=\"1\" xunits=\"fraction\" yunits=\"fraction\"/>");
push(@kml_file,"<rotationXY x=\"0\" y=\"0\" xunits=\"fraction\" yunits=\"fraction\"/>");
push(@kml_file,"<size x=\"0\" y=\"0\" xunits=\"pixels\" yunits=\"pixels\"/>");
push(@kml_file,"<rotation>0</rotation>");
push(@kml_file,"</ScreenOverlay>");
}
print $fh join('',@kml_file);
@kml_file=();
for (my $i=0;$i<(scalar @$bins);$i++) {
my $bin = $bins->[$i];
my $entityidx = $bin->{entityidx};
#carp $entityidx."\n";
#carp @$entityidx."\n";
# Fold singletons into a list
#print "Bin $i contains ".join(',',@$entityidx)."\n";
my @selected_entities = ( @$entities[@$entityidx] );
generate_kml_placemark(
\@selected_entities,
$placename." bin ".($i+1),
$datadesc." less than/equal to ".$bin->{binbound},
$colors->[$i],
$fh);
#my $placemark=[""];
#push(@kml_file,@$placemark);
}
push(@kml_file,"</Document>");
push(@kml_file,"</kml>");
print $fh join('',@kml_file);
return;
}
# altitude_map(entity[]& entities,string fieldname)
# MODIFIES entities - adds altitude attribute based on data value in fieldname for each entity
# returns none
sub altitude_map($$) {
my ($ents,$fname) = @_;
my $minval = $ents->[0]->{$fname};
my $maxval = $ents->[0]->{$fname};
foreach my $ent (@$ents) {
if ($ent->{$fname} < $minval) {
$minval = $ent->{$fname};
} elsif ($ent->{$fname} > $maxval) {
$maxval = $ent->{$fname};
}
}
# Use a 3km altitude scale
my $alt_scale = 3000;
# Place bottom of range 50m above ground to avoid artifacting
my $min_height = 50;
my $multiplier = $alt_scale/($maxval-$minval);
my $offset = $minval - $min_height;
foreach my $ent (@$ents) {
$ent->{altitude} = ($ent->{$fname}-$offset) * $multiplier;
}
( run in 1.169 second using v1.01-cache-2.11-cpan-e1769b4cff6 )