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

Diff of /branches/WIP-pyshapelib-bramz/Thuban/Model/load.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1408 by frank, Mon Jul 14 09:38:29 2003 UTC revision 1664 by bh, Wed Aug 27 15:20:54 2003 UTC
# Line 38  from Thuban.Model.data import DerivedSha Line 38  from Thuban.Model.data import DerivedSha
38  from Thuban.Model.table import DBFTable  from Thuban.Model.table import DBFTable
39  from Thuban.Model.transientdb import TransientJoinedTable  from Thuban.Model.transientdb import TransientJoinedTable
40    
41    from Thuban.Model.xmlreader import XMLReader
42    import resource
43    
44    import postgisdb
45    
46  class LoadError(Exception):  class LoadError(Exception):
     pass  
47    
48  from Thuban.Model.xmlreader import XMLReader      """Exception raised when the thuban file is corrupted
49  import resource  
50        Not all cases of corrupted thuban files will lead to this exception
51        but those that are found by checks in the loading code itself are.
52        """
53    
54    
55    class LoadCancelled(Exception):
56    
57        """Exception raised to indicate that loading was interrupted by the user"""
58    
59    
60  def parse_color(color):  def parse_color(color):
61      """Return the color object for the string color.      """Return the color object for the string color.
# Line 87  class AttrDesc: Line 100  class AttrDesc:
100    
101  class SessionLoader(XMLReader):  class SessionLoader(XMLReader):
102    
103      def __init__(self):      def __init__(self, db_connection_callback = None):
104          """Inititialize the Sax handler."""          """Inititialize the Sax handler."""
105          XMLReader.__init__(self)          XMLReader.__init__(self)
106    
107            self.db_connection_callback = db_connection_callback
108    
109          self.theSession = None          self.theSession = None
110          self.aMap = None          self.aMap = None
111          self.aLayer = None          self.aLayer = None
# Line 101  class SessionLoader(XMLReader): Line 116  class SessionLoader(XMLReader):
116    
117          dispatchers = {          dispatchers = {
118              'session'       : ("start_session",        "end_session"),              'session'       : ("start_session",        "end_session"),
119    
120                'dbconnection': ("start_dbconnection", None),
121    
122                'dbshapesource': ("start_dbshapesource", None),
123              'fileshapesource': ("start_fileshapesource", None),              'fileshapesource': ("start_fileshapesource", None),
124              'derivedshapesource': ("start_derivedshapesource", None),              'derivedshapesource': ("start_derivedshapesource", None),
125              'filetable': ("start_filetable", None),              'filetable': ("start_filetable", None),
# Line 122  class SessionLoader(XMLReader): Line 141  class SessionLoader(XMLReader):
141    
142          # all dispatchers should be used for the 0.8 and 0.9 namespaces too          # all dispatchers should be used for the 0.8 and 0.9 namespaces too
143          for xmlns in ("http://thuban.intevation.org/dtds/thuban-0.8.dtd",          for xmlns in ("http://thuban.intevation.org/dtds/thuban-0.8.dtd",
144                        "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd"):                        "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd",
145                          "http://thuban.intevation.org/dtds/thuban-0.9.dtd"):
146              for key, value in dispatchers.items():              for key, value in dispatchers.items():
147                  dispatchers[(xmlns, key)] = value                  dispatchers[(xmlns, key)] = value
148    
# Line 173  class SessionLoader(XMLReader): Line 193  class SessionLoader(XMLReader):
193                        defined earlier in the .thuban file. Look it up                        defined earlier in the .thuban file. Look it up
194                        self.idmap. If it's the ID of a shapestore the                        self.idmap. If it's the ID of a shapestore the
195                        value will be the table of the shapestore.                        value will be the table of the shapestore.
196    
197               'idref' -- The attribute is the id of an object defined
198                          earlier in the .thuban file. Look it up self.idmap
199    
200               'ascii' -- The attribute is converted to a bytestring with
201                          ascii encoding.
202          """          """
203          normalized = {}          normalized = {}
204    
205          for d in descr:          for d in descr:
206              if d.required and not attrs.has_key(d.fullname):              if d.required and not attrs.has_key(d.fullname):
207                  pass                  raise LoadError("Element %s requires an attribute %r"
208              #raise LoadError("Element %s requires an attribute %r"                                  % (element, d.name))
             #                    % (element, d.name))  
209              value = attrs.get(d.fullname, d.default)              value = attrs.get(d.fullname, d.default)
210    
211              if d.conversion == "shapesource":              if d.conversion in ("idref", "shapesource"):
212                  if value in self.idmap:                  if value in self.idmap:
213                      value = self.idmap[value]                      value = self.idmap[value]
214                  else:                  else:
# Line 202  class SessionLoader(XMLReader): Line 227  class SessionLoader(XMLReader):
227              elif d.conversion == "filename":              elif d.conversion == "filename":
228                  value = os.path.abspath(os.path.join(self.GetDirectory(),                  value = os.path.abspath(os.path.join(self.GetDirectory(),
229                                                       value))                                                       value))
230                elif d.conversion == "ascii":
231                    value = value.encode("ascii")
232                else:
233                    if d.conversion:
234                        raise ValueError("Unknown attribute conversion %r"
235                                         % d.conversion)
236    
237              normalized[d.name] = value              normalized[d.name] = value
238          return normalized          return normalized
239    
240        def start_dbconnection(self, name, qname, attrs):
241            attrs = self.check_attrs(name, attrs,
242                                     [AttrDesc("id", True),
243                                      AttrDesc("dbtype", True),
244                                      AttrDesc("host", False, ""),
245                                      AttrDesc("port", False, ""),
246                                      AttrDesc("user", False, ""),
247                                      AttrDesc("dbname", True)])
248            ID = attrs["id"]
249            dbtype = attrs["dbtype"]
250            if dbtype != "postgis":
251                raise LoadError("dbtype %r not supported" % filetype)
252    
253            del attrs["id"]
254            del attrs["dbtype"]
255    
256            # Try to open the connection and if it fails ask the user for
257            # the correct parameters repeatedly.
258            # FIXME: it would be better not to insist on getting a
259            # connection here. We should handle this more like the raster
260            # images where the layers etc still are created but are not
261            # drawn in case Thuban can't use the data for various reasons
262            while 1:
263                try:
264                    conn = postgisdb.PostGISConnection(**attrs)
265                    break
266                except postgisdb.ConnectionError, val:
267                    if self.db_connection_callback is not None:
268                        attrs = self.db_connection_callback(attrs, str(val))
269                        if attrs is None:
270                            raise LoadCancelled
271                    else:
272                        raise
273    
274            self.idmap[ID] = conn
275            self.theSession.AddDBConnection(conn)
276    
277        def start_dbshapesource(self, name, qname, attrs):
278            attrs = self.check_attrs(name, attrs,
279                                     [AttrDesc("id", True),
280                                      AttrDesc("dbconn", True,
281                                               conversion = "idref"),
282                                      AttrDesc("tablename", True,
283                                               conversion = "ascii")])
284            ID = attrs["id"]
285            db = attrs["dbconn"]
286            tablename = attrs["tablename"]
287            self.idmap[ID] = self.theSession.OpenDBShapeStore(db, tablename)
288    
289      def start_fileshapesource(self, name, qname, attrs):      def start_fileshapesource(self, name, qname, attrs):
290          attrs = self.check_attrs(name, attrs,          attrs = self.check_attrs(name, attrs,
291                                    [AttrDesc("id", True),                                    [AttrDesc("id", True),
# Line 363  class SessionLoader(XMLReader): Line 443  class SessionLoader(XMLReader):
443          elif fieldType == FIELDTYPE_DOUBLE:          elif fieldType == FIELDTYPE_DOUBLE:
444              self.conv = float              self.conv = float
445    
446          self.aLayer.GetClassification().SetFieldInfo(field, fieldType)          self.aLayer.SetClassificationColumn(field)
447    
448      def end_classification(self, name, qname):      def end_classification(self, name, qname):
449          pass          pass
# Line 381  class SessionLoader(XMLReader): Line 461  class SessionLoader(XMLReader):
461      def start_clpoint(self, name, qname, attrs):      def start_clpoint(self, name, qname, attrs):
462          attrib_value = attrs.get((None, 'value'), "0")          attrib_value = attrs.get((None, 'value'), "0")
463    
464          value = self.conv(attrib_value)          field = self.aLayer.GetClassificationColumn()
465            if self.aLayer.GetFieldType(field) == FIELDTYPE_STRING:
466                value = self.encode(attrib_value)
467            else:
468                value = self.conv(attrib_value)
469          self.cl_group = ClassGroupSingleton(value)          self.cl_group = ClassGroupSingleton(value)
470          self.cl_group.SetLabel(self.encode(attrs.get((None, 'label'), "")))          self.cl_group.SetLabel(self.encode(attrs.get((None, 'label'), "")))
471          self.cl_prop = ClassGroupProperties()          self.cl_prop = ClassGroupProperties()
# Line 446  class SessionLoader(XMLReader): Line 529  class SessionLoader(XMLReader):
529          pass          pass
530    
531    
532  def load_session(filename):  def load_session(filename, db_connection_callback = None):
533      """Load a Thuban session from the file object file"""      """Load a Thuban session from the file object file
534    
535      handler = SessionLoader()      The db_connection_callback, if given should be a callable object
536        that can be called like this:
537           db_connection_callback(params, message)
538    
539        where params is a dictionary containing the known connection
540        parameters and message is a string with a message why the connection
541        failed. db_connection_callback should return a new dictionary with
542        corrected and perhaps additional parameters like a password or None
543        to indicate that the user cancelled.
544        """
545        handler = SessionLoader(db_connection_callback)
546      handler.read(filename)      handler.read(filename)
547    
548      session = handler.theSession      session = handler.theSession

Legend:
Removed from v.1408  
changed lines
  Added in v.1664

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26