/[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 1831 - (show annotations)
Thu Oct 16 16:36:11 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: 16909 byte(s)
(TestProjFile): Clarify the doc-string
(ProjFileReadTests): Update doc-string
(ProjFileReadTests.test_get_system_proj_file): Check whether the
system proj files is cached.
(ProjFileLoadTestCase): New base class for the proj file tests
derived from support.FileLoadTestCase to provide some common
behavior.
(TestLoadingProjFile)
(TestLoadingProjFileWithEmptyProjectionlist.file_contents)
(TestProjFileWithInvalidParameters.file_contents): Derive from
ProjFileLoadTestCase
(TestLoadingProjFile.test_caching): New. Test whether the cache
works

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 ProjFile objects"""
137
138 def setUp(self):
139 self.clear_messages()
140 self.proj0 = Projection(["proj=tmerc", "ellps=clrk66"])
141 self.proj1 = Projection(["proj=utm", "ellps=clrk66"])
142 self.proj2 = Projection(["proj=lcc", "ellps=clrk66",
143 "lat_1=0", "lat_2=20"])
144 self.proj_file = ProjFile("some_filename")
145 for msg in [PROJECTION_ADDED, PROJECTION_REMOVED, PROJECTION_REPLACED]:
146 self.proj_file.Subscribe(msg, self.subscribe_with_params, msg)
147
148 def tearDown(self):
149 self.clear_messages()
150 self.proj_file.Destroy()
151
152 def test_add_remove(self):
153 """Test ProjFile.Add() and ProjFile.Remove()"""
154 self.proj_file.Add(self.proj0)
155 self.proj_file.Add(self.proj1)
156 self.assertEquals(self.proj_file.GetProjections(),
157 [self.proj0, self.proj1])
158 self.check_messages([(self.proj0, PROJECTION_ADDED),
159 (self.proj1, PROJECTION_ADDED)])
160 self.clear_messages()
161
162 self.proj_file.Remove(self.proj0)
163 self.assertEquals(self.proj_file.GetProjections(), [self.proj1])
164 self.check_messages([(self.proj0, PROJECTION_REMOVED)])
165
166 def test_remove_non_existing(self):
167 """Test ProjFile.Remove(<proj not in projfile>)"""
168 self.assertRaises(ValueError, self.proj_file.Remove, self.proj0)
169 # Nothing happened, so no messages should have been sent
170 self.check_messages([])
171
172 def test_replace(self):
173 """Test ProjFile.Replace()"""
174 self.proj_file.Add(self.proj0)
175 self.proj_file.Add(self.proj1)
176 self.clear_messages()
177
178 # Replace()
179 self.proj_file.Replace(self.proj0, self.proj2)
180 self.assertEquals(self.proj_file.GetProjections(),
181 [self.proj2, self.proj1])
182 self.check_messages([(self.proj0, self.proj2, PROJECTION_REPLACED)])
183
184 def test_replace_non_existing(self):
185 """Test ProjFile.Replace(<proj not in projfile>, <some proj>)"""
186 self.proj_file.Add(self.proj0)
187 self.proj_file.Add(self.proj1)
188 self.clear_messages()
189 self.assertRaises(ValueError,
190 self.proj_file.Replace, self.proj2, self.proj0)
191 # All projections should still be there
192 self.assertEquals(self.proj_file.GetProjections(),
193 [self.proj0, self.proj1])
194 # Nothing happened, so no messages should have been sent
195 self.check_messages([])
196
197
198 class ProjFileTest(unittest.TestCase, support.FileTestMixin,
199 xmlsupport.ValidationTest):
200
201 """Base class for the proj file tests that read or write files"""
202
203 def filename(self):
204 """Return the filename for the test"""
205 return self.temp_file_name(self.id() + ".proj")
206
207
208 class ProjFileReadTests(ProjFileTest):
209
210 """Test read ProjFile objects from files
211
212 The files only cover error handling and the system projection file.
213 """
214
215 def test_read_non_existing_file(self):
216 """Test read_proj_file with non-existing file"""
217 self.assertRaises(IOError,
218 resource.read_proj_file,
219 self.temp_file_name("nonexistent.proj"))
220
221 def test_read_unreadable_file(self):
222 """Test read_proj_file with unreadable file
223
224 As currently written this only works on unix-like systems and
225 not e.g. on MS Windows.
226 """
227 filename = self.filename()
228 file = open(filename, "w")
229 file.close()
230 os.chmod(filename, 0200) # write-only
231 self.assertRaises(IOError, resource.read_proj_file, filename)
232
233 def test_read_empty_file(self):
234 """Test read_proj_file with empty file"""
235 filename = self.filename()
236 file = open(filename, "w")
237 file.close()
238
239 self.assertRaises(SAXParseException, resource.read_proj_file, filename)
240
241 def test_get_system_proj_file(self):
242 """Test resource.get_system_proj_file()
243
244 This is primarily to test whether the system proj file contains
245 invalid projection paramers and whether the proj file is not
246 empty
247 """
248 projfile, warnings = resource.get_system_proj_file()
249 self.assertEquals(warnings, [])
250 self.assert_(len(projfile.GetProjections()) > 0)
251
252 # see whether it got cached and we get the same projfile object
253 # when we read the file again
254 projfile2, warnings = resource.get_system_proj_file()
255 self.assert_(projfile is projfile2)
256
257
258 class WriteProjFileTests(ProjFileTest):
259
260 """Test cases for writing proj files"""
261
262 def compare_xml(self, xml1, xml2):
263 self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))
264
265 def doTestWrite(self, projfile, expected):
266 filename = self.filename()
267
268 resource.write_proj_file(projfile)
269
270 file = open(filename)
271 written_contents = file.read()
272 file.close()
273 self.compare_xml(written_contents, expected)
274 self.validate_data(written_contents)
275 self.validate_data(expected)
276
277 def test_write(self):
278 """Test write_proj_file"""
279 pf = ProjFile(self.filename())
280 pf.Add(Projection(['proj=tmerc', 'ellps=clrk66',
281 'lat_0=90w', 'lon_0=90w', 'k=1'],
282 "Transverse Mercator",))
283 pf.Add(Projection(["proj=tmerc",
284 "lat_0=0.000000000", "lon_0=-62.000000000",
285 "k=0.999500", "x_0=400000.000", "y_0=0.000",
286 "ellps=clrk80", "units=m"],
287 "Anguilla 1957 / British West Indies Grid",
288 epsg="200"))
289 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
290 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
291 <projectionlist>
292 <projection name="Transverse Mercator">
293 <parameter value="proj=tmerc"/>
294 <parameter value="ellps=clrk66"/>
295 <parameter value="lat_0=90w"/>
296 <parameter value="lon_0=90w"/>
297 <parameter value="k=1"/>
298 </projection>
299 <projection epsg="200"
300 name="Anguilla 1957 / British West Indies Grid">
301 <parameter value="proj=tmerc"/>
302 <parameter value="lat_0=0.000000000"/>
303 <parameter value="lon_0=-62.000000000"/>
304 <parameter value="k=0.999500"/>
305 <parameter value="x_0=400000.000"/>
306 <parameter value="y_0=0.000"/>
307 <parameter value="ellps=clrk80"/>
308 <parameter value="units=m"/>
309 </projection>
310 </projectionlist>
311 '''
312 self.doTestWrite(pf, file_contents)
313
314 def test_write_empty_file(self):
315 """Test write empty ProjFile"""
316 pf = ProjFile(self.filename())
317 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
318 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
319 <projectionlist>
320 </projectionlist>
321 '''
322 self.doTestWrite(pf, file_contents)
323
324
325 class ProjFileLoadTestCase(support.FileLoadTestCase):
326
327 """Base class for the test cases that read specific test files"""
328
329 file_extension = ".proj"
330
331 def tearDown(self):
332 """Clear the cache explicitly"""
333 resource.clear_proj_file_cache()
334
335
336 class TestLoadingProjFile(ProjFileLoadTestCase):
337
338 file_contents = '''\
339 <?xml version="1.0" encoding="UTF-8"?>
340 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
341 <projectionlist>
342 <projection name="Transverse Mercator">
343 <parameter value="proj=tmerc"/>
344 <parameter value="ellps=clrk66"/>
345 <parameter value="lat_0=90w"/>
346 <parameter value="lon_0=90w"/>
347 <parameter value="k=1"/>
348 </projection>
349 <projection epsg="200" name="Anguilla 1957 / British West Indies Grid">
350 <parameter value="proj=tmerc"/>
351 <parameter value="lat_0=0.000000000"/>
352 <parameter value="lon_0=-62.000000000"/>
353 <parameter value="k=0.999500"/>
354 <parameter value="x_0=400000.000"/>
355 <parameter value="y_0=0.000"/>
356 <parameter value="ellps=clrk80"/>
357 <parameter value="units=m"/>
358 </projection>
359 </projectionlist>
360 '''
361
362 def check_projection(self, proj, label, parameters):
363 """Check the values of the proj's label and parameters"""
364 self.assertEquals(proj.Label(), label)
365 params = proj.GetAllParameters()[:]
366 params.sort()
367 self.assertEquals(params, parameters)
368
369 def test(self):
370 projfile, warnings = resource.read_proj_file(self.filename())
371 # no warnings
372 self.assertEquals(warnings, [])
373
374 # There are two projections
375 projs = projfile.GetProjections()
376 self.assertEquals(len(projs), 2)
377
378 self.check_projection(projs[0],
379 "Transverse Mercator",
380 ['ellps=clrk66', 'k=1', 'lat_0=90w', 'lon_0=90w',
381 'proj=tmerc'])
382 self.check_projection(projs[1],
383 "EPSG 200 Anguilla 1957 / British West Indies Grid",
384 ["ellps=clrk80", "k=0.999500",
385 "lat_0=0.000000000", "lon_0=-62.000000000",
386 "proj=tmerc", "units=m",
387 "x_0=400000.000", "y_0=0.000"])
388
389 def test_caching(self):
390 # test whether the projfile cache works
391 projfile, warnings = resource.read_proj_file(self.filename())
392 projfile2, warnings = resource.read_proj_file(self.filename())
393
394 # Both projfiles should be the same object
395 self.assert_(projfile2 is projfile)
396
397 # If we clear the cache we should get a new one.
398 resource.clear_proj_file_cache()
399 projfile3, warnings = resource.read_proj_file(self.filename())
400 self.assert_(projfile3 is not projfile)
401
402
403 class TestLoadingProjFileWithEmptyProjectionlist(ProjFileLoadTestCase):
404
405 file_contents = '''\
406 <?xml version="1.0" encoding="UTF-8"?>
407 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
408 <projectionlist>
409 </projectionlist>
410 '''
411
412 def test(self):
413 projfile, warnings = resource.read_proj_file(self.filename())
414 # no warnings
415 self.assertEquals(warnings, [])
416
417 # There are no projections
418 self.assertEquals(len(projfile.GetProjections()), 0)
419
420
421 class TestProjFileWithInvalidParameters(ProjFileLoadTestCase):
422
423 file_contents = '''\
424 <?xml version="1.0" encoding="UTF-8"?>
425 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
426 <projectionlist>
427 <projection name="Universal Transverse Mercator">
428 <parameter value="proj=utm"/>
429 <parameter value="ellps=clrk66"/>
430 <!-- an invalid zone number to trigger the parameter checking
431 in the proj library -->
432 <parameter value="zone=1000"/>
433 </projection>
434 <projection name="Transverse Mercator">
435 <parameter value="proj=tmerc"/>
436 <parameter value="ellps=clrk66"/>
437 <parameter value="lat_0=90w"/>
438 <parameter value="lon_0=90w"/>
439 <parameter value="k=1"/>
440 </projection>
441 </projectionlist>
442 '''
443
444 def setUp(self):
445 support.FileLoadTestCase.setUp(self)
446
447 def test(self):
448 """Test reading a proj file with invalid parameters"""
449 projfile, warnings = resource.read_proj_file(self.filename())
450 projs = projfile.GetProjections()
451 self.assertEquals(len(projs), 1)
452 params = projs[0].GetAllParameters()[:]
453 params.sort()
454 self.assertEquals(params, ['ellps=clrk66', 'k=1', 'lat_0=90w',
455 'lon_0=90w', 'proj=tmerc'])
456 self.assertEquals(warnings,
457 ['Error in projection "Universal Transverse Mercator":'
458 ' invalid UTM zone number'])
459
460
461 if __name__ == "__main__":
462 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