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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 465 - (hide 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 bh 75 # Copyright (C) 2001, 2002 by Intevation GmbH
2 bh 6 # Authors:
3     # Jan-Oliver Wagner <[email protected]>
4 bh 267 # Bernhard Herzog <[email protected]>
5 jonathan 413 # Jonathan Coles <[email protected]>
6 bh 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 bh 267
18     import xml.sax
19     import xml.sax.handler
20     from xml.sax import make_parser, ErrorHandler
21    
22 jan 374 from Thuban import _
23 jonathan 413 from Thuban.common import *
24    
25 bh 6 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 jonathan 413 from Thuban.Model.classification import Classification, \
31 jonathan 439 ClassGroupDefault, ClassGroupSingleton, ClassGroupRange, ClassGroupMap, \
32     ClassGroupProperties
33 bh 6
34    
35 bh 267 def parse_color(color):
36     """Return the color object for the string color.
37 bh 6
38 bh 267 Color may be either 'None' or of the form '#RRGGBB' in the usual
39     HTML color notation
40 bh 6 """
41     color = string.strip(color)
42     if color == "None":
43 jonathan 413 result = Color.None
44 bh 6 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 jan 374 raise ValueError(_("Invalid hexadecimal color specification %s")
52 bh 6 % color)
53     else:
54 jan 374 raise ValueError(_("Invalid color specification %s") % color)
55 bh 6 return result
56    
57    
58 bh 267 class ProcessSession(xml.sax.handler.ContentHandler):
59 bh 6
60 bh 267 # Dictionary mapping element names (or (URI, element name) pairs for
61 jonathan 365 # documents using namespaces) to method names. The methods should
62 bh 267 # 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 bh 6 def __init__(self, directory):
75     """Inititialize the Sax handler.
76    
77 bh 267 The directory parameter should be the directory containing the
78     session file. It's needed to interpret embedded relative
79     filenames.
80 bh 6 """
81     self.directory = directory
82     self.chars = ''
83     self.theSession = None
84     self.aMap = None
85     self.aLayer = None
86    
87 bh 267 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 bh 6
98 bh 267 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 bh 6
109 bh 267 def start_session(self, name, qname, attrs):
110     self.theSession = Session(attrs.get((None, 'title'), None))
111     start_dispatcher['session'] = "start_session"
112 bh 6
113 bh 267 def end_session(self, name, qname):
114     pass
115     end_dispatcher['session'] = "end_session"
116 bh 6
117 bh 267 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 jonathan 465 stroke = stroke, lineWidth = stroke_width)
155 bh 267 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 jonathan 365 def start_classification(self, name, qname, attrs):
162 jonathan 465 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 jonathan 365 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 jonathan 439 self.cl_group = ClassGroupDefault()
189     self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
190     self.cl_prop = ClassGroupProperties()
191 jonathan 365 start_dispatcher['clnull'] = "start_clnull"
192    
193     def end_clnull(self, name, qname):
194 jonathan 439 self.cl_group.SetProperties(self.cl_prop)
195     self.aLayer.GetClassification().SetDefaultGroup(self.cl_group)
196     del self.cl_group, self.cl_prop
197 jonathan 365 end_dispatcher['clnull'] = "end_clnull"
198    
199     def start_clpoint(self, name, qname, attrs):
200     attrib_value = attrs.get((None, 'value'), "0")
201    
202 jonathan 465 #try:
203     #value = Str2Num(attrib_value)
204     #except:
205     #value = attrib_value
206 jonathan 365
207 jonathan 465 value = self.conv(attrib_value)
208    
209 jonathan 439 self.cl_group = ClassGroupSingleton(value)
210     self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
211     self.cl_prop = ClassGroupProperties()
212 jonathan 413
213 jonathan 365 start_dispatcher['clpoint'] = "start_clpoint"
214    
215     def end_clpoint(self, name, qname):
216 jonathan 439 self.cl_group.SetProperties(self.cl_prop)
217     self.aLayer.GetClassification().AddGroup(self.cl_group)
218     del self.cl_group, self.cl_prop
219 jonathan 365 end_dispatcher['clpoint'] = "end_clpoint"
220    
221     def start_clrange(self, name, qname, attrs):
222    
223     try:
224 jonathan 465 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 jonathan 365 except ValueError:
229 jan 374 raise ValueError(_("Classification range is not a number!"))
230 jonathan 365
231 jonathan 439 self.cl_group = ClassGroupRange(min, max)
232     self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
233     self.cl_prop = ClassGroupProperties()
234 jonathan 413
235 jonathan 365 start_dispatcher['clrange'] = "start_clrange"
236    
237     def end_clrange(self, name, qname):
238 jonathan 439 self.cl_group.SetProperties(self.cl_prop)
239     self.aLayer.GetClassification().AddGroup(self.cl_group)
240     del self.cl_group, self.cl_prop
241 jonathan 365 end_dispatcher['clrange'] = "end_clrange"
242    
243     def start_cldata(self, name, qname, attrs):
244 jonathan 465 self.cl_prop.SetLineColor(
245     parse_color(attrs.get((None, 'stroke'), "None")))
246     self.cl_prop.SetLineWidth(
247 jonathan 390 int(attrs.get((None, 'stroke_width'), "0")))
248 jonathan 439 self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
249 jonathan 365 start_dispatcher['cldata'] = "start_cldata"
250    
251     def end_cldata(self, name, qname):
252     pass
253     end_dispatcher['cldata'] = "end_cldata"
254    
255 bh 267 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 bh 6 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 bh 267 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 bh 6 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