/[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 1888 - (show annotations)
Thu Oct 30 09:31:56 2003 UTC (21 years, 4 months ago) by jan
Original Path: trunk/thuban/test/test_proj.py
File MIME type: text/x-python
File size: 17157 byte(s)
(TestProjection.test_get_projection_units_geo):
Added test for alias 'longlat'.

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