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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 6 by bh, Tue Aug 28 15:41:52 2001 UTC revision 365 by jonathan, Mon Jan 27 11:47:53 2003 UTC
# Line 1  Line 1 
1  # Copyright (C) 2001 by Intevation GmbH  # Copyright (C) 2001, 2002 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
4    # Bernhard Herzog <[email protected]>
5  #  #
6  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
7  # Read the file COPYING coming with GRASS for details.  # Read the file COPYING coming with GRASS for details.
# Line 12  Parser for thuban session files. Line 13  Parser for thuban session files.
13  __version__ = "$Revision$"  __version__ = "$Revision$"
14    
15  import sys, string, os  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  from Thuban.Model.session import Session
22  from Thuban.Model.map import Map  from Thuban.Model.map import Map
23  from Thuban.Model.layer import Layer  from Thuban.Model.layer import Layer
24  from Thuban.Model.color import Color  from Thuban.Model.color import Color
25  from Thuban.Model.proj import Projection  from Thuban.Model.proj import Projection
26    from Thuban.Model.classification import Classification
 oldPython=0  
   
 if not sys.__dict__.has_key("version_info"):  
     # We can assume to have python 1.5.2 or lower here now  
     oldPython=1  
   
 if oldPython:  
     try:  
         from xml.sax.saxexts import make_parser  
         from xml.sax.saxlib import HandlerBase  
         from xml.sax import saxutils  
     except ImportError:  
         sys.stdout.write(("You need to have Python-XML installed or"  
                           " a modern Python!\n"  
                           "Check www.python.org/sigs/xml-sig/\n\n"))  
         raise  
 else:  
     # Do the python 2.0 standard xml thing and map it on the old names  
     import xml.sax  
     import xml.sax.handler  
     HandlerBase=xml.sax.handler.ContentHandler  
     from xml.sax import make_parser  
   
 class testSAXContentHandler(HandlerBase):  
 # SAX compliant  
     def characters(self, ch, start, length):  
         pass  
       
 def test_for_broken_SAX():  
     ch=testSAXContentHandler()  
     try:  
         xml.sax.parseString("""<?xml version="1.0"?>  
             <child1 name="paul">Text goes here</child1>  
         """,ch)  
     except TypeError:  
         return 1  
     return 0  
27    
28    
29  def parse_color(color):  def parse_color(color):
30      """      """Return the color object for the string color.
31      Return the color object for the string color. Color may be either  
32      'None' or of the form '#RRGGBB' in the usual HTML color notation      Color may be either 'None' or of the form '#RRGGBB' in the usual
33        HTML color notation
34      """      """
35      color = string.strip(color)      color = string.strip(color)
36      if color == "None":      if color == "None":
# Line 79  def parse_color(color): Line 49  def parse_color(color):
49      return result      return result
50    
51    
52  class ProcessSession(HandlerBase):  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):      def __init__(self, directory):
69          """Inititialize the Sax handler.          """Inititialize the Sax handler.
70    
71          directory is the directory containing the session file. It's          The directory parameter should be the directory containing the
72          needed to interpret embedded relative filenames          session file. It's needed to interpret embedded relative
73            filenames.
74          """          """
75          self.directory = directory          self.directory = directory
76          self.chars = ''          self.chars = ''
# Line 93  class ProcessSession(HandlerBase): Line 78  class ProcessSession(HandlerBase):
78          self.aMap = None          self.aMap = None
79          self.aLayer = None          self.aLayer = None
80    
81      def startElement(self, name, attrs):      def startElementNS(self, name, qname, attrs):
82          if name == 'session':          """Call the method given for name in self.start_dispatcher
83              self.theSession = Session(attrs.get('title', None))          """
84          elif name == 'map':          if name[0] is None:
85              self.aMap = Map(attrs.get('title', None))              method_name = self.start_dispatcher.get(name[1])
86          elif name == 'projection':          else:
87              self.ProjectionParams = [ ]              # Dispatch with namespace
88          elif name == 'parameter':              method_name = self.start_dispatcher.get(name)
89              self.ProjectionParams.append(attrs.get('value', None))          if method_name is not None:
90          elif name == 'layer':              getattr(self, method_name)(name, qname, attrs)
91              title = attrs.get('title', "")  
92              filename = attrs.get('filename', "")      def endElementNS(self, name, qname):
93              filename = os.path.join(self.directory, filename)          """Call the method given for name in self.end_dispatcher
94              fill = parse_color(attrs.get('fill', "None"))          """
95              stroke = parse_color(attrs.get('stroke', "#000000"))          if name[0] is None:
96              self.aLayer = Layer(title, filename, fill = fill, stroke = stroke)              method_name = self.end_dispatcher.get(name[1])
97          elif name == 'table':          else:
98              print "table title: %s" % attrs.get('title', None)              # Dispatch with namespace
99          elif name == 'labellayer':              method_name = self.end_dispatcher.get(name)
100              self.aLayer = self.aMap.LabelLayer()          if method_name is not None:
101          elif name == 'label':              getattr(self, method_name)(name, qname)
102              x = float(attrs['x'])  
103              y = float(attrs['y'])      def start_session(self, name, qname, attrs):
104              text = attrs['text']          self.theSession = Session(attrs.get((None, 'title'), None))
105              halign = attrs['halign']      start_dispatcher['session'] = "start_session"
106              valign = attrs['valign']  
107              self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)      def end_session(self, name, qname):
108                    pass
109        end_dispatcher['session'] = "end_session"
110      if not oldPython and test_for_broken_SAX():  
111          # works with python 2.0, but is not SAX compliant      def start_map(self, name, qname, attrs):
112          def characters(self, ch):          """Start a map."""
113              self.my_characters(ch)          self.aMap = Map(attrs.get((None, 'title'), None))
114      else:      start_dispatcher['map'] = "start_map"
115          # SAX compliant  
116          def characters(self, ch, start, length):      def end_map(self, name, qname):
117              self.my_characters(ch[start:start+length])          self.theSession.AddMap(self.aMap)
118        end_dispatcher['map'] = "end_map"
119      def my_characters(self, ch):  
120          self.chars = self.chars + ch      def start_projection(self, name, qname, attrs):
121            self.ProjectionParams = [ ]
122      def endElement(self, name):      start_dispatcher['projection'] = "start_projection"
123          # If it's not a parameter element, ignore it  
124          if name == 'session':      def end_projection(self, name, qname):
125              #print "end of session"          self.aMap.SetProjection(Projection(self.ProjectionParams))
126              pass      end_dispatcher['projection'] = "end_projection"
127          if name == 'map':  
128              self.theSession.AddMap(self.aMap)      def start_parameter(self, name, qname, attrs):
129          if name == 'projection':          s = attrs.get((None, 'value'))
130              self.aMap.SetProjection(Projection(self.ProjectionParams))          s = str(s) # we can't handle unicode in proj
131          if name == 'layer':          self.ProjectionParams.append(s)
132              self.aMap.AddLayer(self.aLayer)      start_dispatcher['parameter'] = "start_parameter"
133          if name == 'table':  
134              #print "end of table"      def start_layer(self, name, qname, attrs, layer_class = Layer):
135              pass          """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):  def load_session(filename):
244      """Load a Thuban session from the file object file"""      """Load a Thuban session from the file object file"""
# Line 155  def load_session(filename): Line 246  def load_session(filename):
246      file = open(filename)      file = open(filename)
247      handler = ProcessSession(dir)      handler = ProcessSession(dir)
248    
249      if oldPython:      parser = make_parser()
250          parser = make_parser()      parser.setContentHandler(handler)
251          parser.setDocumentHandler(handler)      parser.setErrorHandler(ErrorHandler())
252          parser.setErrorHandler(saxutils.ErrorPrinter())      parser.setFeature(xml.sax.handler.feature_namespaces, 1)
253          parser.parseFile(file)      parser.parse(file)
254          parser.close()  
     else:  
         xml.sax.parse(file,handler)  
255      session = handler.theSession      session = handler.theSession
256      # Newly loaded session aren't modified      # Newly loaded session aren't modified
257      session.UnsetModified()      session.UnsetModified()
258    
259      return session      return session
260    
 if __name__ == "__main__":  
     # find out the command to run  
     if len(sys.argv) > 1:  
         print "usage: cat <file> | " + sys.argv[0]  
     else:  
         parseSession(sys.stdin)  

Legend:
Removed from v.6  
changed lines
  Added in v.365

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26