Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsannotationlineitem.cpp 3 : : ---------------- 4 : : begin : July 2020 5 : : copyright : (C) 2020 by Nyall Dawson 6 : : email : nyall dot dawson at gmail dot com 7 : : ***************************************************************************/ 8 : : 9 : : /*************************************************************************** 10 : : * * 11 : : * This program is free software; you can redistribute it and/or modify * 12 : : * it under the terms of the GNU General Public License as published by * 13 : : * the Free Software Foundation; either version 2 of the License, or * 14 : : * (at your option) any later version. * 15 : : * * 16 : : ***************************************************************************/ 17 : : 18 : : #include "qgsannotationlineitem.h" 19 : : #include "qgssymbol.h" 20 : : #include "qgssymbollayerutils.h" 21 : : 22 : 0 : QgsAnnotationLineItem::QgsAnnotationLineItem( QgsCurve *curve ) 23 : 0 : : QgsAnnotationItem() 24 : 0 : , mCurve( curve ) 25 : 0 : , mSymbol( std::make_unique< QgsLineSymbol >() ) 26 : 0 : { 27 : : 28 : 0 : } 29 : : 30 : 0 : QgsAnnotationLineItem::~QgsAnnotationLineItem() = default; 31 : : 32 : 0 : QString QgsAnnotationLineItem::type() const 33 : : { 34 : 0 : return QStringLiteral( "linestring" ); 35 : : } 36 : : 37 : 0 : void QgsAnnotationLineItem::render( QgsRenderContext &context, QgsFeedback * ) 38 : : { 39 : 0 : QPolygonF pts = mCurve->asQPolygonF(); 40 : : 41 : : //transform the QPolygonF to screen coordinates 42 : 0 : if ( context.coordinateTransform().isValid() ) 43 : : { 44 : : try 45 : : { 46 : 0 : context.coordinateTransform().transformPolygon( pts ); 47 : 0 : } 48 : : catch ( QgsCsException & ) 49 : : { 50 : : // we don't abort the rendering here, instead we remove any invalid points and just plot those which ARE valid 51 : 0 : } 52 : 0 : } 53 : : 54 : : // remove non-finite points, e.g. infinite or NaN points caused by reprojecting errors 55 : 0 : pts.erase( std::remove_if( pts.begin(), pts.end(), 56 : 0 : []( const QPointF point ) 57 : : { 58 : 0 : return !std::isfinite( point.x() ) || !std::isfinite( point.y() ); 59 : 0 : } ), pts.end() ); 60 : : 61 : 0 : QPointF *ptr = pts.data(); 62 : 0 : for ( int i = 0; i < pts.size(); ++i, ++ptr ) 63 : : { 64 : 0 : context.mapToPixel().transformInPlace( ptr->rx(), ptr->ry() ); 65 : 0 : } 66 : : 67 : 0 : mSymbol->startRender( context ); 68 : 0 : mSymbol->renderPolyline( pts, nullptr, context ); 69 : 0 : mSymbol->stopRender( context ); 70 : 0 : } 71 : : 72 : 0 : bool QgsAnnotationLineItem::writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const 73 : : { 74 : 0 : element.setAttribute( QStringLiteral( "wkt" ), mCurve->asWkt() ); 75 : 0 : element.setAttribute( QStringLiteral( "zIndex" ), zIndex() ); 76 : : 77 : 0 : element.appendChild( QgsSymbolLayerUtils::saveSymbol( QStringLiteral( "lineSymbol" ), mSymbol.get(), document, context ) ); 78 : : 79 : 0 : return true; 80 : 0 : } 81 : : 82 : 0 : QgsAnnotationLineItem *QgsAnnotationLineItem::create() 83 : : { 84 : 0 : return new QgsAnnotationLineItem( new QgsLineString() ); 85 : 0 : } 86 : : 87 : 0 : bool QgsAnnotationLineItem::readXml( const QDomElement &element, const QgsReadWriteContext &context ) 88 : : { 89 : 0 : const QString wkt = element.attribute( QStringLiteral( "wkt" ) ); 90 : 0 : const QgsGeometry geometry = QgsGeometry::fromWkt( wkt ); 91 : 0 : if ( const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( geometry.constGet() ) ) 92 : 0 : mCurve.reset( curve->clone() ); 93 : : 94 : 0 : setZIndex( element.attribute( QStringLiteral( "zIndex" ) ).toInt() ); 95 : : 96 : 0 : const QDomElement symbolElem = element.firstChildElement( QStringLiteral( "symbol" ) ); 97 : 0 : if ( !symbolElem.isNull() ) 98 : 0 : setSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) ); 99 : : 100 : : return true; 101 : 0 : } 102 : : 103 : 0 : QgsRectangle QgsAnnotationLineItem::boundingBox() const 104 : : { 105 : 0 : return mCurve->boundingBox(); 106 : : } 107 : : 108 : 0 : QgsAnnotationLineItem *QgsAnnotationLineItem::clone() 109 : : { 110 : 0 : std::unique_ptr< QgsAnnotationLineItem > item = std::make_unique< QgsAnnotationLineItem >( mCurve->clone() ); 111 : 0 : item->setSymbol( mSymbol->clone() ); 112 : 0 : item->setZIndex( zIndex() ); 113 : 0 : return item.release(); 114 : 0 : } 115 : : 116 : 0 : const QgsLineSymbol *QgsAnnotationLineItem::symbol() const 117 : : { 118 : 0 : return mSymbol.get(); 119 : : } 120 : : 121 : 0 : void QgsAnnotationLineItem::setSymbol( QgsLineSymbol *symbol ) 122 : : { 123 : 0 : mSymbol.reset( symbol ); 124 : 0 : }