使用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

You may also like...