[tests] Add XYX slippy map to test QGIS server

Plus: multi-threading server side (for speed)

This is useful for testing various authentication
shemes on a slippy-map server (that uses multi-threading
in QGIS desktop)
This commit is contained in:
Alessandro Pasotti 2017-11-09 12:23:03 +01:00
parent 3fc4be3f10
commit f29c9c9965

View File

@ -6,6 +6,11 @@ This script launches a QGIS Server listening on port 8081 or on the port
specified on the environment variable QGIS_SERVER_PORT.
QGIS_SERVER_HOST (defaults to 127.0.0.1)
A XYZ slippy maps service is also available for multithreading testing:
?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world
For testing purposes, HTTP Basic can be enabled by setting the following
environment variables:
@ -49,9 +54,13 @@ os.environ['QT_HASH_SEED'] = '1'
import sys
import signal
import ssl
import math
import urllib.parse
from http.server import BaseHTTPRequestHandler, HTTPServer
from qgis.core import QgsApplication
from socketserver import ThreadingMixIn
import threading
from qgis.core import QgsApplication, QgsCoordinateTransform, QgsCoordinateReferenceSystem
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
QGIS_SERVER_PORT = int(os.environ.get('QGIS_SERVER_PORT', '8081'))
@ -100,6 +109,42 @@ if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
qgs_server.serverInterface().registerFilter(filter)
def num2deg(xtile, ytile, zoom):
"""This returns the NW-corner of the square. Use the function with xtile+1 and/or ytile+1
to get the other corners. With xtile+0.5 & ytile+0.5 it will return the center of the tile."""
n = 2.0 ** zoom
lon_deg = xtile / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
lat_deg = math.degrees(lat_rad)
return (lat_deg, lon_deg)
class XYZFilter(QgsServerFilter):
"""XYZ server, example: ?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world"""
def requestReady(self):
handler = self.serverInterface().requestHandler()
if handler.parameter('SERVICE') == 'XYZ':
x = int(handler.parameter('X'))
y = int(handler.parameter('Y'))
z = int(handler.parameter('Z'))
# NW corner
lat_deg, lon_deg = num2deg(x, y, z)
# SE corner
lat_deg2, lon_deg2 = num2deg(x + 1, y + 1, z)
handler.setParameter('SERVICE', 'WMS')
handler.setParameter('REQUEST', 'GetMap')
handler.setParameter('VERSION', '1.3.0')
handler.setParameter('SRS', 'EPSG:4326')
handler.setParameter('HEIGHT', '256')
handler.setParameter('WIDTH', '256')
handler.setParameter('BBOX', "{},{},{},{}".format(lat_deg2, lon_deg, lat_deg, lon_deg2))
xyzfilter = XYZFilter(qgs_server.serverInterface())
qgs_server.serverInterface().registerFilter(xyzfilter)
class Handler(BaseHTTPRequestHandler):
def do_GET(self, post_body=None):
@ -128,8 +173,13 @@ class Handler(BaseHTTPRequestHandler):
return self.do_GET(post_body)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
pass
if __name__ == '__main__':
server = HTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
server = ThreadedHTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
if https:
server.socket = ssl.wrap_socket(server.socket,
certfile=QGIS_SERVER_PKI_CERTIFICATE,