Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm currently following the tutorial to create my first python plugin for QGIS: http://www.qgisworkshop.org/html/workshop/plugins_tutorial.html and have similar issues to this thread: QGIS 2.0 Plugin: Select and Identify a Single Feature

I'm attempting to list attributes of features in a dialog window when selecting a single feature. I don't receive an error message, but the feature isn't selected, nor is attribute information displayed. I'm only wetting my feet in terms of programming and using this forum, so please do excuse any newbie errors. Any suggestions would be greatly appreciated.

I'm posting my entire program as I'm unsure where the problem is coming from:

# Import the PyQt and QGIS libraries
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from qgis.gui import *

# Initialize Qt resources from file resources.py
import resources_rc
# Import the code for the dialog
from zconsodialog import zConsoDialog
import os.path

class zConso:

def __init__(self, iface):
    # Save reference to the QGIS interface
    self.iface = iface
    # reference to map canvas
    self.canvas = self.iface.mapCanvas()
    # out click tool to emit a QgsPoint on every click

    self.clickTool = QgsMapToolEmitPoint(self.canvas)
    # initialize plugin directory
    self.plugin_dir = os.path.dirname(__file__)
    # initialize locale
    locale = QSettings().value("locale/userLocale")[0:2]
    localePath = os.path.join(self.plugin_dir, 'i18n', 'zconso_{}.qm'.format(locale))

    if os.path.exists(localePath):
        self.translator = QTranslator()
        self.translator.load(localePath)

        if qVersion() > '4.3.3':
            QCoreApplication.installTranslator(self.translator)

    # Create the GUI dialog (after translation) and keep reference
    self.dlg = zConsoDialog()

def initGui(self):
    # Create action that will start plugin configuration
    self.action = QAction(
        QIcon(":/plugins/zconso/icon.png"),
        u"Calculer consommation d'une zone", self.iface.mainWindow())

    # connect the action to the run method
    QObject.connect(self.action, SIGNAL("triggered()"), self.run)
    #self.action.triggered.connect(self.run)

    # Add toolbar button and menu item
    self.iface.addToolBarIcon(self.action)
    self.iface.addPluginToMenu(u"&zConso", self.action)

    # connect our custom function to a clickTool signal that the canvas was clicked

    result = QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.handleMouseDown)
    #QMessageBox.information( self.iface.mainWindow(),"Info", "connect = %s"%str(result) )

    # connect our select function to the canvasClicked signal

    result = QObject.connect(self.clickTool, SIGNAL("canvasClicked(const QgsPoint &, Qt::MouseButton)"), self.selectFeature)
    #QMessageBox.information( self.iface.mainWindow(),"Info", "connect = %s"%str(result) )


def unload(self):
    # Remove the plugin menu item and icon
    self.iface.removePluginMenu(u"&zConso", self.action)
    self.iface.removeToolBarIcon(self.action)

def handleMouseDown(self, point, button):

    self.dlg.clearTextBrowser()
    self.dlg.setTextBrowser( str(point.x()) + " , " +str(point.y()) )
    #QMessageBox.information( self.iface.mainWindow(),"Info", "X,Y = %s,%s" % (str(point.x()),str(point.y())) )

def selectFeature(self, point, button):
    QMessageBox.information( self.iface.mainWindow(),"Info", "in selectFeature function" )
    cLayer = self.canvas.currentLayer()

    radius = 5
    rect = QgsRectangle(point.x() - radius,
                        point.y() - radius,
                        point.x() - radius,
                        point.y() - radius)
    cLayer.select(rect, False)
    selected_features = cLayer.selectedFeatures()

    for i in selected_features:
        attrs = i.attributeMap()
        for (k,attr) in attrs.iteritems():

            print "%d: %s" % (k, attr.toString())

    #code from tutorial
    # setup the provider select to filter results based on a rectangle
    #pntGeom = QgsGeometry.fromPoint(point)  
    # scale-dependent buffer of 2 pixels-worth of map units
    #pntBuff = pntGeom.buffer( (self.canvas.mapUnitsPerPixel() * 2),0) 
    #rect = pntBuff.boundingBox()
    # get currentLayer and dataProvider



    #selectList = []
    #if cLayer:
    #        provider = cLayer.dataProvider()
    #        feat = QgsFeature()
    #        # create the select statement
    #        provider.select([],rect) # the arguments mean no attributes returned, and do a bbox filter with our buffered rectangle to limit the amount of features
    #        while provider.nextFeature(feat):
    #            # if the feat geom returned from the selection intersects our point then put it in a list
    #            if feat.geometry().intersects(pntGeom):
    #                selectList.append(feat.id())

    #        # make the actual selection
    #        cLayer.setSelectedFeatures(selectList)
    #else:
    #        QMessageBox.information( self.iface.mainWindow(),"Info", "No layer currently selected in TOC" )



# run method that performs all the real work
def run(self):
    # make our clickTool the tool that we'll use for now

    self.canvas.setMapTool(self.clickTool)

    # show the dialog
    self.dlg.show()
    # Run the dialog event loop
    result = self.dlg.exec_()
    # See if OK was pressed
    if result == 1:
        # do something useful (delete the line containing pass and
        # substitute with your code)
        pass

Mahalo!

share|improve this question
add comment

1 Answer 1

You need to convert the point coordinates to map coordinates prior to creating your selection rectangle in selectFeature:

map_point = self.clickTool.toMapCoordinates(point)
cLayer = self.canvas.currentLayer()

radius = 5
rect = QgsRectangle(map_point.x() - radius,
                    map_point.y() - radius,
                    map_point.x() - radius,
                    map_point.y() - radius)
cLayer.select(rect, False)

You can check the coordinates of your selection rectangle by displaying rect.toString() in a QMessageBox or the log window to make sure they match what you think they should.

share|improve this answer
    
Now a type error is thrown. Type Error : arguments did not match any overloaded call: QgsMapToolEmitPoint.toMapCoordinates(QPoint): argument 1 has unexpected type 'QgsPoint' QgsMapToolEmitPoint.toMapCoordinates(QgsMapLayer, QgsPoint): argument 1 has unexpected type 'QgsPoint' Also, should the point be converted to map units in the mouse handler as well? –  user25976 Feb 24 at 23:27
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.