/[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 365 - (hide 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 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 bh 6 #
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 bh 267
17     import xml.sax
18     import xml.sax.handler
19     from xml.sax import make_parser, ErrorHandler
20    
21 bh 6 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 jonathan 365 from Thuban.Model.classification import Classification
27 bh 6
28    
29 bh 267 def parse_color(color):
30     """Return the color object for the string color.
31 bh 6
32 bh 267 Color may be either 'None' or of the form '#RRGGBB' in the usual
33     HTML color notation
34 bh 6 """
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 bh 267 class ProcessSession(xml.sax.handler.ContentHandler):
53 bh 6
54 bh 267 # Dictionary mapping element names (or (URI, element name) pairs for
55 jonathan 365 # documents using namespaces) to method names. The methods should
56 bh 267 # 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 bh 6 def __init__(self, directory):
69     """Inititialize the Sax handler.
70    
71 bh 267 The directory parameter should be the directory containing the
72     session file. It's needed to interpret embedded relative
73     filenames.
74 bh 6 """
75     self.directory = directory
76     self.chars = ''
77     self.theSession = None
78     self.aMap = None
79     self.aLayer = None
80    
81 bh 267 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 bh 6
92 bh 267 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 bh 6
103 bh 267 def start_session(self, name, qname, attrs):
104     self.theSession = Session(attrs.get((None, 'title'), None))
105     start_dispatcher['session'] = "start_session"
106 bh 6
107 bh 267 def end_session(self, name, qname):
108     pass
109     end_dispatcher['session'] = "end_session"
110 bh 6
111 bh 267 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 jonathan 365 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 bh 267 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 bh 6 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 bh 267 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 bh 6 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