def paint(self, painter, styleoptions, widget=None): try: width, realsize, label, fontsize = self._calc_size() except ZeroDivisionError: return mapunits = self.canvas.mapUnits() # painter.drawRect(self.boundingRect()) array = QPolygon() canvasheight = self.canvas.height() canvaswidth = self.canvas.width() margin = 20 originy = 0 originx = 0 self.setPos(margin, canvasheight - margin) x1, y1 = originx, originy x2, y2 = originx, originy + self.ticksize x3, y3 = originx + width, originy + self.ticksize midx, midy = originx + width / 2, originy + self.ticksize / 2 x4, y4 = originx + width, originy for pen in self.pens: painter.setPen(pen) # Drwa the scale bar painter.drawLine(x1, y1, x2, y2) painter.drawLine(x2, y2, x3, y3) painter.drawLine(x3, y3, x4, y4) painter.drawLine(midx, midy, midx, y1) # Draw the text fontwidth = self.metrics.width("0") fontheight = self.metrics.height() fontheight /= 2 fontwidth /= 2 path = QPainterPath() point = QPointF(x1 - fontwidth, y1 - fontheight) path.addText(point, self.font, "0") painter.setPen(self.whitepen) painter.setBrush(self.blackbrush) painter.setRenderHints(QPainter.Antialiasing) painter.setFont(self.font) painter.drawPath(path) fontwidth = self.metrics.width(label) fontheight = self.metrics.height() fontheight /= 2 fontwidth /= 2 point = QPointF(x4 - fontwidth, y4 - fontheight) path.addText(point, self.font, label) painter.drawPath(path)
def paint(self, painter, option, widget): if not painter: return painter.save() painter.setRenderHint(QPainter.Antialiasing, True) # do a bit of trigonometry to find out how to transform a rotated item such # that the center point is at the point feature x = 0.0 y = 0.0 if self.pixmap.width() > 0 and self.pixmap.height() > 0: half_item_diagonal = math.sqrt( self.pixmap.width() * self.pixmap.width() + self.pixmap.height() * self.pixmap.height()) / 2 diagonal_angle = math.acos( self.pixmap.width() / (half_item_diagonal * 2)) * 180 / math.pi x = half_item_diagonal * math.cos( (self.rotation - diagonal_angle) * math.pi / 180) y = half_item_diagonal * math.sin( (self.rotation - diagonal_angle) * math.pi / 180) painter.rotate(self.rotation) painter.translate(x - self.pixmap.width() / 2.0, -y - self.pixmap.height() / 2.0) painter.drawPixmap(0, 0, self.pixmap) # draw arrow, using a red line over a thicker white line so that the arrow is visible # against a range of backgrounds pen = QPen() pen.setWidth(GuiUtils.scale_icon_size(4)) pen.setColor(QColor(Qt.white)) painter.setPen(pen) painter.drawPath(self.arrow_path) pen.setWidth(GuiUtils.scale_icon_size(1)) pen.setColor(QColor(Qt.red)) painter.setPen(pen) painter.drawPath(self.arrow_path) painter.restore() # draw numeric value beside the symbol painter.save() painter.setRenderHint(QPainter.Antialiasing, True) buffer_pen = QPen() buffer_pen.setColor(Qt.white) buffer_pen.setWidthF(GuiUtils.scale_icon_size(4)) fm = QFontMetricsF(self.marker_font) label = QPainterPath() label.addText(self.pixmap.width(), self.pixmap.height() / 2.0 + fm.height() / 2.0, self.marker_font, str(round(self.rotation, 1))) painter.setPen(buffer_pen) painter.setBrush(Qt.NoBrush) painter.drawPath(label) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(Qt.black)) painter.drawPath(label) painter.restore()
def append_CharacterMarkerSymbolLayerAsSvg(symbol, layer, context: Context): # pylint: disable=too-many-locals """ Appends a CharacterMarkerSymbolLayer to a symbol, rendering the font character to an SVG file. """ font_family = layer.font character = chr(layer.unicode) color = symbol_color_to_qcolor(layer.color) angle = convert_angle(layer.angle) font = QFont(font_family) font.setPointSizeF(layer.size) # Using the rect of a painter path gives better results then using font metrics path = QPainterPath() path.setFillRule(Qt.WindingFill) path.addText(0, 0, font, character) rect = path.boundingRect() font_bounding_rect = QFontMetricsF(font).boundingRect(character) # adjust size -- marker size in esri is the font size, svg marker size in qgis is the svg rect size scale = rect.width() / font_bounding_rect.width() gen = QSvgGenerator() svg_path = symbol_name_to_filename(context.symbol_name, context.picture_folder, 'svg') gen.setFileName(svg_path) gen.setViewBox(rect) painter = QPainter(gen) painter.setFont(font) # todo -- size! if context.parameterise_svg: painter.setBrush(QBrush(QColor(255, 0, 0))) else: painter.setBrush(QBrush(color)) painter.setPen(Qt.NoPen) painter.drawPath(path) painter.end() if context.parameterise_svg: with open(svg_path, 'r') as f: t = f.read() t = t.replace('#ff0000', 'param(fill)') t = t.replace('fill-opacity="1" ', 'fill-opacity="param(fill-opacity)"') t = t.replace( 'stroke="none"', 'stroke="param(outline)" stroke-opacity="param(outline-opacity) 1" stroke-width="param(outline-width) 0"' ) with open(svg_path, 'w') as f: f.write(t) svg_path = context.convert_path(svg_path) out = QgsSvgMarkerSymbolLayer(svg_path) out.setSizeUnit(context.units) out.setSize(context.convert_size(scale * rect.width())) out.setAngle(angle) out.setFillColor(color) out.setStrokeWidth(0) out.setEnabled(layer.enabled) out.setLocked(layer.locked) out.setOffset( adjust_offset_for_rotation( QPointF(context.convert_size(layer.x_offset), -context.convert_size(layer.y_offset)), layer.angle)) out.setOffsetUnit(context.units) symbol.appendSymbolLayer(out)