简体   繁体   English

如何创建在某种程度上适合OpenLayers5的自定义图块

[英]How to create custom tiles that fit on a certain extent OpenLayers5

I want to create a custom tile that is a perfect fit on a certain extent. 我想创建一个在某种程度上非常合适的自定义图块。 For example, I want to be able to map it on the map at exact spots of an Open Source Map. 例如,我希望能够在开放源地图的确切位置上将其映射到地图上。 I saw this example, but it does not explain how the tiles are made and how to make it such that it fits the extent perfectly. 我看到了这个示例,但没有说明如何制作图块以及如何制作图块以使其完全适合范围。 The example below puts custom layer at an extent, I want to know how to create such tiles. 下面的示例在一定程度上放置了自定义层,我想知道如何创建这样的图块。 I am using XYZ source for my code. 我正在使用XYZ源代码。 Example was taken from : 示例取自:

https://openlayers.org/en/latest/examples/arcgis-tiled.html https://openlayers.org/en/latest/examples/arcgis-tiled.html

<!DOCTYPE html>
<html>
  <head>
    <title>Tiled ArcGIS MapServer</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>

  </head>
  <body>
    <div id="map" class="map"></div>
    <script>
      import Map from 'ol/Map.js';
      import View from 'ol/View.js';
      import TileLayer from 'ol/layer/Tile.js';
      import {OSM, TileArcGISRest} from 'ol/source.js';

      var url = 'https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' +
          'Specialty/ESRI_StateCityHighway_USA/MapServer';

      var layers = [
        new TileLayer({
          source: new OSM()
        }),
        new TileLayer({
          extent: [-13884991, 2870341, -7455066, 6338219],
          source: new TileArcGISRest({
            url: url
          })
        })
      ];
      var map = new Map({
        layers: layers,
        target: 'map',
        view: new View({
          center: [-10997148, 4569099],
          zoom: 4
        })
      });
    </script>
  </body>
</html>

In that example the tiles use a standard EPSG:3857 grid, the same as the OSM layer. 在该示例中,图块使用标准的EPSG:3857网格,与OSM层相同。 The extent has been set to limit requests to a specific area (USA including Hawaii and most of Alaska - but not the western end of the Aleutians). 范围已设置为将请求限制在特定区域(美国,包括夏威夷和阿拉斯加的大部分地区,但不包括阿留申群岛的西端)。 At zoom level zero the single tile covers the world (transparent shows as black): 缩放级别为零时,单个图块覆盖整​​个世界(透明显示为黑色):

在此处输入图片说明

If you set the same extent on the OSM layer you would also restrict the area displayed, but it wouldn't affect the tiles. 如果在OSM层上设置相同的范围,则还将限制显示的区域,但不会影响图块。 With global projections it is normal to stick to a standard grid and restrict the layer extent to avoid requests to areas where you don't have tiles. 使用全局投影时,通常会坚持使用标准网格并限制图层范围以避免对没有瓷砖的区域提出请求。 In other projections you can create you own grid, and specify that in OpenLayers using the source's tileGrid option to match what you created. 在其他投影中,您可以创建自己的网格,并在OpenLayers中使用源的tileGrid选项将其指定为匹配您创建的网格。

Here's an example of how to set up a custom tile grid for https://server.arcgisonline.com/ArcGIS/rest/services/Polar/Antarctic_Imagery/MapServer 这是一个如何为https://server.arcgisonline.com/ArcGIS/rest/services/Polar/Antarctic_Imagery/MapServer设置自定义图块网格的示例

 // define polar projection proj4.defs("EPSG:3031", "+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs"); ol.proj.proj4.register(proj4); // redefine transforms to catch errors var inverse = ol.proj.getTransform('EPSG:3031', 'EPSG:3857'); var forward = ol.proj.getTransform('EPSG:3857', 'EPSG:3031'); ol.proj.addCoordinateTransforms( 'EPSG:3857', 'EPSG:3031', function(coordinate) { try { return forward(coordinate) } catch (e) { return [undefined, undefined] } }, function(coordinate) { try { return inverse(coordinate) } catch (e) { return [undefined, undefined] } } ); var baseMapLayer = new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', maxZoom: 23 }) }); var extent = [-3.369955099203E7, -3.369955099203E7, 3.369955099203E7, 3.369955099203E7]; var maxResolution = 238810.81335399998; var resolutions = []; for (var i = 0; i < 24; i++) { resolutions[i] = maxResolution / Math.pow(2, i); } var esriArctic = new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://services.arcgisonline.com/arcgis/rest/services/Polar/Antarctic_Imagery/MapServer/tile/{z}/{y}/{x}', projection: 'EPSG:3031', tileGrid: new ol.tilegrid.TileGrid({ extent: extent, resolutions: resolutions }) }) }); // create a "layer spy" around the pole esriArctic.on('precompose', function(event) { radius = 4000000 / event.frameState.viewState.resolution; var ctx = event.context; var pixelRatio = event.frameState.pixelRatio; ctx.save(); ctx.beginPath(); position = map.getPixelFromCoordinate(ol.proj.fromLonLat([0, -90], 'EPSG:3031')); // only show a circle around the position ctx.arc(position[0] * pixelRatio, position[1] * pixelRatio, radius * pixelRatio, 0, 2 * Math.PI); ctx.clip(); }); // after rendering the layer, restore the canvas context esriArctic.on('postcompose', function(event) { var ctx = event.context; ctx.restore(); }); var map = new ol.Map({ target: 'map', layers: [baseMapLayer, esriArctic], view: new ol.View({ projection: 'EPSG:3031', center: ol.proj.fromLonLat([0, -80], 'EPSG:3031'), zoom: 3 }) }); 
  html, body, #map { width: 100%; height: 100%; overflow: hidden; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script> <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet"/> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script> <body> <div id="map" class="map"></div> </body> 

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

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