使用php代理实现抓取天地图切片到本地并调用

来源:互联网 发布:天书世界暗器进阶数据 编辑:程序博客网 时间:2024/06/10 09:43
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);  ?>


参考地址:

点击打开链接



1 0
原创粉丝点击