def _add_selection(self, item): """Add selection rooted at item """ outline = self._selection_poly(item) selection_item = QGraphicsPolygonItem(self) # selection_item = QGraphicsPathItem(self) selection_item.setPos(self.contentsRect().topLeft()) # selection_item.setPen(QPen(Qt.NoPen)) selection_item.setPen(make_pen(width=1, cosmetic=True)) transform = self._itemgroup.transform() path = transform.map(outline) margin = 4 if item.node.is_leaf: path = QPolygonF(path.boundingRect().adjusted( -margin, -margin, margin, margin)) else: pass # ppath = QPainterPath() # ppath.addPolygon(path) # path = path_outline(ppath, width=margin).toFillPolygon() selection_item.setPolygon(path) # selection_item.setPath(path_outline(path, width=4)) selection_item.unscaled_path = outline self._selection[item] = selection_item item.setSelected(True)
def _add_selection(self, item): """Add selection rooted at item """ outline = self._selection_poly(item) selection_item = QGraphicsPolygonItem(self) # selection_item = QGraphicsPathItem(self) selection_item.setPos(self.contentsRect().topLeft()) # selection_item.setPen(QPen(Qt.NoPen)) selection_item.setPen(make_pen(width=1, cosmetic=True)) transform = self._itemgroup.transform() path = transform.map(outline) margin = 4 if item.node.is_leaf: path = QPolygonF(path.boundingRect() .adjusted(-margin, -margin, margin, margin)) else: pass # ppath = QPainterPath() # ppath.addPolygon(path) # path = path_outline(ppath, width=margin).toFillPolygon() selection_item.setPolygon(path) # selection_item.setPath(path_outline(path, width=4)) selection_item.unscaled_path = outline self._selection[item] = selection_item item.setSelected(True)
def on_actionGotoCell_triggered(self): cells = [str(cid) for cid in self._data.cells] selected, ok = QInputDialog.getItem(self, "Goto cell", "Select the cell to go to", cells, 0) if ok: cid = int(selected) self.ui.actionAdd_cell.setChecked(True) data = self._data if cid not in data.cells: return ls = data.cells_lifespan[cid] prev_pos = self._previousScene.current_data._current_index cur_pos = self._currentScene.current_data._current_index full_poly = data.cells[cid] poly = [pid for pid in full_poly if pid in data[prev_pos]] #log_debug("Cell %d on time %d: %s" % (cid, prev_pos, poly)) if prev_pos < ls.start or prev_pos >= ls.end or not poly: for i in range(*ls.slice().indices(len(data))): poly = [pid for pid in full_poly if pid in data[i]] if poly: log_debug("Found cell %d on image %d with polygon %s" % (cid, i, poly)) new_prev_pos = i break else: log_debug("Cell %d found nowhere in range %s!!!" % (cid, ls.slice())) else: new_prev_pos = prev_pos new_cur_pos = min(max(cur_pos + new_prev_pos - prev_pos, 0), len(data)) self.ui.previousState.setCurrentIndex(new_prev_pos) self.ui.currentState.setCurrentIndex(new_cur_pos) self._previousScene.current_cell = cid self._currentScene.current_cell = cid prev_data = self._previousScene.current_data poly = data.cells[cid] prev_poly = QPolygonF( [prev_data[ptid] for ptid in poly if ptid in prev_data]) prev_bbox = prev_poly.boundingRect() log_debug("Previous bounding box = %dx%d+%d+%d" % (prev_bbox.width(), prev_bbox.height(), prev_bbox.left(), prev_bbox.top())) self.ui.previousData.ensureVisible(prev_bbox)
def on_actionGotoCell_triggered(self): cells = [str(cid) for cid in self._data.cells] selected, ok = QInputDialog.getItem(self, "Goto cell", "Select the cell to go to", cells, 0) if ok: cid = int(selected) self.ui.actionAdd_cell.setChecked(True) data = self._data if cid not in data.cells: return ls = data.cells_lifespan[cid] prev_pos = self._previousScene.current_data._current_index cur_pos = self._currentScene.current_data._current_index full_poly = data.cells[cid] poly = [pid for pid in full_poly if pid in data[prev_pos]] #log_debug("Cell %d on time %d: %s" % (cid, prev_pos, poly)) if prev_pos < ls.start or prev_pos >= ls.end or not poly: for i in range(*ls.slice().indices(len(data))): poly = [pid for pid in full_poly if pid in data[i]] if poly: log_debug("Found cell %d on image %d with polygon %s" % (cid, i, poly)) new_prev_pos = i break else: log_debug("Cell %d found nowhere in range %s!!!" % (cid, ls.slice())) else: new_prev_pos = prev_pos new_cur_pos = min(max(cur_pos + new_prev_pos - prev_pos, 0), len(data)) self.ui.previousState.setCurrentIndex(new_prev_pos) self.ui.currentState.setCurrentIndex(new_cur_pos) self._previousScene.current_cell = cid self._currentScene.current_cell = cid prev_data = self._previousScene.current_data poly = data.cells[cid] prev_poly = QPolygonF([prev_data[ptid] for ptid in poly if ptid in prev_data]) prev_bbox = prev_poly.boundingRect() log_debug("Previous bounding box = %dx%d+%d+%d" % (prev_bbox.width(), prev_bbox.height(), prev_bbox.left(), prev_bbox.top())) self.ui.previousData.ensureVisible(prev_bbox)
class EPoint(ENode): def __init__(self, ENodeHandle): ENode.__init__(self, ENodeHandle) self.__polygon = QPolygonF(QRectF(-50, -15, 100, 30)) self.__updateShape() self.__attributes = {} self.__hiddenAttributes = {} self.__group = QGraphicsItemGroup() self.__group.addToGroup(QGraphicsPolygonItem(self.__polygon)) self.__buildAttributes(self.Handle.lsInputAttributes()) self.__buildAttributes(self.Handle.lsOutputAttributes(), True) self.__muted = None def __updateShape(self): fBBox = QFontMetrics(self.Font).boundingRect(self.Name) if self.__polygon.boundingRect().width() < fBBox.width(): self.__polygon = QPolygonF(QRectF(fBBox).normalized().adjusted(-fBBox.width() / 4, -fBBox.height() / 4, fBBox.height(), fBBox.height() / 2)) def __buildAttributes(self, attributes, opposite=False): rotation = 90 for index, point in enumerate(self.getPoints(len(attributes), opposite)): switch = {0: point.y() - (8 + self.pen().width()), 1: point.y() + (5 + self.pen().width())} connSlot = EDraw.Circle(8, 3, rotation).translated(QPointF(point.x(), switch[opposite])) self.__group.addToGroup(QGraphicsPolygonItem(connSlot)) self.__attributes[connSlot] = dict({self.kGuiAttributeId: attributes[index].Id, self.kGuiAttributeType: attributes[index].Type, self.kGuiAttributeParent: self, self.kGuiAttributePlug: self.Polygon.boundingRect().center(), self.kGuiAttributeLongName: attributes[index].Name}) return @property def Polygon(self): return self.__polygon @property def BoundPolygon(self): return self.__polygon.boundingRect() def mute(self, uuid): self.__muted = uuid def togglePlug(self, plugId): hiddenId = self.mapFromId(plugId)[ENode.kGuiAttributeId] if self.__hiddenAttributes.has_key(hiddenId): self.__hiddenAttributes.pop(hiddenId, None) return self.__hiddenAttributes[self.mapFromId(plugId)[ENode.kGuiAttributeId]] = [] def mapFromPoint(self, QPoint): for attrRect, attrValues in self.__attributes.iteritems(): if attrRect.boundingRect().contains(self.mapFromScene(QPoint)): return attrValues[self.kGuiAttributeId], self.scenePos() return self.Handle.Id, None def mapFromId(self, attrId): for attrValue in self.__attributes.itervalues(): if attrValue[self.kGuiAttributeId] == attrId: return attrValue return None def boundingRect(self): extra = self.pen().width() return self.__group.boundingRect().normalized().adjusted(-extra, -extra, extra, extra) def shape(self): return QGraphicsItem.shape(self) def getLines(self, count, opposite=False): angleOffset = 25 inputLines = [] startAngle = QLineF(QPointF(0.0, 0.0), self.boundingRect().topRight()).angle() + angleOffset endAngle = QLineF(QPointF(0.0, 0.0), self.boundingRect().topLeft()).angle() - angleOffset if opposite: startAngle = QLineF(QPointF(0.0, 0.0), self.boundingRect().bottomLeft()).angle() + angleOffset endAngle = QLineF(QPointF(0.0, 0.0), self.boundingRect().bottomRight()).angle() - angleOffset step = (endAngle - startAngle) / (count - 1) for x in range(0, count): tLine = QLineF(QPointF(0.0, 0.0), QPointF(0, 100)) tLine.setAngle(startAngle) inputLines.append(tLine) startAngle += step return inputLines def getPoints(self, count, opposite=False): result = [] line = QLineF(self.__polygon.boundingRect().topLeft(), self.__polygon.boundingRect().topRight()) if opposite: line = QLineF(self.__polygon.boundingRect().bottomLeft(), self.__polygon.boundingRect().bottomRight()) step = 1.0 / (count + 1) currentStep = step for x in range(0, count): result.append(line.pointAt(currentStep)) currentStep += step return result def paint(self, painter, option, widget=None): painter.setPen(self.pen()) painter.setBrush(EDraw.EColor.DefaultTitleColor) painter.drawRoundedRect(self.__polygon.boundingRect(), 3, 3) painter.setPen(EDraw.EColor.DefaultTitleTextColor) painter.drawText(self.__polygon.boundingRect(), Qt.AlignCenter, self.Name) for connSlot, connData in self.__attributes.iteritems(): if connData[self.kGuiAttributeId] != self.__muted and connData[self.kGuiAttributeId] not in self.__hiddenAttributes.keys(): painter.drawPolygon(connSlot) painter.setBrush(Qt.NoBrush)
class PositionMarker(QgsMapCanvasItem): ''' MapCanvasItem for showing the MobileItem on the MapCanvas Can have different appearences, fixed ones like corss, x or box or a userdefined shape. Can display also a label on the canvas ''' def __init__(self, canvas, params={}): ''' Constructor :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface :param params: A dictionary defining all the properties of the position marker :type params: dictionary ''' self.canvas = canvas self.type = params.get('type', 'BOX').upper() self.size = int(params.get('size', 16)) self.showLabel = bool(params.get('showLabel', True)) s = (self.size - 1) / 2 self.length = float(params.get('length', 98.0)) self.width = float(params.get('width', 17.0)) self.offsetX = float(params.get('offsetX', 0.0)) self.offsetY = float(params.get('offsetY', 0.0)) self.shape = params.get('shape', ((0.0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.50), (-0.5, -0.3))) self.paintShape = QPolygonF( [QPointF(-s, -s), QPointF(s, -s), QPointF(s, s), QPointF(-s, s)]) self.color = self.getColor(params.get('color', 'black')) self.fillColor = self.getColor(params.get('fillColor', 'lime')) self.penWidth = int(params.get('penWidth', 1)) spw = s + self.penWidth + 1 self.bounding = QRectF(-spw, -spw, spw * 2, spw * 2) if self.type in ('CROSS', 'X'): self.penWidth = 5 self.trackLen = int(params.get('trackLength', 100)) self.trackColor = self.getColor( params.get('trackColor', self.fillColor)) self.track = deque() self.position = None self.heading = 0 super(PositionMarker, self).__init__(canvas) self.setZValue(int(params.get('zValue', 100))) self.distArea = QgsDistanceArea() self.distArea.setEllipsoid(u'WGS84') self.distArea.setEllipsoidalMode(True) if self.showLabel: self.label = MarkerLabel(self.canvas, params) self.label.setZValue(self.zValue() + 0.1) self.updateSize() def properties(self): return { 'type': self.type, 'size': self.size, 'length': self.length, 'width': self.width, 'offsetX': self.offsetX, 'offsetY': self.offsetY, 'shape': self.shape, 'color': self.color.rgba(), 'fillColor': self.fillColor.rgba(), 'penWidth': self.penWidth, 'trackLength': self.trackLen, 'trackColor': self.trackColor.rgba(), 'zValue': self.zValue(), 'showLabel': self.showLabel } def setMapPosition(self, pos): if self.position != pos: self.updateTrack() self.position = pos self.setPos(self.toCanvasCoordinates(self.position)) if self.showLabel: self.label.setMapPosition(pos) self.update() def newHeading(self, heading): if self.heading != heading: self.heading = heading self.setRotation(self.canvas.rotation() + self.heading) self.update() def resetPosition(self): self.position = None if self.showLabel: self.label.resetPoition() def updatePosition(self): if self.position: self.prepareGeometryChange() self.updateSize() self.setPos(self.toCanvasCoordinates(self.position)) self.setRotation(self.canvas.rotation() + self.heading) def updateMapMagnification(self): self.updatePosition() if self.showLabel: self.label.updatePosition() for tp in self.track: tp[0].updatePosition() def updateSize(self): if self.type != 'SHAPE': return s = self.canvas.mapSettings() self.distArea.setSourceCrs(s.destinationCrs()) try: p1 = self.toMapCoordinates(QPoint(0, 0)) p2 = self.toMapCoordinates(QPoint(0, 100)) l = self.distArea.measureLine(p1, p2) f = 100 / l except: f = s.outputDpi() / 0.0254 / s.scale() paintLength = max(self.length * f, 50) paintWidth = paintLength * self.width / self.length offsY = self.offsetX / self.length * paintLength offsX = self.offsetY / self.width * paintWidth self.paintShape.clear() for v in self.shape: self.paintShape << QPointF(v[0] * paintWidth - offsX, v[1] * paintLength + offsY) self.size = max(paintLength, paintWidth) self.bounding = self.paintShape.boundingRect() def newTrackPoint(self, pos): tp = QgsVertexMarker(self.canvas) tp.setCenter(pos) tp.setIconType(QgsVertexMarker.ICON_CROSS) tp.setColor(self.trackColor) tp.setZValue(self.zValue() - 0.1) tp.setIconSize(3) tp.setPenWidth(3) return tp def updateTrack(self): if self.position and self.trackLen: if len(self.track) >= self.trackLen: tpr = self.track.popleft() self.canvas.scene().removeItem(tpr[0]) del (tpr) tp = self.newTrackPoint(self.position) self.track.append((tp, self.position)) def setVisible(self, visible): for tp in self.track: tp[0].setVisible(visible) QgsMapCanvasItem.setVisible(self, visible) if self.showLabel: self.label.setVisible(visible) def deleteTrack(self): for tp in self.track: self.canvas.scene().removeItem(tp[0]) self.track.clear() def setTrack(self, track): self.track.clear() for tp in track: tpn = self.newTrackPoint(tp) self.track.append((tpn, tp)) def paint(self, painter, xxx, xxx2): if not self.position: return s = (self.size - 1) / 2 pen = QPen(self.color) pen.setWidth(self.penWidth) painter.setPen(pen) if self.type == 'CROSS': painter.drawLine(QLineF(-s, 0, s, 0)) painter.drawLine(QLineF(0, -s, 0, s)) elif self.type == 'X': painter.drawLine(QLineF(-s, -s, s, s)) painter.drawLine(QLineF(-s, s, s, -s)) elif self.type == 'BOX': brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) elif self.type == 'SHAPE': painter.setRenderHint(QPainter.Antialiasing, True) brush = QBrush(self.fillColor) painter.setBrush(brush) painter.drawConvexPolygon(self.paintShape) def boundingRect(self): return self.bounding def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) def removeFromCanvas(self): self.deleteTrack() if self.showLabel: self.canvas.scene().removeItem(self.label) self.canvas.scene().removeItem(self)