/[thuban]/branches/WIP-pyshapelib-bramz/Extensions/importAPR/importAPR.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Extensions/importAPR/importAPR.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (hide annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 11212 byte(s)
made a copy
1 jan 2630 # Copyright (C) 2003-2005 by Intevation GmbH
2 jan 1728 # Authors:
3 jan 2402 # Jan-Oliver Wagner <[email protected]> (2003, 2004)
4 jan 1728 #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Import a ArcView project file (.apr) and convert it
10     to Thuban.
11     """
12    
13     __version__ = "$Revision$"
14 jan 2203 # $Source$
15     # $Id$
16 jan 1728
17     import os, sys
18    
19     from types import StringType
20    
21 dpinte 2721 import wx
22 jan 1728
23     from Thuban.Model.extension import Extension
24     from Thuban.Model.base import TitledObject, Modifiable
25     from Thuban.UI.command import registry, Command
26 jan 2203 from Thuban.UI.mainwindow import main_menu
27 jan 1728 from Thuban import _
28     from Thuban.Model.layer import Layer
29 jan 1884 from Thuban.Model.classification import ClassGroupRange, ClassGroupSingleton
30 jan 1728
31     from odb import ODBBaseObject
32 jan 1884 from apr import APR_LClass, APR_TClr, APR_BLnSym, APR_BMkSym, APR_BShSym
33 jan 1728
34     class ODBExtension(Extension):
35     def TreeInfo(self):
36     return (_("Extension: %s") % self.title,
37     [ object.TreeInfo() for object in self.objects ])
38    
39     class APR_FTheme(ODBBaseObject):
40     _obj_refs = [ 'Source', 'Legend' ]
41    
42     class APR_Legend(ODBBaseObject):
43     """Legend object.
44     There could one or more Class objects. Each class corresponds to a
45     Child in the Symbols.
46     """
47     _obj_refs = [ 'FieldNames', 'Symbols', 'Class', 'NullSym',
48     'NullValues', 'StatValues' ]
49    
50 jan 2630 class APR_VShSym(ODBBaseObject):
51     """Pattern Object(Symbol).
52     """
53     _obj_refs = [ 'Color', 'OutlineColor', 'BgColor' ]
54     _values = [ 'Outline', 'Outlinewidth', 'Angle', 'YSeparation',
55     'PenSize' ]
56    
57 jan 1728 class APR_Project(ODBBaseObject):
58     _obj_refs = [ 'Doc' ]
59    
60     class APR_ShpSrc(ODBBaseObject):
61     _obj_refs = [ 'Name' ]
62    
63     class APR_SrcName(ODBBaseObject):
64     _obj_refs = [ 'FileName' ]
65    
66     class APR_SymList(ODBBaseObject):
67     _obj_refs = [ 'Child' ]
68    
69     class APR_View(ODBBaseObject):
70 jan 1884 _obj_refs = [ 'Theme', 'ITheme' ]
71 jan 1728
72     class ODB(TitledObject, Modifiable):
73    
74     def __init__(self):
75     TitledObject.__init__(self, 'ODB Object')
76     self._objects = {}
77     self._version = None
78     self._filename = None
79     self.name = None # required for Thuban.model.extension.Extension
80    
81     def SetFileName(self, fname):
82     self._filename = fname
83     self.name = fname
84    
85     def AddObject(self, object):
86     self._objects[object.number] = object
87    
88     def GetObjects(self):
89     return self._objects
90    
91     def GetProject(self):
92     """Return the main Root if it is a Project, else None."""
93     # it is assumed that the first object is the ODB object
94     if self._objects[1].type != 'ODB':
95     return None
96     if self._objects[1].FirstRootClassName != 'Project':
97     return None
98    
99     # it is assumed that the second object is the first root
100     o = self._objects[2]
101     if o.type != 'Project':
102     return None
103     return o
104    
105     def TreeInfo(self):
106     items = []
107     items.append(_('Format version: %s') % self._version)
108     p = self.GetProject()
109     items.append(_('Project Name: %s') % p.Name)
110     for doc in p.Get('Doc'):
111     items.append(doc.TreeInfo())
112     return [_("ODB File '%s'" % self._filename), items]
113    
114     def parse_apr(fname):
115     """Load a ArcView project file.
116    
117     fname -- Filename of the .apr file
118    
119     Return: the ODB class object.
120     """
121     odb = ODB()
122     odb.SetFileName(fname)
123    
124     apr = open(fname, 'r').readlines()
125    
126     # get the version from the first line (eg. from "/3.1")
127     odb._version = apr.pop(0)[1:]
128    
129     i = 0
130     in_object = False
131     for line in apr:
132     i += 1
133     if line[0] == '(':
134     line = line[1:]
135     type, number = line.split('.')
136     number = int(number)
137     class_name = 'APR_' + type
138     try:
139     clazz = eval(class_name)
140     object = clazz(odb, type, number)
141     except:
142     object = ODBBaseObject(odb, type, number)
143     in_object = True
144     continue
145     if line[0] == ')':
146     in_object = False
147     odb.AddObject(object)
148     if in_object:
149     line = line.strip()
150     if len(line) == 0: continue
151     try:
152     property, value = line.split(':', 1)
153     property = property.strip()
154     value = value.strip()
155     except:
156     print "Error in line %d:" % i, line
157     continue
158     if value[0] == '"':
159     value = value[1:-1]
160     setattr(object, property, value)
161     return odb
162    
163     def import_apr_dialog(context):
164     """Request filename from user and run importing of apr file.
165    
166     context -- The Thuban context.
167     """
168 dpinte 2721 dlg = wx.FileDialog(context.mainwindow,
169 jan 1728 _("Select APR file"), ".", "",
170     _("ArcView Project Files (*.apr)|*.apr|") +
171     _("All Files (*.*)|*.*"),
172 dpinte 2721 wx.OPEN|wx.OVERWRITE_PROMPT)
173     if dlg.ShowModal() == wx.ID_OK:
174 jan 1728 filename = dlg.GetPath()
175     dlg.Destroy()
176     else:
177     return
178    
179     odb = parse_apr(filename)
180     if odb is None:
181     context.mainwindow.RunMessageBox(_("Import APR"), _("Loading failed"))
182     return
183     else:
184     context.mainwindow.RunMessageBox(_("Import APR"),
185     _("%d objects loaded" %
186     len(odb.GetObjects().keys())))
187    
188     # find the views of the APR file
189     views = {}
190     p = odb.GetProject()
191     for doc in p.Get('Doc'):
192     if doc.type != 'View':
193     continue
194     views[doc.Name] = doc
195    
196     # it is possible that a APR file has no view at all
197     if len(views) == 0:
198     context.mainwindow.RunMessageBox(_("Import APR"),
199     _("No view found in APR file"))
200     return
201    
202     # let the user select one of the views
203     if len(views) > 1:
204     titles = views.keys()
205 dpinte 2721 dlg = wx.SingleChoiceDialog(context.mainwindow,
206 jan 1728 _('Pick a View to import:'),
207     _('Import APR'), titles,
208 dpinte 2721 style = wx.DEFAULT_DIALOG_STYLE |
209     wx.RESIZE_BORDER)
210     if dlg.ShowModal() == wx.ID_OK:
211 jan 1728 view = views[views.keys()[dlg.GetSelection()]]
212     else:
213     return
214     else:
215     view = views[views.keys()[0]]
216    
217     # load the themes of the View as layers into Thuban
218     count_theme = 0
219     count_theme_fail = 0
220     for theme in view.Get('Theme'):
221     if theme.type != 'FTheme':
222     continue
223     count_theme += 1
224     filename = theme.Get('Source').Get('Name').Get('FileName').Path
225     try:
226     store = context.application.Session().OpenShapefile(filename)
227     except IOError:
228     # the layer couldn't be opened
229     context.mainwindow.RunMessageBox(_('Add Layer'),
230     _("Can't open the file '%s'.") % filename)
231     count_theme_fail += 1
232     else:
233     title = theme.Name
234     apr_legend = theme.Get('Legend')
235    
236     map = context.mainwindow.canvas.Map()
237    
238     # create layer
239     layer = Layer(title, store)
240    
241     # set the field for classification (if there is one in the apr)
242     if hasattr(apr_legend, 'FieldNames'):
243     apr_fieldname = apr_legend.Get('FieldNames').S
244     # unfortunately, the APR file does not store the actual
245     # Name of the column, but always makes the first character
246     # a capital letter, the rest lower case.
247     # Therefore, we have to search through the table of the
248     # layer to find out the correct spelling.
249     table_columns = layer.ShapeStore().Table().Columns()
250     for column in table_columns:
251     if apr_fieldname.lower() == column.name.lower():
252     layer.SetClassificationColumn(column.name)
253     break
254    
255     clazz = layer.GetClassification()
256     apr_classes = apr_legend.Get('Class')
257     if not isinstance(apr_classes, list):
258     apr_classes = [ apr_classes ]
259     apr_symbols = apr_legend.Get('Symbols').Get('Child')
260     if not isinstance(apr_symbols, list):
261     apr_symbols = [ apr_symbols ]
262     i = -1
263     for symbol in apr_symbols:
264     i += 1
265    
266     if hasattr(apr_classes[i], 'IsNoData'):
267     group = clazz.GetDefaultGroup()
268     group.SetLabel(apr_classes[i].Label)
269     continue
270    
271     # create a new group property from the symbol
272     prop = symbol.GetThubanProp()
273    
274 jan 1734 # build range
275     range = apr_classes[i].GetThubanRange()
276    
277     if isinstance(range, StringType):
278     new_group = ClassGroupSingleton(value = range,
279 jan 1728 props = prop,
280     label = apr_classes[i].GetLabel())
281     else:
282     new_group = ClassGroupRange(_range = range,
283     props = prop,
284     label = apr_classes[i].GetLabel())
285     clazz.AppendGroup(new_group)
286    
287     map.AddLayer(layer)
288    
289     map.SetTitle(view.Name)
290    
291     # fit the new map to the window
292     context.mainwindow.canvas.FitMapToWindow()
293    
294     context.mainwindow.RunMessageBox(_('Import APR'),
295     _('Imported %d out of %d themes of view "%s" ...') % \
296     (count_theme - count_theme_fail, count_theme, view.Name))
297    
298     # import_apr as an extension to Thuban
299     if context.session.HasExtensions():
300     for ext in context.session.Extensions():
301     if ext.Title() == apr_import_extension.Title():
302     ext.AddObject(odb)
303     return
304    
305     # no extension found, so lets make a new
306     context.session.AddExtension(apr_import_extension)
307     apr_import_extension.AddObject(odb)
308    
309     if __name__ == "__main__": # import_apr executed as a command line tool
310     if len(sys.argv) == 2:
311     odb = parse_apr(sys.argv[1])
312     print "%d objects loaded" % len(odb.GetObjects().keys())
313    
314     def print_structured_list(lst, indent = ''):
315     for item in lst:
316     if isinstance(item, StringType):
317     print indent + item
318     elif isinstance(item, list):
319     print_structured_list(item, indent + ' ')
320    
321     print_structured_list(odb.TreeInfo())
322     sys.exit(0)
323     else:
324     print 'usage: %s apr-file' % sys.argv[0]
325     sys.exit(1)
326    
327     apr_import_extension = ODBExtension('APR Import')
328    
329     # register the new command
330     registry.Add(Command('import-apr', _('Import apr-file...'), import_apr_dialog,
331     helptext = _('Import a ArcView project file')))
332    
333     # find the experimental menu (create it anew if not found)
334 jan 2203 experimental_menu = main_menu.FindOrInsertMenu('experimental',
335     _('Experimenta&l'))
336 jan 1728
337     # finally add the new entry to the experimental menu
338     experimental_menu.InsertItem('import-apr')

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26