frank: thuban/Extensions/bboxdump __init__.py, NONE, 1.1 bboxdump.py, NONE, 1.1

cvs@intevation.de cvs at intevation.de
Thu Apr 22 19:11:56 CEST 2004


Author: frank

Update of /thubanrepository/thuban/Extensions/bboxdump
In directory doto:/tmp/cvs-serv11616/Extensions/bboxdump

Added Files:
	__init__.py bboxdump.py 
Log Message:
New Extension to dump bounding boxes of all shapes of the selected 
layer. An optional column can be specified to group the objects, 
in this case the bounding box is a union of the separate boxes.
Dump can be displayed in a ScrolledMessageDialog or written to file. 
The Extension is simply a combination of available and well tested
Thuban functionality.

* Extensions/bboxdump/__init__.py: New: Init to make this
	directory a package.

* Extensions/bboxdump/bboxdump.py: New: Dump bounding boxes of 
	all shapes of the selected layer.


--- NEW FILE: __init__.py ---
# Copyright (c) 2003 by Intevation GmbH
# Authors:
# Jan-Oliver Wagner <jan at intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

--- NEW FILE: bboxdump.py ---
# Copyright (C) 2003 by Intevation GmbH
# Authors:
# Frank Koormann <frank at intevation.de>
#
# This program is free software under the GPL (>=v2)
# Read the file COPYING coming with Thuban for details.

"""
Extend thuban with a bounding box dump.

Dumps the bounding boxes of all shapes of the selected layer.
An optional column can be specified to group the objects, 
in this case the bounding box is a union of the separate boxes.
"""

__version__ = '$Revision: 1.1 $'

import os, sys

# only import GUI when not called as command line tool
from wxPython.wx import *
from wxPython.lib.dialogs import wxScrolledMessageDialog

from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
from Thuban.UI.command import registry, Command
from Thuban.UI.mainwindow import main_menu, _has_selected_shape_layer
from Thuban import _

import shapelib
import dbflib

ID_FILENAME = 4001
ID_ATTRIBUTES = 4002
ID_SELFN = 4003

class BBoxDumpDialog(wxDialog):
    """Bounding Box Dump Dialog

    Specify a filename for the dump and optionally a layer's column 
    field to group objects.
    """

    def __init__(self, parent, title, layer = None):
        wxDialog.__init__(self, parent, -1, title,
                          style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)

        if layer is None:
            return wxID_CANCEL

        # Store the layer
        self.layer = layer

        # Filename selection elements
        self.filename = wxTextCtrl(self, ID_FILENAME, "")
        self.button_selectfile = wxButton(self, ID_SELFN, _('Select...'))
        EVT_BUTTON(self, ID_SELFN, self.OnSelectFilename)

        # Column choice elements
        self.choice_column = wxChoice(self, ID_ATTRIBUTES)
        self.choice_column.Append(_('Select...'), None)
        for col in self.layer.ShapeStore().Table().Columns():
                self.choice_column.Append(col.name, col)
        self.choice_column.SetSelection(0)

        # Dialog button elements
        self.button_dump = wxButton(self, wxID_OK, _("OK"))
        EVT_BUTTON(self, wxID_OK, self.OnDump)
        self.button_dump.SetDefault()
        # TODO: Disable the OK button until a filename is entered ...
        # self.button_dump.Enable(False)
        self.button_cancel = wxButton(self, wxID_CANCEL, _("Cancel"))


        # Dialog Layout: three horizontal box sizers.
        topbox = wxBoxSizer(wxVERTICAL)

        hbox = wxBoxSizer(wxHORIZONTAL)
        topbox.Add(hbox, 0, wxALL|wxEXPAND)
        hbox.Add(wxStaticText(self, -1, _("File:")),
                 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
        hbox.Add(self.filename, 1, wxALL|wxEXPAND, 4)
        hbox.Add(self.button_selectfile, 0, wxALL, 4)

        hbox = wxBoxSizer(wxHORIZONTAL)
        topbox.Add(hbox, 0, wxALL|wxEXPAND)
        hbox.Add(wxStaticText(self, -1, _("Group by:")),
                 0, wxALL|wxALIGN_CENTER_VERTICAL, 4)
        hbox.Add(self.choice_column, 1, wxALL|wxEXPAND, 4)

        hbox = wxBoxSizer(wxHORIZONTAL)
        topbox.Add(hbox, 0, wxALL|wxEXPAND)
        hbox.Add(self.button_dump, 0, wxALL|wxALIGN_CENTER,
                  10)
        hbox.Add(self.button_cancel, 0, wxALL|wxALIGN_CENTER,
                  10)

        # Finalize ...
        self.SetAutoLayout(True)
        self.SetSizer(topbox)
        topbox.Fit(self)
        topbox.SetSizeHints(self)

        # Store for later use
        self.parent = parent

    def OnDump(self, event):
        """Bounding Box Dump Dialog event handler OK button.

        Prepare the inputs from the dialog and call processing.
        """
        i = self.choice_column.GetSelection()
        column = self.choice_column.GetClientData(i)
        self.Close()

        ThubanBeginBusyCursor()
        try:
            bboxmessage = bboxdump(self.layer, column, self.filename.GetValue())
        finally:
            ThubanEndBusyCursor()

        if bboxmessage:
            dlg = wxScrolledMessageDialog(
                                self.parent, bboxmessage,
                                _("Bounding Box Dump %s") % self.layer.Title()
                                )
            dlg.ShowModal()

    def OnSelectFilename(self, event):
        """Bounding Box Dump Dialog event handler File Selection.

        Opens a file dialog to specify a file to dump into.
        """
        dlg = wxFileDialog(self, _("Dump Bounding Boxes To"), 
                       os.path.dirname(self.filename.GetValue()), 
                       os.path.basename(self.filename.GetValue()),
                       _("CSV Files (*.csv)|*.csv|") +
                       _("All Files (*.*)|*.*"),
                       wxSAVE|wxOVERWRITE_PROMPT)
        if dlg.ShowModal() == wxID_OK:
            self.filename.SetValue(dlg.GetPath())
            dlg.Destroy()
        else:
            dlg.Destroy()


def bboxdump(layer, column, filename):
    """Bounding Box Dump Processing

    layer    - Layer of shapes to be dumped
    column   - optional column to group shapes (else None)
    filename - optional filename to dump into (else empty string, i.e. dump
               to stdio)
    """
    # Preparation
    shapelist = {}
    bboxmessage = ""
 
    # Collect shape ids to be dumped
    if column is None:
        # A simple dump of shapes bbox is required
        for i in xrange(layer.NumShapes()):
            shapelist[i] = (i,)
    else:
        # group them by column ... 
        for i in xrange(layer.NumShapes()):
            row = layer.ShapeStore().Table().ReadRowAsDict(i)
            att = row[column.name]
            if not shapelist.has_key(att):
                shapelist[att] = []
            shapelist[att].append(i)

    # Dump them, sorted
    keys = shapelist.keys()
    keys.sort()
    for key in keys:
        bbox = layer.ShapesBoundingBox(shapelist[key])
        bboxmessage = bboxmessage + "%.3f,%.3f,%.3f,%.3f,%s\n" % (
                    bbox[0],bbox[1],bbox[2],bbox[3],key) 

    # finally
    if filename != '':
        bboxfile = file(filename,'w+')
        bboxfile.write(bboxmessage)
        bboxfile.close()
        return None
    else:
        return bboxmessage

def LayerBBoxDump(context):
    """Menu Handler BBoxDump
    """
    layer = context.mainwindow.canvas.SelectedLayer()
    if layer is not None:
        dlg = BBoxDumpDialog(context.mainwindow, _("Bounding Box Dump"),
                             layer = layer)
        dlg.ShowModal()


# gns2shp executed as an extension to Thuban

# register the new command
registry.Add(Command('bboxdump', _('BBox Dump'), LayerBBoxDump,
                     helptext = _('Dump Bounding Boxes of Layer Objects'),
                     sensitive = _has_selected_shape_layer))

# find the extensions menu (create it anew if not found)
extensions_menu = main_menu.find_menu('extensions')
if extensions_menu is None:
    extensions_menu = main_menu.InsertMenu('extensions', _('E&xtensions'))

# finally add the new entry to the extensions menu
extensions_menu.InsertItem('bboxdump')





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)