/[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 2356 - (show annotations)
Tue Sep 28 19:31:05 2004 UTC (20 years, 5 months ago) by jan
Original Path: trunk/thuban/Extensions/bboxdump/bboxdump.py
File MIME type: text/x-python
File size: 8169 byte(s)
Added registration of the extension.

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