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

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

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

revision 201 by bh, Mon Jul 8 10:50:53 2002 UTC revision 1251 by jonathan, Fri Jun 20 09:27:55 2003 UTC
# Line 1  Line 1 
1  # Copyright (c) 2001, 2002 by Intevation GmbH  # Copyright (c) 2001, 2002, 2003 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]>
6  #  #
7  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
8  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
# Line 13  Functions to save a session to a file Line 14  Functions to save a session to a file
14  __version__ = "$Revision$"  __version__ = "$Revision$"
15    
16  import os  import os
 import string  
17    
18  import Thuban.Lib.fileutil  import Thuban.Lib.fileutil
19    
20    from Thuban.Model.color import Color
21    from Thuban.Model.layer import Layer, RasterLayer
22    
23    from Thuban.Model.classification import \
24        ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap
25    
26    from Thuban.Model.xmlwriter import XMLWriter
27    
28  def relative_filename(dir, filename):  def relative_filename(dir, filename):
29      """Return a filename relative to dir for the absolute file name absname.      """Return a filename relative to dir for the absolute file name absname.
30    
# Line 29  def relative_filename(dir, filename): Line 37  def relative_filename(dir, filename):
37      else:      else:
38          return filename          return filename
39    
40  def escape(data):  class SessionSaver(XMLWriter):
41      """Escape &, \", ', <, and > in a string of data.  
42        """Class to serialize a session into an XML file.
43    
44        Applications built on top of Thuban may derive from this class and
45        override or extend the methods to save additional information. This
46        additional information should take the form of additional attributes
47        or elements whose names are prefixed with a namespace. To define a
48        namespace derived classes should extend the write_session method to
49        pass the namespaces to the default implementation.
50      """      """
     data = string.replace(data, "&", "&amp;")  
     data = string.replace(data, "<", "&lt;")  
     data = string.replace(data, ">", "&gt;")  
     data = string.replace(data, '"', "&quot;")  
     data = string.replace(data, "'", "&apos;")  
     return data  
   
 def save_session(session, filename):  
     """Save the session session to the file given by filename"""  
     dir = os.path.dirname(filename)  
     file = open(filename, 'w')  
     write = file.write  
     write('<?xml version="1.0" encoding="UTF-8"?>\n')  
     write('<!DOCTYPE session SYSTEM "thuban.dtd">\n')  
     write('<session title="%s">\n' % escape(session.title))  
     for map in session.Maps():  
         write('\t<map title="%s">\n' % escape(map.title))  
         if map.projection and len(map.projection.params) > 0:  
             write('\t\t<projection>\n')  
             for param in map.projection.params:  
                 write('\t\t\t<parameter value="%s"/>\n' % escape(param))  
             write('\t\t</projection>\n')  
51    
52    
53        def __init__(self, session):
54            XMLWriter.__init__(self)
55            self.session = session
56    
57        def write(self, file_or_filename):
58            XMLWriter.write(self, file_or_filename)
59    
60            self.write_header("session", "thuban.dtd")
61            self.write_session(self.session)
62            self.close()
63    
64        def write_session(self, session, attrs = None, namespaces = ()):
65            """Write the session and its contents
66    
67            By default, write a session element with the title attribute and
68            call write_map for each map contained in the session.
69    
70            The optional argument attrs is for additional attributes and, if
71            given, should be a mapping from attribute names to attribute
72            values. The values should not be XML-escaped yet.
73    
74            The optional argument namespaces, if given, should be a sequence
75            of (name, URI) pairs. The namespaces are written as namespace
76            attributes into the session element. This is mainly useful for
77            derived classes that need to store additional information in a
78            thuban session file.
79            """
80            if attrs is None:
81                attrs = {}
82            attrs["title"] = session.title
83            for name, uri in namespaces:
84                attrs["xmlns:" + name] = uri
85            self.open_element("session", attrs)
86            for map in session.Maps():
87                self.write_map(map)
88            self.close_element("session")
89    
90        def write_map(self, map):
91            """Write the map and its contents.
92    
93            By default, write a map element element with the title
94            attribute, call write_projection to write the projection
95            element, call write_layer for each layer contained in the map
96            and finally call write_label_layer to write the label layer.
97            """
98            self.open_element('map title="%s"' % self.encode(map.title))
99            self.write_projection(map.projection)
100          for layer in map.Layers():          for layer in map.Layers():
101              fill = layer.fill              self.write_layer(layer)
102              if fill is None:          self.write_label_layer(map.LabelLayer())
103                  fill = "None"          self.close_element('map')
104    
105        def write_projection(self, projection):
106            """Write the projection.
107            """
108            if projection and len(projection.params) > 0:
109                self.open_element("projection", {"name": projection.GetName()})
110                for param in projection.params:
111                    self.write_element('parameter value="%s"' %
112                                       self.encode(param))
113                self.close_element("projection")
114    
115        def write_layer(self, layer, attrs = None):
116            """Write the layer.
117    
118            The optional argument attrs is for additional attributes and, if
119            given, should be a mapping from attribute names to attribute
120            values. The values should not be XML-escaped yet.
121            """
122    
123            if attrs is None:
124                attrs = {}
125    
126            attrs["title"]   = layer.title
127            attrs["visible"] = ("false", "true")[int(layer.Visible())]
128    
129            if isinstance(layer, Layer):
130                attrs["filename"] = relative_filename(self.dir,
131                                                    layer.ShapeStore().FileName())
132    
133                lc = layer.GetClassification()
134                attrs["stroke"]       = lc.GetDefaultLineColor().hex()
135                attrs["stroke_width"] = str(lc.GetDefaultLineWidth())
136                attrs["fill"]         = lc.GetDefaultFill().hex()
137    
138                self.open_element("layer", attrs)
139                self.write_projection(layer.GetProjection())
140                self.write_classification(layer)
141                self.close_element("layer")
142    
143            elif isinstance(layer, RasterLayer):
144                attrs["filename"] = relative_filename(self.dir, layer.filename)
145                self.open_element("rasterlayer", attrs)
146                self.write_projection(layer.GetProjection())
147                self.close_element("rasterlayer")
148    
149        def write_classification(self, layer, attrs = None):
150            """Write Classification information."""
151    
152            if attrs is None:
153                attrs = {}
154    
155            lc = layer.GetClassification()
156    
157            field = lc.GetField()
158    
159            #
160            # there isn't a classification of anything so do nothing
161            #
162            if field is None: return
163    
164            attrs["field"] = field
165            attrs["field_type"] = str(lc.GetFieldType())
166            self.open_element("classification", attrs)
167    
168            for g in lc:
169                if isinstance(g, ClassGroupDefault):
170                    open_el  = 'clnull label="%s"' % self.encode(g.GetLabel())
171                    close_el = 'clnull'
172                elif isinstance(g, ClassGroupSingleton):
173                    open_el  = 'clpoint label="%s" value="%s"' \
174                               % (self.encode(g.GetLabel()), str(g.GetValue()))
175                    close_el = 'clpoint'
176                elif isinstance(g, ClassGroupRange):
177                    open_el  = 'clrange label="%s" range="%s"' \
178                              % (self.encode(g.GetLabel()), str(g.GetRange()))
179                    close_el = 'clrange'
180              else:              else:
181                  fill = fill.hex()                  assert False, _("Unsupported group type in classification")
182              stroke = layer.stroke                  continue
183              if stroke is None:  
184                  stroke = "None"              data = g.GetProperties()
185              else:              dict = {'stroke'      : data.GetLineColor().hex(),
186                  stroke = stroke.hex()                      'stroke_width': str(data.GetLineWidth()),
187              write(('\t\t<layer title="%s" filename="%s"'                      'fill'        : data.GetFill().hex()}
188                     ' fill="%s" stroke="%s" stroke_width="%d"/>\n') %  
189                    (escape(layer.title),              self.open_element(open_el)
190                     escape(relative_filename(dir, layer.filename)),              self.write_element("cldata", dict)
191                     fill, stroke, layer.stroke_width))              self.close_element(close_el)
192          labels = map.LabelLayer().Labels()  
193            self.close_element("classification")
194    
195        def write_label_layer(self, layer):
196            """Write the label layer.
197            """
198            labels = layer.Labels()
199          if labels:          if labels:
200              write('\t\t<labellayer>\n')              self.open_element('labellayer')
201              for label in labels:              for label in labels:
202                  write(('\t\t\t<label x="%g" y="%g" text="%s"'                  self.write_element(('label x="%g" y="%g" text="%s"'
203                         ' halign="%s" valign="%s"/>\n')                                      ' halign="%s" valign="%s"')
204                        % (label.x, label.y, label.text, label.halign,                                  % (label.x, label.y,
205                           label.valign))                                     self.encode(label.text),
206              write('\t\t</labellayer>\n')                                     label.halign,
207          write('\t</map>\n')                                     label.valign))
208      write('</session>\n')              self.close_element('labellayer')
209    
210    
211    
212    def save_session(session, file, saver_class = None):
213        """Save the session session to a file.
214    
215        The file argument may either be a filename or an open file object.
216    
217        The optional argument saver_class is the class to use to serialize
218        the session. By default or if it's None, the saver class will be
219        SessionSaver.
220    
221        If writing the session is successful call the session's
222        UnsetModified method
223        """
224        if saver_class is None:
225            saver_class = SessionSaver
226        saver = saver_class(session)
227        saver.write(file)
228    
229      # after a successful save consider the session unmodified.      # after a successful save consider the session unmodified.
230      session.UnsetModified()      session.UnsetModified()

Legend:
Removed from v.201  
changed lines
  Added in v.1251

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26