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

Diff of /branches/WIP-pyshapelib-bramz/Extensions/bboxdump/bboxdump.py

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

revision 2196 by frank, Thu Apr 22 17:11:54 2004 UTC revision 2721 by dpinte, Sat Jan 13 15:11:42 2007 UTC
# Line 1  Line 1 
1  # Copyright (C) 2003 by Intevation GmbH  # Copyright (C) 2004 by Intevation GmbH
2  # Authors:  # Authors:
3  # Frank Koormann <[email protected]>  # Frank Koormann <[email protected]> (2004)
4  #  #
5  # This program is free software under the GPL (>=v2)  # This program is free software under the GPL (>=v2)
6  # Read the file COPYING coming with Thuban for details.  # Read the file COPYING coming with Thuban for details.
# Line 14  in this case the bounding box is a union Line 14  in this case the bounding box is a union
14  """  """
15    
16  __version__ = '$Revision$'  __version__ = '$Revision$'
17    # $Source$
18    # $Id$
19    
20  import os, sys  import os, sys
21    import string
22    
23  # only import GUI when not called as command line tool  import wx
24  from wxPython.wx import *  from wx.lib.dialogs import ScrolledMessageDialog
 from wxPython.lib.dialogs import wxScrolledMessageDialog  
25    
26  from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor  from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
27  from Thuban.UI.command import registry, Command  from Thuban.UI.command import registry, Command
# Line 29  from Thuban import _ Line 31  from Thuban import _
31  import shapelib  import shapelib
32  import dbflib  import dbflib
33    
34    # Widget IDs
35  ID_FILENAME = 4001  ID_FILENAME = 4001
36  ID_ATTRIBUTES = 4002  ID_ATTRIBUTES = 4002
37  ID_SELFN = 4003  ID_SELFN = 4003
38    
39  class BBoxDumpDialog(wxDialog):  class BBoxDumpDialog(wx.Dialog):
40      """Bounding Box Dump Dialog      """Bounding Box Dump Dialog
41    
42      Specify a filename for the dump and optionally a layer's column      Specify a filename for the dump and optionally a layer's column
# Line 41  class BBoxDumpDialog(wxDialog): Line 44  class BBoxDumpDialog(wxDialog):
44      """      """
45    
46      def __init__(self, parent, title, layer = None):      def __init__(self, parent, title, layer = None):
47          wxDialog.__init__(self, parent, -1, title,          wx.Dialog.__init__(self, parent, -1, title,
48                            style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)                            style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
49    
50          if layer is None:          if layer is None:
51              return wxID_CANCEL              return wx.ID_CANCEL
52    
53          # Store the layer          # Store the layer
54          self.layer = layer          self.layer = layer
55    
56          # Filename selection elements          # Filename selection elements
57          self.filename = wxTextCtrl(self, ID_FILENAME, "")          self.filename = wx.TextCtrl(self, ID_FILENAME, "")
58          self.button_selectfile = wxButton(self, ID_SELFN, _('Select...'))          self.button_selectfile = wx.Button(self, ID_SELFN, _('Select...'))
59          EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename)          wx.EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename)
60    
61          # Column choice elements          # Column choice elements
62          self.choice_column = wxChoice(self, ID_ATTRIBUTES)          self.choice_column = wx.Choice(self, ID_ATTRIBUTES)
63          self.choice_column.Append(_('Select...'), None)          self.choice_column.Append(_('Select...'), None)
64          for col in self.layer.ShapeStore().Table().Columns():          for col in self.layer.ShapeStore().Table().Columns():
65                  self.choice_column.Append(col.name, col)                  self.choice_column.Append(col.name, col)
66          self.choice_column.SetSelection(0)          self.choice_column.SetSelection(0)
67    
68          # Dialog button elements          # Dialog button elements
69          self.button_dump = wxButton(self, wxID_OK, _("OK"))          self.button_dump = wx.Button(self, wx.ID_OK, _("OK"))
70          EVT_BUTTON(self, wxID_OK, self.OnDump)          wx.EVT_BUTTON(self, wx.ID_OK, self.OnDump)
71          self.button_dump.SetDefault()          self.button_dump.SetDefault()
72          # TODO: Disable the OK button until a filename is entered ...          # TODO: Disable the OK button until a filename is entered ...
73          # self.button_dump.Enable(False)          # self.button_dump.Enable(False)
74          self.button_cancel = wxButton(self, wxID_CANCEL, _("Cancel"))          self.button_cancel = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
75    
76    
77          # Dialog Layout: three horizontal box sizers.          # Dialog Layout: three horizontal box sizers.
78          topbox = wxBoxSizer(wxVERTICAL)          topbox = wx.BoxSizer(wx.VERTICAL)
79    
80          hbox = wxBoxSizer(wxHORIZONTAL)          hbox = wx.BoxSizer(wx.HORIZONTAL)
81          topbox.Add(hbox, 0, wxALL|wxEXPAND)          topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
82          hbox.Add(wxStaticText(self, -1, _("File:")),          hbox.Add(wx.StaticText(self, -1, _("File:")),
83                   0, wxALL|wxALIGN_CENTER_VERTICAL, 4)                   0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
84          hbox.Add(self.filename, 1, wxALL|wxEXPAND, 4)          hbox.Add(self.filename, 1, wx.ALL|wx.EXPAND, 4)
85          hbox.Add(self.button_selectfile, 0, wxALL, 4)          hbox.Add(self.button_selectfile, 0, wx.ALL, 4)
86    
87          hbox = wxBoxSizer(wxHORIZONTAL)          hbox = wx.BoxSizer(wx.HORIZONTAL)
88          topbox.Add(hbox, 0, wxALL|wxEXPAND)          topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
89          hbox.Add(wxStaticText(self, -1, _("Group by:")),          hbox.Add(wx.StaticText(self, -1, _("Group by:")),
90                   0, wxALL|wxALIGN_CENTER_VERTICAL, 4)                   0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
91          hbox.Add(self.choice_column, 1, wxALL|wxEXPAND, 4)          hbox.Add(self.choice_column, 1, wx.ALL|wx.EXPAND, 4)
92    
93          hbox = wxBoxSizer(wxHORIZONTAL)          hbox = wx.BoxSizer(wx.HORIZONTAL)
94          topbox.Add(hbox, 0, wxALL|wxEXPAND)          topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
95          hbox.Add(self.button_dump, 0, wxALL|wxALIGN_CENTER,          hbox.Add(self.button_dump, 0, wx.ALL|wx.ALIGN_CENTER,
96                    10)                    10)
97          hbox.Add(self.button_cancel, 0, wxALL|wxALIGN_CENTER,          hbox.Add(self.button_cancel, 0, wx.ALL|wx.ALIGN_CENTER,
98                    10)                    10)
99    
100          # Finalize ...          # Finalize ...
# Line 119  class BBoxDumpDialog(wxDialog): Line 122  class BBoxDumpDialog(wxDialog):
122              ThubanEndBusyCursor()              ThubanEndBusyCursor()
123    
124          if bboxmessage:          if bboxmessage:
125              dlg = wxScrolledMessageDialog(              dlg = ScrolledMessageDialog(
126                                  self.parent, bboxmessage,                                  self.parent, bboxmessage,
127                                  _("Bounding Box Dump %s") % self.layer.Title()                                  _("Bounding Box Dump %s") % self.layer.Title())
                                 )  
128              dlg.ShowModal()              dlg.ShowModal()
129    
130      def OnSelectFilename(self, event):      def OnSelectFilename(self, event):
# Line 130  class BBoxDumpDialog(wxDialog): Line 132  class BBoxDumpDialog(wxDialog):
132    
133          Opens a file dialog to specify a file to dump into.          Opens a file dialog to specify a file to dump into.
134          """          """
135          dlg = wxFileDialog(self, _("Dump Bounding Boxes To"),          dlg = wx.FileDialog(self, _("Dump Bounding Boxes To"),
136                         os.path.dirname(self.filename.GetValue()),                         os.path.dirname(self.filename.GetValue()),
137                         os.path.basename(self.filename.GetValue()),                         os.path.basename(self.filename.GetValue()),
138                         _("CSV Files (*.csv)|*.csv|") +                         _("CSV Files (*.csv)|*.csv|") +
139                         _("All Files (*.*)|*.*"),                         _("All Files (*.*)|*.*"),
140                         wxSAVE|wxOVERWRITE_PROMPT)                         wx.SAVE|wx.OVERWRITE_PROMPT)
141          if dlg.ShowModal() == wxID_OK:          if dlg.ShowModal() == wx.ID_OK:
142              self.filename.SetValue(dlg.GetPath())              self.filename.SetValue(dlg.GetPath())
143              dlg.Destroy()              dlg.Destroy()
144          else:          else:
# Line 149  def bboxdump(layer, column, filename): Line 151  def bboxdump(layer, column, filename):
151      layer    - Layer of shapes to be dumped      layer    - Layer of shapes to be dumped
152      column   - optional column to group shapes (else None)      column   - optional column to group shapes (else None)
153      filename - optional filename to dump into (else empty string, i.e. dump      filename - optional filename to dump into (else empty string, i.e. dump
154                 to stdio)             to message dialog)
155      """      """
156      # Preparation      # Preparation
157      shapelist = {}      shapelist = {}
158      bboxmessage = ""      bboxmessage = []
159    
160        dlg= wx.ProgressDialog(_("Bounding Box Dump"),
161                              _("Collecting shapes ..."),
162                              layer.ShapeStore().NumShapes(),
163                              None)
164    
165        cnt = 0
166        step =  int(layer.ShapeStore().NumShapes() / 100.0)
167        if step == 0:
168            step = 1
169    
170      # Collect shape ids to be dumped      # Collect shape ids to be dumped
171      if column is None:      if column is None:
172          # A simple dump of shapes bbox is required          # A simple dump of shapes bbox is required
173          for i in xrange(layer.NumShapes()):          for s in layer.ShapeStore().AllShapes():
174                i = s.ShapeID()
175              shapelist[i] = (i,)              shapelist[i] = (i,)
176                if cnt % step == 0:
177                    dlg.Update(cnt)
178                cnt = cnt + 1
179      else:      else:
180          # group them by column ...          # group them by column ...
181          for i in xrange(layer.NumShapes()):          for s in layer.ShapeStore().AllShapes():
182                i = s.ShapeID()
183              row = layer.ShapeStore().Table().ReadRowAsDict(i)              row = layer.ShapeStore().Table().ReadRowAsDict(i)
184              att = row[column.name]              att = row[column.name]
185              if not shapelist.has_key(att):              if not shapelist.has_key(att):
186                  shapelist[att] = []                  shapelist[att] = []
187              shapelist[att].append(i)              shapelist[att].append(i)
188                if cnt % step == 0:
189                    dlg.Update(cnt)
190                cnt = cnt + 1
191    
192        dlg.Destroy()
193        dlg= wx.ProgressDialog(_("Bounding Box Dump"),
194                              _("Dump bounding boxes of selected shapes ..."),
195                              len(shapelist),
196                              None)
197        cnt = 0
198        step = int(len(shapelist) / 100.0)
199        if step == 0:
200            step = 1
201    
202      # Dump them, sorted      # Dump them, sorted
203      keys = shapelist.keys()      keys = shapelist.keys()
204      keys.sort()      keys.sort()
205      for key in keys:      for key in keys:
206          bbox = layer.ShapesBoundingBox(shapelist[key])          bbox = layer.ShapesBoundingBox(shapelist[key])
207          bboxmessage = bboxmessage + "%.3f,%.3f,%.3f,%.3f,%s\n" % (          bboxmessage.append("%.3f,%.3f,%.3f,%.3f,%s\n" % (
208                      bbox[0],bbox[1],bbox[2],bbox[3],key)                              bbox[0], bbox[1], bbox[2], bbox[3], key))
209            if cnt % step == 0:
210                dlg.Update(cnt)
211            cnt = cnt + 1
212        dlg.Destroy()
213    
214      # finally      # finally
215      if filename != '':      if filename != '':
216          bboxfile = file(filename,'w+')          bboxfile = file(filename, 'w+')
217          bboxfile.write(bboxmessage)          bboxfile.write(string.join(bboxmessage))
218          bboxfile.close()          bboxfile.close()
219          return None          return None
220      else:      else:
221          return bboxmessage          return string.join(bboxmessage)
222    
223  def LayerBBoxDump(context):  def LayerBBoxDump(context):
224      """Menu Handler BBoxDump      """Menu Handler BBoxDump
# Line 196  def LayerBBoxDump(context): Line 230  def LayerBBoxDump(context):
230          dlg.ShowModal()          dlg.ShowModal()
231    
232    
233  # gns2shp executed as an extension to Thuban  # bboxdump executed as an extension to Thuban
234    
235  # register the new command  # register the new command
236  registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump,  registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump,
# Line 204  registry.Add(Command('bboxdump', _('BBox Line 238  registry.Add(Command('bboxdump', _('BBox
238                       sensitive = _has_selected_shape_layer))                       sensitive = _has_selected_shape_layer))
239    
240  # find the extensions menu (create it anew if not found)  # find the extensions menu (create it anew if not found)
241  extensions_menu = main_menu.find_menu('extensions')  extensions_menu = main_menu.FindOrInsertMenu('extensions', _('E&xtensions'))
 if extensions_menu is None:  
     extensions_menu = main_menu.InsertMenu('extensions', _('E&xtensions'))  
242    
243  # finally add the new entry to the extensions menu  # finally add the new entry to the extensions menu
244  extensions_menu.InsertItem('bboxdump')  extensions_menu.InsertItem('bboxdump')

Legend:
Removed from v.2196  
changed lines
  Added in v.2721

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26