ProxySimplePHP
User:Lizard wrote a simple caching-Proxy for OSM in PHP.
This should make it simple to use tiles in own projects (Deploying your own Slippy Map) without flooding the tiles-servers. You need to have curl installed.
tiles.php:
<?php
$ttl = 86400; //cache timeout in seconds
$x = intval($_GET['x']);
$y = intval($_GET['y']);
$z = intval($_GET['z']);
$r = strip_tags($_GET['r']);
switch ($r)
{
case 'mapnik':
$r = 'mapnik';
break;
case 'osma':
default:
$r = 'osma';
break;
}
$file = "tiles/$r/${z}_${x}_$y.png";
if (!is_file($file) || filemtime($file)<time()-(86400*30))
{
$server = array();
switch ($r)
{
case 'mapnik':
$server[] = 'a.tile.openstreetmap.org';
$server[] = 'b.tile.openstreetmap.org';
$server[] = 'c.tile.openstreetmap.org';
$url = 'http://'.$server[array_rand($server)];
$url .= "/".$z."/".$x."/".$y.".png";
break;
case 'osma':
default:
$server[] = 'a.tah.openstreetmap.org';
$server[] = 'b.tah.openstreetmap.org';
$server[] = 'c.tah.openstreetmap.org';
$url = 'http://'.$server[array_rand($server)].'/Tiles/tile.php';
$url .= "/".$z."/".$x."/".$y.".png";
break;
}
$ch = curl_init($url);
$fp = fopen($file, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fflush($fp); // need to insert this line for proper output when tile is first requestet
fclose($fp);
}
$exp_gmt = gmdate("D, d M Y H:i:s", time() + $ttl * 60) ." GMT";
$mod_gmt = gmdate("D, d M Y H:i:s", filemtime($file)) ." GMT";
header("Expires: " . $exp_gmt);
header("Last-Modified: " . $mod_gmt);
header("Cache-Control: public, max-age=" . $ttl * 60);
// for MSIE 5
header("Cache-Control: pre-check=" . $ttl * 60, FALSE);
header ('Content-Type: image/png');
readfile($file);
?>
next, create a cache-directory and make it read/writeable
mkdir tiles mkdir tiles/mapnik mkdir tiles/osma chmod -R 777 tiles
This supports URLS of the form http://www.youdomain.tld/tiles.php?z=15&x=17024&y=10792&r=mapnik
...but for URLs suitable for a slippy map (structured as per Slippy map tilenames) you will need a rewrite-rule, for example in .htaccess :
RewriteEngine on RewriteRule ^tiles/([0-9]+)/([0-9]+)/([0-9]+).png$ tiles.php?z=$1&x=$2&y=$3 [L]
Test this in your browser with a tile URL such as http://www.youdomain.tld/tiles/15/17024/10792.png
If this gives you a tile image, then you're ready to point a Slippy Map installation (e.g. OpenLayers) at this caching proxy tile server!
Usage example with OpenLayers
In general, follow the instructions given in OpenLayers_Simple_Example. First create a new file like this one: OSM_LocalTileProxy.js
/**
* Class: OpenLayers.Layer.OSM.MapnikLocalProxy
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.MapnikLocalProxy = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.MapnikLocalProxy
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://yourProxyHost/tiles.php?z=${z}&x=${x}&y=${y}&r=mapnik"
];
options = OpenLayers.Util.extend({ numZoomLevels: 19 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.MapnikLocalProxy"
});
/**
* Class: OpenLayers.Layer.OSM.OsmarenderLocalProxy
*
* Inherits from:
* - <OpenLayers.Layer.OSM>
*/
OpenLayers.Layer.OSM.OsmarenderLocalProxy = OpenLayers.Class(OpenLayers.Layer.OSM, {
/**
* Constructor: OpenLayers.Layer.OSM.OsmarenderLocalProxy
*
* Parameters:
* name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
var url = [
"http://yourProxyHost/tiles.php?z=${z}&x=${x}&y=${y}&r=osma"
];
options = OpenLayers.Util.extend({ numZoomLevels: 18 }, options);
var newArguments = [name, url, options];
OpenLayers.Layer.OSM.prototype.initialize.apply(this, newArguments);
},
CLASS_NAME: "OpenLayers.Layer.OSM.OsmarenderLocalProxy"
});
Now it's time to include the new layers for your proxy cache right after including OpenStreetMap.js by adding this line to your map page:
<script src="openlayers/OSM_LocalTileProxy.js"></script>
The last step is to add these new layers to the other defined layers:
layerMapnikLocalProxy = new OpenLayers.Layer.OSM.MapnikLocalProxy("Mapnik (local proxy)");
map.addLayer(layerMapnikLocalProxy);
layerTilesAtHomeLocalProxy = new OpenLayers.Layer.OSM.OsmarenderLocalProxy("Osmarender (local proxy)");
map.addLayer(layerTilesAtHomeLocalProxy);