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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 465 - (show annotations)
Wed Mar 5 18:18:06 2003 UTC (22 years ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 10317 byte(s)
(ProcessSession): Use proper string conversion function; fixes RTbug #1713.

1 # Copyright (C) 2001, 2002 by Intevation GmbH
2 # Authors:
3 # Jan-Oliver Wagner <[email protected]>
4 # Bernhard Herzog <[email protected]>
5 # Jonathan Coles <[email protected]>
6 #
7 # This program is free software under the GPL (>=v2)
8 # Read the file COPYING coming with GRASS for details.
9
10 """
11 Parser for thuban session files.
12 """
13
14 __version__ = "$Revision$"
15
16 import sys, string, os
17
18 import xml.sax
19 import xml.sax.handler
20 from xml.sax import make_parser, ErrorHandler
21
22 from Thuban import _
23 from Thuban.common import *
24
25 from Thuban.Model.session import Session
26 from Thuban.Model.map import Map
27 from Thuban.Model.layer import Layer
28 from Thuban.Model.color import Color
29 from Thuban.Model.proj import Projection
30 from Thuban.Model.classification import Classification, \
31 ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
32 ClassGroupProperties
33
34
35 def parse_color(color):
36 """Return the color object for the string color.
37
38 Color may be either 'None' or of the form '#RRGGBB' in the usual
39 HTML color notation
40 """
41 color = string.strip(color)
42 if color == "None":
43 result = Color.None
44 elif color[0] == '#':
45 if len(color) == 7:
46 r = string.atoi(color[1:3], 16) / 255.0
47 g = string.atoi(color[3:5], 16) / 255.0
48 b = string.atoi(color[5:7], 16) / 255.0
49 result = Color(r, g, b)
50 else:
51 raise ValueError(_("Invalid hexadecimal color specification %s")
52 % color)
53 else:
54 raise ValueError(_("Invalid color specification %s") % color)
55 return result
56
57
58 class ProcessSession(xml.sax.handler.ContentHandler):
59
60 # Dictionary mapping element names (or (URI, element name) pairs for
61 # documents using namespaces) to method names. The methods should
62 # accept the same parameters as the startElement (or startElementNS)
63 # methods. The start_dispatcher is used by the default startElement
64 # and startElementNS methods to call a method for the open tag of an
65 # element.
66 start_dispatcher = {}
67
68 # end_dispatcher works just like start_dispatcher but it's used by
69 # endElement and endElementNS. The method whose names it maps to
70 # should accept the same parameters as endElement and endElementNS.
71 end_dispatcher = {}
72
73
74 def __init__(self, directory):
75 """Inititialize the Sax handler.
76
77 The directory parameter should be the directory containing the
78 session file. It's needed to interpret embedded relative
79 filenames.
80 """
81 self.directory = directory
82 self.chars = ''
83 self.theSession = None
84 self.aMap = None
85 self.aLayer = None
86
87 def startElementNS(self, name, qname, attrs):
88 """Call the method given for name in self.start_dispatcher
89 """
90 if name[0] is None:
91 method_name = self.start_dispatcher.get(name[1])
92 else:
93 # Dispatch with namespace
94 method_name = self.start_dispatcher.get(name)
95 if method_name is not None:
96 getattr(self, method_name)(name, qname, attrs)
97
98 def endElementNS(self, name, qname):
99 """Call the method given for name in self.end_dispatcher
100 """
101 if name[0] is None:
102 method_name = self.end_dispatcher.get(name[1])
103 else:
104 # Dispatch with namespace
105 method_name = self.end_dispatcher.get(name)
106 if method_name is not None:
107 getattr(self, method_name)(name, qname)
108
109 def start_session(self, name, qname, attrs):
110 self.theSession = Session(attrs.get((None, 'title'), None))
111 start_dispatcher['session'] = "start_session"
112
113 def end_session(self, name, qname):
114 pass
115 end_dispatcher['session'] = "end_session"
116
117 def start_map(self, name, qname, attrs):
118 """Start a map."""
119 self.aMap = Map(attrs.get((None, 'title'), None))
120 start_dispatcher['map'] = "start_map"
121
122 def end_map(self, name, qname):
123 self.theSession.AddMap(self.aMap)
124 end_dispatcher['map'] = "end_map"
125
126 def start_projection(self, name, qname, attrs):
127 self.ProjectionParams = [ ]
128 start_dispatcher['projection'] = "start_projection"
129
130 def end_projection(self, name, qname):
131 self.aMap.SetProjection(Projection(self.ProjectionParams))
132 end_dispatcher['projection'] = "end_projection"
133
134 def start_parameter(self, name, qname, attrs):
135 s = attrs.get((None, 'value'))
136 s = str(s) # we can't handle unicode in proj
137 self.ProjectionParams.append(s)
138 start_dispatcher['parameter'] = "start_parameter"
139
140 def start_layer(self, name, qname, attrs, layer_class = Layer):
141 """Start a layer
142
143 Instantiate a layer of class layer_class from the attributes in
144 attrs which may be a dictionary as well as the normal SAX attrs
145 object and bind it to self.aLayer.
146 """
147 title = attrs.get((None, 'title'), "")
148 filename = attrs.get((None, 'filename'), "")
149 filename = os.path.join(self.directory, filename)
150 fill = parse_color(attrs.get((None, 'fill'), "None"))
151 stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))
152 stroke_width = int(attrs.get((None, 'stroke_width'), "1"))
153 self.aLayer = layer_class(title, filename, fill = fill,
154 stroke = stroke, lineWidth = stroke_width)
155 start_dispatcher['layer'] = "start_layer"
156
157 def end_layer(self, name, qname):
158 self.aMap.AddLayer(self.aLayer)
159 end_dispatcher['layer'] = "end_layer"
160
161 def start_classification(self, name, qname, attrs):
162 field = attrs.get((None, 'field'), None)
163
164 fieldType = attrs.get((None, 'field_type'), None)
165 dbFieldType = self.aLayer.GetFieldType(field)
166
167 if fieldType != dbFieldType:
168 raise ValueError(_("xml field type differs from database!"))
169
170 # setup conversion routines depending on the kind of data
171 # we will be seeing later on
172 if fieldType == FIELDTYPE_STRING:
173 self.conv = str
174 elif fieldType == FIELDTYPE_INT:
175 self.conv = lambda p: int(float(p))
176 elif fieldType == FIELDTYPE_DOUBLE:
177 self.conv = float
178
179 self.aLayer.GetClassification().SetField(field)
180
181 start_dispatcher['classification'] = "start_classification"
182
183 def end_classification(self, name, qname):
184 pass
185 end_dispatcher['classification'] = "end_classification"
186
187 def start_clnull(self, name, qname, attrs):
188 self.cl_group = ClassGroupDefault()
189 self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
190 self.cl_prop = ClassGroupProperties()
191 start_dispatcher['clnull'] = "start_clnull"
192
193 def end_clnull(self, name, qname):
194 self.cl_group.SetProperties(self.cl_prop)
195 self.aLayer.GetClassification().SetDefaultGroup(self.cl_group)
196 del self.cl_group, self.cl_prop
197 end_dispatcher['clnull'] = "end_clnull"
198
199 def start_clpoint(self, name, qname, attrs):
200 attrib_value = attrs.get((None, 'value'), "0")
201
202 #try:
203 #value = Str2Num(attrib_value)
204 #except:
205 #value = attrib_value
206
207 value = self.conv(attrib_value)
208
209 self.cl_group = ClassGroupSingleton(value)
210 self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
211 self.cl_prop = ClassGroupProperties()
212
213 start_dispatcher['clpoint'] = "start_clpoint"
214
215 def end_clpoint(self, name, qname):
216 self.cl_group.SetProperties(self.cl_prop)
217 self.aLayer.GetClassification().AddGroup(self.cl_group)
218 del self.cl_group, self.cl_prop
219 end_dispatcher['clpoint'] = "end_clpoint"
220
221 def start_clrange(self, name, qname, attrs):
222
223 try:
224 min = self.conv(attrs.get((None, 'min'), "0"))
225 max = self.conv(attrs.get((None, 'max'), "0"))
226 #min = Str2Num(attrs.get((None, 'min'), "0"))
227 #max = Str2Num(attrs.get((None, 'max'), "0"))
228 except ValueError:
229 raise ValueError(_("Classification range is not a number!"))
230
231 self.cl_group = ClassGroupRange(min, max)
232 self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
233 self.cl_prop = ClassGroupProperties()
234
235 start_dispatcher['clrange'] = "start_clrange"
236
237 def end_clrange(self, name, qname):
238 self.cl_group.SetProperties(self.cl_prop)
239 self.aLayer.GetClassification().AddGroup(self.cl_group)
240 del self.cl_group, self.cl_prop
241 end_dispatcher['clrange'] = "end_clrange"
242
243 def start_cldata(self, name, qname, attrs):
244 self.cl_prop.SetLineColor(
245 parse_color(attrs.get((None, 'stroke'), "None")))
246 self.cl_prop.SetLineWidth(
247 int(attrs.get((None, 'stroke_width'), "0")))
248 self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
249 start_dispatcher['cldata'] = "start_cldata"
250
251 def end_cldata(self, name, qname):
252 pass
253 end_dispatcher['cldata'] = "end_cldata"
254
255 def start_table(self, name, qname, attrs):
256 print "table title: %s" % attrs.get('title', None)
257 start_dispatcher['table'] = "start_table"
258
259 def end_table(self, name, qname):
260 pass
261 end_dispatcher['table'] = "end_table"
262
263 def start_labellayer(self, name, qname, attrs):
264 self.aLayer = self.aMap.LabelLayer()
265 start_dispatcher['labellayer'] = "start_labellayer"
266
267 def start_label(self, name, qname, attrs):
268 x = float(attrs[(None, 'x')])
269 y = float(attrs[(None, 'y')])
270 text = attrs[(None, 'text')]
271 halign = attrs[(None, 'halign')]
272 valign = attrs[(None, 'valign')]
273 self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
274 start_dispatcher['label'] = "start_label"
275
276 def characters(self, chars):
277 pass
278
279
280 def load_session(filename):
281 """Load a Thuban session from the file object file"""
282 dir = os.path.dirname(filename)
283 file = open(filename)
284 handler = ProcessSession(dir)
285
286 parser = make_parser()
287 parser.setContentHandler(handler)
288 parser.setErrorHandler(ErrorHandler())
289 parser.setFeature(xml.sax.handler.feature_namespaces, 1)
290 parser.parse(file)
291
292 session = handler.theSession
293 # Newly loaded session aren't modified
294 session.UnsetModified()
295
296 return session
297

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26