/[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 1982 - (show annotations)
Thu Nov 27 15:25:34 2003 UTC (21 years, 3 months ago) by bh
Original Path: trunk/thuban/test/test_proj.py
File MIME type: text/x-python
File size: 17773 byte(s)
* Thuban/Model/proj.py (Projection.InverseBBox): New. Inverse
version of ForwardBBox
(Projection._transform_bbox): New. common implementation of
ForwardBBox and InverseBBox
(Projection.ForwardBBox): Use _transform_bbox.

* test/test_proj.py (TestProjection.test): Add test for
InverseBBox

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