/[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 473 - (show annotations)
Wed Mar 5 18:39:45 2003 UTC (22 years ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 10406 byte(s)
import FIELDTYPE constants from table

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26