/[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 267 - (show annotations)
Thu Aug 22 10:25:30 2002 UTC (22 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/Model/load.py
File MIME type: text/x-python
File size: 6628 byte(s)
Get rid of the Python 1.5.2 compatibility
code. Remove the little test code which would be executed when the
module is run as a script which didn't work anymore since it can't
import the other Thuban modules.
(ProcessSession, load_session): Refactor the ProcessSession to
have one method for each element start and end tag so that derived
classes can easily override the processing of individual tags.
Also, always parse with namespaces enabled because applications
built on top of Thuban will likely use namespaces if they extend
the session file format.

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
27
28 def parse_color(color):
29 """Return the color object for the string color.
30
31 Color may be either 'None' or of the form '#RRGGBB' in the usual
32 HTML color notation
33 """
34 color = string.strip(color)
35 if color == "None":
36 result = None
37 elif color[0] == '#':
38 if len(color) == 7:
39 r = string.atoi(color[1:3], 16) / 255.0
40 g = string.atoi(color[3:5], 16) / 255.0
41 b = string.atoi(color[5:7], 16) / 255.0
42 result = Color(r, g, b)
43 else:
44 raise ValueError("Invalid hexadecimal color specification %s"
45 % color)
46 else:
47 raise ValueError("Invalid color specification %s" % color)
48 return result
49
50
51 class ProcessSession(xml.sax.handler.ContentHandler):
52
53 # Dictionary mapping element names (or (URI, element name) pairs for
54 # documents using amespaces) to method names. The methods should
55 # accept the same parameters as the startElement (or startElementNS)
56 # methods. The start_dispatcher is used by the default startElement
57 # and startElementNS methods to call a method for the open tag of an
58 # element.
59 start_dispatcher = {}
60
61 # end_dispatcher works just like start_dispatcher but it's used by
62 # endElement and endElementNS. The method whose names it maps to
63 # should accept the same parameters as endElement and endElementNS.
64 end_dispatcher = {}
65
66
67 def __init__(self, directory):
68 """Inititialize the Sax handler.
69
70 The directory parameter should be the directory containing the
71 session file. It's needed to interpret embedded relative
72 filenames.
73 """
74 self.directory = directory
75 self.chars = ''
76 self.theSession = None
77 self.aMap = None
78 self.aLayer = None
79
80 def startElementNS(self, name, qname, attrs):
81 """Call the method given for name in self.start_dispatcher
82 """
83 if name[0] is None:
84 method_name = self.start_dispatcher.get(name[1])
85 else:
86 # Dispatch with namespace
87 method_name = self.start_dispatcher.get(name)
88 if method_name is not None:
89 getattr(self, method_name)(name, qname, attrs)
90
91 def endElementNS(self, name, qname):
92 """Call the method given for name in self.end_dispatcher
93 """
94 if name[0] is None:
95 method_name = self.end_dispatcher.get(name[1])
96 else:
97 # Dispatch with namespace
98 method_name = self.end_dispatcher.get(name)
99 if method_name is not None:
100 getattr(self, method_name)(name, qname)
101
102 def start_session(self, name, qname, attrs):
103 self.theSession = Session(attrs.get((None, 'title'), None))
104 start_dispatcher['session'] = "start_session"
105
106 def end_session(self, name, qname):
107 pass
108 end_dispatcher['session'] = "end_session"
109
110 def start_map(self, name, qname, attrs):
111 """Start a map."""
112 self.aMap = Map(attrs.get((None, 'title'), None))
113 start_dispatcher['map'] = "start_map"
114
115 def end_map(self, name, qname):
116 self.theSession.AddMap(self.aMap)
117 end_dispatcher['map'] = "end_map"
118
119 def start_projection(self, name, qname, attrs):
120 self.ProjectionParams = [ ]
121 start_dispatcher['projection'] = "start_projection"
122
123 def end_projection(self, name, qname):
124 self.aMap.SetProjection(Projection(self.ProjectionParams))
125 end_dispatcher['projection'] = "end_projection"
126
127 def start_parameter(self, name, qname, attrs):
128 s = attrs.get((None, 'value'))
129 s = str(s) # we can't handle unicode in proj
130 self.ProjectionParams.append(s)
131 start_dispatcher['parameter'] = "start_parameter"
132
133 def start_layer(self, name, qname, attrs, layer_class = Layer):
134 """Start a layer
135
136 Instantiate a layer of class layer_class from the attributes in
137 attrs which may be a dictionary as well as the normal SAX attrs
138 object and bind it to self.aLayer.
139 """
140 title = attrs.get((None, 'title'), "")
141 filename = attrs.get((None, 'filename'), "")
142 filename = os.path.join(self.directory, filename)
143 fill = parse_color(attrs.get((None, 'fill'), "None"))
144 stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))
145 stroke_width = int(attrs.get((None, 'stroke_width'), "1"))
146 self.aLayer = layer_class(title, filename, fill = fill,
147 stroke = stroke, stroke_width = stroke_width)
148 start_dispatcher['layer'] = "start_layer"
149
150 def end_layer(self, name, qname):
151 self.aMap.AddLayer(self.aLayer)
152 end_dispatcher['layer'] = "end_layer"
153
154 def start_table(self, name, qname, attrs):
155 print "table title: %s" % attrs.get('title', None)
156 start_dispatcher['table'] = "start_table"
157
158 def end_table(self, name, qname):
159 pass
160 end_dispatcher['table'] = "end_table"
161
162 def start_labellayer(self, name, qname, attrs):
163 self.aLayer = self.aMap.LabelLayer()
164 start_dispatcher['labellayer'] = "start_labellayer"
165
166 def start_label(self, name, qname, attrs):
167 x = float(attrs[(None, 'x')])
168 y = float(attrs[(None, 'y')])
169 text = attrs[(None, 'text')]
170 halign = attrs[(None, 'halign')]
171 valign = attrs[(None, 'valign')]
172 self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
173 start_dispatcher['label'] = "start_label"
174
175 def characters(self, chars):
176 pass
177
178
179 def load_session(filename):
180 """Load a Thuban session from the file object file"""
181 dir = os.path.dirname(filename)
182 file = open(filename)
183 handler = ProcessSession(dir)
184
185 parser = make_parser()
186 parser.setContentHandler(handler)
187 parser.setErrorHandler(ErrorHandler())
188 parser.setFeature(xml.sax.handler.feature_namespaces, 1)
189 parser.parse(file)
190
191 session = handler.theSession
192 # Newly loaded session aren't modified
193 session.UnsetModified()
194
195 return session
196

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26