#!/usr/bin/perl use strict; use warnings; use Getopt::Long; my $title = 'Panorama created with Panotools::Script'; # '<%MAPTITLE>'; # whatever my $apiversion = '2.x'; # '<%APIVERSION>'; # 2.x my $apikey = 'PUTAPIKEYHERE'; # '<%APIKEY>'; # PUTAPIKEYHERE my $centrelat = 90 ; # '<%CENTRELAT>'; # 90 my $centrelon = 0 ; # '<%CENTRELON>'; # -180 my $initialzoom = 4; # '<%INITIALZOOM>'; # 4 my $prefix = './'; # test my $maxzoom = 9; # '<%MAXZOOM>'; # 9 my $maxzoomp1 = 10; # '<%MAXZOOMP1>'; # 10 my $minres = 0; # 4 GetOptions ('title=s' => \$title, 'apikey=s' => \$apikey, 'centrelat=s' => \$centrelat, 'centrelon=s' => \$centrelon, 'initialzoom=i' => \$initialzoom, 'prefix=s' => \$prefix, 'maxzoom=i' => \$maxzoom, 'maxzoomp1=i' => \$maxzoomp1, 'minres=i' => \$minres); print qq@<?xml version="1.0"?> <!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" xmlns:v="urn:schemas-microsoft-com:vml"> <head> <meta http-equiv="content-type" content="text/html/xml; charset=utf-8" /> <meta name="description" content="Based on GMapImageCutter, Richard Milton, Centre for Advanced Spatial Analysis (CASA), University College London (UCL)" /> <meta name="keywords" content="Google, Maps, Image, Images, Tile, Cutter, GMapImageCutter, GMapCreator" /> <title>$title</title> <style type="text/css"> v\\:* { behavior:url(#default#VML); } </style> <script src="http://maps.google.com/maps?file=api&v=$apiversion&key=$apikey" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ var centreLat=$centrelat; var centreLon=$centrelon; var initialZoom=$initialzoom; var imageWraps=false; //SET THIS TO false TO PREVENT THE IMAGE WRAPPING AROUND var map; //the GMap2 itself ///////////////////// //Custom projection ///////////////////// function CustomProjection(a,b){ this.imageDimension=65536; this.pixelsPerLonDegree=[]; this.pixelOrigin=[]; this.tileBounds=[]; this.tileSize=256; this.isWrapped=b; var b=this.tileSize; var c=1; for(var d=0;d<a;d++){ var e=b/2; this.pixelsPerLonDegree.push(b/360); this.pixelOrigin.push(new GPoint(e,e)); this.tileBounds.push(c); b*=2; c*=2 } } CustomProjection.prototype=new GProjection(); CustomProjection.prototype.fromLatLngToPixel=function(latlng,zoom){ var c=Math.round(this.pixelOrigin[zoom].x+latlng.lng()*this.pixelsPerLonDegree[zoom]); var d=Math.round(this.pixelOrigin[zoom].y+(-2*latlng.lat())*this.pixelsPerLonDegree[zoom]); return new GPoint(c,d) }; CustomProjection.prototype.fromPixelToLatLng=function(pixel,zoom,unbounded){ var d=(pixel.x-this.pixelOrigin[zoom].x)/this.pixelsPerLonDegree[zoom]; var e=-0.5*(pixel.y-this.pixelOrigin[zoom].y)/this.pixelsPerLonDegree[zoom]; return new GLatLng(e,d,unbounded) }; CustomProjection.prototype.tileCheckRange=function(tile,zoom,tilesize){ var tileBounds=this.tileBounds[zoom]; if (tile.y<0 || tile.y >= tileBounds) {return false;} if (this.isWrapped) { if (tile.x<0 || tile.x>=tileBounds) { tile.x = tile.x%tileBounds; if (tile.x < 0) {tile.x+=tileBounds} } } else { if (tile.x<0 || tile.x>=tileBounds) {return false;} } return true; } CustomProjection.prototype.getWrapWidth=function(zoom) { return this.tileBounds[zoom]*this.tileSize; } //////////////////////////////////////////////////////////////////////////// function customGetTileURL(a,b) { //converts tile x,y into keyhole string var c=Math.pow(2,b); var d=a.x; var e=a.y; var f="$prefix"; for(var g=0;g<b;g++){ c=c/2; if(e<c){ if(d<c){f+="q"} else{f+="r";d-=c} } else{ if(d<c){f+="t";e-=c} else{f+="s";d-=c;e-=c} } } return f+".jpg" } function getWindowHeight() { if (window.self&&self.innerHeight) { return self.innerHeight; } if (document.documentElement&&document.documentElement.clientHeight) { return document.documentElement.clientHeight; } return 0; } function resizeMapDiv() { //Resize the height of the div containing the map. //Do not call any map methods here as the resize is called before the map is created. var d=document.getElementById("map"); var offsetTop=0; for (var elem=d; elem!=null; elem=elem.offsetParent) { offsetTop+=elem.offsetTop; } var height=getWindowHeight()-offsetTop-16; if (height>=0) { d.style.height=height+"px"; } } function load() { if (GBrowserIsCompatible()) { resizeMapDiv(); var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, "<a href=\\"http://hugin.sourceforge.net/\\">$title</a>"); var copyrightCollection = new GCopyrightCollection("Hugin"); copyrightCollection.addCopyright(copyright); //create a custom picture layer var pic_tileLayers = [ new GTileLayer(copyrightCollection , 0, 17)]; pic_tileLayers[0].getTileUrl = customGetTileURL; pic_tileLayers[0].isPng = function() { return false; }; pic_tileLayers[0].getOpacity = function() { return 1.0; }; var proj=new CustomProjection($maxzoomp1,imageWraps); var pic_customMap = new GMapType(pic_tileLayers, proj, "Pic", {maxResolution:$maxzoom, minResolution:$minres, errorMessage:"This space intentionally left blank"}); //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 GLargeMapControl()); map.addControl(new GMapTypeControl()); map.addControl(new GOverviewMapControl()); map.enableDoubleClickZoom(); map.enableContinuousZoom(); map.enableScrollWheelZoom(); map.setCenter(new GLatLng(centreLat, centreLon), initialZoom, pic_customMap); ///////////////////////////////////////////////////////////////////////////////////// //Add any markers here e.g. // map.addOverlay(new GMarker(new GLatLng(x,y))); ///////////////////////////////////////////////////////////////////////////////////// } } //]]> </script> </head> <body onresize="resizeMapDiv()" onload="load()" onunload="GUnload()"> <div id="map"></div> </body> </html> @; __END__ =head1 NAME gmaptemplate - HTML template for viewing tiled images with the Google Map API =head1 SYNOPSIS gmaptemplate > index.html Options: --title title The content of the HTML <title> tag --prefix prefix File prefix of tiles relative to root directory --apikey key A Google Maps API key --centrelat deg Latitude -90 to 90 --centrelon deg Longitude -180 to 180 --initialzoom num Start zoom level --maxzoom num Maximum zoom level --maxzoomp1 num Maximum zoom level +1 --minres num Minimum zoom level =head1 DESCRIPTION B<gmaptemplate> is a simple tool to write a HTML file based on a template in the Google Map Image Cutter tool: L<http://www.casa.ucl.ac.uk/software/googlemapimagecutter.asp> Note: to use this HTML online you will need a Google Maps API key from L<http://code.google.com/apis/maps/> =head1 LICENSE The Google Map Image Cutter software and documentation is the property of CASA and University College London. The software is provided free under the terms of the GNU Lesser General Public License. CASA and University College London do not accept any liability for any losses arising from the use of this software. =head1 SEE ALSO L<http://hugin.sourceforge.net/> =head1 AUTHOR Bruno Postle - January 2010. =cut