简体   繁体   English

何时使用 L.TileLayer 与 L.tileLayer

[英]when to use L.TileLayer vs L.tileLayer

I have just been using Leaflet to build a map for a website and noticed that to add a Tile Layer at least two methods can be used, L.TileLayer() and L.tileLayer() , differing in their name only by the case of a single character.我刚刚使用 Leaflet 为网站构建地图,并注意到添加 Tile Layer 至少可以使用两种方法, L.TileLayer()L.tileLayer() ,它们的名称仅在以下情况下有所不同单个字符。

However, while the object returned by both of these methods can be added to a map object returned by L.map() the object returned by L.TileLayer() does not seem to have the addTo() method whilst the object returned by L.tileLayer() .然而,虽然由这两种方法所返回的对象可以被添加到由返回的地图对象L.map()返回的对象L.TileLayer()似乎不具有addTo()而通过返回的对象方法L.tileLayer() Eg both例如两者

var map = L.map('map');
var tiles = new L.TileLayer(<tileUrl>, {attribution: <tileAttrib>});
map.addLayer(tiles);

and

var map = L.map('map');
var tiles = new L.tileLayer(<tileUrl>, {attribution: <tileAttrib>});
map.addLayer(tiles);

as well as

var map = L.map('map');
L.tileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);

whilst同时

var map = L.map('map');
L.TileLayer(<tileUrl>, {attribution: <tileAttrib>}).addTo(map);

fails.失败。 Browsing the documentation of Leaflet it seems the proper method to use is L.tileLayer() so the question then is what is the use of L.TileLayer() ?浏览单张的文件,似乎使用正确的方法是L.tileLayer()这样的问题,那么是什么用的L.TileLayer()

Here's a full example of my code so far, to try the different alternatives simply uncomment the one to test and make sure the others are commented到目前为止,这是我的代码的完整示例,要尝试不同的替代方案,只需取消对要测试的替代方案的注释,并确保对其他替代方案进行了注释

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-transitional.dtd">
        
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
      <meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/>
      <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>
      
      <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.3/dist/leaflet.css"
            integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ=="
            crossorigin=""/>
      <script src="https://unpkg.com/leaflet@1.3.3/dist/leaflet.js"
            integrity="sha512-tAGcCfR4Sc5ZP5ZoVz0quoZDYX5aCtEm/eu1KhSLj2c9eFrylXZknQYmxUssFaVJKvvc0dJQixhGjG2yXWiV9Q=="
            crossorigin=""> </script>
   </head>
   <body onload="makeMap()">
      <script type="text/javascript">
         function makeMap() {
            var tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
            var tileAttrib = 'Map data &copy <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'; 
            var map = L.map('map').setView([63,15],9);
            
            // using tileLayer and addLayer - this works
            var tiles = new L.tileLayer(tileUrl, {attribution: tileAttrib});
            map.addLayer(tiles);
            
            // using tileLayer and addTo - this works
//             L.tileLayer(tileUrl, {attribution: tileAttrib}).addTo(map);
            
            // using TileLayer and addLayer - this works
//             var tiles = new L.TileLayer(tileUrl, {attribution: tileAttrib});
//             map.addLayer(tiles);
            
            // using TileLayer and addTo - this fails
//             L.TileLayer(tileUrl, {attribution: tileAttrib}).addTo(map);
         }
         
      </script>
      <table border=1 style="position: absolute; top: 0; bottom: 0; left: 0; right: 0; width: 100%; height: 100%;">
         <tr style="height: 100%;">
            <td>
               <div id="map" style="width: 100%; height: 100%;"></div>
            </td>
         </tr>
      </table>
   </body>
</html>

TL;DR:特尔;博士:

These two are both valid and equivalent:这两个既有效又等效:

var foo = L.tileLayer(arguments);
var foo = new L.TileLayer(arguments);

These two are syntactically valid (because of Javascript's historical baggage) but will ultimately result in errors:这两个在语法上是有效的(因为 Javascript 的历史包袱),但最终会导致错误:

var foo = new L.tileLayer(arguments);
var foo = L.TileLayer(arguments);

to add a tilelayer at least two methods can be used, L.TileLayer() and L.tileLayer()添加tilelayer至少可以使用两种方法, L.TileLayer()L.tileLayer()

Well, they're not really two methods .好吧,它们并不是真正的两种方法 Technically L.TileLayer is an instance of Object , and L.tileLayer is an instance of Function , which inherits the prototype of Object .从技术上讲, L.TileLayerObject一个实例,而L.tileLayerFunction一个实例,它继承了Object的原型。 And L acts as a namespace rather than a class instance. L充当命名空间而不是类实例。

You see, Object-Oriented Programming in Javascript is weird .你看,Javascript 中的面向对象编程很奇怪 You can use the new keyword with pretty much any object which has a prototype.您可以将new关键字用于几乎任何具有原型的对象。 And prototype-based inheritance is confusing to grasp to most people versed in "proper" OOP.对于大多数精通“正确”OOP 的人来说, 基于原型的继承是难以掌握的。

Nowadays, with the ES2015 standards and the fancy class keywords this is not really a problem (I'd say it's a problem, but hidden under layers of syntactic sugar).如今,有了 ES2015 标准和花哨的class关键字,这并不是一个真正的问题(我会说这是一个问题,但隐藏在语法糖层之下)。 But back in the day, developers had to resort to, let's say, creative solutions for class inheritance which sometimes involves messing with the prototype chain .但在过去,开发人员不得不求助于,比如说,类继承的创造性解决方案,有时涉及弄乱原型链

Leaflet uses a combination of such methods - and as an undesired side effect , L.TileLayer becomes a Function and one can call L.TileLayer() directly and that's quite confusing. Leaflet 使用了这些方法的组合 -作为一种不受欢迎的副作用L.TileLayer变成了一个Function并且可以直接调用L.TileLayer() ,这很令人困惑。

Leaflet also uses the concept of factory functions : A function that returns an instance of a class. Leaflet 还使用了工厂函数的概念:返回类实例的函数。 Quoting from one of the Leaflet tutorials :引自传单教程之一

Most Leaflet classes have a corresponding factory function .大多数 Leaflet 类都有相应的工厂函数 A factory function has the same name as the class, but in lowerCamelCase instead of UpperCamelCase :工厂函数与类具有相同的名称,但使用lowerCamelCase而不是UpperCamelCase

 function myBoxClass(name, options) { return new MyBoxClass(name, options); }

This is meant just as a convenience: it saves the user from typing the new keyword back in an era where the new keyword was feared .这意味着仅仅作为一种方便:它节省打字的用户new在的时代关键词回new关键字是担心

But this creates another undesired side effect , because in Javascript all Function s have a prototype, which means that you can do stuff like但这会产生另一个不受欢迎的副作用,因为在 Javascript 中所有Function都有一个原型,这意味着你可以做类似的事情

 function myFunction() { ... }
 var wtf = new myFunction();

Therefore, new L.tileLayer() is also valid syntax (but fails at runtime).因此, new L.tileLayer()也是有效的语法(但在运行时失败)。


then what is the use of L.TileLayer() ?那么L.TileLayer()什么用呢?

Once again, L.TileLayer() as a function call is an undesired side effect.再一次,作为函数调用的L.TileLayer()是一个不受欢迎的副作用。 But L.TileLayer represents a class and it's important to have a reference to that, because of things like:但是L.TileLayer代表一个类,引用它很重要,因为如下:

 if (layer instanceof L.TileLayer)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM