/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/resource.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/Model/resource.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 7449 byte(s)
made a copy
1 # Copyright (c) 2003 by Intevation GmbH
2 # Authors:
3 # Jonathan Coles <[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 """Handle resources loaded from files such as projections"""
9
10 __version__ = "$Revision$"
11 # $Source$
12 # $Id$
13
14
15 import os
16 import os.path
17 import weakref
18 import traceback
19
20 import Thuban
21 from Thuban import _
22
23 from Thuban.Lib.fileutil import get_application_dir
24
25 from Thuban.Model.xmlreader import XMLReader
26 from Thuban.Model.xmlwriter import XMLWriter
27 from Thuban.Model.proj import Projection, ProjFile
28 from xml.sax import SAXParseException
29
30 projdir = \
31 os.path.join(Thuban.__path__[0], os.pardir, "Resources", "Projections")
32
33
34 PROJ_EXT = ".proj"
35
36 # Determine the status of GDAL support. If GDAL is supported
37 # gdal_support_status will be set to the empty string, otherwise to a
38 # string with information why it isn't supported
39 #
40 # GDAL is supported if we can import both the thuban specific gdalwarp
41 # module and the GDAL python bindings.
42 for _module in ("gdalwarp", "gdal"):
43 try:
44 __import__(_module)
45 except ImportError, val:
46 gdal_support_status = (_("No GDAL support because module '%s'"
47 " cannot be imported. Python exception: '%s'")
48 % (_module, str(val)))
49 break
50 else:
51 gdal_support_status = ""
52
53 def has_gdal_support():
54 return gdal_support_status == ""
55
56
57 projfile_cache = weakref.WeakValueDictionary()
58
59 def clear_proj_file_cache():
60 """Clear the cache of ProjFile objects maintained by read_proj_file.
61
62 This function is probably only useful for the test suite.
63 """
64 projfile_cache.clear()
65
66 def read_proj_file(filename):
67 """Read a .proj file and return a ProjFile object and warnings
68
69 The return value is a tuple with the ProjFile object and a list of
70 strings with warnings messages that might have been generated by the
71 proj file parser.
72
73 The objects returned cached so that reading the same file
74 (identified by its absolute name) several times yields the same
75 ProjFile object. The cache uses weak references so the objects will
76 be removed from the cache once the last reference an object in the
77 cache is removed.
78
79 Raises IOError if the file cannot be opened, OSError if the file
80 cannot be read and SAXParseException if the file is not valid XML.
81 """
82 filename = os.path.abspath(filename)
83 if filename in projfile_cache:
84 return projfile_cache[filename], []
85 else:
86 handler = ProjFileReader()
87 handler.read(filename)
88 proj_file = handler.GetProjFile()
89 projfile_cache[filename] = proj_file
90 return proj_file, handler.GetWarnings()
91
92 def write_proj_file(pf):
93 """Write a single .proj file
94
95 Raises IOError if the file cannot be written.
96 """
97
98 saver = ProjFileSaver(pf)
99 saver.write(pf.GetFilename())
100
101 #
102 # Constants for the get_system_proj_file function
103 #
104
105 # The default projection file with a few predefined projections
106 DEFAULT_PROJ_FILE = "defaults.proj"
107
108 # The epsg projections.
109 EPSG_PROJ_FILE = "epsg.proj"
110
111 # Deprecated EPSG projections.
112 EPSG_DEPRECATED_PROJ_FILE = "epsg-deprecated.proj"
113
114 def get_system_proj_file(filename):
115 """Return the projections from the indicated file and a list with warnings
116
117 The filename argument should be the name of a file in the directory
118 with Thuban's default projection files (Resources/Projections/). If
119 possible callers should not use hardwired string literal for the
120 name to avoid unnecessary duplication. Instead they should use one
121 of the predefined constants, currently DEFAULT_PROJ_FILE,
122 EPSG_PROJ_FILE or EPSG_DEPRECATED_PROJ_FILE.
123
124 The return value is a tuple with the projections in a ProjFile
125 object and a list of strings with warning messages. The warnings
126 list is usually empty but may contain messages about ignored errors.
127
128 If the file could could not be opened return an empty projection
129 file object set to store data in the indicated default file.
130 """
131 fullname = os.path.join(projdir, filename)
132 try:
133 return read_proj_file(fullname)
134 except (OSError, IOError, SAXParseException), val:
135 msg = _('Could not read "%s": %s') % (fullname, str(val))
136 return ProjFile(fullname), [msg]
137
138 def get_user_proj_file():
139 """Return the user's projections and a list with warnings
140
141 The projections read from the user's thuban projection file (usually
142 in ~/.thuban/user.proj). The return value is a tuple with the
143 projections in a ProjFile object and a list of strings with warning
144 messages. The warnings list is usually empty but may contain
145 messages about ignored errors.
146
147 If the file could could not be opened return an empty projection
148 file object set to store data in the default file.
149 """
150 usrdir = get_application_dir()
151 filename = os.path.join(usrdir, "user.proj")
152 try:
153 return read_proj_file(filename)
154 except (OSError, IOError, SAXParseException), val:
155 msg = _('Could not read "%s": %s') % (filename, str(val))
156 return ProjFile(filename), [msg]
157
158
159 class ProjFileReader(XMLReader):
160
161 def __init__(self):
162 XMLReader.__init__(self)
163 self.projfile = ProjFile("")
164 self.warnings = []
165
166 XMLReader.AddDispatchers(self,
167 {'projection': ("start_projection", "end_projection"),
168 'parameter': ("start_parameter", None)})
169
170 def read(self, file_or_filename):
171 XMLReader.read(self, file_or_filename)
172
173 self.projfile.SetFilename(XMLReader.GetFilename(self))
174
175 def start_projection(self, name, qname, attrs):
176 self.params = []
177 name = self.encode(attrs.get((None, 'name')))
178 if name is None:
179 name = _("Unknown")
180 self.name = name
181 self.epsg = self.encode(attrs.get((None, 'epsg')))
182
183 def end_projection(self, name, qname):
184 try:
185 proj = Projection(self.params, self.name, epsg = self.epsg)
186 except IOError, val:
187 self.warnings.append(_('Error in projection "%s": %s')
188 % (self.name, str(val)))
189 else:
190 self.projfile.Add(proj)
191
192 def start_parameter(self, name, qname, attrs):
193 s = attrs.get((None, 'value'))
194 s = str(s) # we can't handle unicode in proj
195 self.params.append(s)
196
197 def GetProjFile(self):
198 return self.projfile
199
200 def GetWarnings(self):
201 """Return the list of warning messages that may have been produced"""
202 return self.warnings
203
204
205 class ProjFileSaver(XMLWriter):
206
207 def __init__(self, pf):
208 XMLWriter.__init__(self)
209 self.__pf = pf
210
211 def write(self, file_or_filename):
212 XMLWriter.write(self, file_or_filename)
213
214 self.write_header("projectionlist", "projfile.dtd")
215 self.write_projfile(self.__pf)
216 self.close()
217
218 def write_projfile(self, pf):
219
220 self.open_element("projectionlist")
221
222 for p in pf.GetProjections():
223 attrs = {"name": p.GetName()}
224 if p.EPSGCode():
225 attrs["epsg"] = p.EPSGCode()
226 self.open_element("projection", attrs)
227
228 for param in p.GetAllParameters():
229 self.write_element("parameter", {"value": param})
230
231 self.close_element("projection")
232
233 self.close_element("projectionlist")
234
235

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26