不完整的地图从切片服务器返回,在缩放级别可用的切片比文档指示的更多

Incomplete map comes back from tile server, more tiles available at zoom level than docs indicate

我在下面的示例中使用了 AngularJS、Leaflet 和 Angular-leaflet-directive,这些示例是我从 Angular-leaflet-directive 项目中获得的。此示例在使用 public 切片服务器时有效,包括示例当前指向的 public ArcGIS 服务器。

根据多个在线文档来源,包括来自 open street maps and mapbox 的这两个文档,在特定缩放级别下可用的图块数量应为 2^z X 2^z,其中 z 是缩放级别。因此,在缩放级别 0 时我们应该得到 1 个图块,在 1 时我们应该得到 4 个图块,依此类推。

我遇到的问题仅在指向私有托管(企业内部网)ESRI ArcGIS 切片服务器时出现。当我尝试按原样查看下面的页面时,但使用私有切片服务器的 url 而不是 http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x},我只能看到缩放级别的部分地图0 和 1。

仔细查看后,我意识到图块服务器想要在缩放级别 0 发送两个图块而不是 1 个,在缩放级别 1 发送 6 个图块而不是 4 个。在更深的缩放级别上问题仍然存在。当查看单个图块的 urls 时(例如 ../0/0/0 和 ../0/0/1 在缩放级别 0),我发现我们确实得到了合成地图期待我们是否将在该缩放级别可用的剩余图块放在一起。这意味着如果传单想要构建整个地图,则信息可用。

总的来说,我对 Leaflet 和 Maps 很陌生,但我觉得通过告诉 leaflet 在给定的缩放级别期望更多的图块,它应该能够获得完整的图片,但是在搜索 leaflet 文档之后,我找不到这样的配置。

我的疑问:有这样的设置吗?如果有,那是什么?也许这个问题遗漏了一些东西,或者我不知道问正确的问题。我在看正确的文档吗?任何指导将不胜感激。

<html>
<head>
  <title>A Leaflet map!</title>
  <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
  <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
  <style>
    #map{ width: 900px; height: 500px; }
  </style>
</head>
<body>

  <div id="map"></div>

  <script>

  // initialize the map
  var map = L.map('map').setView([42.35, -71.08], 13);

  // load a tile layer
   L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
    {
      maxZoom: 17,
      minZoom: 9
    }).addTo(map);

  </script>
</body>
</html>

Maybe the question is missing something or I don't know enough to ask the right question.

我认为您缺少地图投影的概念。如果地图使用 EPSG:3857,则缩放 0 很可能被 1 个图块覆盖。如果它在 EPSG:4326 中,则为 2 个方块。

比较来自 NASA 蓝色大理石传单地图的这些(静态)图像:

两者都是正确的,但它们使用不同的投影(EPSG:3857 在顶部,EPSG:4326 在底部)。

强烈建议您研究您的图块使用的投影。您可能需要对地图投影甚至 Proj4Leaflet 进行一些额外的研究才能使其正常工作,但至少您知道要看什么。

这是我根据@IvanSanchez 的评论提出的解决方案。请注意,我指向一个 public 服务于 EPSG:4326 的服务器并将 crs:L.CRS.EPSG4326 添加到默认值。需要注意的重要一点是,当前稳定版本的传单(0.7.7)不完全支持这一点。为了让它工作,我升级到 1.0.0 Beta2。有关此问题的更多信息,包括使用测试版的替代方法,请参阅 https://github.com/Leaflet/Leaflet/issues/1207

<!DOCTYPE html>
<html ng-app="demoapp">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="lib/angular-1.4.2/angular.min.js"></script>
    <script src="lib/leaflet/dist/leaflet.js"></script>
    <script src="lib/angular-leaflet-directive-master/dist/angular-leaflet-directive.min.js"></script>
    <link rel="stylesheet" href="lib/leaflet/leaflet.css" />
    <script>
        var app = angular.module("demoapp", ["leaflet-directive"]);
        app.controller('BasicCustomParametersController', [ '$scope', function($scope) {
            angular.extend($scope, {
                london: {
                    lat: 51.505,
                    lng: -0.09,
                    zoom: 1,
                    noWrap: false,
                    minZoom: 1,
                    maxZoom: 10
                },
                defaults: {
                   //EPSG:3857
                   // tileLayer: "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}",

                   //EPSG:4326
                    tileLayer: "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/{z}/{y}/{x}",

                    zoomControlPosition: 'topright',
                    tileLayerOptions: {
                        opacity: 0.9,
                        detectRetina: true,
                        reuseTiles: true,
                    },
                    scrollWheelZoom: false,

                   //use EPSG4326.  Not fully supported in leaflet 0.7.7.  Works with 1.0.0 Beta2
                    crs:L.CRS.EPSG4326
                }
            });
        }]);
    </script>
  </head>
  <body ng-controller="BasicCustomParametersController">
    <leaflet lf-center="london" defaults="defaults" width="100%" height="480px"></leaflet>
    <h1>Using custom default parameters</h1>
  </body>
</html>