KML-PolyMap
view release on metacpan or search on metacpan
lib/Geo/KML/PolyMap.pm view on Meta::CPAN
my $legend = generate_legend($bins_colors->[0],$bins_colors->[1],$FONT_PATH);
# KML must be rendered to disk
my ($tmp_fh,$tmp_fn) = tempfile();
_generate_kml($entities,$placename,$datadesc,$nbins,
$bins_colors->[0],$bins_colors->[1],$tmp_fh,$legend_name);
close($tmp_fh);
# Construct the KMZ/ZIP archive and add the kml and legend files
my $kmz = Archive::Zip->new();
#my $kml_member = $kmz->addString(join("",@$kml),"generated_map.kml");
my $kml_member = $kmz->addFile($tmp_fn,"generated_map.kml");
$kml_member->desiredCompressionMethod( COMPRESSION_DEFLATED );
my $leg_member = $kmz->addString($$legend,$legend_name);
$leg_member->desiredCompressionMethod( COMPRESSION_STORED );
# Dump the zip data to the file
#my $kmz_fh;
#open($kmz_fh,">$kmzname") or die "Couldn't create output file in generate_kmz";
if ($kmz->writeToFileHandle($kmzfh) != AZ_OK) {
die "Couldn't write to output file in generate_kmz";
}
#close($kmzfh);
unlink($tmp_fn);
return;
}
sub _kmeans {
my ($data,$clusters,$npass) = @_;
if ($clusters > scalar(@$data)) {
warn "More clusters ($clusters) than data points (".scalar(@$data).")!";
my @result;
for (my $i=0;$i < scalar(@$data); $i++) {
push (@result,$i);
}
return \@result;
}
my %cluster_centroids = ();
for (my $i=0; $i < $clusters; $i++) {
my $idx;
do {
$idx = int(rand(scalar(@$data)));
} while (defined($cluster_centroids{$idx}));
$cluster_centroids{$idx} = 1;
}
my $rcenters = [];
foreach my $cent (keys %cluster_centroids) {
push (@$rcenters,$data->[$cent]);
}
#Assign points to clusters
my $assn = assign_clusters($data,$rcenters);
for (;$npass>0;$npass--) {
#Recalculate centroids
$rcenters = recalculate_centroids($data,$rcenters,$assn);
#Assign points to clusters
my $newassn = assign_clusters($data,$rcenters);
# End the iterations if the assignments don't change
my $done = 1;
for (my $i = 0;$i<scalar(@$newassn) and $done; $i++) {
$done = ($assn->[$i] == $newassn->[$i])
}
if ($done) {
$npass = 0;
} else {
$assn = $newassn;
}
}
return $assn;
}
sub assign_clusters {
my ($data,$centroids) = @_;
my @assn=();
$#assn = scalar(@$data)-1;
for (my $di = 0; $di < scalar(@$data); $di++) {
my $pt = $data->[$di];
my $dist = abs($pt-$centroids->[0]);
my $idx = 0;
for (my $i=1;$i<scalar(@$centroids);$i++) {
my $d2 = abs($pt-$centroids->[$i]);
if ($d2 < $dist) {
$dist = $d2;
$idx = $i;
}
}
$assn[$di] = $idx;
}
# This inverted loop loses on performance
#my @dists;
#for (my $c=0;$c<scalar(@$centroids);$c++) {
# for (my $i=0;$i<scalar(@$data);$i++) {
# my $dist = abs($data->[$i]-$centroids->[$c]);
# if (not defined($dists[$i]) or ($dists[$i] > $dist)) {
# $dists[$i] = $dist;
# $assn[$i] = $c;
# }
# }
#}
return \@assn;
}
sub recalculate_centroids {
my ($data,$centroids,$assignments) = @_;
my @means;
my @counts;
for (my $c=0;$c<scalar(@$centroids);$c++) {
push(@means,0);
push(@counts,0);
}
for (my $i = 0;$i < scalar(@$data);$i++) {
my $t = $assignments->[$i];
$means[$t] += $data->[$i];
$counts[$t]++;
}
( run in 1.602 second using v1.01-cache-2.11-cpan-71847e10f99 )