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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 7873 byte(s)
made a copy
1 # Copyright (C) 2004 by Intevation GmbH
2 # Authors:
3 # Frank Koormann <[email protected]> (2004)
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 """
9 Extend thuban with a bounding box dump.
10
11 Dumps the bounding boxes of all shapes of the selected layer.
12 An optional column can be specified to group the objects,
13 in this case the bounding box is a union of the separate boxes.
14 """
15
16 __version__ = '$Revision$'
17 # $Source$
18 # $Id$
19
20 import os, sys
21 import string
22
23 import wx
24 from wx.lib.dialogs import ScrolledMessageDialog
25
26 from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
27 from Thuban.UI.command import registry, Command
28 from Thuban.UI.mainwindow import main_menu, _has_selected_shape_layer
29 from Thuban import _
30
31 import shapelib
32 import dbflib
33
34 # Widget IDs
35 ID_FILENAME = 4001
36 ID_ATTRIBUTES = 4002
37 ID_SELFN = 4003
38
39 class BBoxDumpDialog(wx.Dialog):
40 """Bounding Box Dump Dialog
41
42 Specify a filename for the dump and optionally a layer's column
43 field to group objects.
44 """
45
46 def __init__(self, parent, title, layer = None):
47 wx.Dialog.__init__(self, parent, -1, title,
48 style = wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)
49
50 if layer is None:
51 return wx.ID_CANCEL
52
53 # Store the layer
54 self.layer = layer
55
56 # Filename selection elements
57 self.filename = wx.TextCtrl(self, ID_FILENAME, "")
58 self.button_selectfile = wx.Button(self, ID_SELFN, _('Select...'))
59 wx.EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename)
60
61 # Column choice elements
62 self.choice_column = wx.Choice(self, ID_ATTRIBUTES)
63 self.choice_column.Append(_('Select...'), None)
64 for col in self.layer.ShapeStore().Table().Columns():
65 self.choice_column.Append(col.name, col)
66 self.choice_column.SetSelection(0)
67
68 # Dialog button elements
69 self.button_dump = wx.Button(self, wx.ID_OK, _("OK"))
70 wx.EVT_BUTTON(self, wx.ID_OK, self.OnDump)
71 self.button_dump.SetDefault()
72 # TODO: Disable the OK button until a filename is entered ...
73 # self.button_dump.Enable(False)
74 self.button_cancel = wx.Button(self, wx.ID_CANCEL, _("Cancel"))
75
76
77 # Dialog Layout: three horizontal box sizers.
78 topbox = wx.BoxSizer(wx.VERTICAL)
79
80 hbox = wx.BoxSizer(wx.HORIZONTAL)
81 topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
82 hbox.Add(wx.StaticText(self, -1, _("File:")),
83 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
84 hbox.Add(self.filename, 1, wx.ALL|wx.EXPAND, 4)
85 hbox.Add(self.button_selectfile, 0, wx.ALL, 4)
86
87 hbox = wx.BoxSizer(wx.HORIZONTAL)
88 topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
89 hbox.Add(wx.StaticText(self, -1, _("Group by:")),
90 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 4)
91 hbox.Add(self.choice_column, 1, wx.ALL|wx.EXPAND, 4)
92
93 hbox = wx.BoxSizer(wx.HORIZONTAL)
94 topbox.Add(hbox, 0, wx.ALL|wx.EXPAND)
95 hbox.Add(self.button_dump, 0, wx.ALL|wx.ALIGN_CENTER,
96 10)
97 hbox.Add(self.button_cancel, 0, wx.ALL|wx.ALIGN_CENTER,
98 10)
99
100 # Finalize ...
101 self.SetAutoLayout(True)
102 self.SetSizer(topbox)
103 topbox.Fit(self)
104 topbox.SetSizeHints(self)
105
106 # Store for later use
107 self.parent = parent
108
109 def OnDump(self, event):
110 """Bounding Box Dump Dialog event handler OK button.
111
112 Prepare the inputs from the dialog and call processing.
113 """
114 i = self.choice_column.GetSelection()
115 column = self.choice_column.GetClientData(i)
116 self.Close()
117
118 ThubanBeginBusyCursor()
119 try:
120 bboxmessage = bboxdump(self.layer, column, self.filename.GetValue())
121 finally:
122 ThubanEndBusyCursor()
123
124 if bboxmessage:
125 dlg = ScrolledMessageDialog(
126 self.parent, bboxmessage,
127 _("Bounding Box Dump %s") % self.layer.Title())
128 dlg.ShowModal()
129
130 def OnSelectFilename(self, event):
131 """Bounding Box Dump Dialog event handler File Selection.
132
133 Opens a file dialog to specify a file to dump into.
134 """
135 dlg = wx.FileDialog(self, _("Dump Bounding Boxes To"),
136 os.path.dirname(self.filename.GetValue()),
137 os.path.basename(self.filename.GetValue()),
138 _("CSV Files (*.csv)|*.csv|") +
139 _("All Files (*.*)|*.*"),
140 wx.SAVE|wx.OVERWRITE_PROMPT)
141 if dlg.ShowModal() == wx.ID_OK:
142 self.filename.SetValue(dlg.GetPath())
143 dlg.Destroy()
144 else:
145 dlg.Destroy()
146
147
148 def bboxdump(layer, column, filename):
149 """Bounding Box Dump Processing
150
151 layer - Layer of shapes to be dumped
152 column - optional column to group shapes (else None)
153 filename - optional filename to dump into (else empty string, i.e. dump
154 to message dialog)
155 """
156 # Preparation
157 shapelist = {}
158 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
171 if column is None:
172 # A simple dump of shapes bbox is required
173 for s in layer.ShapeStore().AllShapes():
174 i = s.ShapeID()
175 shapelist[i] = (i,)
176 if cnt % step == 0:
177 dlg.Update(cnt)
178 cnt = cnt + 1
179 else:
180 # group them by column ...
181 for s in layer.ShapeStore().AllShapes():
182 i = s.ShapeID()
183 row = layer.ShapeStore().Table().ReadRowAsDict(i)
184 att = row[column.name]
185 if not shapelist.has_key(att):
186 shapelist[att] = []
187 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
203 keys = shapelist.keys()
204 keys.sort()
205 for key in keys:
206 bbox = layer.ShapesBoundingBox(shapelist[key])
207 bboxmessage.append("%.3f,%.3f,%.3f,%.3f,%s\n" % (
208 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
215 if filename != '':
216 bboxfile = file(filename, 'w+')
217 bboxfile.write(string.join(bboxmessage))
218 bboxfile.close()
219 return None
220 else:
221 return string.join(bboxmessage)
222
223 def LayerBBoxDump(context):
224 """Menu Handler BBoxDump
225 """
226 layer = context.mainwindow.canvas.SelectedLayer()
227 if layer is not None:
228 dlg = BBoxDumpDialog(context.mainwindow, _("Bounding Box Dump"),
229 layer = layer)
230 dlg.ShowModal()
231
232
233 # bboxdump executed as an extension to Thuban
234
235 # register the new command
236 registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump,
237 helptext = _('Dump Bounding Boxes of Layer Objects'),
238 sensitive = _has_selected_shape_layer))
239
240 # find the extensions menu (create it anew if not found)
241 extensions_menu = main_menu.FindOrInsertMenu('extensions', _('E&xtensions'))
242
243 # finally add the new entry to the extensions menu
244 extensions_menu.InsertItem('bboxdump')

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26