(地图瓦片纠偏最好的方法在这: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);
2、在_update方法中修改如下代码:
for (i = 0; i < queue.length; i++) { this._addTile(queue[i],fragment,ratio); }
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);
_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); } },
_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 });
还有另一种纠偏方法,可以通过处理瓦片图进行纠偏:https://www.cnblogs.com/s0611163/p/12034779.html