1 |
joey |
2108 |
# Copyright (c) 2004 by Intevation GmbH |
2 |
|
|
# Authors: |
3 |
|
|
# Martin Schulze <[email protected]> |
4 |
|
|
# |
5 |
|
|
# This program is free software under the GPL (>=v2) |
6 |
|
|
# Read the file COPYING coming with Thuban for details. |
7 |
|
|
|
8 |
|
|
""" |
9 |
joey |
2112 |
Test for the PyOGCLib from Sean C. Gillies <[email protected]> |
10 |
joey |
2108 |
|
11 |
|
|
http://www.sourceforge.net/projects/pyogclib |
12 |
|
|
|
13 |
joey |
2113 |
Requires the ogclib installed regularily on the system, accessible via |
14 |
|
|
PYTHONPATH or checked out alongside the Thuban checkout. |
15 |
joey |
2108 |
""" |
16 |
|
|
|
17 |
|
|
__version__ = "$Revision$" |
18 |
|
|
# $Source$ |
19 |
|
|
# $Id$ |
20 |
|
|
|
21 |
|
|
import os |
22 |
|
|
import unittest |
23 |
|
|
|
24 |
|
|
from string import split |
25 |
joey |
2113 |
from sys import path |
26 |
joey |
2108 |
|
27 |
joey |
2116 |
from adjustpath import thubandir |
28 |
joey |
2118 |
path.insert(0, thubandir + "/test") |
29 |
joey |
2113 |
|
30 |
joey |
2116 |
import support |
31 |
|
|
|
32 |
joey |
2108 |
# ---------------------------------------------------------------------- |
33 |
|
|
# FIXME: Temporary code until PyOGCLib is a standard requirement |
34 |
|
|
|
35 |
|
|
from sys import path |
36 |
|
|
|
37 |
|
|
# Assume the PyOGCLib to be checked out next to the thuban main directory |
38 |
joey |
2113 |
# setting PYTHONPATH accordingly is fine as well |
39 |
|
|
# |
40 |
joey |
2118 |
pyogclib = os.path.abspath(thubandir + "/../PyOGCLib") |
41 |
|
|
if os.path.isdir(pyogclib) and os.path.isdir(pyogclib + "/ogclib"): |
42 |
|
|
path.insert(0, pyogclib) |
43 |
joey |
2108 |
# ---------------------------------------------------------------------- |
44 |
|
|
|
45 |
joey |
2116 |
_pyogclib_import_error = None |
46 |
joey |
2108 |
try: |
47 |
|
|
from ogclib.WMSClient import WMSClient |
48 |
joey |
2116 |
except ImportError, extra: |
49 |
|
|
_pyogclib_import_error = str(extra) |
50 |
joey |
2108 |
|
51 |
|
|
|
52 |
joey |
2118 |
class TestOGCLib(unittest.TestCase): |
53 |
joey |
2108 |
""" |
54 |
|
|
Defines a test environment for the PyOGCLib, i.e. check whether URL |
55 |
|
|
strings are built properly. |
56 |
|
|
""" |
57 |
|
|
|
58 |
joey |
2116 |
wmsclient = None |
59 |
|
|
|
60 |
joey |
2118 |
def setUp(self): |
61 |
joey |
2116 |
skip_if_no_ogclib() |
62 |
|
|
self.wmsclient = WMSClient() |
63 |
|
|
|
64 |
joey |
2118 |
def compare_URLs(self, foo, bar): |
65 |
joey |
2108 |
""" |
66 |
|
|
Check if two URLs are equal, i.e.: |
67 |
|
|
- check for same base URL |
68 |
|
|
- check same number of HTTP GET arguments |
69 |
|
|
- check whether all arguments from one URL also exist in the second |
70 |
|
|
""" |
71 |
|
|
|
72 |
joey |
2118 |
foo_tuple = split(foo, "?") |
73 |
|
|
bar_tuple = split(bar, "?") |
74 |
joey |
2108 |
|
75 |
|
|
# Check for same base URL |
76 |
|
|
if foo_tuple[0] != bar_tuple[0]: |
77 |
joey |
2118 |
self.fail("%s != %s" %(foo_tuple[0], bar_tuple[0])) |
78 |
joey |
2108 |
|
79 |
joey |
2336 |
# Check for same length of entire HTTP GET argument string |
80 |
joey |
2108 |
if len(foo_tuple) != len(bar_tuple): |
81 |
joey |
2118 |
self.fail("One URL has no arguments"); |
82 |
joey |
2108 |
|
83 |
|
|
# Loop through all HTTP GET arguments for existance |
84 |
|
|
if len(foo_tuple) > 1 and len(bar_tuple) > 1: |
85 |
joey |
2118 |
foo_opts = split(foo_tuple[1], "&") |
86 |
|
|
bar_opts = split(bar_tuple[1], "&") |
87 |
joey |
2108 |
|
88 |
|
|
if len(foo_opts) != len(bar_opts): |
89 |
joey |
2118 |
self.fail("Different number of arguments"); |
90 |
joey |
2108 |
|
91 |
|
|
for part in foo_opts: |
92 |
|
|
if part not in bar_opts: |
93 |
joey |
2118 |
self.fail("%s not in second argument list" % part); |
94 |
joey |
2108 |
|
95 |
|
|
|
96 |
joey |
2118 |
def test_compareURLs(self): |
97 |
joey |
2108 |
"""Perform some tests for own compare routine""" |
98 |
|
|
|
99 |
|
|
result = "http://frida.intevation.org/cgi-bin" |
100 |
joey |
2118 |
self.compare_URLs("http://frida.intevation.org/cgi-bin", result) |
101 |
joey |
2108 |
|
102 |
|
|
result = "http://frida.intevation.org/cgi-bin?foo=eins" |
103 |
joey |
2118 |
self.compare_URLs("http://frida.intevation.org/cgi-bin?foo=eins", result) |
104 |
joey |
2108 |
|
105 |
|
|
result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei" |
106 |
joey |
2118 |
self.compare_URLs("http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei", result) |
107 |
joey |
2108 |
|
108 |
|
|
result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei" |
109 |
joey |
2118 |
self.compare_URLs("http://frida.intevation.org/cgi-bin?bar=zwei&foo=eins", result) |
110 |
joey |
2108 |
|
111 |
|
|
result = "http://frida.intevation.org/cgi-bin?foo=eins&bar=zwei&baz=jan&quux=tux" |
112 |
joey |
2118 |
self.compare_URLs("http://frida.intevation.org/cgi-bin?baz=jan&bar=zwei&quux=tux&foo=eins", result) |
113 |
joey |
2108 |
|
114 |
|
|
|
115 |
joey |
2118 |
def test_CapabilityURL(self): |
116 |
joey |
2108 |
"""Test the getCapabilitiesURL() method""" |
117 |
|
|
|
118 |
|
|
frida = "http://frida.intevation.org/cgi-bin/frida_wms?" |
119 |
|
|
|
120 |
joey |
2116 |
url = self.wmsclient.getCapabilitiesURL(frida, "1.0") |
121 |
joey |
2108 |
result = frida + "WMTVER=1.0&REQUEST=capabilities" |
122 |
joey |
2118 |
self.compare_URLs(url, result) |
123 |
joey |
2108 |
|
124 |
joey |
2116 |
url = self.wmsclient.getCapabilitiesURL(frida, "1.1") |
125 |
joey |
2108 |
result = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetCapabilities" |
126 |
joey |
2118 |
self.compare_URLs(url, result) |
127 |
joey |
2108 |
|
128 |
|
|
|
129 |
joey |
2118 |
def test_GetMapURL(self): |
130 |
joey |
2109 |
"""Test the getMapURL() method""" |
131 |
|
|
|
132 |
|
|
frida = "http://frida.intevation.org/cgi-bin/frida_wms?" |
133 |
|
|
|
134 |
joey |
2112 |
format = 'image/jpeg' |
135 |
|
|
format_enc = 'image%2Fjpeg' |
136 |
joey |
2109 |
width = 400 |
137 |
|
|
height = 350 |
138 |
|
|
epsg = 4326 |
139 |
|
|
bbox = {'minx': -107, 'miny': 40, 'maxx': -109, 'maxy': 41} |
140 |
|
|
layers = [ ] |
141 |
|
|
styles = [ ] |
142 |
|
|
version = '1.1' |
143 |
|
|
|
144 |
|
|
result_base = frida + "WMTVER=1.0&REQUEST=map" + \ |
145 |
joey |
2112 |
"&FORMAT="+format_enc + \ |
146 |
joey |
2118 |
"&SRS=EPSG%s%d" %("%3A", epsg) + \ |
147 |
|
|
"&BBOX=%f%s%f%s%f%s%f" %(bbox['minx'], "%2C", bbox['miny'], "%2C", |
148 |
joey |
2109 |
bbox['maxx'], "%2C", bbox['maxy']) + \ |
149 |
|
|
"&WIDTH=%s" % width + "&HEIGHT=%s" % height |
150 |
|
|
result = result_base + \ |
151 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
152 |
|
|
"&STYLES=" + "%2C".join(styles) |
153 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
154 |
joey |
2109 |
bbox, layers, version=version) |
155 |
|
|
|
156 |
|
|
# Repeat and continue with version 1.1, as denoted in OGC 01-068r3 |
157 |
|
|
version = '1.1' |
158 |
|
|
result_base = frida + "VERSION=1.1&SERVICE=WMS&REQUEST=GetMap" + \ |
159 |
joey |
2112 |
"&FORMAT="+format_enc + \ |
160 |
joey |
2118 |
"&SRS=EPSG%s%d" %("%3A", epsg) + \ |
161 |
|
|
"&BBOX=%f%s%f%s%f%s%f" %(bbox['minx'], "%2C", bbox['miny'], "%2C", |
162 |
joey |
2109 |
bbox['maxx'], "%2C", bbox['maxy']) + \ |
163 |
|
|
"&WIDTH=%s" % width + "&HEIGHT=%s" % height |
164 |
|
|
result = result_base + \ |
165 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
166 |
|
|
"&STYLES=" + "%2C".join(styles) |
167 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
168 |
joey |
2109 |
bbox, layers, version=version) |
169 |
joey |
2118 |
self.compare_URLs(result, url) |
170 |
joey |
2109 |
|
171 |
|
|
result += "&TRANSPARENT=TRUE" |
172 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
173 |
joey |
2109 |
bbox, layers, version=version, |
174 |
|
|
transparent=1 ) |
175 |
joey |
2118 |
self.compare_URLs(result, url) |
176 |
joey |
2109 |
|
177 |
|
|
result += "&BGCOLOR=0xFF00FF" |
178 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
179 |
joey |
2109 |
bbox, layers, version=version, |
180 |
|
|
transparent=1, bgcolor='0xFF00FF') |
181 |
joey |
2118 |
self.compare_URLs(result, url) |
182 |
joey |
2109 |
|
183 |
|
|
layers = [ 'foo' ] |
184 |
|
|
result = result_base + \ |
185 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
186 |
|
|
"&STYLES=" + "%2C".join(styles) |
187 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
188 |
joey |
2109 |
bbox, layers, version=version) |
189 |
joey |
2118 |
self.compare_URLs(result, url) |
190 |
joey |
2109 |
|
191 |
joey |
2118 |
layers.append('bar') |
192 |
joey |
2109 |
result = result_base + \ |
193 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
194 |
|
|
"&STYLES=" + "%2C".join(styles) |
195 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
196 |
joey |
2109 |
bbox, layers, version=version) |
197 |
joey |
2118 |
self.compare_URLs(result, url) |
198 |
joey |
2109 |
|
199 |
|
|
styles = [ 'something' ] |
200 |
|
|
result = result_base + \ |
201 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
202 |
|
|
"&STYLES=" + "%2C".join(styles) |
203 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
204 |
joey |
2109 |
bbox, layers, version=version, |
205 |
|
|
styles = styles) |
206 |
joey |
2118 |
self.compare_URLs(result, url) |
207 |
joey |
2109 |
|
208 |
joey |
2118 |
styles.append('else') |
209 |
joey |
2109 |
result = result_base + \ |
210 |
|
|
"&LAYERS=" + "%2C".join(layers) + \ |
211 |
|
|
"&STYLES=" + "%2C".join(styles) |
212 |
joey |
2116 |
url = self.wmsclient.getMapURL(frida, format, width, height, epsg, |
213 |
joey |
2109 |
bbox, layers, version=version, |
214 |
|
|
styles = styles) |
215 |
joey |
2118 |
self.compare_URLs(result, url) |
216 |
joey |
2109 |
|
217 |
|
|
|
218 |
joey |
2116 |
def skip_if_no_ogclib(): |
219 |
|
|
if _pyogclib_import_error is not None: |
220 |
|
|
raise support.SkipTest(_pyogclib_import_error) |
221 |
|
|
# raise support.SkipTest("No PyOGCLib found, hence no tests available.") |
222 |
|
|
|
223 |
|
|
|
224 |
joey |
2108 |
if __name__ == "__main__": |
225 |
joey |
2116 |
support.run_tests() |
226 |
joey |
2109 |
|
227 |
|
|
""" |
228 |
|
|
|
229 |
|
|
Additional notes: |
230 |
|
|
- Parameter names shall not be case sensitive, but parameter |
231 |
|
|
values shall be case sensitive. [OGC 01-068r3, 6.4.1, p13] |
232 |
|
|
|
233 |
|
|
This is not supported by the compare URL method, but may need to |
234 |
|
|
in the future. |
235 |
|
|
|
236 |
|
|
- Some geospatial inforamtion may be available at multiple times, |
237 |
|
|
like a whether map or satalite photo. Capabilities may announce |
238 |
|
|
available times. [OGC 01-068r3, 6.5.7, p18] |
239 |
|
|
|
240 |
|
|
This is not yet supported by WMSClient |
241 |
|
|
|
242 |
|
|
- According to the specs a comma in LAYERS and STYLES list doesn't |
243 |
|
|
have to be encoded. Maybe this could cause problems with some |
244 |
|
|
servers, just to keep in mind. |
245 |
|
|
|
246 |
|
|
""" |