/[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 2197 - (show annotations)
Tue May 4 17:17:00 2004 UTC (20 years, 10 months ago) by frank
Original Path: trunk/thuban/Extensions/bboxdump/bboxdump.py
File MIME type: text/x-python
File size: 7898 byte(s)
Extensions/bboxdump/__init__.py: Fixed string left over from
	copying.

Extensions/bboxdump/bboxdump.py (bboxdump):
	Use layer.ShapeStore().AllShapes() to loop over shapes instead of
	xrange(layer.NumShapes()). Compile the bboxmessage from a list
	of formatted outputs (string.join) instead of appending to the
	message. Two progress bar dialogs to report progress on the sometimes
	lenghty processing.

1 # Copyright (C) 2003 by Intevation GmbH
2 # Authors:
3 # Frank Koormann <[email protected]>
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
18 import os, sys
19 import string
20
21 from wxPython.wx import *
22 from wxPython.lib.dialogs import wxScrolledMessageDialog
23
24 from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
25 from Thuban.UI.command import registry, Command
26 from Thuban.UI.mainwindow import main_menu, _has_selected_shape_layer
27 from Thuban import _
28
29 import shapelib
30 import dbflib
31
32 # Widget IDs
33 ID_FILENAME = 4001
34 ID_ATTRIBUTES = 4002
35 ID_SELFN = 4003
36
37 class BBoxDumpDialog(wxDialog):
38 """Bounding Box Dump Dialog
39
40 Specify a filename for the dump and optionally a layer's column
41 field to group objects.
42 """
43
44 def __init__(self, parent, title, layer = None):
45 wxDialog.__init__(self, parent, -1, title,
46 style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
47
48 if layer is None:
49 return wxID_CANCEL
50
51 # Store the layer
52 self.layer = layer
53
54 # Filename selection elements
55 self.filename = wxTextCtrl(self, ID_FILENAME, "")
56 self.button_selectfile = wxButton(self, ID_SELFN, _('Select...'))
57 EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename)
58
59 # Column choice elements
60 self.choice_column = wxChoice(self, ID_ATTRIBUTES)
61 self.choice_column.Append(_('Select...'), None)
62 for col in self.layer.ShapeStore().Table().Columns():
63 self.choice_column.Append(col.name, col)
64 self.choice_column.SetSelection(0)
65
66 # Dialog button elements
67 self.button_dump = wxButton(self, wxID_OK, _("OK"))
68 EVT_BUTTON(self, wxID_OK, self.OnDump)
69 self.button_dump.SetDefault()
70 # TODO: Disable the OK button until a filename is entered ...
71 # self.button_dump.Enable(False)
72 self.button_cancel = wxButton(self, wxID_CANCEL, _("Cancel"))
73
74
75 # Dialog Layout: three horizontal box sizers.
76 topbox = wxBoxSizer(wxVERTICAL)
77
78 hbox = wxBoxSizer(wxHORIZONTAL)
79 topbox.Add(hbox, 0, wxALL|wxEXPAND)
80 hbox.Add(wxStaticText(self, -1, _("File:")),
81 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
82 hbox.Add(self.filename, 1, wxALL|wxEXPAND, 4)
83 hbox.Add(self.button_selectfile, 0, wxALL, 4)
84
85 hbox = wxBoxSizer(wxHORIZONTAL)
86 topbox.Add(hbox, 0, wxALL|wxEXPAND)
87 hbox.Add(wxStaticText(self, -1, _("Group by:")),
88 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
89 hbox.Add(self.choice_column, 1, wxALL|wxEXPAND, 4)
90
91 hbox = wxBoxSizer(wxHORIZONTAL)
92 topbox.Add(hbox, 0, wxALL|wxEXPAND)
93 hbox.Add(self.button_dump, 0, wxALL|wxALIGN_CENTER,
94 10)
95 hbox.Add(self.button_cancel, 0, wxALL|wxALIGN_CENTER,
96 10)
97
98 # Finalize ...
99 self.SetAutoLayout(True)
100 self.SetSizer(topbox)
101 topbox.Fit(self)
102 topbox.SetSizeHints(self)
103
104 # Store for later use
105 self.parent = parent
106
107 def OnDump(self, event):
108 """Bounding Box Dump Dialog event handler OK button.
109
110 Prepare the inputs from the dialog and call processing.
111 """
112 i = self.choice_column.GetSelection()
113 column = self.choice_column.GetClientData(i)
114 self.Close()
115
116 ThubanBeginBusyCursor()
117 try:
118 bboxmessage = bboxdump(self.layer, column, self.filename.GetValue())
119 finally:
120 ThubanEndBusyCursor()
121
122 if bboxmessage:
123 dlg = wxScrolledMessageDialog(
124 self.parent, bboxmessage,
125 _("Bounding Box Dump %s") % self.layer.Title())
126 dlg.ShowModal()
127
128 def OnSelectFilename(self, event):
129 """Bounding Box Dump Dialog event handler File Selection.
130
131 Opens a file dialog to specify a file to dump into.
132 """
133 dlg = wxFileDialog(self, _("Dump Bounding Boxes To"),
134 os.path.dirname(self.filename.GetValue()),
135 os.path.basename(self.filename.GetValue()),
136 _("CSV Files (*.csv)|*.csv|") +
137 _("All Files (*.*)|*.*"),
138 wxSAVE|wxOVERWRITE_PROMPT)
139 if dlg.ShowModal() == wxID_OK:
140 self.filename.SetValue(dlg.GetPath())
141 dlg.Destroy()
142 else:
143 dlg.Destroy()
144
145
146 def bboxdump(layer, column, filename):
147 """Bounding Box Dump Processing
148
149 layer - Layer of shapes to be dumped
150 column - optional column to group shapes (else None)
151 filename - optional filename to dump into (else empty string, i.e. dump
152 to message dialog)
153 """
154 # Preparation
155 shapelist = {}
156 bboxmessage = []
157
158 dlg= wxProgressDialog(_("Bounding Box Dump"),
159 _("Collecting shapes ..."),
160 layer.ShapeStore().NumShapes(),
161 None)
162
163 cnt = 0
164 step = int(layer.ShapeStore().NumShapes() / 100.0)
165 if step == 0:
166 step = 1
167
168 # Collect shape ids to be dumped
169 if column is None:
170 # A simple dump of shapes bbox is required
171 for s in layer.ShapeStore().AllShapes():
172 i = s.ShapeID()
173 shapelist[i] = (i,)
174 if cnt % step == 0:
175 dlg.Update(cnt)
176 cnt = cnt + 1
177 else:
178 # group them by column ...
179 for s in layer.ShapeStore().AllShapes():
180 i = s.ShapeID()
181 row = layer.ShapeStore().Table().ReadRowAsDict(i)
182 att = row[column.name]
183 if not shapelist.has_key(att):
184 shapelist[att] = []
185 shapelist[att].append(i)
186 if cnt % step == 0:
187 dlg.Update(cnt)
188 cnt = cnt + 1
189
190 dlg.Destroy()
191 dlg= wxProgressDialog(_("Bounding Box Dump"),
192 _("Dump bounding boxes of selected shapes ..."),
193 len(shapelist),
194 None)
195 cnt = 0
196 step = int(len(shapelist) / 100.0)
197 if step == 0:
198 step = 1
199
200 # Dump them, sorted
201 keys = shapelist.keys()
202 keys.sort()
203 for key in keys:
204 bbox = layer.ShapesBoundingBox(shapelist[key])
205 bboxmessage.append("%.3f,%.3f,%.3f,%.3f,%s\n" % (
206 bbox[0], bbox[1], bbox[2], bbox[3], key))
207 if cnt % step == 0:
208 dlg.Update(cnt)
209 cnt = cnt + 1
210 dlg.Destroy()
211
212 # finally
213 if filename != '':
214 bboxfile = file(filename, 'w+')
215 bboxfile.write(string.join(bboxmessage))
216 bboxfile.close()
217 return None
218 else:
219 return string.join(bboxmessage)
220
221 def LayerBBoxDump(context):
222 """Menu Handler BBoxDump
223 """
224 layer = context.mainwindow.canvas.SelectedLayer()
225 if layer is not None:
226 dlg = BBoxDumpDialog(context.mainwindow, _("Bounding Box Dump"),
227 layer = layer)
228 dlg.ShowModal()
229
230
231 # bboxdump executed as an extension to Thuban
232
233 # register the new command
234 registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump,
235 helptext = _('Dump Bounding Boxes of Layer Objects'),
236 sensitive = _has_selected_shape_layer))
237
238 # find the extensions menu (create it anew if not found)
239 extensions_menu = main_menu.find_menu('extensions')
240 if extensions_menu is None:
241 extensions_menu = main_menu.InsertMenu('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