/[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 1933 - (show annotations)
Tue Nov 11 16:37:53 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: 17266 byte(s)
* Thuban/Model/resource.py (get_system_proj_file): Add a filename
parameter so that this function can be used for all proj files in
Resource/Projections
(DEFAULT_PROJ_FILE, EPSG_PROJ_FILE): New. Predefined filenames for
get_system_proj_file

* Thuban/UI/projdialog.py (ProjFrame.__init__): Instead of one
ProjFile self.__sysProjFile use a dictionary of system ProjFile
objects self._sys_proj_files
(ProjFrame.build_dialog): Adapt to the new changes in the
ProjectionList constructor. Add a check button to toggle whether
EPSG projections are shown
(ProjFrame._OnShowEPSG): New. Handler for the epsg check button
events.
(ProjFrame.load_user_proj, ProjFrame.load_system_proj): Only show
the busy cursor if the files have not yet been loaded by the
dialog.
(ProjFrame.load_system_proj): Add a parameter for the name of the
proj file. Maintain the dictionary of system projections
self._sys_proj_files

* Thuban/UI/projlist.py (ProjectionList): Merge the system_projs,
user_projs parameters into one parameter proj_files which is a
list of proj files.
(ProjectionList._subscribe_proj_files)
(ProjectionList._unsubscribe_proj_files): New. Move
subscription/unsubscription of projfile messages to separate
methods
(ProjectionList.Destroy): The unsubscribe is now done in
_unsubscribe_proj_files
(ProjectionList.update_projections): We now have a list of proj
file objects
(ProjectionList.SetProjFiles): New method to set a new list of
proj file objects

* test/test_proj.py (ProjFileReadTests.test_get_system_proj_file):
Specify explicitly which system proj file to load.

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(DEFAULT_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\
254 = resource.get_system_proj_file(resource.DEFAULT_PROJ_FILE)
255 self.assertEquals(warnings, [])
256 self.assert_(len(projfile.GetProjections()) > 0)
257
258 # see whether it got cached and we get the same projfile object
259 # when we read the file again
260 projfile2, warnings \
261 = resource.get_system_proj_file(resource.DEFAULT_PROJ_FILE)
262 self.assert_(projfile is projfile2)
263
264
265 class WriteProjFileTests(ProjFileTest):
266
267 """Test cases for writing proj files"""
268
269 def compare_xml(self, xml1, xml2):
270 self.assertEquals(sax_eventlist(xml1), sax_eventlist(xml2))
271
272 def doTestWrite(self, projfile, expected):
273 filename = self.filename()
274
275 resource.write_proj_file(projfile)
276
277 file = open(filename)
278 written_contents = file.read()
279 file.close()
280 self.compare_xml(written_contents, expected)
281 self.validate_data(written_contents)
282 self.validate_data(expected)
283
284 def test_write(self):
285 """Test write_proj_file"""
286 pf = ProjFile(self.filename())
287 pf.Add(Projection(['proj=tmerc', 'ellps=clrk66',
288 'lat_0=90w', 'lon_0=90w', 'k=1'],
289 "Transverse Mercator",))
290 pf.Add(Projection(["proj=tmerc",
291 "lat_0=0.000000000", "lon_0=-62.000000000",
292 "k=0.999500", "x_0=400000.000", "y_0=0.000",
293 "ellps=clrk80", "units=m"],
294 "Anguilla 1957 / British West Indies Grid",
295 epsg="200"))
296 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
297 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
298 <projectionlist>
299 <projection name="Transverse Mercator">
300 <parameter value="proj=tmerc"/>
301 <parameter value="ellps=clrk66"/>
302 <parameter value="lat_0=90w"/>
303 <parameter value="lon_0=90w"/>
304 <parameter value="k=1"/>
305 </projection>
306 <projection epsg="200"
307 name="Anguilla 1957 / British West Indies Grid">
308 <parameter value="proj=tmerc"/>
309 <parameter value="lat_0=0.000000000"/>
310 <parameter value="lon_0=-62.000000000"/>
311 <parameter value="k=0.999500"/>
312 <parameter value="x_0=400000.000"/>
313 <parameter value="y_0=0.000"/>
314 <parameter value="ellps=clrk80"/>
315 <parameter value="units=m"/>
316 </projection>
317 </projectionlist>
318 '''
319 self.doTestWrite(pf, file_contents)
320
321 def test_write_empty_file(self):
322 """Test write empty ProjFile"""
323 pf = ProjFile(self.filename())
324 file_contents = '''<?xml version="1.0" encoding="UTF-8"?>
325 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
326 <projectionlist>
327 </projectionlist>
328 '''
329 self.doTestWrite(pf, file_contents)
330
331
332 class ProjFileLoadTestCase(support.FileLoadTestCase):
333
334 """Base class for the test cases that read specific test files"""
335
336 file_extension = ".proj"
337
338 def tearDown(self):
339 """Clear the cache explicitly"""
340 resource.clear_proj_file_cache()
341
342
343 class TestLoadingProjFile(ProjFileLoadTestCase):
344
345 file_contents = '''\
346 <?xml version="1.0" encoding="UTF-8"?>
347 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
348 <projectionlist>
349 <projection name="Transverse Mercator">
350 <parameter value="proj=tmerc"/>
351 <parameter value="ellps=clrk66"/>
352 <parameter value="lat_0=90w"/>
353 <parameter value="lon_0=90w"/>
354 <parameter value="k=1"/>
355 </projection>
356 <projection epsg="200" name="Anguilla 1957 / British West Indies Grid">
357 <parameter value="proj=tmerc"/>
358 <parameter value="lat_0=0.000000000"/>
359 <parameter value="lon_0=-62.000000000"/>
360 <parameter value="k=0.999500"/>
361 <parameter value="x_0=400000.000"/>
362 <parameter value="y_0=0.000"/>
363 <parameter value="ellps=clrk80"/>
364 <parameter value="units=m"/>
365 </projection>
366 </projectionlist>
367 '''
368
369 def check_projection(self, proj, label, parameters):
370 """Check the values of the proj's label and parameters"""
371 self.assertEquals(proj.Label(), label)
372 params = proj.GetAllParameters()[:]
373 params.sort()
374 self.assertEquals(params, parameters)
375
376 def test(self):
377 projfile, warnings = resource.read_proj_file(self.filename())
378 # no warnings
379 self.assertEquals(warnings, [])
380
381 # There are two projections
382 projs = projfile.GetProjections()
383 self.assertEquals(len(projs), 2)
384
385 self.check_projection(projs[0],
386 "Transverse Mercator",
387 ['ellps=clrk66', 'k=1', 'lat_0=90w', 'lon_0=90w',
388 'proj=tmerc'])
389 self.check_projection(projs[1],
390 "EPSG 200 Anguilla 1957 / British West Indies Grid",
391 ["ellps=clrk80", "k=0.999500",
392 "lat_0=0.000000000", "lon_0=-62.000000000",
393 "proj=tmerc", "units=m",
394 "x_0=400000.000", "y_0=0.000"])
395
396 def test_caching(self):
397 # test whether the projfile cache works
398 projfile, warnings = resource.read_proj_file(self.filename())
399 projfile2, warnings = resource.read_proj_file(self.filename())
400
401 # Both projfiles should be the same object
402 self.assert_(projfile2 is projfile)
403
404 # If we clear the cache we should get a new one.
405 resource.clear_proj_file_cache()
406 projfile3, warnings = resource.read_proj_file(self.filename())
407 self.assert_(projfile3 is not projfile)
408
409
410 class TestLoadingProjFileWithEmptyProjectionlist(ProjFileLoadTestCase):
411
412 file_contents = '''\
413 <?xml version="1.0" encoding="UTF-8"?>
414 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
415 <projectionlist>
416 </projectionlist>
417 '''
418
419 def test(self):
420 projfile, warnings = resource.read_proj_file(self.filename())
421 # no warnings
422 self.assertEquals(warnings, [])
423
424 # There are no projections
425 self.assertEquals(len(projfile.GetProjections()), 0)
426
427
428 class TestProjFileWithInvalidParameters(ProjFileLoadTestCase):
429
430 file_contents = '''\
431 <?xml version="1.0" encoding="UTF-8"?>
432 <!DOCTYPE projectionlist SYSTEM "projfile.dtd">
433 <projectionlist>
434 <projection name="Universal Transverse Mercator">
435 <parameter value="proj=utm"/>
436 <parameter value="ellps=clrk66"/>
437 <!-- an invalid zone number to trigger the parameter checking
438 in the proj library -->
439 <parameter value="zone=1000"/>
440 </projection>
441 <projection name="Transverse Mercator">
442 <parameter value="proj=tmerc"/>
443 <parameter value="ellps=clrk66"/>
444 <parameter value="lat_0=90w"/>
445 <parameter value="lon_0=90w"/>
446 <parameter value="k=1"/>
447 </projection>
448 </projectionlist>
449 '''
450
451 def setUp(self):
452 support.FileLoadTestCase.setUp(self)
453
454 def test(self):
455 """Test reading a proj file with invalid parameters"""
456 projfile, warnings = resource.read_proj_file(self.filename())
457 projs = projfile.GetProjections()
458 self.assertEquals(len(projs), 1)
459 params = projs[0].GetAllParameters()[:]
460 params.sort()
461 self.assertEquals(params, ['ellps=clrk66', 'k=1', 'lat_0=90w',
462 'lon_0=90w', 'proj=tmerc'])
463 self.assertEquals(warnings,
464 ['Error in projection "Universal Transverse Mercator":'
465 ' invalid UTM zone number'])
466
467
468 if __name__ == "__main__":
469 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