0

我想创建一个在一定程度上完美契合的自定义瓷砖。例如,我希望能够在开源地图的确切位置将其映射到地图上。我看到了这个例子,但它没有解释瓷砖是如何制作的以及如何制作它以使其完全适合范围。下面的示例在一定程度上放置了自定义图层,我想知道如何创建这样的图块。我正在为我的代码使用 XYZ 源代码。示例取自:

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>
4

1 回答 1

0

在该示例中,图块使用标准 EPSG:3857 网格,与 OSM 层相同。范围已设置为将请求限制在特定区域(美国包括夏威夷和阿拉斯加的大部分地区,但不包括阿留申群岛的西端)。在缩放级别为零时,单个图块覆盖整​​个世界(透明显示为黑色):

在此处输入图像描述

如果您在 OSM 图层上设置相同的范围,您也会限制显示的区域,但不会影响切片。对于全局投影,通常会坚持使用标准网格并限制图层范围以避免请求到您没有切片的区域。在其他投影中,您可以创建自己的网格,并使用源tileGrid选项在 OpenLayers 中指定它以匹配您创建的内容。

下面是如何为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>

于 2019-08-02T09:05:11.270 回答