# Leaflet 地图偏移 地图纠偏

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

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

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

            for (i = 0; i < queue.length; i++) {
}
View Code

        //纠偏
if (this._map.options.offsetX) tilePos.x -= Math.floor(this._map.options.offsetX * ratio);
if (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 = this._map;
if (!map) { return; }
var zoom = this._clampZoom(map.getZoom());

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

var pixelBounds = this._getTiledPixelBounds(center),
tileRange = this._pxBoundsToTileRange(pixelBounds),
tileCenter = tileRange.getCenter(),
queue = [],
margin = this.options.keepBuffer,
noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([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 this._tiles) {
var c = this._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); return; }

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

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

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

var tile = this._tiles[this._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(function (a, b) {
return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
});

if (queue.length !== 0) {
// if it's the first batch of tiles to load
}

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

for (i = 0; i < queue.length; i++) {
}

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

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

var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords));

this._initTile(tile);

// if createTile is defined with a second argument ("done" callback),
// we know that tile is async and will be ready later; otherwise
if (this.createTile.length < 2) {
// mark tile as ready, but delay one frame for opacity animation to happen
}

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

setPosition(tile, tilePos);

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

container.appendChild(tile);
tile: tile,
coords: coords
});
},
View Code

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

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

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

posted @ 2020-07-29 14:09  秋荷雨翔  阅读(50)  评论(0编辑  收藏