Data serving scripts

From World Wind Wiki

(Difference between revisions)
Jump to: navigation, search
Revision as of 08:36, 11 January 2018 (edit)
Monday (Talk | contribs)

← Previous diff
Current revision (21:14, 21 August 2019) (edit) (undo)
F0urtyfive (Talk | contribs)
m (Reverted edits by Monday (Talk); changed back to last version by 164.67.235.138)
 
Line 1: Line 1:
-hll20180112+==PHP scripts==
-http://www.outletmichaelkorsonline.us.com+===Images===
-http://www.coach-outletonlines.us.com+<pre>
-http://www.mulberry-bags.me.uk+<?
-http://www.ralphlaurensale-clearance.me.uk+// This scipt is for serving out your own WW Cached tiles to World Wind, useful for own imagery and for working "off line"
-http://www.adidasnmdr1.us.com+// This script can be named what ever you want, it is controlled via a World Wind XML
-http://www.ultraboost.us+//
-http://wwwcanadagoose-uk.com.co+// thanks to MaurizoZA and Nowak for the script
-http://www.longchampoutletus.us.com+ 
-http://www.philippplein-outlet.com+$X = $_GET['X'];
-http://www.polooutlets.us.org+$Y = $_GET['Y'];
-http://www.katespadeonlineoutlet.us.com+$L = $_GET['L'];
-http://www.canadagoosesalejackets.us.com+$T = $_GET['T'];
-http://www.hermes.us.org+ 
-http://www.ralphlaurensale-clearance.org.uk+function addzeros($string){
-http://www.burberry-outlet-canada.ca+ //echo $string;
-http://www.cheapoakleysunglassesofficial.us.com+ if(strlen($string) >= 4){
-http://www.cheapraybans.com.co+ return $string;
-http://www.air-max2018.us.com+ }
-http://www.red-bottoms.us.com+ 
-http://www.pandorajewelrypandora.us.com+ $string = "0" . "$string";
-http://www.yeezyboost-350.us.com+ 
-http://www.canadagoosejacketscanada.ca+ if(strlen($string) < 4){
-http://www.uggbootsonline.us+ $string = addzeros($string);
-http://www.canadagoosesaleoutlet.us.com+ }
-http://www.uggbootswomen.us.com+ return $string;
-http://wwwcanadagoose-jacketsuk.com.co+}
-http://www.polooutlet.in.net+ 
-http://www.canadagooseoutletus.us.com+ 
-http://www.airmax-2018.com+$ext = ".jpg";
-http://www.adidasyeezyboost-350.us.com+ 
-http://www.hermes-handbags.us+// Change the following to the location of your local root cache folder
-http://www.michaelkorsoutlet.us.org+$url = 'D:/cache/';
-http://www.cheapnfljerseysnflwholesale.us.com+$doneurl = $url . $T . "/" . $L . "/" . addzeros($Y) . "/" . addzeros($Y) .
-http://www.uggsboots.name+"_" . addzeros($X) . $ext;
-http://www.adidas-yeezyshoes.us.com+ 
-http://www.ralphlauren-outlet.me.uk+// Debug tools
-http://www.ralphlauren.me.uk+//header("Location: $doneurl");
-http://www.pandora.us.com+//exit;
-http://www.michaelkorsfactoryoutletsale.us.com+// print ($doneurl);
-http://www.pandora-charms.us.org+//exit;
-http://www.uggsoutletonlines.us.com+ 
-http://www.timberland-outlets.us+ $tileData = file_exists($doneurl) ? file_get_contents($doneurl) :
-http://www.cheapnfljerseysofficial.us.com+false;
-http://www.harden-vol1.com+ if ($tileData === false) die();
-http://www.uggoutletstore.name+ 
-http://www.toryburchoutletonline.com.co+ @header('Content-type: image/jpeg');
-http://www.polo-ralphlauren.in.net+ print($tileData);
-http://www.canadagooseoutlet.name+ 
-http://www.ralphlaurenoutlet.in.net+?>
-http://www.michael-korsoutlet.ca+</pre>
-http://www.uggoutletonline.name+ 
-http://www.cheapjordans.in.net+===Elevation===
-http://www.nikeoutlet.us.com+*simple serving script:
-http://www.nikeairmax.in.net+<pre>
-http://www.uggs-boots.us.org+<?
-http://www.yeezyboost.org.uk+// This scipt is for serving out your own WW Cached tiles to World Wind, useful for own imagery and for working "off line"
-http://www.nike-store.us.com+// This script can be named what ever you want, it is controlled via a World Wind XML
-http://www.uggsaustralia.fr+//
-http://www.uggsoutlet.cc+// thanks to MaurizoZA and Nowak for the script
-http://www.coachfactoryoutlet-storeonline.us.com+ 
-http://www.moncler-outlet.us.org+$X = $_GET['X'];
-http://www.air-jordans.us.com+$Y = $_GET['Y'];
-http://www.pandoracharms.us.com+$L = $_GET['L'];
-http://www.oakley.nom.co+$T = $_GET['T'];
-http://www.coachhandbagsoutlet.us.com+ 
-http://www.moncleroutlets.us.org+function addzeros($string){
-http://www.uggscanadaugg.ca+ //echo $string;
-http://www.christianlouboutinoutlet.us+ if(strlen($string) >= 4){
-http://www.outletlouisvuitton.us.com+ return $string;
-http://www.jordanretro.name+ }
-http://www.guccihandbagsoutlet.us.com+ 
-http://www.oakleysunglassesforwomen.us.com+ $string = "0" . "$string";
-http://www.michael-korshandbags.me.uk+ 
-http://www.outletuggoutlet.us.com+ if(strlen($string) < 4){
-http://www.uggs-boots.fr+ $string = addzeros($string);
-http://www.salvatoreferragamoshoes.us.com+ }
-http://www.katespadeoutletstoreonline.us.com+ return $string;
-http://www.canadagoosejacketssale.com.co+}
-http://www.canadagooseukjackets.me.uk+ 
-http://www.nikezoom.us+ 
-http://www.airmax-97.us+$ext = ".bil.zip";
-http://www.uggoutlet-store.us+ 
-http://www.canadagooseoutlet-jackets.us+// Change the following to the location of your local root cache folder
-http://www.timberlandbootsoutlets.us.com+$url = 'D:/cache/';
-http://www.coachoutlet-onlinesale.us.com+$doneurl = $url . $T . "/" . $L . "/" . addzeros($Y) . "/" . addzeros($Y) . "_" . addzeros($X) . $ext;
-http://www.raybansunglasses.net.co+ 
-http://www.ralph-laurenoutlet.com.co+// Debug tools
-http://www.pandoracharmssaleclearance.uk+//header("Location: $doneurl");
-http://www.canadagooseoutletjackets.com.co+//exit;
-http://www.mbtshoessale.us.com+// print ($doneurl);
-http://www.coachoutletstoreonline.com.co+//exit;
-http://www.adidasnmd-shoes.us+ 
-http://www.kate-spade.us.com+ $tileData = file_exists($doneurl) ? file_get_contents($doneurl) :
-http://www.louisvuittonoutlet.us.org+false;
-http://www.michaelkorsoutletclearance.in.net+ if ($tileData === false) die();
-http://www.adidasshoe.us.com+ 
-http://www.canadagooseoutletjackets.us+ @header('Content-type: application/zip');
-http://www.michaelkorsoutletonlinemichaelkors.us.com+ print($tileData);
-http://www.uggsoutletclearance.us.com+ 
-http://www.canadagoose-outlet.name+?>
-http://www.canadagoosejacketsoutlet.name+</pre>
-http://www.ralphlaurenoutletonline-polo.us.com+ 
-http://www.adidas-nmd.us.com+*another script which can also create new tiles from tif files:
-http://www.adidasnmd.us.org+<pre>
-http://www.katespade.in.net+<?
-http://www.louboutinshoes.in.net+//PHP script for dishing out BILs behind a web server or a geo-trawler.
-http://www.monclerjacketsoutlet.in.net+//It will take a source TIF, use GDAL to cut up the source elevation data into WW tiles
-http://www.uggsoutletstoreonline.us.com+//(and corresponding directory structure), and then GZip the files for delivery.
-http://www.hermesbirkin.in.net+ 
-http://www.adidas-shoes.us.com+$szMapCacheDir="G:/CFSImagery/wwcache/DEM";
-http://www.poloralphlaurenoutletonline.us.com+/* create the main cache directory if necessary */
-http://www.michaelkors-outlet.ca+if (!@is_dir($szMapCacheDir))
-http://www.coachfactory-outletonline.us.org+ makeDirs($szMapCacheDir);
-http://www.nikeoutlet.in.net+ 
-http://www.uggsbootsonline.us.com+/* get the various request parameters
-http://www.cheapmlbjerseyschina.us.com+ * also need to make sure inputs are clean, especially those used to
-http://www.oakleysunglassessalecheap.us.com+ * build paths and filenames
-http://www.katespadehandbagsclearance.us.com+ */
-http://www.nikeshoes.in.net+$X = isset( $_REQUEST['X'] ) ? intval($_REQUEST['X']) : 0;
-http://www.fitflopssale-clearance.us.org+$Y = isset( $_REQUEST['Y'] ) ? intval($_REQUEST['Y']) : 0;
-http://www.longchamp-outlet.us.com+$L = isset( $_REQUEST['L'] ) ? intval($_REQUEST['L']) : 0;
-http://www.pandoracharms.name+$T = isset( $_REQUEST['T'] ) ? intval($_REQUEST['T']) : 103;
-http://www.outletcanadagoose.us+$szExt = ".7z";
-http://www.airmax-97.us.com+ 
-http://www.raybansunglassessalecheap.us.com+$szLevelcache = $szMapCacheDir."/$L";
-http://www.uggbootssales.us.com+$szYcache = sprintf($szLevelcache."/%04d",$Y);
-http://www.cheapoakleysunglasses.com.co+if (!@is_dir($szYcache))
-http://www.coachoutlet-online.us.org+ makeDirs($szYcache);
-http://www.michaelkorsoutletshopping.us.com+$szCacheFile = sprintf($szYcache."/%04d_%04d".$szExt,$Y,$X);
-http://www.ralphlaurenoutletpolo.org.uk+$szIntFile = sprintf($szYcache."/%04d_%04d.bil",$Y,$X);;
-http://www.canadiangoose.us.com+/* Hit Test the cache tile */
-http://www.pandora-outlet.us.com+if (!file_exists($szCacheFile) || $bForce){
-http://www.jordanshoesforsale.us.com+ $lzts = 1.0;
-http://www.michaelkorsoutlet1.us.com+ //Our Layer Zero Tile Size
-http://www.ralph-laurenoutlet.org.uk+
-http://www.ralph-laurenuk.org.uk+ $lat1 = ($Y*$lzts*pow(0.5,$L))-90;
-http://www.coach-outletonline.us.org+ $lon1 = ($X*$lzts*pow(0.5,$L))-180;
-http://www.timberlandbootsoutlet.us.com+ //Lat2 and Lon2 as figured from tile size and level
-http://www.raybansunglasse.com+ $lat2 = $lat1 + $lzts*pow(0.5,$L);
-http://www.adidas-superstar.us.com+ $lon2 = $lon1 + $lzts*pow(0.5,$L);
-http://www.northface-jackets.us.com+ if($T==103){
-http://www.coachoutletcanada.ca+ if(($lat1>-33)||($lon1<138)||($lat2<-36)||($lon2>140)){
-http://www.canadagooseukjackets.org.uk+ header("HTTP/1.0 404 Not Found");
-http://www.michael-korsoutlets.us.com+ exit();
-http://www.ralphlaurenoutletsale.us.com+ }
-http://www.nikeshoes.us.com+ else{
-http://www.supremeclothing.us.org+ $gdalwarp = "gdalwarp.exe -te $lon1 $lat1 $lon2 $lat2 -ot Int16 -ts 150 150 -of ENVI ".
-http://www.thenorthfacejacketsoutlet.us.com+ "G:/CFSImagery/latlong/dem/hillsdem.tif ".$szIntFile;
-http://www.monclerjacketsuk.org.uk+ exec($gdalwarp);
-http://www.uggoutletonlines.us+ $za7 = "7za.exe a ".$szCacheFile." ".$szIntFile;
-http://www.doudounemonclerpascher.fr+ exec($za7);
-http://www.coachoutletus.us.com+ }
-http://www.outletcoachoutlet.us.com+ }
-http://www.ugg-boots.net.co+ if($T==104){
-http://www.airjordanshoes.in.net+ if(($lat1>28)||($lon1<9)||($lat2<27)||($lon2>11)){
-http://www.cheapjordans-shoes.us.com+ header("HTTP/1.0 404 Not Found");
-http://www.cheapjordanshoes.us.com+ exit();
-http://www.raybanssunglassesoutlet.us.com+ }
-http://www.moncleroutlet.me.uk+ else{
-http://www.michaelkorsoutlet.co.uk+ $gdalwarp = "gdalwarp.exe -te $lon1 $lat1 $lon2 $lat2 -ot Int16 -ts 250 250 -of ENVI ".
-http://www.uggbootsoutletstores.us.com+ "G:/CFSImagery/latlong/dem/LibyaDuneslatlonint ".$szIntFile;
-http://www.oakley--sunglasses.us.org+ exec($gdalwarp);
-http://www.louisvuitton-outlet.us.com+ $za7 = "7za.exe a ".$szCacheFile." ".$szIntFile;
-http://www.cheapjordan-shoes.in.net+ exec($za7);
-http://www.uggsoutletus.us.com+ }
-http://www.adadassuperstar.com+ }
-http://www.cheapjordans.com.co+}
-http://www.catboots.us+$h = fopen($szCacheFile, "r");
-http://www.ralphlaurenoutletmalls.us.com+header("Content-Type: "."application/x-7z-compressed");
-http://www.vuittonlouis.us.com+header("Content-Length: " . filesize($szCacheFile));
-http://www.cheapuggs.com.co+header("Expires: " . date( "D, d M Y H:i:s GMT", time() + 31536000 ));
-http://www.burberryoutlet.in.net+header("Cache-Control: max-age=31536000, must-revalidate" );
-http://www.christianlouboutinshoes.us.org+fpassthru($h);
-http://www.michaelkorsoutletonlineclearance.in.net+fclose($h);
-http://www.outletcoachonline.us.com+?>
-http://ugg.bootsoutlet.us.com+</pre>
-http://www.valentinoshoesoutlets.us.com+ 
-http://www.pandoracharmssale-clearance.us.com+===Nowak's one-liner===
-http://www.fitflopssale.us.com+ <? print(file_get_contents('/path/'. sprintf('%u/%04u/%04u_%04u.jpg', $_GET['L'], $_GET['Y'], $_GET['Y'], $_GET['X']))); ?>
-http://www.nfljerseyscheapwholesale.us.com+ 
-http://www.coach-factory-outlet.us.org+==Perl script used for NLT Landsat and SRTM tile serving==
-http://www.yeezyboost.us.com+<pre>
-http://www.thenorthface.us.com+#!/usr/bin/perl
-http://www.2017nikeairmax.us+use strict;
-http://www.monclerjacketssale.us.com+use CGI;
-http://www.supremenewyork.us.com+use Apache::Connection ();
-http://www.coachfactoryonlineoutlet.com.co+ 
-http://www.coach-factoryoutletonline.us.org+my $r = shift;
-http://www.pandorastore.us.com+my $c = $r->connection;
-http://www.ralphlauren-outletpolo.us.com+my $q = new CGI;
-http://www.coachoutletonlinecoachfactoryoutlet.us.com+ 
-http://www.coach-factoryoutlet-online.us.com+# Initialize
-http://www.ugg-outlets.us+my $inDataset = "";
-http://www.canadagoosejacketscoats.org.uk+my $inLevel = "";
-http://www.fredperrypoloshirts.us+my $inX = "";
-http://www.adidascampusshoes.us+my $inY = "";
-http://www.coachoutletmalls.us.com+my $outInvalid = 0;
-http://www.canadagoosejackets-outlet.us+my $outDataType = 0;
-http://wwwmonclerjacketsuk.com.co+my $outPathname = "";
-http://www.ugg-outletstores.us.com+my $outMimeType = "";
-http://www.ferragamo-outlet.us.com+my $outExtension = "";
-http://www.adidas.us.com+my $buff = "";
-http://www.redbottomsshoes.us.com+my $bytesRead = 0;
-http://www.burberry.us.com+my $haveFile = 0;
-http://www.canadagoosejacketsofficial.us.com+ 
-http://www.korsmichaeloutlet.us.com+# Get posted variables
-http://www.coachoutletsonlines.us.com+if (length($q->param('T'))) { # dataset
-http://www.michael-kors-handbags.us.org+ $inDataset = $q->param('T');
-http://www.airjordans.us.com+ $inDataset = int($inDataset);
-http://www.canadagooseoutletjackets.us.com+} else {
-http://www.supreme-clothing.us.com+ $outInvalid = 1;
-http://www.uggsbootscanada.ca+}
-http://www.pandora-jewelryoutlet.us.com+ 
-http://www.longchamphandbagsuk.org.uk+if (length($q->param('L'))) { # level
-http://www.coachfactory-outletstore.us.com+ $inLevel = $q->param('L');
-http://www.poloralphlaurenoutletpolo.us.com+ $inLevel = int($inLevel);
-http://www.uggoutlet-clearance.us.com+} else {
-http://www.uggbootsoutletsale.us.com+ $outInvalid = 1;
-http://www.northfacejacketssale.us.com+}
-http://www.canadagooseoutletcanada.com.co+ 
-http://www.columbiasportswear.us.com+if (length($q->param('X'))) { # x
-http://www.canadagoosesoutlet.ca+ $inX = $q->param('X');
-http://www.canadagooseoutletjackets.ca+ $inX = int($inX);
-http://www.coachoutletstoreonlineclearances.in.net+} else {
-http://www.burberryoutletsale.com.co+ $outInvalid = 1;
-http://www.cheapuggssale.com.co+}
-http://www.mulberryoutlet.org.uk+ 
-http://www.coach-outlets.us.com+if (length($q->param('Y'))) { # y
-http://www.hermesbag.us.com+ $inY = $q->param('Y');
-http://www.yeezyboost-350.co.uk+ $inY = int($inY);
-http://www.northfaceoutlet.us.com+} else {
-http://www.supremeclothing.org.uk+ $outInvalid = 1;
-http://www.uggsoutlets.name+}
-http://www.adidas-yeezyboost.us.com+ 
-http://www.coachfactory-outlet.us.com+# Verify input, create pathname
-http://www.canadagooseoutlets.us+$outPathname = "/wwdata/";
-http://www.adidas-outlet.us.com+$outMimeType = "";
-http://www.canadagooseclothing.us.com+ 
-http://www.michaelkorsoutlets.us.com+if ($inDataset == 100) {
-http://www.rayban-sunglasseoutlet.us.com+ $outPathname .= "100/";
-http://www.northfacejacketsoutlet.com.co+ $outMimeType = "application/x-7z-compressed";
-http://www.birkenstocks.us+ $outExtension = ".7z";
-http://www.philipppleinshirt.com+ $outDataType = 1;
-http://www.jacketscanadagoose.org.uk+} elsif ($inDataset == 106) {
-http://www.fitflops-sale-clearance.us.com+ $outPathname .= "106/";
-http://www.cheapuggs.net.co+ $outMimeType = "application/x-7z-compressed";
-http://www.adidasoutlet.us.com+ $outExtension = ".7z";
-http://www.canadagooseoutletonlines.us+ $outDataType = 1;
-http://www.uggsbootsaustralia.us.com+} elsif ($inDataset == 105) {
-http://www.coachfactoryoutletsonlines.us.com+ $outPathname .= "105/";
-http://www.coachoutlets.us.org+ $outMimeType = "image/jpeg";
-http://www.cheapuggboots.us.com+ $outExtension = ".jpg";
-http://www.michael-korsoutlet.us.com+ $outDataType = 2;
-http://www.moncler-outlets.us.com+} else {
-http://www.pandoracharms-uk.org.uk+ $outInvalid = 1;
-http://www.pandoracharms.com.co+}
-http://www.uggs-boots.us+ 
-http://www.adidasyeezyshoes.us.com+if (($inLevel >= 0) && ($inLevel <= 9)) {
-http://www.canadagooseoutletstores.us+ $outPathname .= "${inLevel}/";
-http://www.nikeoutletonline.us.com+} else {
-http://www.uggshoes.us.com+ $outInvalid = 1;
-http://www.coachcanadaoutlet.ca+}
-http://www.mbtshoes.name+ 
-http://www.pandorajewelryoutlet.in.net+#0005_0006.7z
-http://www.cheapuggs-boots.us.com+#
-http://www.outletcanadagooseoutlet.us.com+#pad with 3 zeroes, if less than 1000
-http://www.moncleroutletonlines.us.com+if ($inY < 1000) {
-http://www.guccioutlets.us.org+ $inY = sprintf("%04u", $inY);
-http://www.uggoutlets.name+}
-hll20180112+$outPathname .= "${inY}/${inY}_";
 + 
 +#pad with 3 zeroes, if less than 1000
 +if ($inX < 1000) {
 + $inX = sprintf("%04u", $inX);
 +}
 +$outPathname .= "${inX}";
 +$outPathname .= "${outExtension}";
 + 
 + 
 +# Display (for debugging purposes)
 +#
 +#if (!$outInvalid) {
 +# $r->content_type('text/plain');
 +#
 +# print "$inDataset $inLevel $inX $inY\n";
 +# print "$outPathname\n\n";
 +#}
 + 
 +if ($outInvalid) {
 + $r->status(400); # BAD_REQUEST
 + exit 0;
 +}
 + 
 + 
 +# Do we have the file?
 +if (-e $outPathname && -r $outPathname) {
 + $haveFile = 1;
 +} else {
 + # handle error
 + 
 + 
 +# if ($outDataType == 2) {
 +# # Can't find the Landsat7 tile, push /wwdata/105/blank.jpg
 +# $outPathname = "/wwdata/105/blank.jpg";
 +# if (!(-e $outPathname) || !(-r $outPathname)) {
 +# print "Can't find blank Landsat7 tile";
 +# exit 0;
 +# }
 +# } else {
 +# $r->content_type('text/plain');
 +#
 +# print "Can't find tile\n";
 +# print "$inDataset $inLevel $inX $inY $outMimeType $outExtension";
 + 
 + 
 + $r->status(404); # NOT_FOUND
 + exit 0;
 +# }
 +}
 +
 +# Send file
 + 
 +# Set up headers
 +$r->content_type("$outMimeType");
 +$r->set_content_length((-s($outPathname)));
 + 
 +# Open and display file
 +open my $fh, "$outPathname";
 +binmode $fh;
 +binmode STDOUT;
 +
 +$bytesRead = read ($fh, $buff, 8192);
 +while ($bytesRead) {
 + print $buff;
 + $r->rflush;
 + last if $c->aborted;
 + $bytesRead = read ($fh, $buff, 8192);
 +}
 +close $fh;
 +exit 0;
 +</pre>
 + 
 +==Python==
 +<pre>
 +# simple python worldwind tile server, v 1.0 2006
 +# author: Frank Kuehnel (RIACS)
 +
 +from mod_python import apache
 +import errno
 + 
 +#todo: make more robust + handle various datasets
 + 
 +datasetBasename = '/Users/admin/apollo/'
 + 
 +def request_error(req):
 + req.content_type = 'text/plain'
 + req.send_http_header()
 + req.write('Invalid WorldWind tile request\n')
 + 
 +def handler(req):
 + global datasetBasename
 + 
 + # we want to have parameters at least
 + if req.args:
 + args = req.args
 + else:
 + request_error(req)
 + return apache.OK
 +
 + args = req.args
 + for elem in args.split('&'):
 + key = elem[0:2]
 + value = elem[2:]
 + if key == 'T=':
 + dataSet = value
 + elif key == 'L=':
 + level = value
 + elif key == 'X=':
 + column = value
 + elif key == 'Y=':
 + row = value
 + 
 + # check parameter
 + try:
 + levelNum = int(level)
 + colNum = int(column)
 + rowNum = int(row)
 + except ValueError:
 + request_error(req)
 + return apache.OK
 + 
 + # load image file
 + try:
 + filepath = '%u/%04u/' % (levelNum, rowNum)
 + filename = '%04u_%04u.jpg' % (rowNum, colNum)
 + fullname = datasetBasename + filepath + filename
 + input = open(fullname,'rb')
 + data = input.read()
 + input.close()
 + except IOError, err:
 + if err.errno == errno.ENOENT:
 + req.content_type = 'text/plain'
 + req.send_http_header()
 + req.write('image tile ' + fullname + ' not available')
 + return apache.OK
 + 
 + # output image
 + req.content_type = 'image/jpeg'
 + req.send_http_header()
 + req.write(data)
 + 
 + return apache.OK
 +</pre>
 + 
 +==IIS==
 +'''WorldWindMaps.aspx.cs''' (the script itself)
 +<pre>
 +using System;
 +using System.Data;
 +using System.Configuration;
 +using System.Collections;
 +using System.Web;
 +using System.Web.Security;
 +using System.Web.UI;
 +using System.Web.UI.WebControls;
 +using System.Web.UI.WebControls.WebParts;
 +using System.Web.UI.HtmlControls;
 +using System.IO;
 +using System.Web.Configuration;
 + 
 +public partial class WorldWindMaps : System.Web.UI.Page
 +{
 + protected void Page_Load(object sender, EventArgs e)
 + {
 + 
 + int X = Convert.ToInt32(Request.QueryString["X"].ToString());
 + int Y = Convert.ToInt32(Request.QueryString["Y"].ToString());
 + int L = Convert.ToInt32(Request.QueryString["L"].ToString());
 + string T = Request.QueryString["T"].ToString(); //T = Dataset in WorldWind parlance
 + 
 + string filePath = WebConfigurationManager.AppSettings[T];
 + 
 + string fileExt = WebConfigurationManager.AppSettings[T + "_EXT"];
 + 
 + filePath += L.ToString() + "\\" + Y.ToString("0000") + "\\" + Y.ToString("0000") + "_" + X.ToString("0000") + fileExt;
 + 
 + FileInfo file = new FileInfo(filePath);
 + 
 + 
 + if (!file.Exists && T == "SRTM")
 + {
 + throw new HttpException(404, "Not Found");
 + Response.End();
 + }
 + 
 + else if (!file.Exists)
 + {
 +
 + string blankfilepath = WebConfigurationManager.AppSettings[T] + "0" + "\\" + "0000" + "\\" + "blank" + fileExt;
 + FileInfo blankfile = new FileInfo(blankfilepath);
 +
 + Response.ClearContent();
 + Response.AddHeader("Content-Length", blankfile.Length.ToString());
 + Response.ContentType = WebConfigurationManager.AppSettings[T + "_MIME"];
 + Response.TransmitFile(blankfile.FullName);
 + }
 + else
 + {
 + 
 + Response.ClearContent();
 + Response.AddHeader("Content-Length", file.Length.ToString());
 + Response.ContentType = WebConfigurationManager.AppSettings[T + "_MIME"];
 + Response.TransmitFile(file.FullName);
 + }
 + }
 +}
 +</pre>
 + 
 +sample '''Web.config''' file
 +<pre>
 +<?xml version="1.0" encoding="utf-8" ?>
 +<configuration>
 + 
 + <!--
 + Note: WorldWind Tile Server
 + -->
 +
 + <appSettings>
 +
 + <!-- WorldWind Image Services -->
 + <add key="SRTM" value="C:\World Wind Cache\Cache\Earth\SRTM\"/>
 + <add key="LANDSAT" value="C:\World Wind Cache\Cache\Earth\Images\NASA Landsat Imagery\NLT Landsat7 (Visible Color)\"/>
 + 
 + <!-- WorldWind Image file extensions -->
 + <add key="SRTM_EXT" value=".bil"/>
 + <add key="LANDSAT_EXT" value=".jpg"/>
 + 
 + <!-- WorldWind Image content (MIME) types -->
 + <add key="SRTM_MIME" value="application/octet-stream"/>
 + <add key="LANDSAT_MIME" value="image/jpeg"/>
 + 
 + </appSettings>
 +
 + <system.web>
 + 
 + <compilation
 + defaultLanguage="c#"
 + debug="true"
 + />
 + 
 + <customErrors
 + mode="Off"
 + />
 + 
 + <authentication mode="Windows" />
 + 
 + <authorization>
 + <allow users="*" /> <!-- Allow all users -->
 + <!-- <allow users="[comma separated list of users]"
 + roles="[comma separated list of roles]"/>
 + <deny users="[comma separated list of users]"
 + roles="[comma separated list of roles]"/>
 + -->
 + </authorization>
 + 
 + <trace
 + enabled="false"
 + requestLimit="10"
 + pageOutput="false"
 + traceMode="SortByTime"
 + localOnly="true"
 + />
 + 
 + <sessionState
 + mode="InProc"
 + stateConnectionString="tcpip=127.0.0.1:42424"
 + sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
 + cookieless="false"
 + timeout="20"
 + />
 + 
 + <globalization
 + requestEncoding="utf-8"
 + responseEncoding="utf-8"
 + />
 +
 + </system.web>
 + 
 +</configuration>
 +</pre>
 +==Java Servlet==
 +This was a script created for verifying and testing download code, it is simple to set up. Developed on JDK 1.6/Tomcat 6.0, Windows Vista x64 Home Premium
 + 
 +Tested this with the wwd-nltls7-g20-l0 (GeoCover 2000) cache pack installed locally. Using WorldWorld.NET 1.4
 + 
 +Servlet class TileRequestHandler.java
 +<pre>
 +package org.wwc.ammianus.tomcat.tileserver;
 + 
 +import java.io.File;
 +import java.io.FileInputStream;
 +import java.io.IOException;
 +import java.text.DecimalFormat;
 +import java.util.HashMap;
 + 
 +import javax.servlet.ServletException;
 +import javax.servlet.ServletOutputStream;
 +import javax.servlet.http.HttpServlet;
 +import javax.servlet.http.HttpServletRequest;
 +import javax.servlet.http.HttpServletResponse;
 + 
 +/**
 + * <p>This servlet handles requests from the World Wind.NET application and returns
 + * tile images or error codes as appropriate. This was a port to Java of a ASP.NET file posted
 + * at <a>http://worldwindcentral.com/wiki/Data_serving_scripts</a></p>
 + *
 + * @author ammianus
 + * @version 0.1
 + *
 + *
 + */
 +public class TileRequestHandler extends HttpServlet {
 +
 + /**
 + * Generated by Eclipse
 + */
 + private static final long serialVersionUID = -6596187549520730077L;
 + /**
 + * settings Map which theoretically could be extended for any layer used in WW
 + * for each layer, use the &lt;DataSetName&gt;&lt;/DataSetName&gt; tag value from @Images.xml file
 + * create three map entries &lt;DataSetName&gt;, &lt;DataSetName&gt;_EXT, &lt;DataSetName&gt;_MIME
 + */
 + private HashMap<String, String> _settings;
 +
 + private int _requestNumber;
 +
 + /**
 + * @see HttpServlet#HttpServlet()
 + */
 + public TileRequestHandler() {
 + super();
 + //use these setting which theoretically could be extended for any layer used in WW
 + //for each layer, use the <DataSetName></DataSetName> tag value from @Images.xml file
 + //create three map entries <DataSetName>, <DataSetName>_EXT, <DataSetName>_MIME
 + _settings = new HashMap<String,String>();
 + _settings.put("geocover2000", "C:\\Users\\Public\\WorldWindCache\\Cache\\Earth\\Images\\NASA Landsat Imagery\\Geocover 2000");
 + _settings.put("geocover2000_EXT", ".jpg");
 + _settings.put("geocover2000_MIME", "image/jpeg");
 +
 + _requestNumber = 0;
 + }
 + 
 + /**
 + * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 + */
 + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 + //increment counter
 + _requestNumber++;
 +
 + //Un-comment this to test whether WW handles 503 return code with Retry-After header
 + //
 + //first request we will send an error with a retry-after header
 + //
 + /*if(_requestNumber == 1){
 + response.setStatus(503);
 + //this appears to be case insensitive for WorldWind, I just picked a random retry-after period
 + response.setHeader("retry-after", "38");
 + System.out.println(_requestNumber+":Response: 503, with retry-after: 38");
 + return;
 + }*/
 +
 + try{
 +
 +
 + //column
 + int X = Integer.parseInt(request.getParameter("X").toString());
 + //row
 + int Y = Integer.parseInt(request.getParameter("Y").toString());
 + //level
 + int L = Integer.parseInt(request.getParameter("L").toString());
 + //DataSet name
 + String T = request.getParameter("T").toString(); //T = Dataset in WorldWind parlance
 +
 +
 + //Un-comment this to test whether WW handles 500 return code
 + //
 + //if(T.equals("geocover2000")){
 + // throw new Exception("Force return of 500 - Server Error");
 + //}
 +
 + //Arguments are in this format URL sent from world wind
 + //e.g. http://localhost:8080/TomcatTileServer/TileRequestHandler?T=geocover2000&L=0&X=47&Y=21
 + String filePath = _settings.get(T);//WebConfigurationManager.AppSettings[T];
 + 
 + String fileExt = _settings.get(T + "_EXT");
 + if(L < 3){
 + DecimalFormat df = new DecimalFormat("0000");
 + filePath += "\\"+L + "\\" + df.format(Y) + "\\" + df.format(Y) + "_" + df.format(X) + fileExt;
 + }else{
 + filePath += "\\level"+(L+1)+fileExt;
 + }
 + //request.get
 + System.out.println(_requestNumber+":Requested File: "+filePath);
 + File file = new File(filePath);
 + 
 + //if file (image for requested tile) is not found on server, return 404
 + if (!file.exists())
 + {
 + response.sendError(HttpServletResponse.SC_NOT_FOUND, "Not Found");
 + }
 + else
 + {
 + //set content length to file size
 + response.setContentLength((int) file.length());
 + //get mime type for this layer
 + response.setContentType(_settings.get(T + "_MIME"));
 + //get the output stream for the response, this will have the file written to it
 + ServletOutputStream stream = response.getOutputStream();
 +
 + //read the file contents and write them to the outputstream
 + FileInputStream fis = new FileInputStream(file);
 + byte[] bytes = new byte[1024];
 + int counter = 0;
 + while(counter < file.length()){
 + fis.read(bytes);
 + counter += 1024;
 + stream.write(bytes);
 + }
 + fis.close();
 + stream.flush();
 + stream.close();
 +
 + //done with response
 + }
 + }catch(Exception e){
 + //uncaught Exception return 500 error
 + response.sendError(500,e.getMessage());
 + System.out.println(_requestNumber+":Response: send 500 error");
 + }
 + 
 + }
 + 
 + /**
 + * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 + */
 + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 + // TODO Auto-generated method stub
 + }
 + 
 +}
 +</pre>
 + 
 +Example WEB-INF\web.xml
 +<pre>
 +<?xml version="1.0" encoding="UTF-8"?>
 +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
 + <display-name>TomcatTileServer</display-name>
 + <welcome-file-list>
 + <welcome-file>index.html</welcome-file>
 + <welcome-file>index.htm</welcome-file>
 + <welcome-file>index.jsp</welcome-file>
 + <welcome-file>default.html</welcome-file>
 + <welcome-file>default.htm</welcome-file>
 + <welcome-file>default.jsp</welcome-file>
 + </welcome-file-list>
 + <servlet>
 + <description></description>
 + <display-name>TileRequestHandler</display-name>
 + <servlet-name>TileRequestHandler</servlet-name>
 + <servlet-class>org.wwc.ammianus.tomcat.tileserver.TileRequestHandler</servlet-class>
 + </servlet>
 + <servlet-mapping>
 + <servlet-name>TileRequestHandler</servlet-name>
 + <url-pattern>/TileRequestHandler</url-pattern>
 + </servlet-mapping>
 +</web-app>
 +</pre>
 +==Note==
 +Some of these scripts were designed for World Wind 1.3 which used 7-zip compression for .bil tiles. Version 1.4 supports both 7-zip and zip.
 + 
 +[[Category:Dev Documentation]]

Current revision

Contents

[edit] PHP scripts

[edit] Images

<?
// This scipt is for serving out your own WW Cached tiles to World Wind, useful for own imagery and for working "off line"
// This script can be named what ever you want, it is controlled via a World Wind XML
//
// thanks to MaurizoZA and Nowak for the script

$X = $_GET['X'];
$Y = $_GET['Y'];
$L = $_GET['L'];
$T = $_GET['T'];

function addzeros($string){
       //echo $string;
       if(strlen($string) >= 4){
               return $string;
       }

       $string = "0" . "$string";

       if(strlen($string) < 4){
               $string = addzeros($string);
       }
       return $string;
}


$ext = ".jpg";

// Change the following to the location of your local root cache folder
$url = 'D:/cache/';
$doneurl = $url . $T . "/" . $L . "/" . addzeros($Y) . "/" . addzeros($Y) .
"_" . addzeros($X) . $ext;

// Debug tools
//header("Location: $doneurl");
//exit;
// print ($doneurl);
//exit;

     $tileData = file_exists($doneurl) ? file_get_contents($doneurl) :
false;
     if ($tileData === false) die();

     @header('Content-type: image/jpeg');
     print($tileData);

?>

[edit] Elevation

  • simple serving script:
<?
// This scipt is for serving out your own WW Cached tiles to World Wind, useful for own imagery and for working "off line"
// This script can be named what ever you want, it is controlled via a World Wind XML
//
// thanks to MaurizoZA and Nowak for the script

$X = $_GET['X'];
$Y = $_GET['Y'];
$L = $_GET['L'];
$T = $_GET['T'];

function addzeros($string){
       //echo $string;
       if(strlen($string) >= 4){
               return $string;
       }

       $string = "0" . "$string";

       if(strlen($string) < 4){
               $string = addzeros($string);
       }
       return $string;
}


$ext = ".bil.zip";

// Change the following to the location of your local root cache folder
$url = 'D:/cache/';
$doneurl = $url . $T . "/" . $L . "/" . addzeros($Y) . "/" . addzeros($Y) . "_" . addzeros($X) . $ext;

// Debug tools
//header("Location: $doneurl");
//exit;
// print ($doneurl);
//exit;

     $tileData = file_exists($doneurl) ? file_get_contents($doneurl) :
false;
     if ($tileData === false) die();

     @header('Content-type: application/zip');
     print($tileData);

?>
  • another script which can also create new tiles from tif files:
<?
//PHP script for dishing out BILs behind a web server or a geo-trawler.
//It will take a source TIF, use GDAL to cut up the source elevation data into WW tiles
//(and corresponding directory structure), and then GZip the files for delivery.

$szMapCacheDir="G:/CFSImagery/wwcache/DEM";
/* create the main cache directory if necessary */
if (!@is_dir($szMapCacheDir))
    makeDirs($szMapCacheDir);

/* get the various request parameters 
 * also need to make sure inputs are clean, especially those used to
 * build paths and filenames
 */
$X = isset( $_REQUEST['X'] ) ? intval($_REQUEST['X']) : 0;
$Y = isset( $_REQUEST['Y'] ) ? intval($_REQUEST['Y']) : 0;
$L = isset( $_REQUEST['L'] ) ? intval($_REQUEST['L']) : 0;
$T = isset( $_REQUEST['T'] ) ? intval($_REQUEST['T']) : 103;
$szExt = ".7z";

$szLevelcache = $szMapCacheDir."/$L";
$szYcache = sprintf($szLevelcache."/%04d",$Y);
if (!@is_dir($szYcache))
    makeDirs($szYcache);
$szCacheFile = sprintf($szYcache."/%04d_%04d".$szExt,$Y,$X);
$szIntFile = sprintf($szYcache."/%04d_%04d.bil",$Y,$X);;
/* Hit Test the cache tile */
if (!file_exists($szCacheFile) || $bForce){
 $lzts = 1.0;
 //Our Layer Zero Tile Size
 
 $lat1 = ($Y*$lzts*pow(0.5,$L))-90;
 $lon1 = ($X*$lzts*pow(0.5,$L))-180;
 //Lat2 and Lon2 as figured from tile size and level
 $lat2 = $lat1 + $lzts*pow(0.5,$L);
 $lon2 = $lon1 + $lzts*pow(0.5,$L);
 if($T==103){
 if(($lat1>-33)||($lon1<138)||($lat2<-36)||($lon2>140)){
  header("HTTP/1.0 404 Not Found");
  exit();
 }
 else{
  $gdalwarp = "gdalwarp.exe -te $lon1 $lat1 $lon2 $lat2 -ot Int16 -ts 150 150 -of ENVI ".
  "G:/CFSImagery/latlong/dem/hillsdem.tif ".$szIntFile;
  exec($gdalwarp);
  $za7 = "7za.exe a ".$szCacheFile." ".$szIntFile;
  exec($za7);
 }
 }
 if($T==104){
 if(($lat1>28)||($lon1<9)||($lat2<27)||($lon2>11)){
  header("HTTP/1.0 404 Not Found");
  exit();
 }
 else{
  $gdalwarp = "gdalwarp.exe -te $lon1 $lat1 $lon2 $lat2 -ot Int16 -ts 250 250 -of ENVI ".
  "G:/CFSImagery/latlong/dem/LibyaDuneslatlonint ".$szIntFile;
  exec($gdalwarp);
  $za7 = "7za.exe a ".$szCacheFile." ".$szIntFile;
  exec($za7);
 }
 }
}
$h = fopen($szCacheFile, "r");
header("Content-Type: "."application/x-7z-compressed");
header("Content-Length: " . filesize($szCacheFile));
header("Expires: " . date( "D, d M Y H:i:s GMT", time() + 31536000 ));
header("Cache-Control: max-age=31536000, must-revalidate" );
fpassthru($h);
fclose($h);
?>

[edit] Nowak's one-liner

<? print(file_get_contents('/path/'. sprintf('%u/%04u/%04u_%04u.jpg', $_GET['L'], $_GET['Y'], $_GET['Y'], $_GET['X']))); ?>

[edit] Perl script used for NLT Landsat and SRTM tile serving

#!/usr/bin/perl
use strict;
use CGI;
use Apache::Connection ();

my $r = shift;
my $c = $r->connection;
my $q = new CGI;

# Initialize
my $inDataset = "";
my $inLevel = "";
my $inX = "";
my $inY = "";
my $outInvalid = 0;
my $outDataType = 0;
my $outPathname = "";
my $outMimeType = "";
my $outExtension = "";
my $buff = "";
my $bytesRead = 0;
my $haveFile = 0;

# Get posted variables
if (length($q->param('T'))) {     # dataset
  $inDataset = $q->param('T');
  $inDataset = int($inDataset);
} else {
  $outInvalid = 1;
}

if (length($q->param('L'))) {    # level
  $inLevel = $q->param('L');
  $inLevel = int($inLevel);
} else {
  $outInvalid = 1;
}

if (length($q->param('X'))) {    # x
  $inX = $q->param('X');
  $inX = int($inX);
} else {
  $outInvalid = 1;
}

if (length($q->param('Y'))) {    # y
  $inY = $q->param('Y');
  $inY = int($inY);
} else {
  $outInvalid = 1;
}

# Verify input, create pathname
$outPathname = "/wwdata/";
$outMimeType = "";

if ($inDataset == 100) {
    $outPathname .= "100/";
    $outMimeType = "application/x-7z-compressed";
    $outExtension = ".7z";
    $outDataType = 1;
} elsif ($inDataset == 106) {
    $outPathname .= "106/";
    $outMimeType = "application/x-7z-compressed";
    $outExtension = ".7z";
    $outDataType = 1;
} elsif ($inDataset == 105) {
    $outPathname .= "105/";
    $outMimeType = "image/jpeg";
    $outExtension = ".jpg";
    $outDataType = 2;
} else {
    $outInvalid = 1;
}

if (($inLevel >= 0) && ($inLevel <= 9)) {
  $outPathname .= "${inLevel}/";
} else {
  $outInvalid = 1;
}

#0005_0006.7z
#
#pad with 3 zeroes, if less than 1000
if ($inY < 1000) {
    $inY = sprintf("%04u", $inY);
}
$outPathname .= "${inY}/${inY}_";

#pad with 3 zeroes, if less than 1000
if ($inX < 1000) {
    $inX = sprintf("%04u", $inX);
}
$outPathname .= "${inX}";
$outPathname .= "${outExtension}";


# Display (for debugging purposes)
#
#if (!$outInvalid) {
#  $r->content_type('text/plain');
#
#  print "$inDataset $inLevel $inX $inY\n";
#  print "$outPathname\n\n";
#}

if ($outInvalid) {
  $r->status(400);     # BAD_REQUEST
  exit 0;
}


# Do we have the file?
if (-e $outPathname && -r $outPathname) {
  $haveFile = 1;
} else {
  # handle error


#  if ($outDataType == 2) {
#     # Can't find the Landsat7 tile, push /wwdata/105/blank.jpg
#     $outPathname = "/wwdata/105/blank.jpg";
#     if (!(-e $outPathname) || !(-r $outPathname)) {
#       print "Can't find blank Landsat7 tile";
#       exit 0;
#     }
#  } else {
#     $r->content_type('text/plain');
#
#     print "Can't find tile\n";
#     print "$inDataset $inLevel $inX $inY $outMimeType $outExtension";


     $r->status(404);      # NOT_FOUND
     exit 0;
#  }
}
 
# Send file

# Set up headers
$r->content_type("$outMimeType");
$r->set_content_length((-s($outPathname)));

# Open and display file
open my $fh, "$outPathname";
binmode $fh;
binmode STDOUT;
  
$bytesRead = read ($fh, $buff, 8192);
while ($bytesRead) {
  print $buff;
  $r->rflush;
  last if $c->aborted;
  $bytesRead = read ($fh, $buff, 8192);
}
close $fh;
exit 0;

[edit] Python

# simple python worldwind tile server, v 1.0 2006
# author: Frank Kuehnel (RIACS)
 
from mod_python import apache
import errno

#todo: make more robust + handle various datasets

datasetBasename = '/Users/admin/apollo/'

def request_error(req):
	req.content_type = 'text/plain'
	req.send_http_header()
	req.write('Invalid WorldWind tile request\n')

def handler(req):
	global datasetBasename	

	# we want to have parameters at least
	if req.args:
		args = req.args
	else:
		request_error(req)
		return apache.OK
		
	args = req.args
	for elem in args.split('&'):
		key   = elem[0:2]
		value = elem[2:]
		if key == 'T=':
			dataSet = value
		elif key == 'L=':
			level = value
		elif key == 'X=':
			column = value
		elif key == 'Y=':
			row = value

	# check parameter
	try:
		levelNum = int(level)
		colNum = int(column)
		rowNum = int(row)
	except ValueError:
		request_error(req)
		return apache.OK

	# load image file
	try:
		filepath = '%u/%04u/' % (levelNum, rowNum)
		filename = '%04u_%04u.jpg' % (rowNum, colNum)
		fullname = datasetBasename + filepath + filename
		input = open(fullname,'rb')
		data  = input.read()
		input.close()
	except IOError, err:
		if err.errno == errno.ENOENT:
                        req.content_type = 'text/plain'
			req.send_http_header()
                        req.write('image tile ' + fullname + ' not available')
                        return apache.OK

	# output image
	req.content_type = 'image/jpeg'
	req.send_http_header()
	req.write(data)

	return apache.OK

[edit] IIS

WorldWindMaps.aspx.cs (the script itself)

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Web.Configuration;

public partial class WorldWindMaps : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

        int X = Convert.ToInt32(Request.QueryString["X"].ToString());
        int Y = Convert.ToInt32(Request.QueryString["Y"].ToString());
        int L = Convert.ToInt32(Request.QueryString["L"].ToString());
        string T = Request.QueryString["T"].ToString(); //T = Dataset in WorldWind parlance

        string filePath = WebConfigurationManager.AppSettings[T];

        string fileExt = WebConfigurationManager.AppSettings[T + "_EXT"];

        filePath += L.ToString() + "\\" + Y.ToString("0000") + "\\" + Y.ToString("0000") + "_" + X.ToString("0000") + fileExt;

        FileInfo file = new FileInfo(filePath);


        if (!file.Exists && T == "SRTM")
        {
            throw new HttpException(404, "Not Found");
            Response.End();
        }

        else if (!file.Exists)
        {
            
		string blankfilepath = WebConfigurationManager.AppSettings[T] + "0" + "\\" + "0000" + "\\" + "blank" + fileExt;
		FileInfo blankfile = new FileInfo(blankfilepath);
      	
		Response.ClearContent();
        	Response.AddHeader("Content-Length", blankfile.Length.ToString());
        	Response.ContentType = WebConfigurationManager.AppSettings[T + "_MIME"];
        	Response.TransmitFile(blankfile.FullName);
        }
	else
	{

        	Response.ClearContent();
        	Response.AddHeader("Content-Length", file.Length.ToString());
        	Response.ContentType = WebConfigurationManager.AppSettings[T + "_MIME"];
        	Response.TransmitFile(file.FullName);
	}
    }
}

sample Web.config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

   <!--
     Note: WorldWind Tile Server
   -->
   
	<appSettings>
			
        <!-- WorldWind Image Services -->
        <add key="SRTM" value="C:\World Wind Cache\Cache\Earth\SRTM\"/>
        <add key="LANDSAT" value="C:\World Wind Cache\Cache\Earth\Images\NASA Landsat Imagery\NLT Landsat7 (Visible Color)\"/>

        <!-- WorldWind Image file extensions -->
        <add key="SRTM_EXT" value=".bil"/>
        <add key="LANDSAT_EXT" value=".jpg"/>

        <!-- WorldWind Image content (MIME) types -->
        <add key="SRTM_MIME" value="application/octet-stream"/>
        <add key="LANDSAT_MIME" value="image/jpeg"/>

	</appSettings>
     
  <system.web>

    <compilation 
         defaultLanguage="c#"
         debug="true"
    />

    <customErrors 
    mode="Off" 
    /> 

    <authentication mode="Windows" /> 

    <authorization>
        <allow users="*" /> <!-- Allow all users -->
            <!--  <allow     users="[comma separated list of users]"
                             roles="[comma separated list of roles]"/>
                  <deny      users="[comma separated list of users]"
                             roles="[comma separated list of roles]"/>
            -->
    </authorization>

    <trace
        enabled="false"
        requestLimit="10"
        pageOutput="false"
        traceMode="SortByTime"
		localOnly="true"
    />

    <sessionState 
            mode="InProc"
            stateConnectionString="tcpip=127.0.0.1:42424"
            sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes"
            cookieless="false" 
            timeout="20" 
    />

    <globalization 
            requestEncoding="utf-8" 
            responseEncoding="utf-8" 
   />
   
 </system.web>

</configuration>

[edit] Java Servlet

This was a script created for verifying and testing download code, it is simple to set up. Developed on JDK 1.6/Tomcat 6.0, Windows Vista x64 Home Premium

Tested this with the wwd-nltls7-g20-l0 (GeoCover 2000) cache pack installed locally. Using WorldWorld.NET 1.4

Servlet class TileRequestHandler.java

package org.wwc.ammianus.tomcat.tileserver;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * <p>This servlet handles requests from the World Wind.NET application and returns 
 * tile images or error codes as appropriate. This was a port to Java of a ASP.NET file posted
 * at <a>http://worldwindcentral.com/wiki/Data_serving_scripts</a></p>
 * 
 * @author ammianus
 * @version 0.1
 * 
 * 
 */
public class TileRequestHandler extends HttpServlet {
	
	/**
	 * Generated by Eclipse
	 */
	private static final long serialVersionUID = -6596187549520730077L;
	/**
	 * settings Map which theoretically could be extended for any layer used in WW
	 * for each layer, use the <DataSetName></DataSetName> tag value from @Images.xml file
	 * create three map entries <DataSetName>, <DataSetName>_EXT, <DataSetName>_MIME
	 */
	private HashMap<String, String> _settings;
	
	private int _requestNumber;
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public TileRequestHandler() {
        super();
        //use these setting which theoretically could be extended for any layer used in WW
        //for each layer, use the <DataSetName></DataSetName> tag value from @Images.xml file
        //create three map entries <DataSetName>, <DataSetName>_EXT, <DataSetName>_MIME
        _settings = new HashMap<String,String>();
        _settings.put("geocover2000", "C:\\Users\\Public\\WorldWindCache\\Cache\\Earth\\Images\\NASA Landsat Imagery\\Geocover 2000");
        _settings.put("geocover2000_EXT", ".jpg");
        _settings.put("geocover2000_MIME", "image/jpeg");
        
        _requestNumber = 0;
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	//increment counter
    	_requestNumber++;
    	
    	//Un-comment this to test whether WW handles 503 return code with Retry-After header
    	//
    	//first request we will send an error with a retry-after header
    	//
    	/*if(_requestNumber == 1){
    		response.setStatus(503);
    		//this appears to be case insensitive for WorldWind, I just picked a random retry-after period
    		response.setHeader("retry-after", "38");
    		System.out.println(_requestNumber+":Response: 503, with retry-after: 38");
    		return;
    	}*/
    	
    	try{
    	
    		
    	//column	
    	int X = Integer.parseInt(request.getParameter("X").toString());
    	//row
    	int Y = Integer.parseInt(request.getParameter("Y").toString());
    	//level
    	int L = Integer.parseInt(request.getParameter("L").toString());
    	//DataSet name
    	String T = request.getParameter("T").toString(); //T = Dataset in WorldWind parlance
    	
    	
    	//Un-comment this to test whether WW handles 500 return code
    	//
    	//if(T.equals("geocover2000")){
    	//	throw new Exception("Force return of 500 - Server Error");	
    	//}
    	
    	//Arguments are in this format URL sent from world wind
    	//e.g. http://localhost:8080/TomcatTileServer/TileRequestHandler?T=geocover2000&L=0&X=47&Y=21
    	String filePath = _settings.get(T);//WebConfigurationManager.AppSettings[T];

    	String fileExt = _settings.get(T + "_EXT");
    	if(L < 3){
    		DecimalFormat df = new DecimalFormat("0000");	
    		filePath += "\\"+L + "\\" + df.format(Y) + "\\" + df.format(Y) + "_" + df.format(X) + fileExt;
    	}else{
    		filePath += "\\level"+(L+1)+fileExt;
    	}
    	//request.get
    	System.out.println(_requestNumber+":Requested File: "+filePath);
    	File file = new File(filePath);

    	//if file (image for requested tile) is not found on server, return 404
    	if (!file.exists())
    	{
    		response.sendError(HttpServletResponse.SC_NOT_FOUND, "Not Found");
    	}
    	else
    	{
    		//set content length to file size
    		response.setContentLength((int) file.length());
    		//get mime type for this layer
    		response.setContentType(_settings.get(T + "_MIME"));
    		//get the output stream for the response, this will have the file written to it
    		ServletOutputStream stream = response.getOutputStream();
    		
    		//read the file contents and write them to the outputstream
    		FileInputStream fis = new FileInputStream(file);
    		byte[] bytes = new byte[1024];
    		int counter = 0;
    		while(counter < file.length()){
    			fis.read(bytes);
    			counter += 1024;
    			stream.write(bytes);
    		}
    		fis.close();
    		stream.flush();
    		stream.close();
    		
    		//done with response
    	}
    	}catch(Exception e){
    		//uncaught Exception return 500 error
    		response.sendError(500,e.getMessage());
    		System.out.println(_requestNumber+":Response: send 500 error");
    	}

    }

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

}

Example WEB-INF\web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>TomcatTileServer</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <description></description>
    <display-name>TileRequestHandler</display-name>
    <servlet-name>TileRequestHandler</servlet-name>
    <servlet-class>org.wwc.ammianus.tomcat.tileserver.TileRequestHandler</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>TileRequestHandler</servlet-name>
    <url-pattern>/TileRequestHandler</url-pattern>
  </servlet-mapping>
</web-app>

[edit] Note

Some of these scripts were designed for World Wind 1.3 which used 7-zip compression for .bil tiles. Version 1.4 supports both 7-zip and zip.

Personal tools