/[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 2004 by bh, Tue Dec 2 13:25:55 2003 UTC revision 2658 by jan, Wed Jul 27 21:50:30 2005 UTC
# Line 1  Line 1 
1  # Copyright (C) 2001, 2002, 2003 by Intevation GmbH  # Copyright (C) 2001, 2002, 2003, 2004, 2005 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
4  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
5  # Jonathan Coles <[email protected]>  # Jonathan Coles <[email protected]>
6    # Frank Koormann <[email protected]>
7  #  #
8  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
9  # Read the file COPYING coming with GRASS for details.  # Read the file COPYING coming with GRASS for details.
# Line 100  class AttrDesc: Line 101  class AttrDesc:
101    
102  class SessionLoader(XMLReader):  class SessionLoader(XMLReader):
103    
104      def __init__(self, db_connection_callback = None):      def __init__(self, db_connection_callback = None,
105                           shapefile_callback = None):
106          """Inititialize the Sax handler."""          """Inititialize the Sax handler."""
107          XMLReader.__init__(self)          XMLReader.__init__(self)
108    
109          self.db_connection_callback = db_connection_callback          self.db_connection_callback = db_connection_callback
110            self.shapefile_callback = shapefile_callback
111          self.theSession = None          self.theSession = None
112          self.aMap = None          self.aMap = None
113          self.aLayer = None          self.aLayer = None
# Line 144  class SessionLoader(XMLReader): Line 146  class SessionLoader(XMLReader):
146                        "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd",                        "http://thuban.intevation.org/dtds/thuban-0.9-dev.dtd",
147                        "http://thuban.intevation.org/dtds/thuban-0.9.dtd",                        "http://thuban.intevation.org/dtds/thuban-0.9.dtd",
148                        "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd",                        "http://thuban.intevation.org/dtds/thuban-1.0-dev.dtd",
149                        "http://thuban.intevation.org/dtds/thuban-1.0rc1.dtd"):                        "http://thuban.intevation.org/dtds/thuban-1.0rc1.dtd",
150                          "http://thuban.intevation.org/dtds/thuban-1.0.0.dtd",
151                          "http://thuban.intevation.org/dtds/thuban-1.1-dev.dtd"):
152              for key, value in dispatchers.items():              for key, value in dispatchers.items():
153                  dispatchers[(xmlns, key)] = value                  dispatchers[(xmlns, key)] = value
154    
# Line 244  class SessionLoader(XMLReader): Line 248  class SessionLoader(XMLReader):
248                                      % (element, d.name))                                      % (element, d.name))
249              elif d.conversion == "filename":              elif d.conversion == "filename":
250                  value = os.path.abspath(os.path.join(self.GetDirectory(),                  value = os.path.abspath(os.path.join(self.GetDirectory(),
251                                                       value))                                                       self.encode(value)))
252              elif d.conversion == "ascii":              elif d.conversion == "ascii":
253                  value = value.encode("ascii")                  value = value.encode("ascii")
254              elif d.conversion:              elif d.conversion:
# Line 256  class SessionLoader(XMLReader): Line 260  class SessionLoader(XMLReader):
260              normalized[d.name] = value              normalized[d.name] = value
261          return normalized          return normalized
262    
263        def open_shapefile(self, filename):
264            """Open shapefile, with alternative path handling.
265            
266               If a shapefile cannot be opened and an IOError is raised, check for
267               an alternative. This alternative can be specified interactively by
268               the user or taken from a list of (potential) locations, depending on
269               the callback implementation.
270                
271               The alternative is rechecked. If taken from a list the user
272               has to confirm the alternative.
273            """
274    
275            # Flag if the alternative path was specified interactively / from list.
276            from_list = 0
277            while 1:
278                try:
279                    store = self.theSession.OpenShapefile(filename)
280                    if from_list:
281                        # A valid path has been guessed from a list
282                        # Let the user confirm - or select an alternative.
283                        filename, from_list = self.shapefile_callback(
284                                                filename, "check")
285                        if filename is None:
286                            # Selection cancelled
287                            raise LoadCancelled
288                        elif store.FileName() == filename:
289                            # Proposed file has been accepted
290                            break
291                        else:
292                            # the filename has been changed, try the new file
293                            pass
294                    else:
295                        break
296                except IOError:
297                    if self.shapefile_callback is not None:
298                        filename, from_list = self.shapefile_callback(
299                                                filename,
300                                                mode = "search",
301                                                second_try = from_list)
302                        if filename is None:
303                            raise LoadCancelled
304                    else:
305                        raise
306            return store
307    
308      def start_dbconnection(self, name, qname, attrs):      def start_dbconnection(self, name, qname, attrs):
309          attrs = self.check_attrs(name, attrs,          attrs = self.check_attrs(name, attrs,
310                                   [AttrDesc("id", True),                                   [AttrDesc("id", True),
# Line 299  class SessionLoader(XMLReader): Line 348  class SessionLoader(XMLReader):
348                                    AttrDesc("dbconn", True,                                    AttrDesc("dbconn", True,
349                                             conversion = "idref"),                                             conversion = "idref"),
350                                    AttrDesc("tablename", True,                                    AttrDesc("tablename", True,
351                                               conversion = "ascii"),
352                                      # id_column and geometry_column were
353                                      # newly introduced with thuban-1.1.dtd
354                                      # where they're required.  Since we
355                                      # support the older formats too we
356                                      # have them optional here.
357                                      AttrDesc("id_column", False, "gid",
358                                               conversion = "ascii"),
359                                      AttrDesc("geometry_column", False,
360                                             conversion = "ascii")])                                             conversion = "ascii")])
361          ID = attrs["id"]          # The default value of geometry_column to use when instantiating
362          db = attrs["dbconn"]          # the db shapestore is None which we currently can't easily use
363          tablename = attrs["tablename"]          # in check_attrs
364          self.idmap[ID] = self.theSession.OpenDBShapeStore(db, tablename)          geometry_column = attrs["geometry_column"]
365            if not geometry_column:
366                geometry_column = None
367            dbopen = self.theSession.OpenDBShapeStore
368            self.idmap[attrs["id"]] = dbopen(attrs["dbconn"], attrs["tablename"],
369                                             id_column = attrs["id_column"],
370                                             geometry_column=geometry_column)
371    
372      def start_fileshapesource(self, name, qname, attrs):      def start_fileshapesource(self, name, qname, attrs):
373          attrs = self.check_attrs(name, attrs,          attrs = self.check_attrs(name, attrs,
# Line 316  class SessionLoader(XMLReader): Line 380  class SessionLoader(XMLReader):
380          filetype = attrs["filetype"]          filetype = attrs["filetype"]
381          if filetype != "shapefile":          if filetype != "shapefile":
382              raise LoadError("shapesource filetype %r not supported" % filetype)              raise LoadError("shapesource filetype %r not supported" % filetype)
383          self.idmap[ID] = self.theSession.OpenShapefile(filename)          self.idmap[ID] = self.open_shapefile(filename)
384    
385      def start_derivedshapesource(self, name, qname, attrs):      def start_derivedshapesource(self, name, qname, attrs):
386          attrs = self.check_attrs(name, attrs,          attrs = self.check_attrs(name, attrs,
# Line 427  class SessionLoader(XMLReader): Line 491  class SessionLoader(XMLReader):
491          if attrs.has_key((None, "shapestore")):          if attrs.has_key((None, "shapestore")):
492              store = self.idmap[attrs[(None, "shapestore")]]              store = self.idmap[attrs[(None, "shapestore")]]
493          else:          else:
494              store = self.theSession.OpenShapefile(filename)              store = self.open_shapefile(filename)
495    
496          self.aLayer = layer_class(title, store,          self.aLayer = layer_class(title, store,
497                                    fill = fill, stroke = stroke,                                    fill = fill, stroke = stroke,
498                                    lineWidth = stroke_width,                                    lineWidth = stroke_width,
# Line 443  class SessionLoader(XMLReader): Line 508  class SessionLoader(XMLReader):
508          filename = os.path.join(self.GetDirectory(), filename)          filename = os.path.join(self.GetDirectory(), filename)
509          filename = self.encode(filename)          filename = self.encode(filename)
510          visible  = self.encode(attrs.get((None, 'visible'), "true")) != "false"          visible  = self.encode(attrs.get((None, 'visible'), "true")) != "false"
511            opacity  = float(attrs.get((None, 'opacity'), "1"))
512            masktype = str(attrs.get((None, 'masktype'), "bit"))
513    
514          self.aLayer = layer_class(title, filename, visible = visible)          masktypes = {"none": layer_class.MASK_NONE,
515                         "bit":  layer_class.MASK_BIT,
516                         "alpha": layer_class.MASK_ALPHA}
517    
518            self.aLayer = layer_class(title, filename,
519                                      visible = visible,
520                                      opacity = opacity,
521                                      masktype = masktypes[masktype])
522    
523      def end_rasterlayer(self, name, qname):      def end_rasterlayer(self, name, qname):
524          self.aMap.AddLayer(self.aLayer)          self.aMap.AddLayer(self.aLayer)
525          self.aLayer = None          self.aLayer = None
526    
527      def start_classification(self, name, qname, attrs):      def start_classification(self, name, qname, attrs):
528            # field and field_type are optional because the classification
529            # can also be empty, ie. have only a default.
530          attrs = self.check_attrs(name, attrs,          attrs = self.check_attrs(name, attrs,
531                                   [AttrDesc("field", True),                                   [AttrDesc("field", False),
532                                    AttrDesc("field_type", True)])                                    AttrDesc("field_type", False)])
533    
534          field = attrs["field"]          field = attrs["field"]
535          fieldType = attrs["field_type"]          fieldType = attrs["field_type"]
536    
537            if field == "": return # no need to set classification column.
538    
539          dbFieldType = self.aLayer.GetFieldType(field)          dbFieldType = self.aLayer.GetFieldType(field)
540    
541          if fieldType != dbFieldType:          if fieldType != dbFieldType:
# Line 505  class SessionLoader(XMLReader): Line 584  class SessionLoader(XMLReader):
584          del self.cl_group, self.cl_prop          del self.cl_group, self.cl_prop
585    
586      def start_clrange(self, name, qname, attrs):      def start_clrange(self, name, qname, attrs):
587            attrs = self.check_attrs(name, attrs,
588                                     [AttrDesc("range", False, None),
589                                      AttrDesc("min", False, None),
590                                      AttrDesc("max", False, None)])
591    
592          range = attrs.get((None, 'range'), None)          range = attrs['range']
593          # for backward compatibility (min/max are not saved)          # for backward compatibility (min/max are not saved)
594          min   = attrs.get((None, 'min'), None)          min   = attrs['min']
595          max   = attrs.get((None, 'max'), None)          max   = attrs['max']
596    
597          try:          try:
598              if range is not None:              if range is not None:
# Line 537  class SessionLoader(XMLReader): Line 620  class SessionLoader(XMLReader):
620              parse_color(attrs.get((None, 'stroke'), "None")))              parse_color(attrs.get((None, 'stroke'), "None")))
621          self.cl_prop.SetLineWidth(          self.cl_prop.SetLineWidth(
622              int(attrs.get((None, 'stroke_width'), "0")))              int(attrs.get((None, 'stroke_width'), "0")))
623            self.cl_prop.SetSize(int(attrs.get((None, 'size'), "5")))
624          self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))          self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
625    
626      def end_cldata(self, name, qname):      def end_cldata(self, name, qname):
# Line 546  class SessionLoader(XMLReader): Line 630  class SessionLoader(XMLReader):
630          self.aLayer = self.aMap.LabelLayer()          self.aLayer = self.aMap.LabelLayer()
631    
632      def start_label(self, name, qname, attrs):      def start_label(self, name, qname, attrs):
633          x = float(attrs[(None, 'x')])          attrs = self.check_attrs(name, attrs,
634          y = float(attrs[(None, 'y')])                                   [AttrDesc("x", True, conversion = float),
635          text = self.encode(attrs[(None, 'text')])                                    AttrDesc("y", True, conversion = float),
636          halign = attrs[(None, 'halign')]                                    AttrDesc("text", True),
637          valign = attrs[(None, 'valign')]                                    AttrDesc("halign", True,
638                                               conversion = "ascii"),
639                                      AttrDesc("valign", True,
640                                               conversion = "ascii")])
641            x = attrs['x']
642            y = attrs['y']
643            text = attrs['text']
644            halign = attrs['halign']
645            valign = attrs['valign']
646            if halign not in ("left", "center", "right"):
647                raise LoadError("Unsupported halign value %r" % halign)
648            if valign not in ("top", "center", "bottom"):
649                raise LoadError("Unsupported valign value %r" % valign)
650          self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)          self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
651    
652      def characters(self, chars):      def characters(self, chars):
653          pass          pass
654    
655    
656  def load_session(filename, db_connection_callback = None):  def load_session(filename, db_connection_callback = None,
657                               shapefile_callback = None):
658      """Load a Thuban session from the file object file      """Load a Thuban session from the file object file
659    
660      The db_connection_callback, if given should be a callable object      The db_connection_callback, if given should be a callable object
# Line 570  def load_session(filename, db_connection Line 667  def load_session(filename, db_connection
667      corrected and perhaps additional parameters like a password or None      corrected and perhaps additional parameters like a password or None
668      to indicate that the user cancelled.      to indicate that the user cancelled.
669      """      """
670      handler = SessionLoader(db_connection_callback)      handler = SessionLoader(db_connection_callback, shapefile_callback)
671      handler.read(filename)      handler.read(filename)
672    
673      session = handler.theSession      session = handler.theSession

Legend:
Removed from v.2004  
changed lines
  Added in v.2658

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26