Openlayers写的天地图的扩展类,可命名为tianditu.js,添加到html引用即可,或者直接放到html的script标签中
OpenLayers.Layer.TiandituLayer = OpenLayers.Class(OpenLayers.Layer.Grid, {
mapType : "EMap",
mirrorUrls : [
"http://t0.tianditu.com/DataServer",
"http://t1.tianditu.com/DataServer",
"http://t2.tianditu.com/DataServer",
"http://t3.tianditu.com/DataServer",
"http://t4.tianditu.com/DataServer",
"http://t5.tianditu.com/DataServer",
"http://t6.tianditu.com/DataServer",
"http://t7.tianditu.com/DataServer"
],
topLevel : 2,
bottomLevel : 18,
topLevelIndex : 0,
bottomLevelIndex : 18,
topTileFromX : -180,
topTileFromY : 90,
topTileToX : 180,
topTileToY : -270,
isBaseLayer : false,
initialize : function (name, url, options) {
options.topLevel = options.topLevel ? options.topLevel : this.topLevel;
options.bottomLevel = options.bottomLevel ? options.bottomLevel : this.bottomLevel;
options.maxResolution = this.getResolutionForLevel(options.topLevel);
options.minResolution = this.getResolutionForLevel(options.bottomLevel);
var newArguments = [name, url, {}, options];
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
},
clone : function (obj) {
if (obj == null) {
obj = new OpenLayers.Layer.TiandituLayer(this.name, this.url, this.options);
}
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
return obj;
},
getURL : function (bounds) {
var level = this.getLevelForResolution(this.map.getResolution());
var coef = 360 / Math.pow(2, level);
var x_num = this.topTileFromX < this.topTileToX ? Math.round((bounds.left - this.topTileFromX) / coef) : Math.round((this.topTileFromX - bounds.right) / coef);
var y_num = this.topTileFromY < this.topTileToY ? Math.round((bounds.bottom - this.topTileFromY) / coef) : Math.round((this.topTileFromY - bounds.top) / coef);
var type = this.mapType;
if (type == "EMap") {
type = "vec_c";
}
if (type == "EMapANNO") {
type = "cva_c";
}
if (type == "Img") {
type = "img_c";
}
if (type == "ImgANNO") {
type = "cia_c";
}
if (type == "TMap") {
type = "ter_c"
}
if (type == "TMapANNO") {
type = "cta_c"
}
var url = this.url;
if (this.mirrorUrls != null) {
url = this.selectUrl(x_num+y_num, this.mirrorUrls);
}
return this.getFullRequestString({
T : type,
X : x_num,
Y : y_num,
L : level
}, url);
},
selectUrl : function (a, b) {
return b[a % b.length]
},
getLevelForResolution : function (res) {
var ratio = this.getMaxResolution() / res;
if (ratio < 1)
return 0;
for (var level = 0; ratio / 2 >= 1; ) {
level++;
ratio /= 2;
}
return level;
},
getResolutionForLevel : function (level) {
return 360 / 256 / Math.pow(2, level);
},
getMaxResolution : function () {
return this.getResolutionForLevel(this.topLevelIndex)
},
getMinResolution : function () {
return this.getResolutionForLevel(this.bottomLevelIndex)
},
addTile : function (bounds, position) {
var url = this.getURL(bounds);
return new OpenLayers.Tile.Image(this, position, bounds, url, this.tileSize);
},
CLASS_NAME : "OpenLayers.Layer.TiandituLayer"
});
写一个简单的html文件,如果本地没有Openlayers的css和js可使用网上的文件:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<script src="../lib/OpenLayers.js"></script>
<script type="text/javascript">
var lon = 50;
var lat = 0;
var zoom = 0;
var map, layer, layer1;
function init(){
map = new OpenLayers.Map( 'map',{allOverlays:true} );
layer = new OpenLayers.Layer.TiandituLayer( "1:100万矢量图",
"http://tile0.tianditu.com/DataServer", {
mapType:"EMap",
mirrorUrls : [
"http://localhost/proxy.php"
],
transitionEffect: "resize",
wrapDateLine:true
}
);
layer1 = new OpenLayers.Layer.TiandituLayer( "1:100万矢量图",
"http://tile0.tianditu.com/DataServer", {
mapType:"EMapANNO",
mirrorUrls : [
"http://localhost/proxy.php"
]
}
);
map.addLayers([layer,layer1]);
map.addControl(new OpenLayers.Control.MousePosition());
map.setCenter(new OpenLayers.LonLat(116.30884, 39.93719), 15);
}
</script>
</head>
<body οnlοad="init()">
<div id="map" class="smallmap" style="width:1000px;height:600px;"></div>
</body>
</html>
http://localhost/proxy.php
表示放在本地Apache目录下的代理,proxy.php文件代码如下:
<?php
$ttl = 86400; //cache timeout in seconds
$x = intval($_GET['X']);
$y = intval($_GET['Y']);
$z = intval($_GET['L']);
$r = strip_tags($_GET['T']);
//新建文件
function createFolder($path)
{
if (!file_exists($path))
{
createFolder(dirname($path));
mkdir($path, 0777);
}
}
$path ='./tiles/'.$r.'/'.$z;
createFolder($path);
//检查图片请求
function check_url($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
$headers = curl_getinfo($ch);
curl_close($ch);
return $headers['http_code'];
}
//图片的位置
$file = "tiles/$r/$z/${x}_$y.png";
//判断是否有缓存过的图片
if (!is_file($file) || filemtime($file)<time()-(86400*30)||filesize($file)<300)
{
$server = array();
$server[] = 't0.tianditu.com/DataServer?';
$server[] = 't1.tianditu.com/DataServer?';
$server[] = 't2.tianditu.com/DataServer?';
$server[] = 't3.tianditu.com/DataServer?';
$server[] = 't4.tianditu.com/DataServer?';
$server[] = 't5.tianditu.com/DataServer?';
$server[] = 't6.tianditu.com/DataServer?';
$url = 'http://'.$server[array_rand($server)];
$url .= "T=".$r."&X=".$x."&Y=".$y."&L=".$z;
//若请求状态不是‘200’则使用本地的透明图片替换
$satus = check_url($url);
if($satus == '404'){
$url="http://localhost/tiles/transparent.png";
}
//调用本地地图服务,其实就是去文件中根据文件夹层去找图片
// $server[]='localhost';
// $url = 'http://'.$server[array_rand($server)];
// $url .='tiles/$r/$z/${x}_$y.png';
//抓取网页的库curl_init
$ch = curl_init($url);
$fp = fopen($file, "w");
curl_setopt($ch, CURLOPT_FILE, $fp);// 设置要抓取的URL
curl_setopt($ch, CURLOPT_HEADER, 0);// 设置header
curl_exec($ch);//运行curl请求网页
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);
?>
参考地址: