/[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 365 - (show annotations)
Mon Jan 27 11:47:53 2003 UTC (22 years, 1 month ago) by jonathan
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 8933 byte(s)
added support to load classification information

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26