關於openlaeyrs獲取谷歌衛星地圖的無偏瓦片

更新:好像谷歌地圖的瓦片地址khm3這個一直在變化啊,近來變成khm0了,自己也得跟着變化。。。
還有,這兩天發現天地圖自己的標註和無偏googlemap居然是重合的,結果我國內版的谷歌瓦片對應不上天地圖的標註了。。。他們自己都不用火星座標系的嗎?


谷歌地圖的衛星影像在國內是偏移的,比如國內能訪問的那個http://www.google.cn/maps,還有Google Map API上專門提供給中國的http://maps.google.cn/maps/api/的這兩個都是偏移過的,而https://www.google.com/maps/,以及https://maps.googleapis.com/maps/api就是沒有偏移的。
一個驗證:
中國版的地圖
這裏寫圖片描述
同一x/y/縮放級別下的國外版的地圖
這裏寫圖片描述
從資源裏面找到同一個xyz的瓦片看一下
中國的
這裏寫圖片描述
國外的
這裏寫圖片描述
可以發現兩點:

  1. 請求瓦片的時候,發送的是Web Mercator下地圖顯示中心的經緯度結合瓦片的長寬算出的一個值。請求國內/國外的地址,發回的對應的瓦片就是偏移/未偏移的。
  2. 道路圖層聽說是國內哪家合作提供的,因此和偏移過的瓦片是重合的。

由於我這邊是想和影像做一些疊加,所以座標必須是無偏的。看了一下國外的訪問地址是https://khms3.google.com/kh/v=726?x=28415&y=11580&z=15
這個v有人猜測是版本號,我也不知道。。。改了一下openlayers的瓦片獲取程序,感覺偏移基本沒了。
而網上比較流行的一個地址是http://mt1.google.cn/maps/vt,要有一個layers是s@110,這個就有偏了。。。但是和國內的服務都是契合的
稍微改一下openlayers獲取瓦片的class,url就是https://khm3.google.com/kh

OpenLayers.Layer.GoogleLayer2 = OpenLayers.Class(OpenLayers.Layer.XYZ, {
    url: null,
    tileOrigin: null,
    tileSize: new OpenLayers.Size(256, 256),
    type: 'png',
    useScales: false,
    overrideDPI: false,
    initialize: function(name, url, options) {
        this.v = options.v;
        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, arguments);
    },
    getURL: function(bounds) {
        var res = this.getResolution();
        var originTileX = (this.tileOrigin.lon + (res * this.tileSize.w / 2));
        var originTileY = (this.tileOrigin.lat - (res * this.tileSize.h / 2));
        var center = bounds.getCenterLonLat();
        var x = (Math.round(Math.abs((center.lon - originTileX) / (res * this.tileSize.w))));
        var y = (Math.round(Math.abs((originTileY - center.lat) / (res * this.tileSize.h))));
        var z = this.map.getZoom();
        var url = this.url;
        var s = '' + x + y + z;
        if (OpenLayers.Util.isArray(url)) {
            url = this.selectUrl(s, url);
        }
        url = url + '/v=${v}&?&x=${x}&y=${y}&z=${z}'; //&L=4&X=12&Y=3
        url = OpenLayers.String.format(url, { 'v': this.v, 'x': x, 'y': y, 'z': z });
        return OpenLayers.Util.urlAppend(
            url, OpenLayers.Util.getParameterString(this.params)
        );
    },

    CLASS_NAME: 'OpenLayers.Layer.GoogleLayer2'
});

幾個參考:http://blog.csdn.net/aliqing777/article/details/9818985
http://www.sosaw.com/threads-296984-1-1.html
https://stackoverflow.com/questions/7200682/why-have-these-google-satellite-map-tile-links-stopped-working

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章