How to cache QGIS Server WMS?

It seems that the raster tiles started to go out of fashion, but still I need a solution to do it somehow for my QGIS Server WMS.

Until now, I tried TileCache, but I could not get it to work in OL3, and it also seems a bit "old".

So what would be my best bet if I later want to use the cached layer in my OL3 application? TileStache, Mapproxy, MapCache?

I have a QGIS Server under CentOS 7.

+5
source share
2 answers

It's a bit heavy, but I used GeoServer ( http://geoserver.org/ ) to serve my card tiles (it has a GeoWebCache built in). You need to run it through a J2EE server (e.g. Jetty), but it works great for us at the moment.

+1
source

QGIS Server works well with MapProxy . With QGIS Server + MapProxy you get the best out of QGIS style plus tile cache speed.

MapProxy is written in Python, and you probably already installed Python on the server. You can (and should) run MapProxy in a virtual environment. MapProxy's instructions are clear enough, and it really is a matter of minutes to launch it and retrieve data from QGIS Server.

  1. It is much easier than GeoWebCache.
  2. It caches and maintains tiles (just use tiled: true in your WMS request)
  3. This works very well with OpenLayers. Once you install it, you will get a demo page with OpenLayers examples.
  4. You can call GetFeatureInfo requests for a cached source.
  5. You can call GetLegendGraphic requests for a cached source.
  6. It can handle user-defined grids (if you use the same in OpenLayers)
  7. You can request more than one tile in parallel and take advantage of the support of the parallel rendering of QGIS Server (if enabled).
  8. Since QGIS Server can store projects on Postgis, you can easily update the project without any downloads. MapProxy will use updated styles from QGIS Server.

example

The MapProxy documentation has some very good little examples.

This is one of the most difficult examples because it uses a custom mesh and CRS that is different from EPSG: 3857. If you use the regular GLOBAL_MERCATOR mesh, this will be much easier (on the MapProxy side and the OpenLayers side).

This is a small mapproxy.yaml example of a custom mesh mapproxy.yaml configuration. Source - QGIS Server. I added a GetFeatureInfo request with a click of the mouse to show how these requests can be redirected to QGIS Server. I also added a layer legend (using 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 ] 

The following OpenLayers file can take tiles from 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.imtqy.com/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.imtqy.com/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> 
0
source

All Articles