扩展Leaflet:图层(layer)

来源:互联网 发布:如何查询dj影像数据 编辑:程序博客网 时间:2024/05/17 17:57

        在Leaflet中,图层(layer)是随地图移动而移动的任何东西。本文首先解释如果做简单的扩展,然后看下如果创建它。

扩展方法(Extension methods)

        一些Leaflet类拥有所谓的“扩展方法(extension  methods)”:为子类编写代码的入口。

        其中一个就是L.TileLayer.getTileUrl()。无论何时当新的tile需要知道加载哪个图时就会在L.TileLayer内部调用该方法。通过创建L.TileLayer的子类和重写getTileUrl()方法,我们能够创建定制的行为。

        让我们用一个定制的L.TileLayer为例进行说明,该L.TileLayer可以展示随机的小猫图片。

L.TileLayer.Kitten = L.TileLayer.extend({    getTileUrl: function(coords) {        var i = Math.ceil( Math.random() * 4 );        return "http://placekitten.com/256/256?image=" + i;    },    getAttribution: function() {        return "<a href='http://placekitten.com/attribution.html'>PlaceKitten</a>"    }});L.tileLayer.kitten = function() {    return new L.TileLayer.Kitten();}L.tileLayer.kitten().addTo(map);

        通常getTileLayer()获取瓦片坐标(比如coords.x、coords.y和coords.z)并生成一个瓦片URL。在我们的例子中,我们忽略这些并且仅仅使用一些随机数来每次获取一个不同的小猫。

分离插件代码(Splitting away the plugin code)

        在之前的例子中,L.TileLayer.Kitten定义在了和使用位置相同的地方。对于插件而言,将插件代码分离到自己的文件中,然后在使用的时候再包含是一种更好的方式。

        对于KittenLayer,你应该创建一个类似L.KittenLayer.js文件,在该文件中写入如下代码:

L.TileLayer.Kitten = L.TileLayer.extend({    getTileUrl: function(coords) {        var i = Math.ceil( Math.random() * 4 );        return "http://placekitten.com/256/256?image=" + i;    },    getAttribution: function() {        return "<a href='http://placekitten.com/attribution.html'>PlaceKitten</a>"    }});

        然后在展示地图的时候包含这个文件:

<html>…<script src='leaflet.js'><script src='L.KittenLayer.js'><script>    var map = L.map('map-div-id');    L.tileLayer.kitten().addTo(map);</script>…

L.GripLayer和DOM元素

        另外一种扩展方式是L.GridLayer.createTile()。L.TileLayer假设存在一系列网格图片(比如<img>元素),L.GridLayer并不这样认为,它允许创建任意的一系列HTML网格元素。

        L.GridLayer允许创建除了<div>、<canvas>或者<picture>(或者任意东西)之外的一系列网格<img>元素。createTile()仅仅返回给定瓦片坐标的HTML元素实例。知晓如果在DOM中操作元素是很重要的:Leaflet能够处理HTML元素实例,因此使用诸如JQuery等JS库创建的元素,Leaflet处理起来存在一些问题。

        定制的GridLayer的一个实例是在div中展示瓦片坐标。这对于Leaflet内部调试和理解瓦片坐标如何工作特别有用。

        

L.GridLayer.DebugCoords = L.GridLayer.extend({    createTile: function (coords) {        var tile = document.createElement('div');        tile.innerHTML = [coords.x, coords.y, coords.z].join(', ');        tile.style.outline = '1px solid red';        return tile;    }});L.gridLayer.debugCoords = function(opts) {    return new L.GridLayer.DebugCoords(opts);};map.addLayer( L.gridLayer.debugCoords() );
        如果元素需要进行一些异步的初始化,那么使用第二个函数参数done 然后当瓦片已经就绪(比如当一张图片已经完全加载)或者存在错误时调用它。这里我们仅仅人为的延迟瓦片加载。

createTile: function (coords, done) {    var tile = document.createElement('div');    tile.innerHTML = [coords.x, coords.y, coords.z].join(', ');    tile.style.outline = '1px solid red';    setTimeout(function () {        done(null, tile);// Syntax is 'done(error, tile)'    }, 500 + Math.random() * 1500);    return tile;}

        使用定制的GridLayer,插件可以有效的控制HTML元素组成表格。一些插件已经采用该方式使用<canvas>实现了高级渲染。

        一个很基础的<canva> GridLayer是下面这样的:

L.GridLayer.CanvasCircles = L.GridLayer.extend({    createTile: function (coords) {        var tile = document.createElement('canvas');        var tileSize = this.getTileSize();        tile.setAttribute('width', tileSize.x);        tile.setAttribute('height', tileSize.y);        var ctx = tile.getContext('2d');        // Draw whatever is needed in the canvas context        // For example, circles which get bigger as we zoom in        ctx.beginPath();        ctx.arc(tileSize.x/2, tileSize.x/2, 4 + coords.z*4, 0, 2*Math.PI, false);        ctx.fill();        return tile;    }});

像素起点(The pixel orgin)

 

        创建定制的L.Layer是可行的,但是需要深入了解Leaflet如果放置HTML元素,下面是简要说明:

  • L.Map容器拥有“地图窗格”,也就是<div>
  • L.Layer是地图窗格中的HTML元素
  • 地图将所有的LatLng转换为地图上CRS中的坐标,然后将其在转换为绝对的“像素坐标”(CRS的起点和像素坐标的起点相同)
  • 当L.Map就绪时(拥有一个中心LatLng和一个缩放水平),左上角的绝对像素坐标就成为“像素起点”
  • 每个L.Layer都是根据像素起点和图层的LatLng的绝对像素坐标从其地图窗格的偏移
  • 像素起点会在L.Map上发生的每个zoomend或者viewreset事件之后重置,并且每个L.Layer如果有必要还需重新计算其位置
  • 像素起点不会在摇晃地图时(when panning the map around)重置,而是将整个窗格重新定位

这可能让人感到困惑,因此我们来分析一下如下的说明图:


(未完。。。)


原文地址:http://leafletjs.com/examples/extending/extending-2-layers.html


0 0
原创粉丝点击