6
6
specified on the environment variable QGIS_SERVER_PORT.
7
7
QGIS_SERVER_HOST (defaults to 127.0.0.1)
8
8
9
+ A XYZ map service is also available for multithreading testing:
10
+
11
+ ?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world
12
+
13
+
9
14
For testing purposes, HTTP Basic can be enabled by setting the following
10
15
environment variables:
11
16
49
54
import sys
50
55
import signal
51
56
import ssl
57
+ import math
52
58
import urllib .parse
53
59
from http .server import BaseHTTPRequestHandler , HTTPServer
54
- from qgis .core import QgsApplication
55
- from qgis .server import QgsServer , QgsServerRequest , QgsBufferServerRequest , QgsBufferServerResponse
60
+ from socketserver import ThreadingMixIn
61
+ import threading
62
+
63
+ from qgis .core import QgsApplication , QgsCoordinateTransform , QgsCoordinateReferenceSystem
64
+ from qgis .server import QgsServer , QgsServerRequest , QgsBufferServerRequest , QgsBufferServerResponse , QgsServerFilter
56
65
57
66
QGIS_SERVER_PORT = int (os .environ .get ('QGIS_SERVER_PORT' , '8081' ))
58
67
QGIS_SERVER_HOST = os .environ .get ('QGIS_SERVER_HOST' , '127.0.0.1' )
77
86
78
87
79
88
if os .environ .get ('QGIS_SERVER_HTTP_BASIC_AUTH' ) is not None :
80
- from qgis .server import QgsServerFilter
81
89
import base64
82
90
83
91
class HTTPBasicFilter (QgsServerFilter ):
@@ -100,6 +108,42 @@ def responseComplete(self):
100
108
qgs_server .serverInterface ().registerFilter (filter )
101
109
102
110
111
+ def num2deg (xtile , ytile , zoom ):
112
+ """This returns the NW-corner of the square. Use the function with xtile+1 and/or ytile+1
113
+ to get the other corners. With xtile+0.5 & ytile+0.5 it will return the center of the tile."""
114
+ n = 2.0 ** zoom
115
+ lon_deg = xtile / n * 360.0 - 180.0
116
+ lat_rad = math .atan (math .sinh (math .pi * (1 - 2 * ytile / n )))
117
+ lat_deg = math .degrees (lat_rad )
118
+ return (lat_deg , lon_deg )
119
+
120
+
121
+ class XYZFilter (QgsServerFilter ):
122
+ """XYZ server, example: ?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world"""
123
+
124
+ def requestReady (self ):
125
+ handler = self .serverInterface ().requestHandler ()
126
+ if handler .parameter ('SERVICE' ) == 'XYZ' :
127
+ x = int (handler .parameter ('X' ))
128
+ y = int (handler .parameter ('Y' ))
129
+ z = int (handler .parameter ('Z' ))
130
+ # NW corner
131
+ lat_deg , lon_deg = num2deg (x , y , z )
132
+ # SE corner
133
+ lat_deg2 , lon_deg2 = num2deg (x + 1 , y + 1 , z )
134
+ handler .setParameter ('SERVICE' , 'WMS' )
135
+ handler .setParameter ('REQUEST' , 'GetMap' )
136
+ handler .setParameter ('VERSION' , '1.3.0' )
137
+ handler .setParameter ('SRS' , 'EPSG:4326' )
138
+ handler .setParameter ('HEIGHT' , '256' )
139
+ handler .setParameter ('WIDTH' , '256' )
140
+ handler .setParameter ('BBOX' , "{},{},{},{}" .format (lat_deg2 , lon_deg , lat_deg , lon_deg2 ))
141
+
142
+
143
+ xyzfilter = XYZFilter (qgs_server .serverInterface ())
144
+ qgs_server .serverInterface ().registerFilter (xyzfilter )
145
+
146
+
103
147
class Handler (BaseHTTPRequestHandler ):
104
148
105
149
def do_GET (self , post_body = None ):
@@ -128,8 +172,13 @@ def do_POST(self):
128
172
return self .do_GET (post_body )
129
173
130
174
175
+ class ThreadedHTTPServer (ThreadingMixIn , HTTPServer ):
176
+ """Handle requests in a separate thread."""
177
+ pass
178
+
179
+
131
180
if __name__ == '__main__' :
132
- server = HTTPServer ((QGIS_SERVER_HOST , QGIS_SERVER_PORT ), Handler )
181
+ server = ThreadedHTTPServer ((QGIS_SERVER_HOST , QGIS_SERVER_PORT ), Handler )
133
182
if https :
134
183
server .socket = ssl .wrap_socket (server .socket ,
135
184
certfile = QGIS_SERVER_PKI_CERTIFICATE ,
0 commit comments