Skip to content

Commit

Permalink
[tests] Add XYX slippy map to test QGIS server
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
elpaso committed Nov 9, 2017
1 parent 3fc4be3 commit f29c9c9
Showing 1 changed file with 52 additions and 2 deletions.
54 changes: 52 additions & 2 deletions tests/src/python/qgis_wrapped_server.py
Expand Up @@ -6,6 +6,11 @@
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:
Expand Down Expand Up @@ -49,9 +54,13 @@
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'))
Expand Down Expand Up @@ -100,6 +109,42 @@ def responseComplete(self):
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):
Expand Down Expand Up @@ -128,8 +173,13 @@ def do_POST(self):
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,
Expand Down

0 comments on commit f29c9c9

Please sign in to comment.