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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 268 - (show annotations)
Thu Aug 22 10:25:43 2002 UTC (22 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/Model/save.py
File MIME type: text/x-python
File size: 7429 byte(s)
(Saver): New class to handle serializing a
session into an XML file. The main reason to introduce a class is
that applications built on Thuban can derive from it so that they
can save additional information in a session file.
(save_session): Delegate almost all the work to the Saver class.
Rename the filename argument to file because it may be a file like
object now.

1 # Copyright (c) 2001, 2002 by Intevation GmbH
2 # Authors:
3 # Jan-Oliver Wagner <[email protected]>
4 # Bernhard Herzog <[email protected]>
5 #
6 # This program is free software under the GPL (>=v2)
7 # Read the file COPYING coming with Thuban for details.
8
9 """
10 Functions to save a session to a file
11 """
12
13 __version__ = "$Revision$"
14
15 import os
16 import string
17
18 import Thuban.Lib.fileutil
19
20 def relative_filename(dir, filename):
21 """Return a filename relative to dir for the absolute file name absname.
22
23 This is almost the same as the function in fileutil, except that dir
24 can be an empty string in which case filename will be returned
25 unchanged.
26 """
27 if dir:
28 return Thuban.Lib.fileutil.relative_filename(dir, filename)
29 else:
30 return filename
31
32 def escape(data):
33 """Escape &, \", ', <, and > in a string of data.
34 """
35 data = string.replace(data, "&", "&amp;")
36 data = string.replace(data, "<", "&lt;")
37 data = string.replace(data, ">", "&gt;")
38 data = string.replace(data, '"', "&quot;")
39 data = string.replace(data, "'", "&apos;")
40 return data
41
42 class Saver:
43
44 """Class to serialize a session into an XML file.
45
46 Applications built on top of Thuban may derive from this class and
47 override or extend the methods to save additinal information. This
48 additional information should take the form of additional attributes
49 or elements whose names are prefixed with a namespace. To define a
50 namespace derived classes should extend the write_session method to
51 pass the namespaces to the default implementation.
52 """
53
54 def __init__(self, session):
55 self.session = session
56
57 def write(self, file_or_filename):
58 """Write the session to a file.
59
60 The argument may be either a file object or a filename. If it's
61 a filename, the file will be opened for writing. Files of
62 shapefiles will be stored as filenames relative to the directory
63 the file is stored in (as given by os.path.dirname(filename)) if
64 they have a common parent directory other than the root
65 directory.
66
67 If the argument is a file object (which is determined by the
68 presence of a write method) all filenames will be absolut
69 filenames.
70 """
71 if hasattr(file_or_filename, "write"):
72 # it's a file object
73 self.file = file_or_filename
74 self.dir = ""
75 else:
76 filename = file_or_filename
77 self.dir = os.path.dirname(filename)
78 self.file = open(filename, 'w')
79 self.write_header()
80 self.write_session(self.session)
81
82 def write_element(self, element, attrs, empty = 0, indentation = ""):
83 # Helper function to write an element open tag with attributes
84 self.file.write("%s<%s" % (indentation, element))
85 for name, value in attrs.items():
86 self.file.write(' %s="%s"' % (escape(name), escape(value)))
87 if empty:
88 self.file.write("/>\n")
89 else:
90 self.file.write(">\n")
91
92 def write_header(self):
93 """Write the XML header"""
94 write = self.file.write
95 write('<?xml version="1.0" encoding="UTF-8"?>\n')
96 write('<!DOCTYPE session SYSTEM "thuban.dtd">\n')
97
98 def write_session(self, session, attrs = None, namespaces = ()):
99 """Write the session and its contents
100
101 By default, write a session element with the title attribute and
102 call write_map for each map contained in the session.
103
104 The optional argument attrs is for additional attributes and, if
105 given, should be a mapping from attribute names to attribute
106 values. The values should not be XML-escaped yet.
107
108 The optional argument namespaces, if given, should be a sequence
109 of (name, URI) pairs. The namespaces are written as namespace
110 attributes into the session element. This is mainly useful for
111 derived classes that need to store additional information in a
112 thuban session file.
113 """
114 if attrs is None:
115 attrs = {}
116 attrs["title"] = session.title
117 for name, uri in namespaces:
118 attrs["xmlns:" + name] = uri
119 self.write_element("session", attrs)
120 for map in session.Maps():
121 self.write_map(map)
122 self.file.write('</session>\n')
123
124 def write_map(self, map):
125 """Write the map and its contents.
126
127 By default, write a map element element with the title
128 attribute, call write_projection to write the projection
129 element, call write_layer for each layer contained in the map
130 and finally call write_label_layer to write the label layer.
131 """
132 write = self.file.write
133 write('\t<map title="%s">\n' % escape(map.title))
134 self.write_projection(map.projection)
135 for layer in map.Layers():
136 self.write_layer(layer)
137 self.write_label_layer(map.LabelLayer())
138 write('\t</map>\n')
139
140 def write_projection(self, projection):
141 """Write the projection.
142 """
143 if projection and len(projection.params) > 0:
144 self.file.write('\t\t<projection>\n')
145 for param in projection.params:
146 self.file.write('\t\t\t<parameter value="%s"/>\n'
147 % escape(param))
148 self.file.write('\t\t</projection>\n')
149
150 def write_layer(self, layer, attrs = None):
151 """Write the layer.
152
153 The optional argument attrs is for additional attributes and, if
154 given, should be a mapping from attribute names to attribute
155 values. The values should not be XML-escaped yet.
156 """
157 if attrs is None:
158 attrs = {}
159 attrs["title"] = layer.title
160 attrs["filename"] = relative_filename(self.dir, layer.filename)
161 attrs["stroke_width"] = str(layer.stroke_width)
162 fill = layer.fill
163 if fill is None:
164 attrs["fill"] = "None"
165 else:
166 attrs["fill"] = fill.hex()
167 stroke = layer.stroke
168 if stroke is None:
169 attrs["stroke"] = "None"
170 else:
171 attrs["stroke"] = stroke.hex()
172 self.write_element("layer", attrs, empty = 1, indentation = "\t\t")
173
174 def write_label_layer(self, layer):
175 """Write the label layer.
176 """
177 labels = layer.Labels()
178 if labels:
179 self.file.write('\t\t<labellayer>\n')
180 for label in labels:
181 self.file.write(('\t\t\t<label x="%g" y="%g" text="%s"'
182 ' halign="%s" valign="%s"/>\n')
183 % (label.x, label.y, label.text, label.halign,
184 label.valign))
185 self.file.write('\t\t</labellayer>\n')
186
187
188
189 def save_session(session, file, saver_class = None):
190 """Save the session session to a file.
191
192 The file argument may either be a filename or an open file object.
193
194 The optional argument saver_class is the class to use to serialize
195 the session. By default or if it's None, the saver class will be
196 Saver.
197
198 If writing the session is successful call the session's
199 UnsetModified method
200 """
201 if saver_class is None:
202 saver_class = Saver
203 saver = saver_class(session)
204 saver.write(file)
205
206 # after a successful save consider the session unmodified.
207 session.UnsetModified()

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26