/[thuban]/branches/WIP-pyshapelib-bramz/test/test_proj.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/test/test_proj.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1827 - (show annotations)
Tue Oct 14 16:04:35 2003 UTC (21 years, 4 months ago) by bh
Original Path: trunk/thuban/test/test_proj.py
File MIME type: text/x-python
File size: 16002 byte(s)
Execute support.run_tests when run as
__main__ so that missing unsubscribes are detected
(TestProjFile.tearDown): Destroy the proj_file properly

1 # Copyright (c) 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[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 Test the Thuban-specific Projection class
10 """
11
12 __version__ = "$Revision$"
13 # $Source$
14 # $Id$
15
16 import unittest
17 import os
18
19 import xmlsupport
20 import support
21 support.initthuban()
22
23 from Thuban import _
24 from Thuban.Model.proj import Projection, ProjFile, \
25 PROJ_UNITS_METERS, PROJ_UNITS_DEGREES
26 from Thuban.Model.messages import PROJECTION_ADDED, PROJECTION_REMOVED, \
27 PROJECTION_REPLACED
28 import Thuban.Model.resource as resource
29
30 from xmlsupport import sax_eventlist
31
32 from xml.sax import SAXParseException
33
34
35 class TestProjection(unittest.TestCase, support.FloatComparisonMixin):
36
37 """Test cases for the Thuban-specific Projection class
38 """
39
40 def test(self):
41 """Test Projection"""
42 params = ["zone=26", "proj=utm", "ellps=clrk66"]
43 proj = Projection(params)
44 self.assertEquals(proj.params, params)
45
46 # It's not clear whether this value is really the correct one
47 # but a test failure here probably still means a bug somewhere
48 self.assertFloatSeqEqual(proj.Forward(0, 0),
49 [3623101.8103431347, 0.0],
50 epsilon = 1e-5)
51 self.assertFloatSeqEqual(proj.Inverse(3623101.8103431347, 0.0),
52 [-0.00065775699878736467, 0])
53
54 self.assertFloatSeqEqual(proj.ForwardBBox((0, 0, 2, 2)),
55 (3620891.3077618643, 0.0,
56 3875381.8535437919, 252962.10480170773),
57 epsilon = 1e-5)
58
59 # GetName()
60 self.assertEquals(proj.GetName(), _("Unknown"))
61
62 # GetParameter()
63 self.assertEquals(proj.GetParameter("zone"), "26")
64 self.assertEquals(proj.GetParameter("proj"), "utm")
65 self.assertEquals(proj.GetParameter("ellps"), "clrk66")
66 self.assertEquals(proj.GetParameter("hallo"), "")
67
68 # GetAllParameters()
69 self.assertEquals(proj.GetAllParameters(), params)
70
71 # GetName()
72 proj = Projection(params, "MyName")
73 self.assertEquals(proj.GetName(), "MyName")
74
75 def test_get_parameter_without_equals_sign(self):
76 """Test Projection.GetParameter() for a parameter without '=' sign"""
77 proj = Projection(["proj=utm", "zone=34", "south", "ellps=clrk66"])
78 # The Projection class pretends that for parameters specified
79 # without a value the value is the same as the parameter name.
80 self.assertEquals(proj.GetParameter("south"), "south")
81
82 def test_get_projection_units_geo(self):
83 """Test Projection.GetProjectedUnits() for geographic projection"""
84 proj = Projection(["proj=latlong", "to_meter=0.017453292519943295",
85 "ellps=clrk66"])
86 self.assertEquals(proj.GetProjectedUnits(), PROJ_UNITS_DEGREES)
87
88 def test_get_projection_units_normal(self):
89 """Test Projection.GetProjectedUnits() for normal projection"""
90 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"])
91 self.assertEquals(proj.GetProjectedUnits(), PROJ_UNITS_METERS)
92
93 def test_label(self):
94 """Test Projection.Label() without epsg"""
95 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"],
96 name = "My Projection")
97 self.assertEquals(proj.Label(), "My Projection")
98
99 def test_label_epsg(self):
100 """Test Projection.Label() with epsg"""
101 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"],
102 name = "My Projection", epsg="42")
103 self.assertEquals(proj.Label(), "EPSG 42 My Projection")
104
105 def test_epsgcode_for_non_epsg_projection(self):
106 """Test Projection.EPSGCode() without epsg"""
107 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"],
108 name = "My Projection")
109 self.assertEquals(proj.EPSGCode(), None)
110
111 def test_epsgcode_for_real_epsg_projection(self):
112 """Test Projection.EPSGCode() with epsg"""
113 proj = Projection(["zone=26", "proj=utm", "ellps=clrk66"],
114 name = "My Projection", epsg="42")
115 self.assertEquals(proj.EPSGCode(), "42")
116
117
118
119 class TestProjFileSimple:
120
121 def test_init(self):
122 """Test ProjFile coinstructor"""
123 proj_file = ProjFile("some_filename")
124 self.assertEquals(proj_file.GetFilename(), "some_filename")
125 self.assertEquals(len(proj_file.GetProjections()), 0)
126
127 def test_set_filename(self):
128 """Test ProjFile.SetFilename()"""
129 proj_file = ProjFile("some_filename")
130 proj.SetFilename("other_name")
131 self.assertEquals(proj_file.GetFilename(), "other_name")
132
133
134 class TestProjFile(unittest.TestCase, support.SubscriberMixin):
135
136 """Test cases for reading and writing projection files.
137 """
138
139 def setUp(self):
140 self.clear_messages()
141 self.proj0 = Projection(["proj=tmerc", "ellps=clrk66"])
142 self.proj1 = Projection(["proj=utm", "ellps=clrk66"])
143 self.proj2 = Projection(["proj=lcc", "ellps=clrk66",
144 "lat_1=0", "lat_2=20"])
145 self.proj_file = ProjFile("some_filename")
146 for msg in [PROJECTION_ADDED, PROJECTION_REMOVED, PROJECTION_REPLACED]:
147 self.proj_file.Subscribe(msg, self.subscribe_with_params, msg)
148
149 def tearDown(self):
150 self.clear_messages()
151 self.proj_file.Destroy()
152
153 def test_add_remove(self):
154 """Test ProjFile.Add() and ProjFile.Remove()"""
155 self.proj_file.Add(self.proj0)
156 self.proj_file.Add(self.proj1)
157 self.assertEquals(self.proj_file.GetProjections(),
158 [self.proj0, self.proj1])
159 self.check_messages([(self.proj0, PROJECTION_ADDED),
160 (self.proj1, PROJECTION_ADDED)])
161 self.clear_messages()
162
163 self.proj_file.Remove(self.proj0)
164 self.assertEquals(self.proj_file.GetProjections(), [self.proj1])
165 self.check_messages([(self.proj0, PROJECTION_REMOVED)])
166
167 def test_remove_non_existing(self):
168 """Test ProjFile.Remove(<proj not in projfile>)"""
169 self.assertRaises(ValueError, self.proj_file.Remove, self.proj0)
170 # Nothing happened, so no messages should have been sent
171 self.check_messages([])
172
173 def test_replace(self):
174 """Test ProjFile.Replace()"""
175 self.proj_file.Add(self.proj0)
176 self.proj_file.Add(self.proj1)
177 self.clear_messages()
178
179 # Replace()
180 self.proj_file.Replace(self.proj0, self.proj2)
181 self.assertEquals(self.proj_file.GetProjections(),
182 [self.proj2, self.proj1])
183 self.check_messages([(self.proj0, self.proj2, PROJECTION_REPLACED)])
184
185 def test_replace_non_existing(self):
186 """Test ProjFile.Replace(<proj not in projfile>, <some proj>)"""
187 self.proj_file.Add(self.proj0)
188 self.proj_file.Add(self.proj1)
189 self.clear_messages()
190 self.assertRaises(ValueError,
191 self.proj_file.Replace, self.proj2, self.proj0)
192 # All projections should still be there
193 self.assertEquals(self.proj_file.GetProjections(),
194 [self.proj0, self.proj1])
195 # Nothing happened, so no messages should have been sent
196 self.check_messages([])
197
198
199 class ProjFileTest(unittest.TestCase, support.FileTestMixin,
200 xmlsupport.ValidationTest):
201
202 """Base class for the proj file tests that read or write files"""
203
204 def filename(self):
205 """Return the filename for the test"""
206 return self.temp_file_name(self.id() + ".proj")
207
208
209 class ProjFileReadTests(ProjFileTest):
210
211 """Test read ProjFile objects from files"""
212
213 def test_read_non_existing_file(self):
214 """Test read_proj_file with non-existing file"""
215 self.assertRaises(IOError,
216 resource.read_proj_file,
217 self.temp_file_name("nonexistent.proj"))
218
219 def test_read_unreadable_file(self):
220 """Test read_proj_file with unreadable file
221
222 As currently written this only works on unix-like systems and
223 not e.g. on MS Windows.
224 """
225 filename = self.filename()
226 file = open(filename, "w")
227 file.close()
228 os.chmod(filename, 0200) # write-only
229 self.assertRaises(IOError, resource.read_proj_file, filename)
230
231 def test_read_empty_file(self):
232 """Test read_proj_file with empty file"""
233 filename = self.filename()
234 file = open(filename, "w")
235 file.close()
236
237 self.assertRaises(SAXParseException, resource.read_proj_file, filename)
238
239 def test_get_system_proj_file(self):
240 """Test resource.get_system_proj_file()
241
242 This is primarily to test whether the system proj file contains
243 invalid projection paramers and whether the proj file is not
244 empty
245 """
246 projfile, warnings = resource.get_system_proj_file()
247 self.assertEquals(warnings, [])
248 self.assert_(len(projfile.GetProjections()) > 0)
249
250
251 class WriteProjFileTests(ProjFileTest):
252
253 """Test cases for writing proj files"""
254
255 def compare_xml(self, xml1, xml2):
256 self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))
257
258 def doTestWrite(self, projfile, expected):
259 filename = self.filename()
260
261 resource.write_proj_file(projfile)
262
263 file = open(filename)
264 written_contents = file.read()
265 file.close()
266 self.compare_xml(written_contents, expected)
267 self.validate_data(written_contents)
268 self.validate_data(expected)
269
270 def test_write(self):
271 """Test write_proj_file"""
272 pf = ProjFile(self.filename())
273 pf.Add(Projection(['proj=tmerc', 'ellps=clrk66',
274 'lat_0=90w', 'lon_0=90w', 'k=1'],
275 "Transverse Mercator",))
276 pf.Add(Projection(["proj=tmerc",
277 "lat_0=0.000000000", "lon_0=-62.000000000",
278 "k=0.999500", "x_0=400000.000", "y_0=0.000",
279 "ellps=clrk80", "units=m"],
280 "Anguilla 1957 / British West Indies Grid",
281 epsg="200"))
282 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
283 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
284 <projectionlist>
285 <projection name="Transverse Mercator">
286 <parameter value="proj=tmerc"/>
287 <parameter value="ellps=clrk66"/>
288 <parameter value="lat_0=90w"/>
289 <parameter value="lon_0=90w"/>
290 <parameter value="k=1"/>
291 </projection>
292 <projection epsg="200"
293 name="Anguilla 1957 / British West Indies Grid">
294 <parameter value="proj=tmerc"/>
295 <parameter value="lat_0=0.000000000"/>
296 <parameter value="lon_0=-62.000000000"/>
297 <parameter value="k=0.999500"/>
298 <parameter value="x_0=400000.000"/>
299 <parameter value="y_0=0.000"/>
300 <parameter value="ellps=clrk80"/>
301 <parameter value="units=m"/>
302 </projection>
303 </projectionlist>
304 '''
305 self.doTestWrite(pf, file_contents)
306
307 def test_write_empty_file(self):
308 """Test write empty ProjFile"""
309 pf = ProjFile(self.filename())
310 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
311 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
312 <projectionlist>
313 </projectionlist>
314 '''
315 self.doTestWrite(pf, file_contents)
316
317
318 class TestLoadingProjFile(support.FileLoadTestCase):
319
320 file_extension = ".proj"
321 file_contents = '''\
322 <?xml version="1.0" encoding="UTF-8"?>
323 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
324 <projectionlist>
325 <projection name="Transverse Mercator">
326 <parameter value="proj=tmerc"/>
327 <parameter value="ellps=clrk66"/>
328 <parameter value="lat_0=90w"/>
329 <parameter value="lon_0=90w"/>
330 <parameter value="k=1"/>
331 </projection>
332 <projection epsg="200" name="Anguilla 1957 / British West Indies Grid">
333 <parameter value="proj=tmerc"/>
334 <parameter value="lat_0=0.000000000"/>
335 <parameter value="lon_0=-62.000000000"/>
336 <parameter value="k=0.999500"/>
337 <parameter value="x_0=400000.000"/>
338 <parameter value="y_0=0.000"/>
339 <parameter value="ellps=clrk80"/>
340 <parameter value="units=m"/>
341 </projection>
342 </projectionlist>
343 '''
344
345 def check_projection(self, proj, label, parameters):
346 """Check the values of the proj's label and parameters"""
347 self.assertEquals(proj.Label(), label)
348 params = proj.GetAllParameters()[:]
349 params.sort()
350 self.assertEquals(params, parameters)
351
352 def test(self):
353 projfile, warnings = resource.read_proj_file(self.filename())
354 # no warnings
355 self.assertEquals(warnings, [])
356
357 # There are two projections
358 projs = projfile.GetProjections()
359 self.assertEquals(len(projs), 2)
360
361 self.check_projection(projs[0],
362 "Transverse Mercator",
363 ['ellps=clrk66', 'k=1', 'lat_0=90w', 'lon_0=90w',
364 'proj=tmerc'])
365 self.check_projection(projs[1],
366 "EPSG 200 Anguilla 1957 / British West Indies Grid",
367 ["ellps=clrk80", "k=0.999500",
368 "lat_0=0.000000000", "lon_0=-62.000000000",
369 "proj=tmerc", "units=m",
370 "x_0=400000.000", "y_0=0.000"])
371
372
373 class TestLoadingProjFileWithEmptyProjectionlist(support.FileLoadTestCase):
374
375 file_extension = ".proj"
376 file_contents = '''\
377 <?xml version="1.0" encoding="UTF-8"?>
378 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
379 <projectionlist>
380 </projectionlist>
381 '''
382
383 def test(self):
384 projfile, warnings = resource.read_proj_file(self.filename())
385 # no warnings
386 self.assertEquals(warnings, [])
387
388 # There are no projections
389 self.assertEquals(len(projfile.GetProjections()), 0)
390
391
392 class TestProjFileWithInvalidParameters(unittest.TestCase,
393 support.FileLoadTestCase):
394
395 file_extension = ".proj"
396 file_contents = '''\
397 <?xml version="1.0" encoding="UTF-8"?>
398 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
399 <projectionlist>
400 <projection name="Universal Transverse Mercator">
401 <parameter value="proj=utm"/>
402 <parameter value="ellps=clrk66"/>
403 <!-- an invalid zone number to trigger the parameter checking
404 in the proj library -->
405 <parameter value="zone=1000"/>
406 </projection>
407 <projection name="Transverse Mercator">
408 <parameter value="proj=tmerc"/>
409 <parameter value="ellps=clrk66"/>
410 <parameter value="lat_0=90w"/>
411 <parameter value="lon_0=90w"/>
412 <parameter value="k=1"/>
413 </projection>
414 </projectionlist>
415 '''
416
417 def setUp(self):
418 support.FileLoadTestCase.setUp(self)
419
420 def test(self):
421 """Test reading a proj file with invalid parameters"""
422 projfile, warnings = resource.read_proj_file(self.filename())
423 projs = projfile.GetProjections()
424 self.assertEquals(len(projs), 1)
425 params = projs[0].GetAllParameters()[:]
426 params.sort()
427 self.assertEquals(params, ['ellps=clrk66', 'k=1', 'lat_0=90w',
428 'lon_0=90w', 'proj=tmerc'])
429 self.assertEquals(warnings,
430 ['Error in projection "Universal Transverse Mercator":'
431 ' invalid UTM zone number'])
432
433
434 if __name__ == "__main__":
435 support.run_tests()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26