6

光栅图块似乎已经开始过时了,但我仍然需要一个解决方案来以某种方式为我的 QGIS Server 的 WMS 做到这一点。

到目前为止,我已经尝试过 TileCache,但我无法让它在 OL3 中工作,而且它似乎也有点“老旧”。

那么,如果以后我想在我的 OL3 应用程序中使用缓存层,我的最佳出价是多少?TileStache、Mapproxy、MapCache?

我的 QGIS 服务器在 CentOS 7 下运行。

4

2 回答 2

3

QGIS Server 与MapProxy配合得很好。使用 QGIS Server+MapProxy,您将获得最好的 QGIS 样式以及切片缓存的速度。

MapProxy 是用 Python 编写的,您可能已经在服务器上安装了 Python。您可以(并且应该)在虚拟环境中运行 MapProxy。MapProxy 的说明非常清楚,启动并运行它并从 QGIS Server 获取数据确实是几分钟的问题。

  1. 它比 GeoWebCache 轻得多
  2. 它缓存并提供切片(仅tiled: true在您的 WMS 请求中使用)
  3. 它与 OpenLayers 配合得很好。安装后,您将获得一个演示页面,其中包含 OpenLayers 示例。
  4. 您可以针对缓存的源调用 GetFeatureInfo 请求
  5. 您可以针对缓存的源调用 GetLegendGraphic 请求
  6. 它可以处理自定义网格(只要您在 OpenLayers 中使用相同的网格)
  7. 您可以并行请求多个图块并利用 QGIS Server 并行渲染支持(如果启用)。
  8. 由于 QGIS Server 可以将项目存储在 Postgis 上,因此您可以轻松更新项目而无需任何上传。MapProxy 将使用来自 QGIS Server 的更新样式。

例子

MapProxy 文档中有非常好的小示例。

这是最复杂的示例之一,因为它使用自定义网格和 EPSG:3857 以外的 CRS。如果您使用通常的GLOBAL_MERCATOR网格,它会简单得多(在 MapProxy 端和 OpenLayers 端)。

这是一个mapproxy.yaml带有自定义网格的配置文件的小示例。来源是 QGIS 服务器。我GetFeatureInfo在鼠标单击时添加了一个请求,以显示如何将这些请求转发到 QGIS 服务器。我还添加了图层的图例(使用service=WMS&REQUEST=GetLegendGraphic&VERSION=1.3.0)。

layers:
  - name: caop
    title: CAOP by QGIS Server
    sources: [caop_cache_continente]
caches:
  caop_cache_continente:
    meta_size: [4, 4]
    meta_buffer: 20
    # 20+4x256+20
    # width=1064&height=1064
    use_direct_from_level: 14
    concurrent_tile_creators: 2
    link_single_color_images: true
    grids: [continente]
    sources: [continente_wms]
sources:
  continente_wms:
    type: wms
    wms_opts:
      featureinfo: true
      legendgraphic: true
    req:
      url: http://continente.qgis.demo/cgi-bin/qgis_mapserv.fcgi
      layers: freguesia
      transparent: true
grids:
  continente:
    srs: 'EPSG:3763'
    bbox_srs: 'EPSG:3763'
    bbox: [-127104, -301712, 173088, 278544]
    origin: nw
    res: [ 1172.625, 586.3125, 293.15625, 146.578125, 73.2890625, 36.64453125, 18.322265625, 9.1611328125, 4.58056640625, 2.290283203125, 1.1451416015625, 0.57257080078125, 0.286285400390625, 0.1431427001953125, 0.07157135009765625 ]

以下 OpenLayers 文件能够从 MapProxy 获取切片。

<!DOCTYPE html>
<html>

<head>
  <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
  <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css"
    type="text/css">
  <style>
    .map {
      height: 600px;
      width: 100%;
    }
  </style>
  <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
  <script src="resources/js/proj4js/proj4.js"></script>
  <title>OpenLayers example using QGIS Server and MapProxy</title>
</head>

<body>
  <div id="map" class="map"></div>
  <p><image src="http://mapproxy.qgis.demo/mapproxy/service?service=WMS&REQUEST=GetLegendGraphic&VERSION=1.3.0&style=default&FORMAT=image/png&LAYER=caop&transparent=true"></image></p>
  <div id="nodelist"><em>Click on the map to get feature info</em></div>
  <script>
    proj4.defs("EPSG:3763", "+proj=tmerc +lat_0=39.66825833333333 +lon_0=-8.133108333333334 +k=1 +x_0=0 +y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
    ol.proj.proj4.register(proj4);
    var projection = new ol.proj.Projection({
      code: 'EPSG:3763',
      extent: [-127104, -301712, 173088, 278544]
    });

    var projectionExtent = projection.getExtent();

    var size = ol.extent.getWidth(projectionExtent) / 256;
    var newresolutions = new Array(15);
    var newmatrixIds = new Array(15);
    for (var z = 0; z < 15; ++z) {
      newresolutions[z] = size / Math.pow(2, z);
      newmatrixIds[z] = z;
    }

    var tileGrid = new ol.tilegrid.WMTS({
      origin: ol.extent.getTopLeft(projectionExtent), // [ 270000, 3650000 ]
      resolutions: newresolutions,
      matrixIds: newmatrixIds,
      tileSize: [256, 256]
    });

    var caop = new ol.layer.Tile({
      source: new ol.source.TileWMS({
        url: 'http://mapproxy.qgis.demo/mapproxy/service?',
        params: { layers: 'caop', tiled: true, srs: "EPSG:3763" },
        format: 'image/png',
        projection: projection,
        tileGrid: tileGrid
      })
    });

    var map = new ol.Map({
      layers: [caop],
      target: 'map',
      view: new ol.View({
        projection: projection,
        center: [0, 0],
        zoom: 1
      })
    });

    map.on('singleclick', function (evt) {
      document.getElementById('nodelist').innerHTML = "Loading... please wait...";
      var view = map.getView();
      var viewResolution = view.getResolution();
      var url = caop.getSource().getGetFeatureInfoUrl(
        evt.coordinate, viewResolution, view.getProjection(),
        { 'INFO_FORMAT': 'text/html', 'FEATURE_COUNT': 50 });
      if (url) {
        document.getElementById('nodelist').innerHTML = '<iframe seamless src="' + url + '" style="width:100%"></iframe>';
      }
    });
  </script>
</body>

</html>
于 2019-06-29T17:09:30.053 回答
1

它有点重量级,但我一直在使用 GeoServer ( http://geoserver.org/ ) 来提供我的地图图块(它内置了 GeoWebCache)。您需要通过 J2EE 服务器(如 Jetty)运行它,但目前它对我们来说运行良好。

于 2015-07-28T11:41:22.137 回答