2

To start I am going to be upfront, I am trying to add a feature to a QGIS Plugin Called instantprint. I am trying to add rotation to the tool so that you can align features to the print box and have them print in that orientation. First I managed to successfully create a python function to capture the rotation value of the canvas and apply it to the map in the composer see below

from qgis.core import *
from qgis.gui import *
from qgis.utils import iface

@qgsfunction(args='auto', group='Custom')
def CanvasRotation(feature, parent):
    return (iface.mapCanvas().rotation())

This function can be used in the data defined rotation like CanvasRotation() so that your map rotation matches your canvas. This allows you to use your map rotation to set how you want the map to be aligned.

The issue I am into now is the Map box is defined by the extent of the Map view port which skewes due to the rotation. So I changed the rubber band def to incorporate the roation in hopes to resolve this.

Original Code:

 def __createRubberBand(self):
    self.__cleanup()
    extent = self.mapitem.extent()
    center = self.iface.mapCanvas().extent().center()
    self.corner = QPointF(center.x() - 0.5 * extent.width(), center.y() - 0.5 * extent.height())
    self.rect = QRectF(self.corner.x(), self.corner.y(), extent.width(), extent.height())
    self.mapitem.setExtent(QgsRectangle(self.rect))
    self.rubberband = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.PolygonGeometry)
    self.rubberband.setToCanvasRectangle(self.__canvasRect(self.rect))
    self.rubberband.setColor(QColor(127, 127, 255, 127))

    self.pressPos = None

I added the rotation math to the self.corner = part to:

def __createRubberBand(self):
    self.__cleanup()
    extent = self.mapitem.extent()
    center = self.iface.mapCanvas().extent().center()
    self.corner = (QPointF(center.x - ((((((0.5)*(extent.width)))*((math.cos(iface.mapCanvas().rotation()))))-((((0.5)*(extent.width)))*((math.sin(iface.mapCanvas().rotation()))))))), (center.y - ((((0.5)*(extent.width)))*((math.sin(iface.mapCanvas().rotation()))))+((((0.5)*(extent.width)))*((math.cos(iface.mapCanvas().rotation()))))))
    self.rect = QRectF(self.corner.x(), self.corner.y(), extent.width(), extent.height())
    self.mapitem.setExtent(QgsRectangle(self.rect))
    self.rubberband = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.PolygonGeometry)
    self.rubberband.setToCanvasRectangle(self.__canvasRect(self.rect))
    self.rubberband.setColor(QColor(127, 127, 255, 127))

The plugin loads up but when I run it I get an error TypeError: unsupported operand type(s) for *: 'float' and 'builtin_function_or_method'.

I added all the imports I needed for the functions I am using, not sure what I did wrong. I checked my math a few times and didn't see any issues there but I might have missed something there are quite a few bracks. It almost looks like the results of the math are not what the tool is looking for.

1 Answer 1

3

The error is related with (0.5)*(extent.width). You try to multiply a float (0.5) by a method (extent.width). width doesn't call the method. To call a method, you have to use parentheses. So it has to be extent.width(). Also center.x and center.y have to be center.x() and center.y(). You used all in original code correctly, but missed in the next one.

Try in this way:

def __createRubberBand(self):
    self.__cleanup()
    extent = self.mapitem.extent()
    center = self.iface.mapCanvas().extent().center()

    r = iface.mapCanvas().rotation()    
    rs = math.sin(r)
    rc = math.cos(r)    
    w = 0.5 * extent.width() ##
                                  ##                              ##
    self.corner = QPointF(center.x() - (w * rc - w * rs), center.y() - (w * rs + w * rc))
    self.rect = QRectF(self.corner.x(), self.corner.y(), extent.width(), extent.height())
    self.mapitem.setExtent(QgsRectangle(self.rect))
    self.rubberband = QgsRubberBand(self.iface.mapCanvas(), QgsWkbTypes.PolygonGeometry)
    self.rubberband.setToCanvasRectangle(self.__canvasRect(self.rect))
    self.rubberband.setColor(QColor(127, 127, 255, 127))

I'm not sure if it solves your other problem, but it helps you not to get that error.

1
  • I clearly see what is going on and the error goes away when I implement that code but it doesn't seem to change how the tool responds when compared to the original. I am left to thinking I must be changing the wrong spot to get my desired result. Thank you for the help
    – MrKingsley
    Commented Jan 15, 2020 at 14:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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