Leaflet源码解析--TileLayer
TileLayer类继承关系
var TileLayer = d({
var GridLayer = d({
TileLayer DOM树
介绍⼀下Leaflet中pane的DOM树结构,⼀个map-pane>tile-pane>layer,如果tileLayer没有设定
zIndex,MT_GOOGLE,DEBUG_GRID,WIND_CONT这三层按照加载顺序显⽰。
#map > div.leaflet-pane.leaflet-map-pane > div.leaflet-pane.leaflet-tile-pane > div.leaflet-layer.MT_GOOGLE
当进⾏海图缩放操作时,将出现⼏层⽡⽚的tile-container,tile-container中⽤来容纳⽡⽚。当缩放动作结束,之前⼀层⽡⽚的container 将会消失,两层⽡⽚的zIndex由各⾃的⽐例尺决定。
Leaflet中HTML元素使⽤
/
/ @option pane: String = 'overlayPane'
// By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pan e by default.
//默认情况下,该层将被添加到地图的[overlay pane](#map-overlaypane)。覆盖此选项将会导致图层被默认的放到另⼀层
pane:'overlayPane',
// @method getPane(name? : String): HTMLElement
// Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
// 返回⼀个Html的元素,如果提供name返回已经命名的pane,不提供name参量,返回⾃⼰的pane。
getPane:function(name){
return this._Pane(name ?(this.options[name]|| name):this.options.pane);
},
Layer提供getPane⽅法返回的是HTML 元素,本⾝可以通过DOM HTML⽅法进⾏操作。也可以通过Leaflet中提供的L.DomUtil中的⽅法进⾏操作。官⽅例⼦的使⽤⽅法如下:
L.DomUtil.setPosition(this._container,point);
TileLayer 源码解析
提供⼀段L.GridLayer的使⽤⽅法,L.GridLayer中做三件事:
_initContainer():初始化元素(其中使⽤Pane加载)
_resetView():在不同⽐例尺下为_level数组赋值
_update():将获得的所有tile⼀次性加载到_level.el上
_level这个tileLayer中最重要的元素。
_level中拥有当前zoom下element与原点值。
el:div.leaflet-tile-container.leaflet-zoom-animated
origin:Point {x: 2477, y: 1208}
zoom:4
onAdd:function(){
this._initContainer();
//⼀层layer中拥有多层tile-container,这⾥level的意思的不同⽐例尺的level
//也有不同zIndex的level意思
this._levels ={};
this._tiles ={};
this._resetView();
this._update();
},
_initContainer:function(){
if(this._container){return;}
//创建layer层
this._container =create$1('div','leaflet-layer '+(this.options.className ||''));
//没设置的话 zIndex=1
this._updateZIndex();
if(this.options.opacity <1){
this._updateOpacity();
}
//就是HTML元素的操作,都简单不赘述
},
_resetView:function(e){
html导航源码var animating = e &&(e.pinch || e.flyTo);
this._setView(this._Center(),this._Zoom(), animating, animating);
},
//在缩放时触发
_setView:function(center, zoom, noPrune, noUpdate){
var tileZoom =this._und(zoom));
if((this.options.maxZoom !== undefined && tileZoom >this.options.maxZoom)||
(this.options.minZoom !== undefined && tileZoom <this.options.minZoom)){
tileZoom = undefined;
}
var tileZoomChanged =this.options.updateWhenZooming &&(tileZoom !==this._tileZoom); if(!noUpdate || tileZoomChanged){
this._tileZoom = tileZoom;
if(this._abortLoading){
this._abortLoading();
}
//更新level 更新⽹格
this._updateLevels();
this._resetGrid();
//⽐例尺发⽣变化
if(tileZoom !== undefined){
//center是this._Center() LatLon类型
this._update(center);
}
if(!noPrune){
this._pruneTiles();
}
// Flag to prevent _updateOpacity from pruning tiles during
// a zoom anim or a pinch gesture
this._noPrune =!!noPrune;
}
/
/设置level中tile的贴⽚位置
this._setZoomTransforms(center, zoom);
},
_setZoomTransforms:function(center, zoom){
for(var i in this._levels){
this._setZoomTransform(this._levels[i], center, zoom);
}
},
_setZoomTransform:function(level, center, zoom){
var scale =this._ZoomScale(zoom, ),
translate = igin.multiplyBy(scale)
.
subtract(this._map._getNewPixelOrigin(center, zoom)).round();
//此处level.el已经为tile的img,transfrom在map初始化时已经定义完成,tile的贴⽚位置在setTransform得出
if(any3d){
setTransform(level.el, translate, scale);
}else{
setPosition(level.el, translate);
}
},
// 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._Zoom());
if(center === undefined){ center = Center();}
if(this._tileZoom === undefined){return;}// if out of minzoom/maxzoom
//使⽤center与zoom计算出像素坐标边界,⽤来计算那些tile需要进⾏更换
var pixelBounds =this._getTiledPixelBounds(center),
tileRange =this._pxBoundsToTileRange(pixelBounds),
tileCenter = Center(),
queue =[],
margin =this.options.keepBuffer,
noPruneRange =new BottomLeft().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');}
//下⾯的代码逻辑复杂
//⼤概意思就是将获得的Tiles放到fragment⾥⾯,批量加载到_level⾥⾯的leaflet-tile-container,⽡⽚就加载上了for(var key in this._tiles){
var c =this._tiles[key].coords;
if(c.z !==this._tileZoom ||!ains(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;}
// 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;}
if(!this._tiles[this._tileCoordsToKey(coords)]){
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
if(!this._loading){
this._loading =true;
// @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 = ateDocumentFragment();
for(i =0; i < queue.length; i++){
this._addTile(queue[i], fragment);
}
this._level.el.appendChild(fragment);
}
},
_updateLevels:function(){
var zoom =this._tileZoom,
maxZoom =this.options.maxZoom;
if(zoom === undefined){return undefined;}
//多层level更新zIndex ⽤于显⽰层级,最终只保留最新⼀层,其他level删除
for(var z in this._levels){
if(this._levels[z].el.children.length || z === zoom){
this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
this._onUpdateLevel(z);
}else{
remove(this._levels[z].el);
this._removeTilesAtZoom(z);
this._onRemoveLevel(z);
delete this._levels[z];
}
}
/
/level新建
var level =this._levels[zoom],
map =this._map;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论