/[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 2696 - (hide annotations)
Sun Sep 17 23:19:21 2006 UTC (18 years, 5 months ago) by bernhard
Original Path: trunk/thuban/test/test_proj.py
File MIME type: text/x-python
File size: 18770 byte(s)
test/test_proj.py: new test_lc_numeric_robustness()

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