/[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 413 - (show annotations)
Wed Feb 19 16:52:04 2003 UTC (22 years ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 9191 byte(s)
(ProcessSession): Use new methods on Layer
        to get the classifcation and use the new ClassData* classes to
        hold the classification data. Use Str2Num to convert numbers
        properly.

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 ClassDataDefault, ClassDataPoint, ClassDataRange, ClassDataMap
32
33
34 def parse_color(color):
35 """Return the color object for the string color.
36
37 Color may be either 'None' or of the form '#RRGGBB' in the usual
38 HTML color notation
39 """
40 color = string.strip(color)
41 if color == "None":
42 result = Color.None
43 elif color[0] == '#':
44 if len(color) == 7:
45 r = string.atoi(color[1:3], 16) / 255.0
46 g = string.atoi(color[3:5], 16) / 255.0
47 b = string.atoi(color[5:7], 16) / 255.0
48 result = Color(r, g, b)
49 else:
50 raise ValueError(_("Invalid hexadecimal color specification %s")
51 % color)
52 else:
53 raise ValueError(_("Invalid color specification %s") % color)
54 return result
55
56
57 class ProcessSession(xml.sax.handler.ContentHandler):
58
59 # Dictionary mapping element names (or (URI, element name) pairs for
60 # documents using namespaces) to method names. The methods should
61 # accept the same parameters as the startElement (or startElementNS)
62 # methods. The start_dispatcher is used by the default startElement
63 # and startElementNS methods to call a method for the open tag of an
64 # element.
65 start_dispatcher = {}
66
67 # end_dispatcher works just like start_dispatcher but it's used by
68 # endElement and endElementNS. The method whose names it maps to
69 # should accept the same parameters as endElement and endElementNS.
70 end_dispatcher = {}
71
72
73 def __init__(self, directory):
74 """Inititialize the Sax handler.
75
76 The directory parameter should be the directory containing the
77 session file. It's needed to interpret embedded relative
78 filenames.
79 """
80 self.directory = directory
81 self.chars = ''
82 self.theSession = None
83 self.aMap = None
84 self.aLayer = None
85
86 def startElementNS(self, name, qname, attrs):
87 """Call the method given for name in self.start_dispatcher
88 """
89 if name[0] is None:
90 method_name = self.start_dispatcher.get(name[1])
91 else:
92 # Dispatch with namespace
93 method_name = self.start_dispatcher.get(name)
94 if method_name is not None:
95 getattr(self, method_name)(name, qname, attrs)
96
97 def endElementNS(self, name, qname):
98 """Call the method given for name in self.end_dispatcher
99 """
100 if name[0] is None:
101 method_name = self.end_dispatcher.get(name[1])
102 else:
103 # Dispatch with namespace
104 method_name = self.end_dispatcher.get(name)
105 if method_name is not None:
106 getattr(self, method_name)(name, qname)
107
108 def start_session(self, name, qname, attrs):
109 self.theSession = Session(attrs.get((None, 'title'), None))
110 start_dispatcher['session'] = "start_session"
111
112 def end_session(self, name, qname):
113 pass
114 end_dispatcher['session'] = "end_session"
115
116 def start_map(self, name, qname, attrs):
117 """Start a map."""
118 self.aMap = Map(attrs.get((None, 'title'), None))
119 start_dispatcher['map'] = "start_map"
120
121 def end_map(self, name, qname):
122 self.theSession.AddMap(self.aMap)
123 end_dispatcher['map'] = "end_map"
124
125 def start_projection(self, name, qname, attrs):
126 self.ProjectionParams = [ ]
127 start_dispatcher['projection'] = "start_projection"
128
129 def end_projection(self, name, qname):
130 self.aMap.SetProjection(Projection(self.ProjectionParams))
131 end_dispatcher['projection'] = "end_projection"
132
133 def start_parameter(self, name, qname, attrs):
134 s = attrs.get((None, 'value'))
135 s = str(s) # we can't handle unicode in proj
136 self.ProjectionParams.append(s)
137 start_dispatcher['parameter'] = "start_parameter"
138
139 def start_layer(self, name, qname, attrs, layer_class = Layer):
140 """Start a layer
141
142 Instantiate a layer of class layer_class from the attributes in
143 attrs which may be a dictionary as well as the normal SAX attrs
144 object and bind it to self.aLayer.
145 """
146 title = attrs.get((None, 'title'), "")
147 filename = attrs.get((None, 'filename'), "")
148 filename = os.path.join(self.directory, filename)
149 fill = parse_color(attrs.get((None, 'fill'), "None"))
150 stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))
151 stroke_width = int(attrs.get((None, 'stroke_width'), "1"))
152 self.aLayer = layer_class(title, filename, fill = fill,
153 stroke = stroke, stroke_width = stroke_width)
154 start_dispatcher['layer'] = "start_layer"
155
156 def end_layer(self, name, qname):
157 self.aMap.AddLayer(self.aLayer)
158 end_dispatcher['layer'] = "end_layer"
159
160 def start_classification(self, name, qname, attrs):
161 self.aLayer.GetClassification().SetField(
162 attrs.get((None, 'field'), None))
163 start_dispatcher['classification'] = "start_classification"
164
165 def end_classification(self, name, qname):
166 pass
167 end_dispatcher['classification'] = "end_classification"
168
169 def start_clnull(self, name, qname, attrs):
170 self.cl_data = ClassDataDefault()
171 self.cl_data.SetLabel(attrs.get((None, 'label'), ""))
172 start_dispatcher['clnull'] = "start_clnull"
173
174 def end_clnull(self, name, qname):
175 self.aLayer.GetClassification().SetDefaultData(self.cl_data)
176 del self.cl_data
177 end_dispatcher['clnull'] = "end_clnull"
178
179 def start_clpoint(self, name, qname, attrs):
180 attrib_value = attrs.get((None, 'value'), "0")
181
182 try:
183 value = Str2Num(attrib_value)
184 except:
185 value = attrib_value
186
187 self.cl_data = ClassDataPoint(value)
188 self.cl_data.SetLabel(attrs.get((None, 'label'), ""))
189
190 start_dispatcher['clpoint'] = "start_clpoint"
191
192 def end_clpoint(self, name, qname):
193 self.aLayer.GetClassification().AddClassData(self.cl_data)
194 del self.cl_data
195 end_dispatcher['clpoint'] = "end_clpoint"
196
197 def start_clrange(self, name, qname, attrs):
198
199 try:
200 min = Str2Num(attrs.get((None, 'min'), "0"))
201 max = Str2Num(attrs.get((None, 'max'), "0"))
202 except ValueError:
203 raise ValueError(_("Classification range is not a number!"))
204
205 self.cl_data = ClassDataRange(min, max)
206 self.cl_data.SetLabel(attrs.get((None, 'label'), ""))
207
208 start_dispatcher['clrange'] = "start_clrange"
209
210 def end_clrange(self, name, qname):
211 self.aLayer.GetClassification().AddClassData(self.cl_data)
212 del self.cl_data
213 end_dispatcher['clrange'] = "end_clrange"
214
215 def start_cldata(self, name, qname, attrs):
216 self.cl_data.SetStroke(parse_color(attrs.get((None, 'stroke'), "None")))
217 self.cl_data.SetStrokeWidth(
218 int(attrs.get((None, 'stroke_width'), "0")))
219 self.cl_data.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
220 start_dispatcher['cldata'] = "start_cldata"
221
222 def end_cldata(self, name, qname):
223 pass
224 end_dispatcher['cldata'] = "end_cldata"
225
226 def start_table(self, name, qname, attrs):
227 print "table title: %s" % attrs.get('title', None)
228 start_dispatcher['table'] = "start_table"
229
230 def end_table(self, name, qname):
231 pass
232 end_dispatcher['table'] = "end_table"
233
234 def start_labellayer(self, name, qname, attrs):
235 self.aLayer = self.aMap.LabelLayer()
236 start_dispatcher['labellayer'] = "start_labellayer"
237
238 def start_label(self, name, qname, attrs):
239 x = float(attrs[(None, 'x')])
240 y = float(attrs[(None, 'y')])
241 text = attrs[(None, 'text')]
242 halign = attrs[(None, 'halign')]
243 valign = attrs[(None, 'valign')]
244 self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
245 start_dispatcher['label'] = "start_label"
246
247 def characters(self, chars):
248 pass
249
250
251 def load_session(filename):
252 """Load a Thuban session from the file object file"""
253 dir = os.path.dirname(filename)
254 file = open(filename)
255 handler = ProcessSession(dir)
256
257 parser = make_parser()
258 parser.setContentHandler(handler)
259 parser.setErrorHandler(ErrorHandler())
260 parser.setFeature(xml.sax.handler.feature_namespaces, 1)
261 parser.parse(file)
262
263 session = handler.theSession
264 # Newly loaded session aren't modified
265 session.UnsetModified()
266
267 return session
268

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26