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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1982 - (hide 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 bh 1259 # Copyright (c) 2002, 2003 by Intevation GmbH
2 bh 333 # 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 jonathan 719 import os
18 bh 333
19 bh 1756 import xmlsupport
20 bh 333 import support
21     support.initthuban()
22    
23 bh 1684 from Thuban import _
24 bh 1793 from Thuban.Model.proj import Projection, ProjFile, \
25     PROJ_UNITS_METERS, PROJ_UNITS_DEGREES
26 bh 1825 from Thuban.Model.messages import PROJECTION_ADDED, PROJECTION_REMOVED, \
27     PROJECTION_REPLACED
28 jonathan 698 import Thuban.Model.resource as resource
29 bh 333
30 bh 1259 from xmlsupport import sax_eventlist
31 jonathan 698
32 jonathan 719 from xml.sax import SAXParseException
33 jonathan 698
34 jonathan 719
35 bh 333 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 jonathan 761 params = ["zone=26", "proj=utm", "ellps=clrk66"]
43     proj = Projection(params)
44     self.assertEquals(proj.params, params)
45 bh 333
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 bh 1982 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 bh 333
65 jonathan 761 # GetName()
66     self.assertEquals(proj.GetName(), _("Unknown"))
67    
68     # GetParameter()
69 jonathan 714 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 bh 333
74 jonathan 761 # GetAllParameters()
75     self.assertEquals(proj.GetAllParameters(), params)
76 bh 333
77 jonathan 761 # GetName()
78     proj = Projection(params, "MyName")
79     self.assertEquals(proj.GetName(), "MyName")
80    
81 bh 1798 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 bh 1793 def test_get_projection_units_geo(self):
89 jan 1888 """Test Projection.GetProjectedUnits() for geographic projection.
90     Test for the alias 'longlat' as well.
91     """
92 bh 1793 proj = Projection(["proj=latlong", "to_meter=0.017453292519943295",
93     "ellps=clrk66"])
94     self.assertEquals(proj.GetProjectedUnits(), PROJ_UNITS_DEGREES)
95 jan 1888 proj = Projection(["proj=longlat", "to_meter=0.017453292519943295",
96     "ellps=clrk66"])
97     self.assertEquals(proj.GetProjectedUnits(), PROJ_UNITS_DEGREES)
98 jonathan 761
99 bh 1793 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 bh 1818 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 bh 1793
110 bh 1818 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 jonathan 698
116 bh 1818 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 jonathan 698
122 bh 1818 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 jonathan 698
128    
129    
130 bh 1821 class TestProjFileSimple:
131 bh 1813
132 bh 1821 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 bh 1813
138 bh 1821 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 bh 1813
144    
145 bh 1825 class TestProjFile(unittest.TestCase, support.SubscriberMixin):
146 bh 1821
147 bh 1831 """Test cases for ProjFile objects"""
148 jonathan 698
149 bh 1821 def setUp(self):
150 bh 1825 self.clear_messages()
151 bh 1821 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 bh 1825 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 jonathan 742
159 bh 1827 def tearDown(self):
160     self.clear_messages()
161     self.proj_file.Destroy()
162    
163 bh 1821 def test_add_remove(self):
164     """Test ProjFile.Add() and ProjFile.Remove()"""
165 bh 1825 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 jonathan 742
173 bh 1825 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 bh 1821 def test_remove_non_existing(self):
178     """Test ProjFile.Remove(<proj not in projfile>)"""
179 bh 1825 self.assertRaises(ValueError, self.proj_file.Remove, self.proj0)
180     # Nothing happened, so no messages should have been sent
181     self.check_messages([])
182 jonathan 742
183 bh 1821 def test_replace(self):
184     """Test ProjFile.Replace()"""
185 bh 1825 self.proj_file.Add(self.proj0)
186     self.proj_file.Add(self.proj1)
187     self.clear_messages()
188 jonathan 761
189 bh 1821 # Replace()
190 bh 1825 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 jonathan 742
195 bh 1821 def test_replace_non_existing(self):
196     """Test ProjFile.Replace(<proj not in projfile>, <some proj>)"""
197 bh 1825 self.proj_file.Add(self.proj0)
198     self.proj_file.Add(self.proj1)
199     self.clear_messages()
200 bh 1821 self.assertRaises(ValueError,
201 bh 1825 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 jonathan 742
208    
209 bh 1821 class ProjFileTest(unittest.TestCase, support.FileTestMixin,
210     xmlsupport.ValidationTest):
211 jonathan 742
212 bh 1821 """Base class for the proj file tests that read or write files"""
213 jonathan 742
214 bh 1821 def filename(self):
215     """Return the filename for the test"""
216     return self.temp_file_name(self.id() + ".proj")
217 jonathan 742
218    
219 bh 1821 class ProjFileReadTests(ProjFileTest):
220 jonathan 752
221 bh 1831 """Test read ProjFile objects from files
222 jonathan 761
223 bh 1831 The files only cover error handling and the system projection file.
224     """
225    
226 bh 1811 def test_read_non_existing_file(self):
227     """Test read_proj_file with non-existing file"""
228 jonathan 719 self.assertRaises(IOError,
229 bh 1811 resource.read_proj_file,
230     self.temp_file_name("nonexistent.proj"))
231 jonathan 719
232 bh 1811 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 bh 1966 if os.name != "posix":
239     raise support.SkipTest("Test only works on posix systems")
240 bh 1813 filename = self.filename()
241 jonathan 719 file = open(filename, "w")
242     file.close()
243     os.chmod(filename, 0200) # write-only
244 jonathan 1167 self.assertRaises(IOError, resource.read_proj_file, filename)
245 jonathan 719
246 bh 1811 def test_read_empty_file(self):
247     """Test read_proj_file with empty file"""
248 bh 1813 filename = self.filename()
249 jonathan 719 file = open(filename, "w")
250     file.close()
251    
252 jonathan 1167 self.assertRaises(SAXParseException, resource.read_proj_file, filename)
253 jonathan 719
254 bh 1787 def test_get_system_proj_file(self):
255 bh 1933 """Test resource.get_system_proj_file(DEFAULT_PROJ_FILE)
256 jonathan 698
257 bh 1787 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 bh 1933 projfile, warnings\
262     = resource.get_system_proj_file(resource.DEFAULT_PROJ_FILE)
263 bh 1787 self.assertEquals(warnings, [])
264     self.assert_(len(projfile.GetProjections()) > 0)
265    
266 bh 1831 # see whether it got cached and we get the same projfile object
267     # when we read the file again
268 bh 1933 projfile2, warnings \
269     = resource.get_system_proj_file(resource.DEFAULT_PROJ_FILE)
270 bh 1831 self.assert_(projfile is projfile2)
271 bh 1787
272 bh 1831
273 bh 1821 class WriteProjFileTests(ProjFileTest):
274 bh 1813
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 bh 1818 def doTestWrite(self, projfile, expected):
281 bh 1813 filename = self.filename()
282    
283 bh 1818 resource.write_proj_file(projfile)
284 bh 1813
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 bh 1818 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 bh 1813
329     def test_write_empty_file(self):
330     """Test write empty ProjFile"""
331 bh 1818 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 bh 1813
339    
340 bh 1831 class ProjFileLoadTestCase(support.FileLoadTestCase):
341 bh 1818
342 bh 1831 """Base class for the test cases that read specific test files"""
343    
344 bh 1818 file_extension = ".proj"
345 bh 1831
346     def tearDown(self):
347     """Clear the cache explicitly"""
348     resource.clear_proj_file_cache()
349    
350    
351     class TestLoadingProjFile(ProjFileLoadTestCase):
352    
353 bh 1818 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 bh 1831 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 bh 1818
409 bh 1831 # Both projfiles should be the same object
410     self.assert_(projfile2 is projfile)
411 bh 1818
412 bh 1831 # 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 bh 1818 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 bh 1831 class TestProjFileWithInvalidParameters(ProjFileLoadTestCase):
437 bh 1787
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 bh 333 if __name__ == "__main__":
477 bh 1827 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