forked from gvellut/FreehandRasterGeoreferencer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrastershadowmapcanvasitem.py
130 lines (105 loc) · 4.67 KB
/
rastershadowmapcanvasitem.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
from PyQt5.QtCore import QPointF, QRectF
from PyQt5.QtGui import QPainter
from qgis.core import QgsPointXY, QgsRectangle
from qgis.gui import QgsMapCanvasItem
class RasterShadowMapCanvasItem(QgsMapCanvasItem):
def __init__(self, canvas):
QgsMapCanvasItem.__init__(self, canvas)
self.canvas = canvas
self.reset()
def reset(self, layer=None):
self.layer = layer
self.setVisible(False)
self.dx = 0
self.dy = 0
self.drotation = 0
self.fxscale = 1
self.fyscale = 1
def setDeltaDisplacement(self, dx, dy, doUpdate):
self.dx = dx
self.dy = dy
if doUpdate:
self.setVisible(self.layer is None)
self.updateRect()
self.update()
def setDeltaRotation(self, rotation, doUpdate):
self.drotation = rotation
if doUpdate:
self.updateRect()
self.update()
def setDeltaRotationFromPoint(self, rotation, startPoint, doUpdate):
# Rotation around a point other than center of raster
self.drotation = rotation
if doUpdate:
self.updateRectFromPoint(startPoint)
self.update()
def setDeltaScale(self, xscale, yscale, doUpdate):
self.fxscale = xscale
self.fyscale = yscale
if doUpdate:
self.updateRect()
self.update()
def updateRect(self):
topLeft, topRight, bottomRight, bottomLeft = self.cornerCoordinates()
left = min(topLeft.x(), topRight.x(), bottomRight.x(), bottomLeft.x())
right = max(topLeft.x(), topRight.x(), bottomRight.x(), bottomLeft.x())
top = max(topLeft.y(), topRight.y(), bottomRight.y(), bottomLeft.y())
bottom = min(topLeft.y(), topRight.y(), bottomRight.y(), bottomLeft.y())
self.setRect(QgsRectangle(left, bottom, right, top))
def updateRectFromPoint(self, startPoint):
topLeft, topRight, bottomRight, bottomLeft = self.cornerCoordinatesFromPoint(
startPoint
)
left = min(topLeft.x(), topRight.x(), bottomRight.x(), bottomLeft.x())
right = max(topLeft.x(), topRight.x(), bottomRight.x(), bottomLeft.x())
top = max(topLeft.y(), topRight.y(), bottomRight.y(), bottomLeft.y())
bottom = min(topLeft.y(), topRight.y(), bottomRight.y(), bottomLeft.y())
self.setRect(QgsRectangle(left, bottom, right, top))
def cornerCoordinates(self):
center = QgsPointXY(
self.layer.center.x() + self.dx, self.layer.center.y() + self.dy
)
return self.layer.transformedCornerCoordinates(
center,
self.layer.rotation + self.drotation,
self.layer.xScale * self.fxscale,
self.layer.yScale * self.fyscale,
)
def cornerCoordinatesFromPoint(self, startPoint):
return self.layer.transformedCornerCoordinatesFromPoint(
startPoint, self.drotation, 1, 1
)
def paint(self, painter, options, widget):
painter.save()
self.prepareStyle(painter)
self.drawRaster(painter)
painter.restore()
def drawRaster(self, painter):
mapUPerPixel = self.canvas.mapUnitsPerPixel()
scaleX = self.layer.xScale * self.fxscale / mapUPerPixel
scaleY = self.layer.yScale * self.fyscale / mapUPerPixel
rect = QRectF(
QPointF(-self.layer.image.width() / 2.0, -self.layer.image.height() / 2.0),
QPointF(self.layer.image.width() / 2.0, self.layer.image.height() / 2.0),
)
targetRect = self.boundingRect()
painter.setRenderHint(QPainter.SmoothPixmapTransform, True)
# draw the image on the canvas item rectangle
# center displacement already taken into account in canvas
# item rectangle so no update
painter.translate(targetRect.center())
painter.rotate(self.layer.rotation + self.drotation)
painter.scale(scaleX, scaleY)
painter.drawImage(rect, self.layer.image)
def prepareStyle(self, painter):
painter.setOpacity(min(0.5, 1 - self.layer.transparency / 100.0))