/[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 1159 - (show annotations)
Thu Jun 12 12:40:27 2003 UTC (21 years, 8 months ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 9931 byte(s)
(XMLReader): Moved into seperate file xmlreader.py.

1 # Copyright (C) 2001, 2002, 2003 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 string, os
17
18 import xml.sax
19 import xml.sax.handler
20 from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
21
22 from Thuban import _
23
24 from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
25 FIELDTYPE_STRING
26
27 from Thuban.Model.session import Session
28 from Thuban.Model.map import Map
29 from Thuban.Model.layer import Layer, RasterLayer
30 from Thuban.Model.color import Color
31 from Thuban.Model.proj import Projection
32 from Thuban.Model.range import Range
33 from Thuban.Model.classification import Classification, \
34 ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
35 ClassGroupProperties
36
37 from Thuban.Model.xmlreader import XMLReader
38 import resource
39
40 def parse_color(color):
41 """Return the color object for the string color.
42
43 Color may be either 'None' or of the form '#RRGGBB' in the usual
44 HTML color notation
45 """
46 color = string.strip(color)
47 if color == "None":
48 result = Color.Transparent
49 elif color[0] == '#':
50 if len(color) == 7:
51 r = string.atoi(color[1:3], 16) / 255.0
52 g = string.atoi(color[3:5], 16) / 255.0
53 b = string.atoi(color[5:7], 16) / 255.0
54 result = Color(r, g, b)
55 else:
56 raise ValueError(_("Invalid hexadecimal color specification %s")
57 % color)
58 else:
59 raise ValueError(_("Invalid color specification %s") % color)
60 return result
61
62 class SessionLoader(XMLReader):
63
64 def __init__(self):
65 """Inititialize the Sax handler."""
66 XMLReader.__init__(self)
67
68 self.theSession = None
69 self.aMap = None
70 self.aLayer = None
71
72 XMLReader.AddDispatchers(self,
73 {'session' : ("start_session", "end_session"),
74 'map' : ("start_map", "end_map"),
75 'projection' : ("start_projection", "end_projection"),
76 'parameter' : ("start_parameter", None),
77 'layer' : ("start_layer", "end_layer"),
78 'rasterlayer' : ("start_rasterlayer", "end_rasterlayer"),
79 'classification': ("start_classification", "end_classification"),
80 'clnull' : ("start_clnull", "end_clnull"),
81 'clpoint' : ("start_clpoint", "end_clpoint"),
82 'clrange' : ("start_clrange", "end_clrange"),
83 'cldata' : ("start_cldata", "end_cldata"),
84 'table' : ("start_table", "end_table"),
85 'labellayer' : ("start_labellayer", None),
86 'label' : ("start_label", None)})
87
88 def start_session(self, name, qname, attrs):
89 self.theSession = Session(self.encode(attrs.get((None, 'title'), None)))
90
91 def end_session(self, name, qname):
92 pass
93
94 def start_map(self, name, qname, attrs):
95 """Start a map."""
96 self.aMap = Map(attrs.get((None, 'title'), None))
97
98 def end_map(self, name, qname):
99 self.theSession.AddMap(self.aMap)
100 self.aMap = None
101
102 def start_projection(self, name, qname, attrs):
103 self.ProjectionName = self.encode(attrs.get((None, 'name'), None))
104 self.ProjectionParams = [ ]
105
106 def end_projection(self, name, qname):
107 if self.aLayer is not None:
108 obj = self.aLayer
109 elif self.aMap is not None:
110 obj = self.aMap
111 else:
112 assert False, "projection tag out of context"
113 pass
114
115 obj.SetProjection(
116 Projection(self.ProjectionParams, self.ProjectionName))
117
118 def start_parameter(self, name, qname, attrs):
119 s = attrs.get((None, 'value'))
120 s = str(s) # we can't handle unicode in proj
121 self.ProjectionParams.append(s)
122
123 def start_layer(self, name, qname, attrs, layer_class = Layer):
124 """Start a layer
125
126 Instantiate a layer of class layer_class from the attributes in
127 attrs which may be a dictionary as well as the normal SAX attrs
128 object and bind it to self.aLayer.
129 """
130 title = self.encode(attrs.get((None, 'title'), ""))
131 filename = attrs.get((None, 'filename'), "")
132 filename = os.path.join(self.GetDirectory(), filename)
133 filename = self.encode(filename)
134 visible = self.encode(attrs.get((None, 'visible'), "true")) != "false"
135 fill = parse_color(attrs.get((None, 'fill'), "None"))
136 stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))
137 stroke_width = int(attrs.get((None, 'stroke_width'), "1"))
138 self.aLayer = layer_class(title,
139 self.theSession.OpenShapefile(filename),
140 fill = fill, stroke = stroke,
141 lineWidth = stroke_width,
142 visible = visible)
143
144 def end_layer(self, name, qname):
145 self.aMap.AddLayer(self.aLayer)
146 self.aLayer = None
147
148 def start_rasterlayer(self, name, qname, attrs, layer_class = RasterLayer):
149 title = self.encode(attrs.get((None, 'title'), ""))
150 filename = attrs.get((None, 'filename'), "")
151 filename = os.path.join(self.GetDirectory(), filename)
152 filename = self.encode(filename)
153 visible = self.encode(attrs.get((None, 'visible'), "true")) != "false"
154
155 self.aLayer = layer_class(title, filename, visible = visible)
156
157 def end_rasterlayer(self, name, qname):
158 self.aMap.AddLayer(self.aLayer)
159 self.aLayer = None
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 def end_classification(self, name, qname):
182 pass
183
184 def start_clnull(self, name, qname, attrs):
185 self.cl_group = ClassGroupDefault()
186 self.cl_group.SetLabel(self.encode(attrs.get((None, 'label'), "")))
187 self.cl_prop = ClassGroupProperties()
188
189 def end_clnull(self, name, qname):
190 self.cl_group.SetProperties(self.cl_prop)
191 self.aLayer.GetClassification().SetDefaultGroup(self.cl_group)
192 del self.cl_group, self.cl_prop
193
194 def start_clpoint(self, name, qname, attrs):
195 attrib_value = attrs.get((None, 'value'), "0")
196
197 value = self.conv(attrib_value)
198
199 self.cl_group = ClassGroupSingleton(value)
200 self.cl_group.SetLabel(self.encode(attrs.get((None, 'label'), "")))
201 self.cl_prop = ClassGroupProperties()
202
203
204 def end_clpoint(self, name, qname):
205 self.cl_group.SetProperties(self.cl_prop)
206 self.aLayer.GetClassification().AppendGroup(self.cl_group)
207 del self.cl_group, self.cl_prop
208
209 def start_clrange(self, name, qname, attrs):
210
211 range = attrs.get((None, 'range'), None)
212 # for backward compatibility (min/max are not saved)
213 min = attrs.get((None, 'min'), None)
214 max = attrs.get((None, 'max'), None)
215
216 try:
217 if range is not None:
218 self.cl_group = ClassGroupRange(Range(range))
219 elif min is not None and max is not None:
220 self.cl_group = ClassGroupRange(self.conv(min), self.conv(max))
221 else:
222 self.cl_group = ClassGroupRange(Range(None))
223
224 except ValueError:
225 raise ValueError(_("Classification range is not a number!"))
226
227 self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
228 self.cl_prop = ClassGroupProperties()
229
230
231 def end_clrange(self, name, qname):
232 self.cl_group.SetProperties(self.cl_prop)
233 self.aLayer.GetClassification().AppendGroup(self.cl_group)
234 del self.cl_group, self.cl_prop
235
236 def start_cldata(self, name, qname, attrs):
237 self.cl_prop.SetLineColor(
238 parse_color(attrs.get((None, 'stroke'), "None")))
239 self.cl_prop.SetLineWidth(
240 int(attrs.get((None, 'stroke_width'), "0")))
241 self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
242
243 def end_cldata(self, name, qname):
244 pass
245
246 def start_table(self, name, qname, attrs):
247 #print "table title: %s" % attrs.get('title', None)
248 pass
249
250 def end_table(self, name, qname):
251 pass
252
253 def start_labellayer(self, name, qname, attrs):
254 self.aLayer = self.aMap.LabelLayer()
255
256 def start_label(self, name, qname, attrs):
257 x = float(attrs[(None, 'x')])
258 y = float(attrs[(None, 'y')])
259 text = self.encode(attrs[(None, 'text')])
260 halign = attrs[(None, 'halign')]
261 valign = attrs[(None, 'valign')]
262 self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
263
264 def characters(self, chars):
265 pass
266
267
268 def load_session(filename):
269 """Load a Thuban session from the file object file"""
270
271 handler = SessionLoader()
272 handler.read(filename)
273
274 session = handler.theSession
275 # Newly loaded session aren't modified
276 session.UnsetModified()
277
278 return session
279

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26