【问题标题】:How to cache QGIS Server WMS?如何缓存 QGIS Server WMS?
【发布时间】:2015-07-28 09:40:43
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我正在使用 WMS-->Tilecache(只是 tilecache cgi 模块)-->OL3 (EPSG:3857)。实际工作正常。

标签: openlayers-3 qgis tilestache


【解决方案1】:

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

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

  1. 比 GeoWebCache 轻很多
  2. 它缓存并提供切片(只需在您的 WMS 请求中使用 tiled: true
  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>

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 谢谢,我知道 Geoserver,但那是一个不同的地图服务器软件。我使用 QGIS Server 是有原因的;它能够提供与您在 QGIS Desktop 中设计的完全相同的符号系统。我有 300 个符号/层。
    猜你喜欢
    • 1970-01-01
    • 2018-10-06
    • 2015-10-26
    • 2021-07-23
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 2010-12-24
    • 2019-02-03
    相关资源
    最近更新 更多