使用php代理实现抓取天地图切片到本地并调用
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 onload="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); ?>
参考地址:
转载自:https://blog.csdn.net/nothing_is_imposible/article/details/21934605