Mapboxjs中的拼贴层上是否存在maxNativeZoom的问题?

时间:2018-01-10 20:23:43

标签: leaflet mapbox

我目前正在从2.1.5升级到3.1.1。 我在tile图层上遇到了maxNativeZoom选项的问题。

基本上看起来它被忽略了,地图一直在缩放显示白色瓷砖。

我的期望是瓷砖应该自动缩放。

这在版本2.1.5中运行良好。

以下是小提琴:

2.1.5:https://jsfiddle.net/jfwkq0s4/4/

3.1.1:http://jsfiddle.net/dbpfcoqo/6/

以下是来自上述小提琴的小样本代码:



L.mapbox.accessToken = 'pk.eyJ1IjoidHZibG9tYmVyZyIsImEiOiJjaXZsZmpsMWwwNXBuMnRudmJqNGQyMjJwIn0.842ovgKydac51tg6b9qKbg';
var map = L.mapbox.map('map', null, { maxZoom: 20})
.setView([40, -74.50], 9);

var layer = new L.mapbox.tileLayer('mapbox.streets', { maxNativeZoom: 17, maxZoom: 20 });

map.addLayer(layer);




我想知道MapBox / Leaflet是否改变了设置这些值的方式,或者他们当前版本不再支持它们?

该选项仍列在其文档中。

我感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

This seems to be a bug in Mapbox.js starting with version 3.0.0 (which uses Leaflet 1.0.1 or 1.0.2 internally).

It is visible on Mapbox.js example page for over zoom tiles: https://www.mapbox.com/mapbox.js/example/v1.0.0/overzoom/

I see that you have already opened an issue on Mapbox.js repository: https://github.com/mapbox/mapbox.js/issues/1250

What seems to happen is that Mapbox correctly freezes the X and Y coordinates of the tile past maxNativeZoom, but not the Z (zoom) value. Therefore it displays totally incorrect tiles, if available.

This bug is specific to Mapbox.js, Leaflet behaves as expected:

var map = L.map('map', {
  maxZoom: 20
}).setView([48.86, 2.35], 11);

L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
  maxNativeZoom: 11,
  maxZoom: 20
}).addTo(map);

var $zoomLevel = document.getElementById("zoomLevel");
map.on('zoomend', showZoomLevel);
showZoomLevel();

function showZoomLevel() {
  $zoomLevel.innerHTML = map.getZoom();
}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.2/dist/leaflet.css">
<script src="https://unpkg.com/leaflet@1.0.2/dist/leaflet-src.js"></script>

Zoom level: <span id='zoomLevel'></span>
<div id="map" style="height: 170px"></div>

答案 1 :(得分:2)

这是我的修复。我也将把它发送给MapBox。有两个主要问题。

  1. 第一个问题是minZoom和maxZoom始终被地图框图块图层设置覆盖。

  2. 第二个问题是没有根据maxNativeZoom正确设置z点。

  3. 这似乎对我有用。有关详细信息,请参阅代码示例。

    	var customTileLayer = function (url, options) {
    		var formatPattern = /\.((?:png|jpg)\d*)(?=$|\?)/;
    		var tileLayerExtend = L.mapbox.TileLayer.extend({
    			_setTileJSON: function (json) {
    				//util.strict(json, 'object');
    				/*We had to create a function for this since util is private in mapbox */
    				strict(json, 'object');
    
    				if (!this.options.format) {
    					var match = json.tiles[0].match(formatPattern);
    					if (match) {
    						this.options.format = match[1];
    					}
    				}
    
    				var minZoom = this.options.minZoom || json.minzoom || 0;
    				var maxZoom = this.options.maxZoom || json.maxzoom || 18;
    
    				L.extend(this.options, {
    					tiles: json.tiles,
    					attribution: this.options.sanitizer(json.attribution),
    					minZoom: minZoom,
    					maxZoom: maxZoom,
    					tms: json.scheme === 'tms',
    					// bounds: json.bounds && util.lbounds(json.bounds)
    					/*We had to create a function for this since util is private in mapbox */
    					bounds: json.bounds && lBounds(json.bounds)
    				});
    
    				this._tilejson = json;
    				this.redraw();
    				return this;
    			},
    			getTileUrl: function (tilePoint) {
    				var tiles = this.options.tiles,
    					index = Math.floor(Math.abs(tilePoint.x + tilePoint.y) % tiles.length),
    					url = tiles[index];
    
    				tilePoint.z = this._getZoomForUrl();
    
    				var templated = L.Util.template(url, tilePoint);
    				if (!templated || !this.options.format) {
    					return templated;
    				} else {
    					return templated.replace(formatPattern,
    						(L.Browser.retina ? this.scalePrefix : '.') + this.options.format);
    				}
    			}
    		});
    
    		return new tileLayerExtend(url, options);
    	};
    
    	var lBounds = function(_) {
    		return new L.LatLngBounds([[_[1], _[0]], [_[3], _[2]]]);
    	};
    
    	var strict = function (_, type) {
    		if (typeof _ !== type) {
    			throw new Error('Invalid argument: ' + type + ' expected');
    		}
    	};
      
      L.mapbox.accessToken = 'pk.eyJ1IjoidHZibG9tYmVyZyIsImEiOiJjaXZsZmpsMWwwNXBuMnRudmJqNGQyMjJwIn0.842ovgKydac51tg6b9qKbg';
    var map = L.mapbox.map('map', null, { maxZoom: 20})
        .setView([40, -74.50], 9);
        
    var layer = new customTileLayer('mapbox.streets', { maxNativeZoom: 17, maxZoom: 20 });
    var $zoomLevel = document.getElementById("zoomLevel");
    
    map.addLayer(layer);   
    $zoomLevel.innerHTML = map.getZoom();
    map.on('zoomend', function(e) {
    	var zoom = e.target.getZoom();
      $zoomLevel.innerHTML= zoom;
    });
      
      
    body { margin:0; padding:0; }
    #container { position: absolute; top: 0; bottom: 0; width: 100%; height: 100%; }
    #map { height: 100%; width:100%; }
    <script src="https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.js"></script>
    <link href="https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.css" rel="stylesheet" />
    
    <div id="container">
      <span id='zoomLevel'></span>
      <div id='map'></div>
    </div>