Leaflet 地图偏移 地图纠偏

(地图瓦片纠偏最好的方法在这:https://www.cnblogs.com/s0611163/p/15606460.html)

    地图区域是一个市,偏移量可以近似认为是固定不变的,通过修改Leaflet-src.js源码中的_update方法和_addTile方法对瓦片进行偏移纠偏。

    Leaflet版本v1.3.4,要修改的_update和_addTile方法和最新版本1.6.0区别不大。

1、在_update方法中添加如下代码,瓦片图偏移后,在边缘位置需要补充瓦片图显示,不然边缘会出现空白:

        //处理纠偏后瓦片显示
        var ratio = 1 / Math.pow(2,(18 - this._tileZoom)); 计算纠偏比率
        var deltaX = 0;
        var deltaY = 0if (this._map.options.offsetX) deltaX = this._map.options.offsetX * ratio / 256this._map.options.offsetY) deltaY = this._map.options.offsetY * ratio / 256if (deltaX > 0) tileRange.max.x += (Math.round(deltaX) + 1);
        if (deltaY > 0) tileRange.max.y += (Math.round(deltaY) + 1if (deltaX < 0) tileRange.min.x -= (Math.floor(deltaX) - 1if (deltaY < 0) tileRange.min.y -= (Math.floor(deltaY) - 1);
View Code

2、在_update方法中修改如下代码:

            for (i = 0; i < queue.length; i++) {
                this._addTile(queue[i],fragment,ratio);
            }
View Code

3、在_addTile方法中添加如下代码,重新计算瓦片的像素位置:

        纠偏
        this._map.options.offsetX) tilePos.x -= Math.floor(this._map.options.offsetX * ratio);
        this._map.options.offsetY) tilePos.y -= Math.floor(this._map.options.offsetY * ratio);
View Code

 

_update方法完整代码:

     Private method to load tiles in the grid's active zoom level according to map bounds
    _update: function (center) {
        var map = ._map;
        if (!map) { return; }
        var zoom = ._clampZoom(map.getZoom());

        if (center === undefined) { center = map.getCenter(); }
        this._tileZoom === undefined) { return; }     if out of minzoom/maxzoom

        var pixelBounds = ._getTiledPixelBounds(center),tileRange = ._pxBoundsToTileRange(pixelBounds),tileCenter = tileRange.getCenter(),queue = [],margin = .options.keepBuffer,noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin,-margin]),tileRange.getTopRight().add([margin,-margin]));

         Sanity check: panic if the tile range contains Infinity somewhere.
        if (!(isFinite(tileRange.min.x) &&
              isFinite(tileRange.min.y) &&
              isFinite(tileRange.max.x) &&
              isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }

        for (var key in ._tiles) {
            var c = ._tiles[key].coords;
            if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x,c.y))) {
                this._tiles[key].current = false;
            }
        }

         _update just loads more tiles. If the tile zoom level differs too much
         from the map's,let _setView reset levels and prune old tiles.
        if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center,zoom); ; }

        if (deltaY < 0) tileRange.min.y -= (Math.floor(deltaY) - 1);

         create a queue of coordinates to load tiles from
        var j = tileRange.min.y; j <= tileRange.max.y; j++) {
            var i = tileRange.min.x; i <= tileRange.max.x; i++var coords =  Point(i,j);
                coords.z = ._tileZoom;

                if (!this._isValidTile(coords)) { continue; }

                var tile = this._tiles[._tileCoordsToKey(coords)];
                if (tile) {
                    tile.current = true;
                } else {
                    queue.push(coords);
                }
            }
        }

         sort tile queue to load tiles in order of their distance to center
        queue.sort( (a,b) {
            return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
        });

        if (queue.length !== 0 if it's the first batch of tiles to load
            ._loading) {
                this._loading = ;
                 @event loading: Event
                 Fired when the grid layer starts loading tiles.
                this.fire('loading');
            }

             create DOM fragment to append tiles in one batch
            var fragment = document.createDocumentFragment();

            ._level.el.appendChild(fragment);
        }
    },
View Code

_addTile方法完整代码:

    _addTile:  (coords,container,ratio) {
        var tilePos = ._getTilePos(coords),key = ._tileCoordsToKey(coords);

        this.createTile(this._wrapCoords(coords),bind(this._tileReady,,coords));

        ._initTile(tile);

         if createTile is defined with a second argument ("done" callback),
         we know that tile is async and will be ready later; otherwise
        this.createTile.length < 2 mark tile as ready,but delay one frame for opacity animation to happen
            requestAnimFrame(bind(this,coords,1)">nullthis._map.options.offsetY * ratio);

        setPosition(tile,tilePos);

         save tile in cache
        this._tiles[key] = {
            el: tile,coords: coords,current: 
        };

        container.appendChild(tile);
         @event tileloadstart: TileEvent
         Fired when a tile is requested and starts loading.
        this.fire('tileloadstart'View Code

 

如何使用:

1、JS引用由leaflet.js修改为引用leaflet-src.js

2、创建地图见如下代码,注意offsetX和offsetY参数,不同的城市,参数值不同,参数值可以用太乐地图下载器软件中的纠偏工具计算:

new L.Map('map',{ center: centerLatLng,zoom: 12,minZoom: 8,maxZoom: 18,maxBounds: mapBounds,offsetX: 1020,offsetY: 517,layers: [tileLayer],attributionControl: false,doubleClickZoom: false });
View Code

 

还有另一种纠偏方法,可以通过处理瓦片图进行纠偏:https://www.cnblogs.com/s0611163/p/12034779.html

 

相关文章

https://www.osgeo.cn/qgis-tutorial/overview.html https:...
设计方案是工程建设最关键的环节,也是影响城市规划的基本因...
BIM与GIS的区别与联系http://www.bimcn.org/cjwt/2018111516...
成功有感之给年轻人的10个忠告1、努力工作要努力,随随便便过...
鉴于陆地多边形为ShapelyMultiPolygon,我想找到代表例如多边...
背景与宣言传统的GISC/S开发已经很被别人不屑了,在时代的洪...