sub generateGMap
{ opt_default(level=>6, posterize=>16, colors=>255, cgr=>0, apikey=>"YOUR_GOOGLE_MAP_KEY_HERE");
my @argv = opt_get(@_);
my $file = shift @argv;
my $level = opt_val("level");
my $javascript = opt_val("javascript");
my $posterize = opt_val("colors");
my $cgr = opt_val("cgr");
my $apikey = opt_val("apikey");
$posterize = 16 if($cgr);
$level = 3 if ($level < 3);
my $filename = basename($file);
my $name = $filename;
if($name =~ /(.*)\..*$/){
$name = $1;
}
mkdir($name);
my ($width, $height);
if(`identify $file` =~ /\s(\d+)x(\d+)\s/){
$width = $1;
$height = $2;
}else{
die("Either ImageMagick is not available, or the given file is not a proper image.");
}
my $maxwidth = 256 * 2 ** ($level - 1);
if($width == $height){
if($width == $maxwidth && $file =~ /png$/){
system(sprintf("cp %s %s/level%d.png", $file, $name, $level - 1));
}else{
system(sprintf("convert +dither -colors $posterize -size %dx%d -resize %dx%d %s %s/level%d.png", $width, $height, $maxwidth, $maxwidth, $file, $name, $level - 1));
}
}else{
my ($xdif, $ydif, $size) = (0,0, $width);
if($width > $height){
$size = $width;
$ydif = int(($width - $height) / 2); }else{
$size = $height;
$xdif = int(($height - $width) / 2); }
system(sprintf("convert +dither -colors $posterize -extent %dx%d -roll +%s+%s %s %s/%s.png", $size, $size, $xdif, $ydif, $file, $name, $name));
system(sprintf("convert +dither -colors $posterize %s/%s.png -size %dx%d -resize %dx%d %s/level%d.png", $name, $name, $size, $size, $maxwidth, $maxwidth, $name, $level - 1));
}
chdir($name);
my $maxlevel = $level - 1;
for(my $i = $maxlevel; $i >= 0; $i --){
my $tiles = 2 ** $i;
my $size = $tiles * 256;
my $pid = fork();
if($pid){
}elsif(defined $pid){
my $j = $i - 1;
exit if ($j < 0);
system(sprintf("convert +dither -colors $posterize level%d.png -size %dx%d -resize %dx%d level%d.png", $i, $size, $size, $size/2, $size/2, $j)) unless(-e "level$j.png");
exit;
}else{
die("fork failed.");
}
system("convert +dither -colors $posterize level$i.png -crop 256x256 level$i-%d.png");
for(my $y = 1; $y <= $tiles; $y ++){
for(my $x = 1; $x <= $tiles; $x ++){
rename(sprintf("level%d-%d.png", $i, ($y - 1) * $tiles + ($x - 1)), sprintf("level%d-%d-%d.png", $i, $x - 1, $y - 1));
}
}
waitpid($pid, 0);
}
open(OUT, '>' . 'index.html') || die($!);
print OUT << "__HTML__"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <title>Google Map View of $name - generated by G-language GAE</title>
<script src="http://maps.google.com/maps?file=api&v=2.156&key=$apikey" type="text/javascript" charset="utf-8"></script> <script src="http://googlemaps.googlermania.com/gmapkit/api?js=gmapkitmapcontrols3d.js" type="text/javascript"></script>
<script type="text/javascript"> //<![CDATA[
var map;
function customGetTileURL(a,b) { return "level" + b + "-" + a.x + "-" + a.y + ".png" }
function resize(){ var map_obj=document.getElementById("map"); var disp=getDispSize(); map_obj.style.width=(disp.width - 20)+"px"; map_obj.style.height=(disp.height - 20)+"px"; if( map ){ map.checkResize(); map.panTo(new GLatLng(0, 0)); } }
function getDispSize(){ if(document.all){ if(window.opera){ return {width:document.body.clientWidth,height:document.body.clientHeight}; }else{ return {width:document.documentElement.clientWidth,height:document.documentElement.clientHeight}; } } else if(document.layers || document.getElementById){ return {width:window.innerWidth,height:window.innerHeight}; } }
function xy2latlng(x,y) { var pi = Math.PI; var rd = pi / 180; var length = 8192; var lng = (x * 360) / length - 180; var tmp = (2 * pi * y / length) - pi; var lat = (pi / 4 - Math.atan2(Math.exp(tmp), 1)) * 2 / rd; if (lat > 85.05) lat = 85.05; if (lat < -85.05) lat = -85.05; return [lat, lng]; }
function load() { if (GBrowserIsCompatible()) { resize();
var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, "<a href=\\"http://www.g-language.org/\\" target=\\"_blank\\"><img src=\\"http://restauro-g.iab.keio.ac.jp/Res-Pic/glang.png\\" border=0></a>"); var copyrightCollection = new GCopyrightCollection(); copyrightCollection.addCopyright(copyright);
// Create a new Mercator projection instance var zoomlevel = $maxlevel; var projection = new GMercatorProjection(18);
// add an exposed copy of the tileBounds array projection.tileBounds = []; var c = 1; for(var d = 0; d <= 17; d++){ projection.tileBounds.push(c); c *= 2 }
// == a method that checks if the y value is in range // == but *doesnt* wrap the x value == projection.tileCheckRange = function(a,b,c){ var d=this.tileBounds[b]; if (a.y<0||a.y>=d) { return false; }
if(a.x<0||a.x>=d){ return false; } return true }
// == a method that returns the width of the tilespace == projection.getWrapWidth = function(zoom) { return 99999999999999; }
//create a custom picture layer var pic_tileLayers = [ new GTileLayer(copyrightCollection , 0, 17)]; pic_tileLayers[0].getTileUrl = customGetTileURL; pic_tileLayers[0].isPng = function(){ return true}; pic_tileLayers[0].getOpacity = function() { return 1.0; }; var pic_customMap = new GMapType(pic_tileLayers, projection, "View1", {maxResolution:zoomlevel, minResolution:1, errorMessage:"Data not available"});
//Now create the custom map. Would normally be G_NORMAL_MAP,G_SATELLITE_MAP,G_HYBRID_MAP map = new GMap2(document.getElementById("map"), {mapTypes:[pic_customMap]}); map.addControl(new GMapKitMapControls3d()); //GLargeMapControl()); map.addControl(new GMapTypeControl()); map.addControl(new GOverviewMapControl()); map.enableDoubleClickZoom(); map.enableContinuousZoom(); map.enableScrollWheelZoom(); map.setCenter(new GLatLng(0, 0), 2, pic_customMap);
///////////////////////////////////////////////////////////////////////////////////// //Add any markers here e.g. // map.addOverlay(new GMarker(new GLatLng(x,y))); /////////////////////////////////////////////////////////////////////////////////////
$javascript; } } __HTML__
if($cgr){
print OUT << "__HTML__"
function doSearch() { map.clearOverlays();
var seq = document.getElementById('query').value.toLowerCase(); if(seq.length < 1) return; if(seq.match(/[^atgcnATGCN]/)) return;
var i = 0; var j = 0; for(i = 0; i <= seq.length; i ++){ if(seq.substr(i,1) == 'n') j ++; }
var sequences = new Array(); sequences.push(seq);
for(i = 0; i<j; i++){ for(var n = 0; n < sequences.length; n ++){ if(sequences[n].match(/n/)){ sequences.push(sequences[n].replace(/n/, 't')); sequences.push(sequences[n].replace(/n/, 'g')); sequences.push(sequences[n].replace(/n/, 'c')); sequences[n] = sequences[n].replace(/n/, 'a'); } } }
for (i = 0; i <= sequences.length; i ++){ if(sequences[i] == null){continue;} var width = 4096/Math.pow(2, seq.length - 1); var ud = sequences[i]; var rl = sequences[i]; ud = ud.replace(/[ac]/g, 0); ud = ud.replace(/[gt]/g, 1); rl = rl.replace(/[ag]/g, 0); rl = rl.replace(/[ct]/g, 1); var x = parseInt(ud, 2) * width; var y = parseInt(rl, 2) * width; var x1 = xy2latlng(x,y); var x2 = xy2latlng(x + width, y); var x3 = xy2latlng(x + width, y + width); var x4 = xy2latlng(x + width/2, y + width); var x5 = xy2latlng(x, y + width);
var polygon = new GPolygon([ new GLatLng(x1[0], x1[1]), new GLatLng(x2[0], x2[1]), new GLatLng(x3[0], x3[1]), new GLatLng(x4[0], x4[1]), new GLatLng(x4[0], x5[1]), new GLatLng(x1[0], x1[1]) ]); if(seq.length > 6) map.addOverlay(new GMarker(new GLatLng(x1[0], x1[1])));
map.addOverlay(polygon, '#000000', 3, 0.5, '#FF0000', 0.5); } }
//]]> </script> </head> <body onresize="resize()" onload="load()" onunload="GUnload()"> <div style="z-index:100;position:absolute;left:40%;margin-top:10px;"> Search: <input type="search" name="query" id="query" placeholder="Search" autosave="gbt" results="10" size=30 onKeyUp="doSearch()"/> </div> <div id="map" style="z-index:0;position:absolute"></div> </body> </html>
__HTML__
}else{
print OUT << "__HTML__" //]]> </script> </head> <body onresize="resize()" onload="load()" onunload="GUnload()"> <div id="map"></div> </body> </html>
__HTML__ }
close(OUT);
chdir("../");
msg_error("Google Map View is generated in $name directory.\n"); } |