/[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 694 by jonathan, Wed Apr 16 16:39:18 2003 UTC revision 784 by jonathan, Tue Apr 29 17:30:18 2003 UTC
# Line 1  Line 1 
1  # Copyright (C) 2001, 2002 by Intevation GmbH  # Copyright (C) 2001, 2002, 2003 by Intevation GmbH
2  # Authors:  # Authors:
3  # Jan-Oliver Wagner <[email protected]>  # Jan-Oliver Wagner <[email protected]>
4  # Bernhard Herzog <[email protected]>  # Bernhard Herzog <[email protected]>
# Line 13  Parser for thuban session files. Line 13  Parser for thuban session files.
13    
14  __version__ = "$Revision$"  __version__ = "$Revision$"
15    
16  import sys, string, os  import string, os
17    
18  import xml.sax  import xml.sax
19  import xml.sax.handler  import xml.sax.handler
20  from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException  from xml.sax import make_parser, ErrorHandler, SAXNotRecognizedException
21    
22  from Thuban import _  from Thuban import _
 from Thuban.common import *  
23    
24  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \  from Thuban.Model.table import FIELDTYPE_INT, FIELDTYPE_DOUBLE, \
25       FIELDTYPE_STRING       FIELDTYPE_STRING
# Line 58  def parse_color(color): Line 57  def parse_color(color):
57      return result      return result
58    
59    
60  class XMLProcessor(xml.sax.handler.ContentHandler):  class XMLReader(xml.sax.handler.ContentHandler):
61    
62      # Dictionary mapping element names (or (URI, element name) pairs for      # Dictionary mapping element names (or (URI, element name) pairs for
63      # documents using namespaces) to method names. The methods should      # documents using namespaces) to method names. The methods should
# Line 74  class XMLProcessor(xml.sax.handler.Conte Line 73  class XMLProcessor(xml.sax.handler.Conte
73      end_dispatcher = {}      end_dispatcher = {}
74    
75    
76      def __init__(self, directory):      def __init__(self):
77          """Inititialize the Sax handler.          self.chars = ''
78            self.__directory = ""
79            self.__dispatchers = {}
80    
81        def read(self, file_or_filename):
82    
83            if hasattr(file_or_filename, "read"):
84                # it's a file object
85                self.__directory = ""
86                self.__file = file_or_filename
87            else:
88                filename = file_or_filename
89                self.__directory = os.path.dirname(filename)
90                self.__file = open(filename)
91    
92            parser = make_parser()
93            parser.setContentHandler(self)
94            parser.setErrorHandler(ErrorHandler())
95            parser.setFeature(xml.sax.handler.feature_namespaces, 1)
96    
97            #
98            # Well, this isn't pretty, but it appears that if you
99            # use Python 2.2 without the site-package _xmlplus then
100            # the following will fail, and without them it will work.
101            # However, if you do have the site-package and you don't
102            # call these functions, the reader raises an exception
103            #
104            # The reason we set these to 0 in the first place is
105            # because there is an unresolved issue with external
106            # entities causing an exception in the reader
107            #
108            try:
109                parser.setFeature(xml.sax.handler.feature_validation,0)
110                parser.setFeature(xml.sax.handler.feature_external_ges,0)
111                parser.setFeature(xml.sax.handler.feature_external_pes,0)
112            except SAXNotRecognizedException:
113                pass
114    
115            parser.parse(self.__file)
116    
117            self.close()
118    
119        def close(self):
120            self.__file.close()
121            
122        def GetFilename(self):
123            if hasattr(self.__file, "name"):
124                return self.__file.name
125    
126            return ""
127    
128          The directory parameter should be the directory containing the      def GetDirectory(self):
129          session file. It's needed to interpret embedded relative          return self.__directory
130          filenames.  
131    
132        def AddDispatchers(self, dict):
133            """Add the function names that should be used to process XML tags.
134    
135            dict -- a dictionary whose keys are XML tag strings and whose values
136                    are pairs of strings such that the first string is
137                    the name of the function that should be called when the
138                    XML tag opens and the second string is the name of the
139                    function that should be called when the XML tag closes.
140                    If a pair element is None, no function is called.
141          """          """
142          self.directory = directory  
143          self.chars = ''          self.__dispatchers.update(dict)
144    
145      def startElementNS(self, name, qname, attrs):      def startElementNS(self, name, qname, attrs):
146          """Call the method given for name in self.start_dispatcher          """Call the method given for name in self.start_dispatcher
147          """          """
148          if name[0] is None:          if name[0] is None:
149              method_name = self.start_dispatcher.get(name[1])              method_name = self.__dispatchers.get(name[1])
150          else:          else:
151              # Dispatch with namespace              # Dispatch with namespace
152              method_name = self.start_dispatcher.get(name)              method_name = self.__dispatchers.get(name)
153          if method_name is not None:          if method_name is not None and method_name[0] is not None:
154              getattr(self, method_name)(name, qname, attrs)              getattr(self, method_name[0])(name, qname, attrs)
155    
156      def endElementNS(self, name, qname):      def endElementNS(self, name, qname):
157          """Call the method given for name in self.end_dispatcher          """Call the method given for name in self.end_dispatcher
158          """          """
159          if name[0] is None:          if name[0] is None:
160              method_name = self.end_dispatcher.get(name[1])              method_name = self.__dispatchers.get(name[1])
161          else:          else:
162              # Dispatch with namespace              # Dispatch with namespace
163              method_name = self.end_dispatcher.get(name)              method_name = self.__dispatchers.get(name)
164          if method_name is not None:          if method_name is not None and method_name[1] is not None:
165              getattr(self, method_name)(name, qname)              getattr(self, method_name[1])(name, qname)
   
     def GetDirectory(self):  
         return self.directory  
166    
167  class ProcessSession(XMLProcessor):  class SessionLoader(XMLReader):
168    
169      def __init__(self, directory):      def __init__(self):
170          """Inititialize the Sax handler."""          """Inititialize the Sax handler."""
171          XMLProcessor.__init__(self, directory)          XMLReader.__init__(self)
172    
173          self.theSession = None          self.theSession = None
174          self.aMap = None          self.aMap = None
175          self.aLayer = None          self.aLayer = None
176    
177            XMLReader.AddDispatchers(self,
178                {'session'       : ("start_session",        "end_session"),
179                 'map'           : ("start_map",            "end_map"),
180                 'projection'    : ("start_projection",     "end_projection"),
181                 'parameter'     : ("start_parameter",      None),
182                 'layer'         : ("start_layer",          "end_layer"),
183                 'classification': ("start_classification", "end_classification"),
184                 'clnull'        : ("start_clnull",         "end_clnull"),
185                 'clpoint'       : ("start_clpoint",        "end_clpoint"),
186                 'clrange'       : ("start_clrange",        "end_clrange"),
187                 'cldata'        : ("start_cldata",         "end_cldata"),
188                 'table'         : ("start_table",          "end_table"),
189                 'labellayer'    : ("start_labellayer",     None),
190                 'label'         : ("start_label",          None)})
191    
192      def start_session(self, name, qname, attrs):      def start_session(self, name, qname, attrs):
193          self.theSession = Session(attrs.get((None, 'title'), None))          self.theSession = Session(attrs.get((None, 'title'), None))
     XMLProcessor.start_dispatcher['session'] = "start_session"  
194    
195      def end_session(self, name, qname):      def end_session(self, name, qname):
196          pass          pass
     XMLProcessor.end_dispatcher['session'] = "end_session"  
197    
198      def start_map(self, name, qname, attrs):      def start_map(self, name, qname, attrs):
199          """Start a map."""          """Start a map."""
200          self.aMap = Map(attrs.get((None, 'title'), None))          self.aMap = Map(attrs.get((None, 'title'), None))
201      XMLProcessor.start_dispatcher['map'] = "start_map"          self.__projReceiver = self.aMap
202    
203      def end_map(self, name, qname):      def end_map(self, name, qname):
204          self.theSession.AddMap(self.aMap)          self.theSession.AddMap(self.aMap)
205      XMLProcessor.end_dispatcher['map'] = "end_map"          self.__projReceiver = None
206    
207      def start_projection(self, name, qname, attrs):      def start_projection(self, name, qname, attrs):
208            self.ProjectionName = attrs.get((None, 'name'), None)
209          self.ProjectionParams = [ ]          self.ProjectionParams = [ ]
     XMLProcessor.start_dispatcher['projection'] = "start_projection"  
210    
211      def end_projection(self, name, qname):      def end_projection(self, name, qname):
212          self.aMap.SetProjection(Projection(self.ProjectionParams))          self.__projReceiver.SetProjection(
213      XMLProcessor.end_dispatcher['projection'] = "end_projection"              Projection(self.ProjectionParams, self.ProjectionName))
214    
215      def start_parameter(self, name, qname, attrs):      def start_parameter(self, name, qname, attrs):
216          s = attrs.get((None, 'value'))          s = attrs.get((None, 'value'))
217          s = str(s) # we can't handle unicode in proj          s = str(s) # we can't handle unicode in proj
218          self.ProjectionParams.append(s)          self.ProjectionParams.append(s)
     XMLProcessor.start_dispatcher['parameter'] = "start_parameter"  
219    
220      def start_layer(self, name, qname, attrs, layer_class = Layer):      def start_layer(self, name, qname, attrs, layer_class = Layer):
221          """Start a layer          """Start a layer
# Line 160  class ProcessSession(XMLProcessor): Line 227  class ProcessSession(XMLProcessor):
227          title = attrs.get((None, 'title'), "")          title = attrs.get((None, 'title'), "")
228          filename = attrs.get((None, 'filename'), "")          filename = attrs.get((None, 'filename'), "")
229          filename = os.path.join(self.GetDirectory(), filename)          filename = os.path.join(self.GetDirectory(), filename)
230            visible  = attrs.get((None, 'visible'), "true")
231          fill = parse_color(attrs.get((None, 'fill'), "None"))          fill = parse_color(attrs.get((None, 'fill'), "None"))
232          stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))          stroke = parse_color(attrs.get((None, 'stroke'), "#000000"))
233          stroke_width = int(attrs.get((None, 'stroke_width'), "1"))          stroke_width = int(attrs.get((None, 'stroke_width'), "1"))
234          self.aLayer = layer_class(title, filename, fill = fill,          self.aLayer = layer_class(title,
235                                    stroke = stroke, lineWidth = stroke_width)                                    self.theSession.OpenShapefile(filename),
236      XMLProcessor.start_dispatcher['layer'] = "start_layer"                                    fill = fill, stroke = stroke,
237                                      lineWidth = stroke_width,
238                                      visible = visible != "false")
239    
240            self.__projReceiver = self.aLayer
241    
242      def end_layer(self, name, qname):      def end_layer(self, name, qname):
243          self.aMap.AddLayer(self.aLayer)          self.aMap.AddLayer(self.aLayer)
244      XMLProcessor.end_dispatcher['layer'] = "end_layer"          self.__projReceiver = None
245    
246      def start_classification(self, name, qname, attrs):      def start_classification(self, name, qname, attrs):
247          field = attrs.get((None, 'field'), None)          field = attrs.get((None, 'field'), None)
# Line 191  class ProcessSession(XMLProcessor): Line 263  class ProcessSession(XMLProcessor):
263    
264          self.aLayer.GetClassification().SetField(field)          self.aLayer.GetClassification().SetField(field)
265    
     XMLProcessor.start_dispatcher['classification'] = "start_classification"  
266    
267      def end_classification(self, name, qname):      def end_classification(self, name, qname):
268          pass          pass
     XMLProcessor.end_dispatcher['classification'] = "end_classification"  
269    
270      def start_clnull(self, name, qname, attrs):      def start_clnull(self, name, qname, attrs):
271          self.cl_group = ClassGroupDefault()          self.cl_group = ClassGroupDefault()
272          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
273          self.cl_prop = ClassGroupProperties()          self.cl_prop = ClassGroupProperties()
     XMLProcessor.start_dispatcher['clnull'] = "start_clnull"  
274    
275      def end_clnull(self, name, qname):      def end_clnull(self, name, qname):
276          self.cl_group.SetProperties(self.cl_prop)          self.cl_group.SetProperties(self.cl_prop)
277          self.aLayer.GetClassification().SetDefaultGroup(self.cl_group)          self.aLayer.GetClassification().SetDefaultGroup(self.cl_group)
278          del self.cl_group, self.cl_prop          del self.cl_group, self.cl_prop
     XMLProcessor.end_dispatcher['clnull'] = "end_clnull"  
279    
280      def start_clpoint(self, name, qname, attrs):      def start_clpoint(self, name, qname, attrs):
281          attrib_value = attrs.get((None, 'value'), "0")          attrib_value = attrs.get((None, 'value'), "0")
282    
         #try:  
             #value  = Str2Num(attrib_value)  
         #except:  
             #value  = attrib_value  
   
283          value = self.conv(attrib_value)          value = self.conv(attrib_value)
284    
285          self.cl_group = ClassGroupSingleton(value)          self.cl_group = ClassGroupSingleton(value)
286          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
287          self.cl_prop = ClassGroupProperties()          self.cl_prop = ClassGroupProperties()
288    
     XMLProcessor.start_dispatcher['clpoint'] = "start_clpoint"  
289    
290      def end_clpoint(self, name, qname):      def end_clpoint(self, name, qname):
291          self.cl_group.SetProperties(self.cl_prop)          self.cl_group.SetProperties(self.cl_prop)
292          self.aLayer.GetClassification().AppendGroup(self.cl_group)          self.aLayer.GetClassification().AppendGroup(self.cl_group)
293          del self.cl_group, self.cl_prop          del self.cl_group, self.cl_prop
     XMLProcessor.end_dispatcher['clpoint'] = "end_clpoint"  
294    
295      def start_clrange(self, name, qname, attrs):      def start_clrange(self, name, qname, attrs):
296    
297          try:          try:
298              min = self.conv(attrs.get((None, 'min'), "0"))              min = self.conv(attrs.get((None, 'min'), "0"))
299              max = self.conv(attrs.get((None, 'max'), "0"))              max = self.conv(attrs.get((None, 'max'), "0"))
             #min = Str2Num(attrs.get((None, 'min'), "0"))  
             #max = Str2Num(attrs.get((None, 'max'), "0"))  
300          except ValueError:          except ValueError:
301              raise ValueError(_("Classification range is not a number!"))              raise ValueError(_("Classification range is not a number!"))
302    
# Line 245  class ProcessSession(XMLProcessor): Line 304  class ProcessSession(XMLProcessor):
304          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))          self.cl_group.SetLabel(attrs.get((None, 'label'), ""))
305          self.cl_prop = ClassGroupProperties()          self.cl_prop = ClassGroupProperties()
306    
     XMLProcessor.start_dispatcher['clrange'] = "start_clrange"  
307    
308      def end_clrange(self, name, qname):      def end_clrange(self, name, qname):
309          self.cl_group.SetProperties(self.cl_prop)          self.cl_group.SetProperties(self.cl_prop)
310          self.aLayer.GetClassification().AppendGroup(self.cl_group)          self.aLayer.GetClassification().AppendGroup(self.cl_group)
311          del self.cl_group, self.cl_prop          del self.cl_group, self.cl_prop
     XMLProcessor.end_dispatcher['clrange'] = "end_clrange"  
312    
313      def start_cldata(self, name, qname, attrs):      def start_cldata(self, name, qname, attrs):
314          self.cl_prop.SetLineColor(          self.cl_prop.SetLineColor(
# Line 259  class ProcessSession(XMLProcessor): Line 316  class ProcessSession(XMLProcessor):
316          self.cl_prop.SetLineWidth(          self.cl_prop.SetLineWidth(
317              int(attrs.get((None, 'stroke_width'), "0")))              int(attrs.get((None, 'stroke_width'), "0")))
318          self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))          self.cl_prop.SetFill(parse_color(attrs.get((None, 'fill'), "None")))
     XMLProcessor.start_dispatcher['cldata'] = "start_cldata"  
319    
320      def end_cldata(self, name, qname):      def end_cldata(self, name, qname):
321          pass          pass
     XMLProcessor.end_dispatcher['cldata'] = "end_cldata"  
322    
323      def start_table(self, name, qname, attrs):      def start_table(self, name, qname, attrs):
324          #print "table title: %s" % attrs.get('title', None)          #print "table title: %s" % attrs.get('title', None)
325          pass          pass
     XMLProcessor.start_dispatcher['table'] = "start_table"  
326    
327      def end_table(self, name, qname):      def end_table(self, name, qname):
328          pass          pass
     XMLProcessor.end_dispatcher['table'] = "end_table"  
329    
330      def start_labellayer(self, name, qname, attrs):      def start_labellayer(self, name, qname, attrs):
331          self.aLayer = self.aMap.LabelLayer()          self.aLayer = self.aMap.LabelLayer()
     XMLProcessor.start_dispatcher['labellayer'] = "start_labellayer"  
332    
333      def start_label(self, name, qname, attrs):      def start_label(self, name, qname, attrs):
334          x = float(attrs[(None, 'x')])          x = float(attrs[(None, 'x')])
# Line 285  class ProcessSession(XMLProcessor): Line 337  class ProcessSession(XMLProcessor):
337          halign = attrs[(None, 'halign')]          halign = attrs[(None, 'halign')]
338          valign = attrs[(None, 'valign')]          valign = attrs[(None, 'valign')]
339          self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)          self.aLayer.AddLabel(x, y, text, halign = halign, valign = valign)
     XMLProcessor.start_dispatcher['label'] = "start_label"  
340    
341      def characters(self, chars):      def characters(self, chars):
342          pass          pass
343    
344    
 def load_xmlfile(filename, handler):  
     file = open(filename)  
   
     parser = make_parser()  
     parser.setContentHandler(handler)  
     parser.setErrorHandler(ErrorHandler())  
     parser.setFeature(xml.sax.handler.feature_namespaces, 1)  
   
     #  
     # Well, this isn't pretty, but it appears that if you  
     # use Python 2.2 without the site-package _xmlplus then  
     # the following will fail, and without them it will work.  
     # However, if you do have the site-package and you don't  
     # call these functions, the reader raises an exception  
     #  
     # The reason we set these to 0 in the first place is  
     # because there is an unresolved issue with external  
     # entities causing an exception in the reader  
     #  
     try:  
         parser.setFeature(xml.sax.handler.feature_validation, 0)  
         parser.setFeature(xml.sax.handler.feature_external_ges, 0)  
         parser.setFeature(xml.sax.handler.feature_external_pes, 0)  
     except SAXNotRecognizedException:  
         pass  
   
     parser.parse(file)  
   
345  def load_session(filename):  def load_session(filename):
346      """Load a Thuban session from the file object file"""      """Load a Thuban session from the file object file"""
347    
348      dir = os.path.dirname(filename)      handler = SessionLoader()
349      handler = ProcessSession(dir)      handler.read(filename)
   
     load_xmlfile(filename, handler)  
350    
351      session = handler.theSession      session = handler.theSession
352      # Newly loaded session aren't modified      # Newly loaded session aren't modified

Legend:
Removed from v.694  
changed lines
  Added in v.784

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26