LCOV - code coverage report
Current view: top level - core/symbology - qgsvectorfieldsymbollayer.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 0 220 0.0 %
Date: 2021-03-26 12:19:53 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :          qgsvectorfieldsymbollayer.cpp
       3                 :            :          -----------------------------
       4                 :            :   begin                : Octorer 25, 2011
       5                 :            :   copyright            : (C) 2011 by Marco Hugentobler
       6                 :            :   email                : marco dot hugentobler at sourcepole dot ch
       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 "qgsvectorfieldsymbollayer.h"
      19                 :            : #include "qgsvectorlayer.h"
      20                 :            : #include "qgsunittypes.h"
      21                 :            : #include "qgssymbollayerutils.h"
      22                 :            : 
      23                 :          0 : QgsVectorFieldSymbolLayer::QgsVectorFieldSymbolLayer()
      24                 :          0 : {
      25                 :          0 :   setSubSymbol( new QgsLineSymbol() );
      26                 :          0 : }
      27                 :            : 
      28                 :          0 : void QgsVectorFieldSymbolLayer::setOutputUnit( QgsUnitTypes::RenderUnit unit )
      29                 :            : {
      30                 :          0 :   QgsMarkerSymbolLayer::setOutputUnit( unit );
      31                 :          0 :   mDistanceUnit = unit;
      32                 :          0 : }
      33                 :            : 
      34                 :          0 : QgsUnitTypes::RenderUnit QgsVectorFieldSymbolLayer::outputUnit() const
      35                 :            : {
      36                 :          0 :   if ( QgsMarkerSymbolLayer::outputUnit() == mDistanceUnit )
      37                 :            :   {
      38                 :          0 :     return mDistanceUnit;
      39                 :            :   }
      40                 :          0 :   return QgsUnitTypes::RenderUnknownUnit;
      41                 :          0 : }
      42                 :            : 
      43                 :          0 : void QgsVectorFieldSymbolLayer::setMapUnitScale( const QgsMapUnitScale &scale )
      44                 :            : {
      45                 :          0 :   QgsMarkerSymbolLayer::setMapUnitScale( scale );
      46                 :          0 :   mDistanceMapUnitScale = scale;
      47                 :          0 : }
      48                 :            : 
      49                 :          0 : QgsMapUnitScale QgsVectorFieldSymbolLayer::mapUnitScale() const
      50                 :            : {
      51                 :          0 :   if ( QgsMarkerSymbolLayer::mapUnitScale() == mDistanceMapUnitScale )
      52                 :            :   {
      53                 :          0 :     return mDistanceMapUnitScale;
      54                 :            :   }
      55                 :          0 :   return QgsMapUnitScale();
      56                 :          0 : }
      57                 :            : 
      58                 :          0 : QgsSymbolLayer *QgsVectorFieldSymbolLayer::create( const QVariantMap &properties )
      59                 :            : {
      60                 :          0 :   QgsVectorFieldSymbolLayer *symbolLayer = new QgsVectorFieldSymbolLayer();
      61                 :          0 :   if ( properties.contains( QStringLiteral( "x_attribute" ) ) )
      62                 :            :   {
      63                 :          0 :     symbolLayer->setXAttribute( properties[QStringLiteral( "x_attribute" )].toString() );
      64                 :          0 :   }
      65                 :          0 :   if ( properties.contains( QStringLiteral( "y_attribute" ) ) )
      66                 :            :   {
      67                 :          0 :     symbolLayer->setYAttribute( properties[QStringLiteral( "y_attribute" )].toString() );
      68                 :          0 :   }
      69                 :          0 :   if ( properties.contains( QStringLiteral( "distance_unit" ) ) )
      70                 :            :   {
      71                 :          0 :     symbolLayer->setDistanceUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "distance_unit" )].toString() ) );
      72                 :          0 :   }
      73                 :          0 :   if ( properties.contains( QStringLiteral( "distance_map_unit_scale" ) ) )
      74                 :            :   {
      75                 :          0 :     symbolLayer->setDistanceMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "distance_map_unit_scale" )].toString() ) );
      76                 :          0 :   }
      77                 :          0 :   if ( properties.contains( QStringLiteral( "scale" ) ) )
      78                 :            :   {
      79                 :          0 :     symbolLayer->setScale( properties[QStringLiteral( "scale" )].toDouble() );
      80                 :          0 :   }
      81                 :          0 :   if ( properties.contains( QStringLiteral( "vector_field_type" ) ) )
      82                 :            :   {
      83                 :          0 :     symbolLayer->setVectorFieldType( static_cast< VectorFieldType >( properties[QStringLiteral( "vector_field_type" )].toInt() ) );
      84                 :          0 :   }
      85                 :          0 :   if ( properties.contains( QStringLiteral( "angle_orientation" ) ) )
      86                 :            :   {
      87                 :          0 :     symbolLayer->setAngleOrientation( static_cast< AngleOrientation >( properties[QStringLiteral( "angle_orientation" )].toInt() ) );
      88                 :          0 :   }
      89                 :          0 :   if ( properties.contains( QStringLiteral( "angle_units" ) ) )
      90                 :            :   {
      91                 :          0 :     symbolLayer->setAngleUnits( static_cast< AngleUnits >( properties[QStringLiteral( "angle_units" )].toInt() ) );
      92                 :          0 :   }
      93                 :          0 :   if ( properties.contains( QStringLiteral( "size" ) ) )
      94                 :            :   {
      95                 :          0 :     symbolLayer->setSize( properties[QStringLiteral( "size" )].toDouble() );
      96                 :          0 :   }
      97                 :          0 :   if ( properties.contains( QStringLiteral( "size_unit" ) ) )
      98                 :            :   {
      99                 :          0 :     symbolLayer->setSizeUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "size_unit" )].toString() ) );
     100                 :          0 :   }
     101                 :          0 :   if ( properties.contains( QStringLiteral( "size_map_unit_scale" ) ) )
     102                 :            :   {
     103                 :          0 :     symbolLayer->setSizeMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "size_map_unit_scale" )].toString() ) );
     104                 :          0 :   }
     105                 :          0 :   if ( properties.contains( QStringLiteral( "offset" ) ) )
     106                 :            :   {
     107                 :          0 :     symbolLayer->setOffset( QgsSymbolLayerUtils::decodePoint( properties[QStringLiteral( "offset" )].toString() ) );
     108                 :          0 :   }
     109                 :          0 :   if ( properties.contains( QStringLiteral( "offset_unit" ) ) )
     110                 :            :   {
     111                 :          0 :     symbolLayer->setOffsetUnit( QgsUnitTypes::decodeRenderUnit( properties[QStringLiteral( "offset_unit" )].toString() ) );
     112                 :          0 :   }
     113                 :          0 :   if ( properties.contains( QStringLiteral( "offset_map_unit_scale" ) ) )
     114                 :            :   {
     115                 :          0 :     symbolLayer->setOffsetMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( properties[QStringLiteral( "offset_map_unit_scale" )].toString() ) );
     116                 :          0 :   }
     117                 :          0 :   return symbolLayer;
     118                 :          0 : }
     119                 :            : 
     120                 :          0 : bool QgsVectorFieldSymbolLayer::setSubSymbol( QgsSymbol *symbol )
     121                 :            : {
     122                 :          0 :   if ( symbol->type() == QgsSymbol::Line )
     123                 :            :   {
     124                 :          0 :     mLineSymbol.reset( static_cast<QgsLineSymbol *>( symbol ) );
     125                 :          0 :     return true;
     126                 :          0 :   }
     127                 :          0 :   return false;
     128                 :          0 : }
     129                 :          0 : 
     130                 :          0 : void QgsVectorFieldSymbolLayer::renderPoint( QPointF point, QgsSymbolRenderContext &context )
     131                 :          0 : {
     132                 :          0 :   if ( !mLineSymbol )
     133                 :            :   {
     134                 :          0 :     return;
     135                 :            :   }
     136                 :          0 : 
     137                 :          0 :   const QgsRenderContext &ctx = context.renderContext();
     138                 :            : 
     139                 :          0 :   if ( !context.feature() )
     140                 :            :   {
     141                 :            :     //preview
     142                 :          0 :     QPolygonF line;
     143                 :          0 :     line << QPointF( 0, 50 );
     144                 :          0 :     line << QPointF( 100, 50 );
     145                 :          0 :     mLineSymbol->renderPolyline( line, nullptr, context.renderContext() );
     146                 :            :     return;
     147                 :          0 :   }
     148                 :            : 
     149                 :          0 :   const QgsFeature f( *context.feature() );
     150                 :            : 
     151                 :          0 :   double xComponent = 0;
     152                 :          0 :   double yComponent = 0;
     153                 :            : 
     154                 :          0 :   double xVal = 0;
     155                 :          0 :   if ( mXIndex != -1 )
     156                 :            :   {
     157                 :          0 :     xVal = f.attribute( mXIndex ).toDouble();
     158                 :          0 :   }
     159                 :          0 :   double yVal = 0;
     160                 :          0 :   if ( mYIndex != -1 )
     161                 :            :   {
     162                 :          0 :     yVal = f.attribute( mYIndex ).toDouble();
     163                 :          0 :   }
     164                 :            : 
     165                 :          0 :   const QgsMapToPixel &m2p = ctx.mapToPixel();
     166                 :          0 :   const double mapRotation = m2p.mapRotation();
     167                 :            : 
     168                 :          0 :   QPolygonF line;
     169                 :          0 :   line << point;
     170                 :            : 
     171                 :          0 :   QPointF destPoint;
     172                 :          0 :   switch ( mVectorFieldType )
     173                 :            :   {
     174                 :            :     case Cartesian:
     175                 :            :     {
     176                 :          0 :       destPoint = QPointF( point.x() + mScale * ctx.convertToPainterUnits( xVal, mDistanceUnit, mDistanceMapUnitScale ),
     177                 :          0 :                            point.y() - mScale * ctx.convertToPainterUnits( yVal, mDistanceUnit, mDistanceMapUnitScale ) );
     178                 :          0 :       break;
     179                 :            :     }
     180                 :            : 
     181                 :            :     case Polar:
     182                 :            :     {
     183                 :          0 :       convertPolarToCartesian( xVal, yVal, xComponent, yComponent );
     184                 :          0 :       destPoint = QPointF( point.x() + mScale * ctx.convertToPainterUnits( xComponent, mDistanceUnit, mDistanceMapUnitScale ),
     185                 :          0 :                            point.y() - mScale * ctx.convertToPainterUnits( yComponent, mDistanceUnit, mDistanceMapUnitScale ) );
     186                 :          0 :       break;
     187                 :            :     }
     188                 :            : 
     189                 :            :     case Height:
     190                 :            :     {
     191                 :          0 :       destPoint = QPointF( point.x(), point.y() - ( mScale * ctx.convertToPainterUnits( yVal, mDistanceUnit, mDistanceMapUnitScale ) ) );
     192                 :          0 :       break;
     193                 :            :     }
     194                 :            :   }
     195                 :            : 
     196                 :          0 :   if ( !qgsDoubleNear( mapRotation, 0.0 ) && mVectorFieldType != Height )
     197                 :            :   {
     198                 :          0 :     const double radians = mapRotation * M_PI / 180.0;
     199                 :          0 :     destPoint = QPointF( cos( radians ) * ( destPoint.x() - point.x() ) - sin( radians ) * ( destPoint.y() - point.y() ) + point.x(),
     200                 :          0 :                          sin( radians ) * ( destPoint.x() - point.x() ) + cos( radians ) * ( destPoint.y() - point.y() ) + point.y() );
     201                 :          0 :   }
     202                 :            : 
     203                 :          0 :   line << destPoint;
     204                 :          0 :   mLineSymbol->renderPolyline( line, &f, context.renderContext() );
     205                 :          0 : }
     206                 :            : 
     207                 :          0 : void QgsVectorFieldSymbolLayer::startRender( QgsSymbolRenderContext &context )
     208                 :            : {
     209                 :          0 :   if ( mLineSymbol )
     210                 :            :   {
     211                 :          0 :     mLineSymbol->startRender( context.renderContext(), context.fields() );
     212                 :          0 :   }
     213                 :            : 
     214                 :          0 :   QgsFields fields = context.fields();
     215                 :          0 :   if ( !fields.isEmpty() )
     216                 :            :   {
     217                 :          0 :     mXIndex = fields.lookupField( mXAttribute );
     218                 :          0 :     mYIndex = fields.lookupField( mYAttribute );
     219                 :          0 :   }
     220                 :            :   else
     221                 :            :   {
     222                 :          0 :     mXIndex = -1;
     223                 :          0 :     mYIndex = -1;
     224                 :            :   }
     225                 :          0 : }
     226                 :            : 
     227                 :          0 : void QgsVectorFieldSymbolLayer::stopRender( QgsSymbolRenderContext &context )
     228                 :            : {
     229                 :          0 :   if ( mLineSymbol )
     230                 :            :   {
     231                 :          0 :     mLineSymbol->stopRender( context.renderContext() );
     232                 :          0 :   }
     233                 :          0 : }
     234                 :            : 
     235                 :          0 : QgsVectorFieldSymbolLayer *QgsVectorFieldSymbolLayer::clone() const
     236                 :            : {
     237                 :          0 :   QgsSymbolLayer *clonedLayer = QgsVectorFieldSymbolLayer::create( properties() );
     238                 :          0 :   if ( mLineSymbol )
     239                 :            :   {
     240                 :          0 :     clonedLayer->setSubSymbol( mLineSymbol->clone() );
     241                 :          0 :   }
     242                 :          0 :   return static_cast< QgsVectorFieldSymbolLayer * >( clonedLayer );
     243                 :          0 : }
     244                 :            : 
     245                 :          0 : QVariantMap QgsVectorFieldSymbolLayer::properties() const
     246                 :            : {
     247                 :          0 :   QVariantMap properties;
     248                 :          0 :   properties[QStringLiteral( "x_attribute" )] = mXAttribute;
     249                 :          0 :   properties[QStringLiteral( "y_attribute" )] = mYAttribute;
     250                 :          0 :   properties[QStringLiteral( "distance_unit" )] = QgsUnitTypes::encodeUnit( mDistanceUnit );
     251                 :          0 :   properties[QStringLiteral( "distance_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mDistanceMapUnitScale );
     252                 :          0 :   properties[QStringLiteral( "scale" )] = QString::number( mScale );
     253                 :          0 :   properties[QStringLiteral( "vector_field_type" )] = QString::number( mVectorFieldType );
     254                 :          0 :   properties[QStringLiteral( "angle_orientation" )] = QString::number( mAngleOrientation );
     255                 :          0 :   properties[QStringLiteral( "angle_units" )] = QString::number( mAngleUnits );
     256                 :          0 :   properties[QStringLiteral( "size" )] = QString::number( mSize );
     257                 :          0 :   properties[QStringLiteral( "size_unit" )] = QgsUnitTypes::encodeUnit( mSizeUnit );
     258                 :          0 :   properties[QStringLiteral( "size_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mSizeMapUnitScale );
     259                 :          0 :   properties[QStringLiteral( "offset" )] = QgsSymbolLayerUtils::encodePoint( mOffset );
     260                 :          0 :   properties[QStringLiteral( "offset_unit" )] = QgsUnitTypes::encodeUnit( mOffsetUnit );
     261                 :          0 :   properties[QStringLiteral( "offset_map_unit_scale" )] = QgsSymbolLayerUtils::encodeMapUnitScale( mOffsetMapUnitScale );
     262                 :          0 :   return properties;
     263                 :          0 : }
     264                 :            : 
     265                 :          0 : bool QgsVectorFieldSymbolLayer::usesMapUnits() const
     266                 :            : {
     267                 :          0 :   return mDistanceUnit == QgsUnitTypes::RenderMapUnits || mDistanceUnit == QgsUnitTypes::RenderMetersInMapUnits
     268                 :          0 :          || mOffsetUnit == QgsUnitTypes::RenderMapUnits || mOffsetUnit == QgsUnitTypes::RenderMetersInMapUnits
     269                 :          0 :          || mSizeUnit == QgsUnitTypes::RenderMapUnits || mSizeUnit == QgsUnitTypes::RenderMetersInMapUnits;
     270                 :            : }
     271                 :            : 
     272                 :          0 : void QgsVectorFieldSymbolLayer::toSld( QDomDocument &doc, QDomElement &element, const QVariantMap &props ) const
     273                 :            : {
     274                 :          0 :   element.appendChild( doc.createComment( QStringLiteral( "VectorField not implemented yet..." ) ) );
     275                 :          0 :   mLineSymbol->toSld( doc, element, props );
     276                 :          0 : }
     277                 :            : 
     278                 :          0 : QgsSymbolLayer *QgsVectorFieldSymbolLayer::createFromSld( QDomElement &element )
     279                 :            : {
     280                 :          0 :   Q_UNUSED( element )
     281                 :          0 :   return nullptr;
     282                 :            : }
     283                 :            : 
     284                 :          0 : void QgsVectorFieldSymbolLayer::drawPreviewIcon( QgsSymbolRenderContext &context, QSize size )
     285                 :            : {
     286                 :          0 :   if ( mLineSymbol )
     287                 :            :   {
     288                 :          0 :     mLineSymbol->drawPreviewIcon( context.renderContext().painter(), size );
     289                 :          0 :   }
     290                 :          0 : }
     291                 :            : 
     292                 :          0 : QSet<QString> QgsVectorFieldSymbolLayer::usedAttributes( const QgsRenderContext &context ) const
     293                 :            : {
     294                 :          0 :   QSet<QString> attributes = QgsMarkerSymbolLayer::usedAttributes( context );
     295                 :          0 :   if ( !mXAttribute.isEmpty() )
     296                 :            :   {
     297                 :          0 :     attributes.insert( mXAttribute );
     298                 :          0 :   }
     299                 :          0 :   if ( !mYAttribute.isEmpty() )
     300                 :            :   {
     301                 :          0 :     attributes.insert( mYAttribute );
     302                 :          0 :   }
     303                 :          0 :   if ( mLineSymbol )
     304                 :            :   {
     305                 :          0 :     attributes.unite( mLineSymbol->usedAttributes( context ) );
     306                 :          0 :   }
     307                 :          0 :   return attributes;
     308                 :          0 : }
     309                 :            : 
     310                 :          0 : bool QgsVectorFieldSymbolLayer::hasDataDefinedProperties() const
     311                 :            : {
     312                 :          0 :   if ( QgsSymbolLayer::hasDataDefinedProperties() )
     313                 :          0 :     return true;
     314                 :          0 :   if ( mLineSymbol && mLineSymbol->hasDataDefinedProperties() )
     315                 :          0 :     return true;
     316                 :          0 :   return false;
     317                 :          0 : }
     318                 :            : 
     319                 :          0 : void QgsVectorFieldSymbolLayer::convertPolarToCartesian( double length, double angle, double &x, double &y ) const
     320                 :            : {
     321                 :            :   //convert angle to degree and to north orientation
     322                 :          0 :   if ( mAngleOrientation == CounterclockwiseFromEast )
     323                 :            :   {
     324                 :          0 :     if ( angle <= 90 )
     325                 :            :     {
     326                 :          0 :       angle = 90 - angle;
     327                 :          0 :     }
     328                 :            :     else
     329                 :            :     {
     330                 :          0 :       angle = 360 - angle + 90;
     331                 :            :     }
     332                 :          0 :   }
     333                 :            : 
     334                 :          0 :   if ( mAngleUnits == Degrees )
     335                 :            :   {
     336                 :          0 :     angle = angle * M_PI / 180.0;
     337                 :          0 :   }
     338                 :            : 
     339                 :          0 :   x = length * std::sin( angle );
     340                 :          0 :   y = length * std::cos( angle );
     341                 :          0 : }
     342                 :            : 
     343                 :          0 : void QgsVectorFieldSymbolLayer::setColor( const QColor &color )
     344                 :            : {
     345                 :          0 :   if ( mLineSymbol )
     346                 :          0 :     mLineSymbol->setColor( color );
     347                 :            : 
     348                 :          0 :   mColor = color;
     349                 :          0 : }
     350                 :            : 
     351                 :          0 : QColor QgsVectorFieldSymbolLayer::color() const
     352                 :            : {
     353                 :          0 :   return mLineSymbol ? mLineSymbol->color() : mColor;
     354                 :            : }
     355                 :            : 
     356                 :            : 

Generated by: LCOV version 1.14