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