63#define strcasecmp( a, b ) stricmp( a, b ) 
   75  mMapSettings = settings;
 
 
   91  mLayerNameAttribute.clear();
 
   92  mLayerOverriddenName.clear();
 
   94  mLayerList.reserve( layers.size() );
 
   95  for ( 
const DxfLayer &dxfLayer : layers )
 
   97    mLayerList << dxfLayer.layer();
 
   98    if ( dxfLayer.layerOutputAttributeIndex() >= 0 )
 
  100      mLayerNameAttribute.insert( dxfLayer.layer()->id(), dxfLayer.layerOutputAttributeIndex() );
 
  102    if ( dxfLayer.buildDataDefinedBlocks() )
 
  104      mLayerDDBlockMaxNumberOfClasses.insert( dxfLayer.layer()->id(), dxfLayer.dataDefinedBlocksMaximumNumberOfClasses() );
 
  106    if ( dxfLayer.overriddenName() != QString() )
 
  108      mLayerOverriddenName.insert( dxfLayer.layer()->id(), dxfLayer.overriddenName() );
 
 
  141  if ( !mForce2d && p.
is3D() && std::isfinite( p.
z() ) )
 
 
  148  int minDist = std::numeric_limits<int>::max();
 
  150  for ( 
int i = 1; i < static_cast< int >( 
sizeof( sDxfColors ) / 
sizeof( *sDxfColors ) ) && minDist > 0; ++i )
 
  152    int dist = color_distance( color.rgba(), i );
 
  153    if ( dist >= minDist )
 
  160  if ( minDist == 0 && minDistAt != 7 )
 
  164    if ( color.alpha() == 255 )
 
  168  int c = ( color.red() & 0xff ) * 0x10000 + ( color.green() & 0xff ) * 0x100 + ( color.blue() & 0xff );
 
  170  if ( transparencyCode != -1 && color.alpha() < 255 )
 
  171    writeGroup( transparencyCode, 0x2000000 | color.alpha() );
 
 
  176  mTextStream << QStringLiteral( 
"%1\n" ).arg( code, 3, 10, QChar( 
' ' ) );
 
 
  181  mTextStream << QStringLiteral( 
"%1\n" ).arg( i, 6, 10, QChar( 
' ' ) );
 
 
  187  if ( !s.contains( 
'.' ) )
 
  188    s += QLatin1String( 
".0" );
 
  189  mTextStream << s << 
'\n';
 
 
  194  mTextStream << s << 
'\n';
 
 
  204  if ( !d->isOpen() && !d->open( QIODevice::WriteOnly | QIODevice::Truncate ) )
 
  209  mTextStream.setDevice( d );
 
  210#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
  211  mTextStream.setCodec( encoding.toLocal8Bit() );
 
  213  mTextStream.setEncoding( QStringConverter::encodingForName( encoding.toLocal8Bit() ).value_or( QStringConverter::Utf8 ) );
 
  222    for ( 
QgsMapLayer *ml : std::as_const( mLayerList ) )
 
  256  QList<QgsMapLayer *> layers;
 
  257  QStringList skippedLayers;
 
  258  for ( 
QgsMapLayer *ml : std::as_const( mLayerList ) )
 
  281      skippedLayers << ml->name();
 
  300  if ( !skippedLayers.isEmpty() )
 
  302    mFeedbackMessage = QObject::tr( 
"The following empty layers were skipped: %1" ).arg( skippedLayers.join( QLatin1String( 
", " ) ) );
 
 
  313void QgsDxfExport::writeHeader( 
const QString &codepage )
 
  315  writeGroup( 999, QStringLiteral( 
"DXF created from QGIS" ) );
 
  321  writeGroup( 9, QStringLiteral( 
"$ACADVER" ) );
 
  333  writeGroup( 9, QStringLiteral( 
"$LTSCALE" ) );
 
  345  writeGroup( 9, QStringLiteral( 
"$PSLTSCALE" ) );
 
  348  writeGroup( 9, QStringLiteral( 
"$HANDSEED" ) );
 
  351  writeGroup( 9, QStringLiteral( 
"$DWGCODEPAGE" ) );
 
  360    handle = mNextHandleId++;
 
  362  Q_ASSERT_X( handle < 
DXF_HANDMAX, 
"QgsDxfExport::writeHandle(int, int)", 
"DXF handle too large" );
 
  364  writeGroup( code, QString::number( handle, 16 ) );
 
 
  368void QgsDxfExport::writeTables()
 
  375  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
 
  376  switch ( mSymbologyExport )
 
  381      slList = symbolLayers( context );
 
  394  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  397  writeDefaultLinetypes();
 
  400  for ( 
const auto &symbolLayer : std::as_const( slList ) )
 
  402    writeSymbolLayerLinetype( symbolLayer.first );
 
  409  writeGroup( 2, QStringLiteral( 
"BLOCK_RECORD" ) );
 
  412  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  415  const QStringList blockStrings = QStringList() << QStringLiteral( 
"*Model_Space" ) << QStringLiteral( 
"*Paper_Space" ) << QStringLiteral( 
"*Paper_Space0" );
 
  416  for ( 
const QString &block : blockStrings )
 
  418    writeGroup( 0, QStringLiteral( 
"BLOCK_RECORD" ) );
 
  420    writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  421    writeGroup( 100, QStringLiteral( 
"AcDbBlockTableRecord" ) );
 
  426  for ( 
const auto &symbolLayer : std::as_const( slList ) )
 
  432    if ( hasBlockBreakingDataDefinedProperties( ml, symbolLayer.second ) )
 
  435      if ( !mDataDefinedBlockInfo.contains( ml ) )
 
  440      const QHash <uint, DataDefinedBlockInfo> &symbolClasses = mDataDefinedBlockInfo[ml];
 
  441      for ( 
const auto &blockInfo : symbolClasses )
 
  443        writeSymbolTableBlockRef( blockInfo.blockName );
 
  450    QString name = QStringLiteral( 
"symbolLayer%1" ).arg( i++ );
 
  451    writeSymbolTableBlockRef( name );
 
  460  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  464  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  465  writeGroup( 100, QStringLiteral( 
"AcDbRegAppTableRecord" ) );
 
  474  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  482  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  490  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  494  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  495  writeGroup( 100, QStringLiteral( 
"AcDbViewportTableRecord" ) );
 
  534  writeGroup( 2, QStringLiteral( 
"DIMSTYLE" ) );
 
  536  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  537  writeGroup( 100, QStringLiteral( 
"AcDbDimStyleTable" ) );
 
  541  QSet<QString> layerNames;
 
  542  const QList< QgsMapLayer * > layers = mMapSettings.
layers();
 
  545    if ( !layerIsScaleBasedVisible( ml ) )
 
  552    int attrIdx = mLayerNameAttribute.value( vl->
id(), -1 );
 
  559      const QSet<QVariant> values = vl->
uniqueValues( attrIdx );
 
  560      for ( 
const QVariant &v : values )
 
  572  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  577  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  578  writeGroup( 100, QStringLiteral( 
"AcDbLayerTableRecord" ) );
 
  582  writeGroup( 6, QStringLiteral( 
"CONTINUOUS" ) );
 
  585  for ( 
const QString &
layerName : std::as_const( layerNames ) )
 
  589    writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  590    writeGroup( 100, QStringLiteral( 
"AcDbLayerTableRecord" ) );
 
  594    writeGroup( 6, QStringLiteral( 
"CONTINUOUS" ) );
 
  603  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTable" ) );
 
  609  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  610  writeGroup( 100, QStringLiteral( 
"AcDbTextStyleTableRecord" ) );
 
  611  writeGroup( 2, QStringLiteral( 
"STANDARD" ) );
 
  618  writeGroup( 3, QStringLiteral( 
"romans.shx" ) );
 
  626void QgsDxfExport::writeSymbolTableBlockRef( 
const QString &blockName )
 
  628  writeGroup( 0, QStringLiteral( 
"BLOCK_RECORD" ) );
 
  630  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
  631  writeGroup( 100, QStringLiteral( 
"AcDbBlockTableRecord" ) );
 
  635void QgsDxfExport::writeBlocks()
 
  640  static const QStringList blockStrings = QStringList() << QStringLiteral( 
"*Model_Space" ) << QStringLiteral( 
"*Paper_Space" ) << QStringLiteral( 
"*Paper_Space0" );
 
  641  for ( 
const QString &block : blockStrings )
 
  645    writeGroup( 330, QString::number( mBlockHandles[ block ], 16 ) );
 
  646    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
  648    writeGroup( 100, QStringLiteral( 
"AcDbBlockBegin" ) );
 
  656    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
  658    writeGroup( 100, QStringLiteral( 
"AcDbBlockEnd" ) );
 
  664  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
 
  665  switch ( mSymbologyExport )
 
  670      slList = symbolLayers( ct );
 
  677  for ( 
const auto &symbolLayer : std::as_const( slList ) )
 
  687    if ( hasBlockBreakingDataDefinedProperties( ml, symbolLayer.second ) )
 
  689      if ( !mDataDefinedBlockInfo.contains( ml ) )
 
  695      const QHash <uint, DataDefinedBlockInfo> &symbolClasses = mDataDefinedBlockInfo[ml];
 
  696      for ( 
const auto &blockInfo : symbolClasses )
 
  698        ctx.setFeature( &blockInfo.feature );
 
  699        ctx.renderContext().expressionContext().setFeature( blockInfo.feature );
 
  700        writeSymbolLayerBlock( blockInfo.blockName, ml, ctx );
 
  707    QString block( QStringLiteral( 
"symbolLayer%1" ).arg( mBlockCounter++ ) );
 
  708    writeSymbolLayerBlock( block, ml, ctx );
 
  710    mPointSymbolBlocks.insert( ml, block );
 
  711    mPointSymbolBlockSizes.insert( ml, ml->
dxfSize( *
this, ctx ) );
 
  712    mPointSymbolBlockAngles.insert( ml, ml->
dxfAngle( ctx ) );
 
  719  mBlockHandle = QString::number( mBlockHandles[ blockName ], 16 );
 
  723  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
  725  writeGroup( 100, QStringLiteral( 
"AcDbBlockBegin" ) );
 
  743  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
  745  writeGroup( 100, QStringLiteral( 
"AcDbBlockEnd" ) );
 
  748void QgsDxfExport::writeEntities()
 
  751  writeGroup( 2, QStringLiteral( 
"ENTITIES" ) );
 
  753  mBlockHandle = QString::number( mBlockHandles[ QStringLiteral( 
"*Model_Space" )], 16 );
 
  762         job->renderer->usingSymbolLevels() )
 
  764      writeEntitiesSymbolLevels( job );
 
  786      QString lName( 
dxfLayerName( job->splitLayerAttribute.isNull() ? job->layerDerivedName : fet.attribute( job->splitLayerAttribute ).toString() ) );
 
  788      sctx.setFeature( &fet );
 
  790      if ( !job->renderer->willRenderFeature( fet, mRenderContext ) )
 
  795        addFeature( sctx, ct, lName, 
nullptr, 
nullptr ); 
 
  799        const QgsSymbolList symbolList = job->renderer->symbolsForFeature( fet, mRenderContext );
 
  800        bool hasSymbology = symbolList.size() > 0;
 
  812              bool isGeometryGenerator = ( symbolLayer->layerType() == QLatin1String( 
"GeometryGenerator" ) );
 
  813              if ( isGeometryGenerator )
 
  815                addGeometryGeneratorSymbolLayer( sctx, ct, lName, symbolLayer, 
true );
 
  819                addFeature( sctx, ct, lName, symbolLayer, symbol );
 
  824        else if ( hasSymbology )
 
  835            addGeometryGeneratorSymbolLayer( sctx, ct, lName, s->
symbolLayer( 0 ), 
false );
 
  839            addFeature( sctx, ct, lName, s->
symbolLayer( 0 ), s );
 
  843        if ( job->labelProvider )
 
  845          job->labelProvider->registerFeature( fet, mRenderContext );
 
  850        else if ( job->ruleBasedLabelProvider )
 
  852          job->ruleBasedLabelProvider->registerFeature( fet, mRenderContext );
 
  861  QImage image( 10, 10, QImage::Format_ARGB32_Premultiplied );
 
  862  image.setDotsPerMeterX( 96 / 25.4 * 1000 );
 
  863  image.setDotsPerMeterY( 96 / 25.4 * 1000 );
 
  864  QPainter painter( &image );
 
  872void QgsDxfExport::prepareRenderers()
 
  874  Q_ASSERT( mJobs.empty() ); 
 
  884                                std::floor( mMapSettings.
extent().
width() * mFactor ),
 
  885                                std::floor( mMapSettings.
extent().
height() * mFactor ), 0 ) );
 
  891  mLabelingEngine = std::make_unique<QgsDefaultLabelingEngine>();
 
  892  mLabelingEngine->setMapSettings( mMapSettings );
 
  895  const QList< QgsMapLayer * > layers = mMapSettings.
layers();
 
  905    if ( !layerIsScaleBasedVisible( vl ) )
 
  908    QString splitLayerAttribute;
 
  909    int splitLayerAttributeIndex = mLayerNameAttribute.value( vl->
id(), -1 );
 
  911    if ( splitLayerAttributeIndex >= 0 && splitLayerAttributeIndex < fields.
size() )
 
  912      splitLayerAttribute = fields.
at( splitLayerAttributeIndex ).
name();
 
  918void QgsDxfExport::writeEntitiesSymbolLevels( 
DxfLayerJob *job )
 
  920  QHash< QgsSymbol *, QList<QgsFeature> > features;
 
  938    QgsDebugError( QStringLiteral( 
"QgsDxfExport::writeEntitiesSymbolLevels(): extent reprojection failed" ) );
 
  954    featureSymbol = job->
renderer->symbolForFeature( fet, ctx );
 
  955    if ( !featureSymbol )
 
  960    QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
 
  961    if ( it == features.end() )
 
  963      it = features.insert( featureSymbol, QList<QgsFeature>() );
 
  965    it.value().append( fet );
 
  973    for ( 
int j = 0; j < symbol->symbolLayerCount(); j++ )
 
  975      int level = symbol->symbolLayer( j )->renderingPass();
 
  976      if ( level < 0 || level >= 1000 ) 
 
  979      while ( level >= levels.count() ) 
 
  981      levels[level].append( item );
 
  990      QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.symbol() );
 
  991      if ( levelIt == features.end() )
 
  996      int llayer = item.layer();
 
  997      const QList<QgsFeature> &featureList = levelIt.value();
 
  998      for ( 
const QgsFeature &feature : featureList )
 
 1000        sctx.setFeature( &feature );
 
 1001        addFeature( sctx, ct, job->
layerName, levelIt.key()->symbolLayer( llayer ), levelIt.key() );
 
 1007void QgsDxfExport::stopRenderers()
 
 1009  qDeleteAll( mJobs );
 
 1013void QgsDxfExport::writeEndFile()
 
 1020void QgsDxfExport::startSection()
 
 1022  writeGroup( 0, QStringLiteral( 
"SECTION" ) );
 
 1025void QgsDxfExport::endSection()
 
 1038                      msl->
sizeUnit(), mMapUnits ) / 2.0;
 
 1050  QHash< const QgsSymbolLayer *, QString >::const_iterator blockIt = mPointSymbolBlocks.constFind( symbolLayer );
 
 1051  if ( symbolLayer && blockIt != mPointSymbolBlocks.constEnd() )
 
 1053    writePointBlockReference( pt, symbolLayer, ctx, layer, angle, blockIt.value(), mPointSymbolBlockAngles.value( symbolLayer ), mPointSymbolBlockSizes.value( symbolLayer ) );
 
 1058  QHash< const QgsSymbolLayer *, QHash <uint, DataDefinedBlockInfo> >::const_iterator ddBlockIt = mDataDefinedBlockInfo.constFind( symbolLayer );
 
 1059  if ( symbolLayer && ctx.
feature() && ddBlockIt != mDataDefinedBlockInfo.constEnd() )
 
 1061    const QHash <uint, DataDefinedBlockInfo> &symbolLayerDDBlocks = ddBlockIt.value();
 
 1065    uint ddSymbolHash = dataDefinedSymbolClassHash( *( ctx.
feature() ), props );
 
 1066    if ( symbolLayerDDBlocks.contains( ddSymbolHash ) )
 
 1068      const DataDefinedBlockInfo &info = symbolLayerDDBlocks[ddSymbolHash];
 
 1069      writePointBlockReference( pt, symbolLayer, ctx, layer, angle, info.blockName, info.angle, info.size );
 
 1076  if ( msl && symbol )
 
 1086void QgsDxfExport::writePointBlockReference( 
const QgsPoint &pt, 
const QgsSymbolLayer *symbolLayer, 
QgsSymbolRenderContext &ctx, 
const QString &layer, 
double angle, 
const QString &blockName, 
double blockAngle, 
double blockSize )
 
 1088  const double scale = symbolLayer->
dxfSize( *
this, ctx ) / blockSize;
 
 1093  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1094  writeGroup( 100, QStringLiteral( 
"AcDbBlockReference" ) );
 
 1098  if ( std::isfinite( scale ) && scale != 1.0 )
 
 1114  std::sort( fields.begin(), fields.end() );
 
 1116  for ( 
const auto &field : std::as_const( fields ) ) 
 
 1118    QVariant attValue = fet.
attribute( field );
 
 1121      hashValue =  
qHash( attValue );
 
 1125      hashValue = hashValue ^ 
qHash( attValue );
 
 1135  int n = line.size();
 
 1138    QgsDebugError( QStringLiteral( 
"writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
 
 1144    QgsDebugError( QStringLiteral( 
"writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
 
 1148  if ( mForce2d || !line.at( 0 ).is3D() )
 
 1150    bool polygon = line[0] == line[ line.size() - 1 ];
 
 1154    writeGroup( 0, QStringLiteral( 
"LWPOLYLINE" ) );
 
 1157    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1158    writeGroup( 100, QStringLiteral( 
"AcDbPolyline" ) );
 
 1166    for ( 
int i = 0; i < n; i++ )
 
 1171    writeGroup( 0, QStringLiteral( 
"POLYLINE" ) );
 
 1174    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1178    writeGroup( 100, QStringLiteral( 
"AcDb3dPolyline" ) );
 
 1182    for ( 
int i = 0; i < n; i++ )
 
 1187      writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1190      writeGroup( 100, QStringLiteral( 
"AcDbVertex" ) );
 
 1191      writeGroup( 100, QStringLiteral( 
"AcDb3dPolylineVertex" ) );
 
 1199    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 
 1205void QgsDxfExport::appendCurve( 
const QgsCurve &
c, QVector<QgsPoint> &points, QVector<double> &bulges )
 
 1210      appendLineString( *
dynamic_cast<const QgsLineString *
>( &
c ), points, bulges );
 
 1214      appendCircularString( *
dynamic_cast<const QgsCircularString *
>( &
c ), points, bulges );
 
 1218      appendCompoundCurve( *
dynamic_cast<const QgsCompoundCurve *
>( &
c ), points, bulges );
 
 1222      QgsDebugError( QStringLiteral( 
"Unexpected curve type %1" ).arg( 
c.wktTypeStr() ) );
 
 1227void QgsDxfExport::appendLineString( 
const QgsLineString &ls, QVector<QgsPoint> &points, QVector<double> &bulges )
 
 1229  for ( 
int i = 0; i < ls.
numPoints(); i++ )
 
 1232    if ( !points.isEmpty() && points.last() == p )
 
 1240void QgsDxfExport::appendCircularString( 
const QgsCircularString &cs, QVector<QgsPoint> &points, QVector<double> &bulges )
 
 1242  for ( 
int i = 0; i < cs.
numPoints() - 2; i += 2 )
 
 1248    if ( points.isEmpty() || points.last() != p1 )
 
 1250    else if ( !bulges.isEmpty() )
 
 1251      bulges.removeLast();
 
 1253    double a = ( M_PI - ( p1 - p2 ).
angle() + ( p3 - p2 ).
angle() ) / 2.0;
 
 1254    bulges << sin( a ) / cos( a );
 
 1261void QgsDxfExport::appendCompoundCurve( 
const QgsCompoundCurve &cc, QVector<QgsPoint> &points, QVector<double> &bulges )
 
 1263  for ( 
int i = 0; i < cc.
nCurves(); i++ )
 
 1267    appendCurve( *
c, points, bulges );
 
 1276    QgsDebugError( QStringLiteral( 
"writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
 
 1282    QgsDebugError( QStringLiteral( 
"writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
 
 1286  QVector<QgsPoint> points;
 
 1287  QVector<double> bulges;
 
 1288  appendCurve( curve, points, bulges );
 
 1290  if ( mForce2d || !curve.
is3D() )
 
 1292    writeGroup( 0, QStringLiteral( 
"LWPOLYLINE" ) );
 
 1295    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1296    writeGroup( 100, QStringLiteral( 
"AcDbPolyline" ) );
 
 1311    writeGroup( 70, 
static_cast<int>( polylineFlags ) );
 
 1314    for ( 
int i = 0; i < points.size(); i++ )
 
 1317      if ( bulges[i] != 0.0 )
 
 1323    writeGroup( 0, QStringLiteral( 
"POLYLINE" ) );
 
 1326    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1330    writeGroup( 100, QStringLiteral( 
"AcDb3dPolyline" ) );
 
 1334    for ( 
int i = 0; i < points.size(); i++ )
 
 1339      writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1342      writeGroup( 100, QStringLiteral( 
"AcDbVertex" ) );
 
 1343      writeGroup( 100, QStringLiteral( 
"AcDb3dPolylineVertex" ) );
 
 1345      if ( bulges[i] != 0.0 )
 
 1353    writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 
 1364  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1367  writeGroup( 100, QStringLiteral( 
"AcDbHatch" ) );
 
 1373  writeGroup( 70, hatchPattern == QLatin1String( 
"SOLID" ) ); 
 
 1377  for ( 
int i = 0; i < polygon.size(); ++i )
 
 1384    for ( 
int j = 0; j < polygon[i].size(); ++j )
 
 
 1403  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1406  writeGroup( 100, QStringLiteral( 
"AcDbHatch" ) );
 
 1412  writeGroup( 70, hatchPattern == QLatin1String( 
"SOLID" ) ); 
 
 1415  QVector<QVector<QgsPoint>> points;
 
 1416  QVector<QVector<double>> bulges;
 
 1419  points.reserve( ringCount + 1 );
 
 1420  bulges.reserve( ringCount + 1 );
 
 1422  points << QVector<QgsPoint>();
 
 1423  bulges << QVector<double>();
 
 1424  appendCurve( *polygon.
exteriorRing(), points.last(), bulges.last() );
 
 1426  for ( 
int i = 0; i < ringCount; i++ )
 
 1428    points << QVector<QgsPoint>();
 
 1429    bulges << QVector<double>();
 
 1430    appendCurve( *polygon.
interiorRing( i ), points.last(), bulges.last() );
 
 1433  bool hasBulges = 
false;
 
 1434  for ( 
int i = 0; i < points.size() && !hasBulges; ++i )
 
 1435    for ( 
int j = 0; j < points[i].size() && !hasBulges; ++j )
 
 1436      hasBulges = bulges[i][j] != 0.0;
 
 1440  for ( 
int i = 0; i < points.size(); ++i )
 
 1447    for ( 
int j = 0; j < points[i].size(); ++j )
 
 
 1471  double lblX = label->
getX();
 
 1472  double lblY = label->
getY();
 
 1497    switch ( offsetQuad )
 
 1547      const QString haliString = exprVal.toString();
 
 1548      if ( haliString.compare( QLatin1String( 
"Center" ), Qt::CaseInsensitive ) == 0 )
 
 1552      else if ( haliString.compare( QLatin1String( 
"Right" ), Qt::CaseInsensitive ) == 0 )
 
 1566      const QString valiString = exprVal.toString();
 
 1567      if ( valiString.compare( QLatin1String( 
"Bottom" ), Qt::CaseInsensitive ) != 0 )
 
 1569        if ( valiString.compare( QLatin1String( 
"Base" ), Qt::CaseInsensitive ) == 0 )
 
 1573        else if ( valiString.compare( QLatin1String( 
"Half" ), Qt::CaseInsensitive ) == 0 )
 
 1592  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1593  writeGroup( 100, QStringLiteral( 
"AcDbPoint" ) );
 
 
 1604  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1607  writeGroup( 100, QStringLiteral( 
"AcDbHatch" ) );
 
 
 1638  writeGroup( 0, QStringLiteral( 
"LWPOLYLINE" ) );
 
 1642  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1643  writeGroup( 100, QStringLiteral( 
"AcDbPolyline" ) );
 
 
 1662  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1665  writeGroup( 100, QStringLiteral( 
"AcDbText" ) );
 
 1676  writeGroup( 7, QStringLiteral( 
"STANDARD" ) ); 
 
 1677  writeGroup( 100, QStringLiteral( 
"AcDbText" ) );
 
 
 1686#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 
 1687  if ( !mTextStream.codec()->canEncode( text ) )
 
 1690    QgsDebugError( QStringLiteral( 
"could not encode:%1" ).arg( text ) );
 
 1697  writeGroup( 100, QStringLiteral( 
"AcDbEntity" ) );
 
 1698  writeGroup( 100, QStringLiteral( 
"AcDbMText" ) );
 
 1705  while ( t.length() > 250 )
 
 1721  writeGroup( 7, QStringLiteral( 
"STANDARD" ) );  
 
 
 1736    geom.transform( ct );
 
 1745    penColor = colorFromSymbolLayer( symbolLayer, ctx );
 
 1749  Qt::PenStyle penStyle( Qt::SolidLine );
 
 1750  Qt::BrushStyle brushStyle( Qt::NoBrush );
 
 1752  double offset = 0.0;
 
 1756    width = symbolLayer->
dxfWidth( *
this, ctx );
 
 1757    offset = symbolLayer->
dxfOffset( *
this, ctx );
 
 1771  QString lineStyleName = QStringLiteral( 
"CONTINUOUS" );
 
 1774    lineStyleName = lineStyleFromSymbolLayer( symbolLayer );
 
 1780    writePoint( geom.constGet()->coordinateSequence().at( 0 ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol, angle );
 
 1787    for ( 
int i = 0; i < cs.size(); i++ )
 
 1789      writePoint( cs.at( i ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol, angle );
 
 1794  if ( penStyle != Qt::NoPen )
 
 1797    std::unique_ptr< QgsAbstractGeometry > tempGeom;
 
 1812            sourceGeom = tempGeom.get();
 
 1814            sourceGeom = geom.constGet();
 
 1820          writePolyline( *curve, layer, lineStyleName, penColor, width );
 
 1832              writePolyline( *curve, layer, lineStyleName, penColor, width );
 
 1849            sourceGeom = tempGeom.get();
 
 1851            sourceGeom = geom.constGet();
 
 1870              Q_ASSERT( polygon );
 
 1888  if ( brushStyle != Qt::NoBrush )
 
 1898        Q_ASSERT( polygon );
 
 1899        writePolygon( *polygon, layer, QStringLiteral( 
"SOLID" ), brushColor );
 
 1912          Q_ASSERT( polygon );
 
 1913          writePolygon( *polygon, layer, QStringLiteral( 
"SOLID" ), brushColor );
 
 1930  return symbolLayer->
dxfColor( ctx );
 
 1933QString QgsDxfExport::lineStyleFromSymbolLayer( 
const QgsSymbolLayer *symbolLayer )
 
 1935  QString lineStyleName = QStringLiteral( 
"CONTINUOUS" );
 
 1938    return lineStyleName;
 
 1941  QHash< const QgsSymbolLayer *, QString >::const_iterator lineTypeIt = mLineStyles.constFind( symbolLayer );
 
 1942  if ( lineTypeIt != mLineStyles.constEnd() )
 
 1944    lineStyleName = lineTypeIt.value();
 
 1945    return lineStyleName;
 
 1949    return lineNameFromPenStyle( symbolLayer->
dxfPenStyle() );
 
 1956  int current_distance = std::numeric_limits<int>::max();
 
 1957  for ( 
int i = 1; i < static_cast< int >( 
sizeof( sDxfColors ) / 
sizeof( *sDxfColors ) ); ++i )
 
 1959    int dist = color_distance( pixel, i );
 
 1960    if ( dist < current_distance )
 
 1962      current_distance = dist;
 
 
 1971int QgsDxfExport::color_distance( QRgb p1, 
int index )
 
 1973  if ( index > 255 || index < 0 )
 
 1978  double redDiff = qRed( p1 ) - sDxfColors[index][0];
 
 1979  double greenDiff = qGreen( p1 ) - sDxfColors[index][1];
 
 1980  double blueDiff = qBlue( p1 ) - sDxfColors[index][2];
 
 1982  QgsDebugMsgLevel( QStringLiteral( 
"color_distance( r:%1 g:%2 b:%3 <=> i:%4 r:%5 g:%6 b:%7 ) => %8" )
 
 1983                    .arg( qRed( p1 ) ).arg( qGreen( p1 ) ).arg( qBlue( p1 ) )
 
 1985                    .arg( mDxfColors[index][0] )
 
 1986                    .arg( mDxfColors[index][1] )
 
 1987                    .arg( mDxfColors[index][2] )
 
 1988                    .arg( redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff ), 2 );
 
 1990  return redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff;
 
 1993QRgb QgsDxfExport::createRgbEntry( qreal r, qreal g, qreal b )
 
 1995  return QColor::fromRgbF( r, g, b ).rgb();
 
 2000  return mRenderContext;
 
 2015    return mapUnitsPerPixel;
 
 
 2029  double minSizeMU = std::numeric_limits<double>::lowest();
 
 2032    minSizeMU = scale.
minSizeMM * pixelToMMFactor * mapUnitsPerPixel;
 
 2036    minSizeMU = std::max( minSizeMU, value );
 
 2038  value = std::max( value, minSizeMU );
 
 2040  double maxSizeMU = std::numeric_limits<double>::max();
 
 2043    maxSizeMU = scale.
maxSizeMM * pixelToMMFactor * mapUnitsPerPixel;
 
 2047    maxSizeMU = std::min( maxSizeMU, value );
 
 2049  value = std::min( value, maxSizeMU );
 
 
 2052QList< QPair< QgsSymbolLayer *, QgsSymbol * > > QgsDxfExport::symbolLayers( 
QgsRenderContext &context )
 
 2054  QList< QPair< QgsSymbolLayer *, QgsSymbol * > > symbolLayers;
 
 2065        maxSymbolLayers = 1;
 
 2067      for ( 
int i = 0; i < maxSymbolLayers; ++i )
 
 2069        symbolLayers.append( qMakePair( symbol->
symbolLayer( i ), symbol ) );
 
 2074  return symbolLayers;
 
 2077void QgsDxfExport::writeDefaultLinetypes()
 
 2080  for ( 
const QString <ype : { QStringLiteral( 
"ByLayer" ), QStringLiteral( 
"ByBlock" ), QStringLiteral( 
"CONTINUOUS" ) } )
 
 2084    writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
 2085    writeGroup( 100, QStringLiteral( 
"AcDbLinetypeTableRecord" ) );
 
 2088    writeGroup( 3, QStringLiteral( 
"Defaultstyle" ) );
 
 2094  double das = dashSize();
 
 2095  double dss = dashSeparatorSize();
 
 2096  double dos = dotSize();
 
 2098  QVector<qreal> dashVector( 2 );
 
 2099  dashVector[0] = das;
 
 2100  dashVector[1] = dss;
 
 2103  QVector<qreal> dotVector( 2 );
 
 2108  QVector<qreal> dashDotVector( 4 );
 
 2109  dashDotVector[0] = das;
 
 2110  dashDotVector[1] = dss;
 
 2111  dashDotVector[2] = dos;
 
 2112  dashDotVector[3] = dss;
 
 2115  QVector<qreal> dashDotDotVector( 6 );
 
 2116  dashDotDotVector[0] = das;
 
 2117  dashDotDotVector[1] = dss;
 
 2118  dashDotDotVector[2] = dos;
 
 2119  dashDotDotVector[3] = dss;
 
 2120  dashDotDotVector[4] = dos;
 
 2121  dashDotDotVector[5] = dss;
 
 2125void QgsDxfExport::writeSymbolLayerLinetype( 
const QgsSymbolLayer *symbolLayer )
 
 2134  if ( !customLinestyle.isEmpty() )
 
 2136    QString name = QStringLiteral( 
"symbolLayer%1" ).arg( mSymbolLayerCounter++ );
 
 2137    writeLinetype( name, customLinestyle, unit );
 
 2138    mLineStyles.insert( symbolLayer, name );
 
 2142int QgsDxfExport::nLineTypes( 
const QList< QPair< QgsSymbolLayer *, QgsSymbol * > > &symbolLayers )
 
 2145  for ( 
const auto &symbolLayer : symbolLayers )
 
 2159void QgsDxfExport::writeLinetype( 
const QString &styleName, 
const QVector<qreal> &pattern, 
Qgis::RenderUnit u )
 
 2162  for ( qreal size : pattern )
 
 2170  writeGroup( 100, QStringLiteral( 
"AcDbSymbolTableRecord" ) );
 
 2171  writeGroup( 100, QStringLiteral( 
"AcDbLinetypeTableRecord" ) );
 
 2180  for ( qreal size : pattern )
 
 2183    double segmentLength = ( isGap ? -size : size );
 
 2209  geomExpr.prepare( &expressionContext );
 
 2217    symbolExpressionContextScope->
setFeature( f );
 
 2222    for ( 
int i = 0; i < nSymbolLayers; ++i )
 
 2224      addFeature( ctx, ct, layer, symbol->
symbolLayer( i ), symbol );
 
 2233  if ( !sl || !symbol )
 
 2238  bool blockBreak = 
false;
 
 2245    blockBreak = !properties.isEmpty();
 
 2251double QgsDxfExport::dashSize()
 const 
 2253  double size = mSymbologyScale * 0.002;
 
 2254  return sizeToMapUnits( size );
 
 2257double QgsDxfExport::dotSize()
 const 
 2259  double size = mSymbologyScale * 0.0006;
 
 2260  return sizeToMapUnits( size );
 
 2263double QgsDxfExport::dashSeparatorSize()
 const 
 2265  double size = mSymbologyScale * 0.0006;
 
 2266  return sizeToMapUnits( size );
 
 2269double QgsDxfExport::sizeToMapUnits( 
double s )
 const 
 2275QString QgsDxfExport::lineNameFromPenStyle( Qt::PenStyle style )
 
 2280      return QStringLiteral( 
"DASH" );
 
 2282      return QStringLiteral( 
"DOT" );
 
 2283    case Qt::DashDotLine:
 
 2284      return QStringLiteral( 
"DASHDOT" );
 
 2285    case Qt::DashDotDotLine:
 
 2286      return QStringLiteral( 
"DASHDOTDOT" );
 
 2289      return QStringLiteral( 
"CONTINUOUS" );
 
 2295  if ( name.isEmpty() )
 
 2296    return QStringLiteral( 
"0" );
 
 2321  layerName.replace( QLatin1String( 
"\r\n" ), QLatin1String( 
"_" ) );
 
 
 2328bool QgsDxfExport::layerIsScaleBasedVisible( 
const QgsMapLayer *layer )
 const 
 2342  for ( 
QgsMapLayer *ml : std::as_const( mLayerList ) )
 
 2345    if ( vl && vl->
id() == 
id )
 
 2347      int attrIdx = mLayerNameAttribute.value( vl->
id(), -1 );
 
 2352  return QStringLiteral( 
"0" );
 
 
 2357  const QByteArray codec = name.toLocal8Bit();
 
 2358  if ( QTextCodec::codecForName( codec ) )
 
 2361    for ( i = 0; i < static_cast< int >( 
sizeof( DXF_ENCODINGS ) / 
sizeof( *DXF_ENCODINGS ) ) && strcasecmp( codec.data(), DXF_ENCODINGS[i][1] ) != 0; ++i )
 
 2364    if ( i != 
static_cast< int >( 
sizeof( DXF_ENCODINGS ) / 
sizeof( *DXF_ENCODINGS ) ) )
 
 2366      return DXF_ENCODINGS[i][0];
 
 
 2376  const QList< QByteArray > codecs = QTextCodec::availableCodecs();
 
 2378  for ( 
const QByteArray &codec : codecs )
 
 2381    for ( i = 0; i < static_cast< int >( 
sizeof( DXF_ENCODINGS ) / 
sizeof( *DXF_ENCODINGS ) ) && strcasecmp( codec.data(), DXF_ENCODINGS[i][1] ) != 0; ++i )
 
 2384    if ( i < 
static_cast< int >( 
sizeof( DXF_ENCODINGS ) / 
sizeof( *DXF_ENCODINGS ) ) )
 
 
 2396  if ( !mLayerOverriddenName.value( vl->
id(), QString() ).isEmpty() )
 
 2398    return mLayerOverriddenName.value( vl->
id() );
 
 
 2425  const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->
dataDefinedValues();
 
 2430  QgsDebugMsgLevel( QStringLiteral( 
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
 
 2460  QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
 
 2463  QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
 
 2466  QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
 
 2472  QString dxfLayer = mDxfLayerNames[layerId][fid];
 
 2474  QString wrapchr = tmpLyr.
wrapChar.isEmpty() ? QStringLiteral( 
"\n" ) : tmpLyr.
wrapChar;
 
 2479    bool prependSymb = 
false;
 
 2497        prependSymb = 
false;
 
 2506        symb = symb + wrapchr;
 
 2510        prependSymb = 
false;
 
 2511        symb = wrapchr + symb;
 
 2520      txt.prepend( symb );
 
 2530    txt.replace( QChar( QChar::LineFeed ), 
' ' );
 
 2531    txt.replace( QChar( QChar::CarriageReturn ), 
' ' );
 
 2536    txt.replace( QString( QChar( QChar::CarriageReturn ) ) + QString( QChar( QChar::LineFeed ) ), QStringLiteral( 
"\\P" ) );
 
 2537    txt.replace( QChar( QChar::CarriageReturn ), QStringLiteral( 
"\\P" ) );
 
 2538    txt = txt.replace( wrapchr, QLatin1String( 
"\\P" ) );
 
 2539    txt.replace( QLatin1String( 
" " ), QLatin1String( 
"\\~" ) );
 
 2543      txt.prepend( 
"\\L" ).append( 
"\\l" );
 
 2548      txt.prepend( 
"\\O" ).append( 
"\\o" );
 
 2553      txt.prepend( 
"\\K" ).append( 
"\\k" );
 
 2556    txt.prepend( QStringLiteral( 
"\\f%1|i%2|b%3;\\H%4;" )
 
 2558                 .arg( tmpLyr.
format().
font().italic() ? 1 : 0 )
 
 2559                 .arg( tmpLyr.
format().
font().bold() ? 1 : 0 )
 
 2560                 .arg( label->
getHeight() / ( 1 + txt.count( QStringLiteral( 
"\\P" ) ) ) * 0.75 ) );
 
 
 2568  if ( !mDxfLayerNames.contains( layerId ) )
 
 2569    mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
 
 2571  mDxfLayerNames[layerId][fid] = 
layerName;
 
 
 2587  QString splitLayerFieldName;
 
 2589  if ( mLayerOutputAttributeIndex >= 0 && mLayerOutputAttributeIndex < fields.
size() )
 
 2591    splitLayerFieldName = fields.
at( mLayerOutputAttributeIndex ).
name();
 
 2594  return splitLayerFieldName;
 
 
 2597void QgsDxfExport::createDDBlockInfo()
 
 2599  int symbolLayerNr = 0;
 
 2602    int ddMaxNumberOfClasses = -1;
 
 2603    bool createDDBlocks = mLayerDDBlockMaxNumberOfClasses.contains( job->
featureSource.
id() );
 
 2604    if ( createDDBlocks )
 
 2606      ddMaxNumberOfClasses = mLayerDDBlockMaxNumberOfClasses[job->
featureSource.
id()];
 
 2615    for ( 
const QgsSymbol *symbol : symbols )
 
 2626        maxSymbolLayers = 1;
 
 2629      for ( 
int i = 0; i < maxSymbolLayers; ++i )
 
 2639        if ( !hasBlockBreakingDataDefinedProperties( sl, symbol ) || !createDDBlocks )
 
 2654        QHash <uint, QPair<int, DataDefinedBlockInfo> > blockSymbolMap; 
 
 2659          uint symbolHash = dataDefinedSymbolClassHash( fet, properties );
 
 2660          if ( blockSymbolMap.contains( symbolHash ) )
 
 2662            blockSymbolMap[symbolHash].first += 1;
 
 2666          sctx.setFeature( &fet );
 
 2667          sctx.renderContext().expressionContext().setFeature( fet );
 
 2669          DataDefinedBlockInfo blockInfo;
 
 2670          blockInfo.blockName = QStringLiteral( 
"symbolLayer%1class%2" ).arg( symbolLayerNr ).arg( symbolHash );
 
 2671          blockInfo.angle = sl->
dxfAngle( sctx );
 
 2672          blockInfo.size = sl->
dxfSize( *
this, sctx );
 
 2673          blockInfo.feature = fet;
 
 2675          blockSymbolMap.insert( symbolHash, qMakePair( 1, blockInfo ) );
 
 2680        QMultiMap<int, uint> occurrences;
 
 2681        QHash <uint, QPair<int, DataDefinedBlockInfo> >::const_iterator blockSymbolIt = blockSymbolMap.constBegin();
 
 2682        for ( ; blockSymbolIt != blockSymbolMap.constEnd(); ++blockSymbolIt )
 
 2684          occurrences.insert( blockSymbolIt.value().first, blockSymbolIt.key() );
 
 2687        QHash <uint, DataDefinedBlockInfo > applyBlockSymbolMap;
 
 2688        int nInsertedClasses = 0;
 
 2689        QMultiMap<int, uint>::const_iterator occIt = occurrences.constEnd();
 
 2690        while ( occurrences.size() > 0 && occIt != occurrences.constBegin() )
 
 2693          applyBlockSymbolMap.insert( occIt.value(), blockSymbolMap[occIt.value()].second );
 
 2695          if ( ddMaxNumberOfClasses != -1 && nInsertedClasses >= ddMaxNumberOfClasses )
 
 2702        mDataDefinedBlockInfo.insert( sl, applyBlockSymbolMap );
 
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
 
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
 
DistanceUnit
Units of distance.
 
@ NoGeometry
Geometry is not required. It may still be returned if e.g. required for a filter condition.
 
LabelQuadrantPosition
Label quadrant positions.
 
@ Miter
Use mitered joins.
 
@ FollowPlacement
Alignment follows placement of label, e.g., labels to the left of a feature will be drawn with right ...
 
RenderUnit
Rendering size units.
 
@ Millimeters
Millimeters.
 
@ Flat
Flat cap (in line with start/end of line)
 
QFlags< SymbolRenderHint > SymbolRenderHints
Symbol render hints.
 
WkbType
The WKB type describes the number of dimensions a geometry has.
 
@ CompoundCurve
CompoundCurve.
 
@ MultiPolygon
MultiPolygon.
 
@ MultiLineString
MultiLineString.
 
@ CircularString
CircularString.
 
@ CurvePolygon
CurvePolygon.
 
@ MultiSurface
MultiSurface.
 
@ PerFeature
Keeps the number of features and export symbology per feature.
 
@ PerSymbolLayer
Exports one feature per symbol layer (considering symbol levels)
 
@ NoSymbology
Export only data.
 
@ Reverse
Reverse/inverse transform (from destination to source)
 
Abstract base class for all geometries.
 
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
 
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
 
Circular string geometry type.
 
int numPoints() const override
Returns the number of points in the curve.
 
QgsPoint pointN(int i) const
Returns the point at index i within the circular string.
 
Compound curve geometry type.
 
int nCurves() const
Returns the number of curves in the geometry.
 
const QgsCurve * curveAt(int i) const
Returns the curve at the specified index.
 
Represents a coordinate reference system (CRS).
 
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
 
Qgis::DistanceUnit mapUnits
 
Custom exception class for Coordinate Reference System related exceptions.
 
Curve polygon geometry type.
 
int numInteriorRings() const
Returns the number of interior rings contained with the curve polygon.
 
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
 
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
 
Abstract base class for curved geometry type.
 
QgsCoordinateSequence coordinateSequence() const override
Retrieves the sequence of geometries, rings and nodes.
 
virtual int numPoints() const =0
Returns the number of points in the curve.
 
virtual bool isClosed() const
Returns true if the curve is closed.
 
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
 
ExportResult
The result of an export as dxf operation.
 
@ DeviceNotWritableError
Device not writable error.
 
@ Success
Successful export.
 
@ EmptyExtentError
Empty extent, no extent given and no extent could be derived from layers.
 
@ InvalidDeviceError
Invalid device error.
 
void writeCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
 
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
 
ExportResult writeToFile(QIODevice *d, const QString &codec)
Export to a dxf file in the given encoding.
 
void writeLine(const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
 
void writeGroup(int code, int i)
Write a tuple of group code and integer value.
 
QString layerName(const QString &id, const QgsFeature &f) const
Gets layer name for feature.
 
void setFlags(QgsDxfExport::Flags flags)
Sets the export flags.
 
QgsRectangle extent() const
Gets extent of area to export.
 
@ FlagHairlineWidthExport
 
@ FlagOnlySelectedFeatures
Use only selected features for the export.
 
@ FlagNoMText
Export text as TEXT elements. If not set, text will be exported as MTEXT elements.
 
void writeInt(int i)
Write an integer value.
 
void writeMText(const QString &layer, const QString &text, const QgsPoint &pt, double width, double angle, const QColor &color)
Write mtext (MTEXT)
 
QgsDxfExport()
Constructor for QgsDxfExport.
 
int writeHandle(int code=5, int handle=0)
Write a tuple of group code and a handle.
 
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination CRS, or an invalid CRS if no reprojection will be done.
 
HAlign
Horizontal alignments.
 
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Set destination CRS.
 
void addLayers(const QList< QgsDxfExport::DxfLayer > &layers)
Add layers to export.
 
static QString dxfLayerName(const QString &name)
Returns cleaned layer name for use in DXF.
 
void writeDouble(double d)
Write a floating point value.
 
void writeText(const QString &layer, const QString &text, const QgsPoint &pt, double size, double angle, const QColor &color, QgsDxfExport::HAlign hali=QgsDxfExport::HAlign::Undefined, QgsDxfExport::VAlign vali=QgsDxfExport::VAlign::Undefined)
Write text (TEXT)
 
void writeString(const QString &s)
Write a string value.
 
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
 
QFlags< DxfPolylineFlag > DxfPolylineFlags
 
void drawLabel(const QString &layerId, QgsRenderContext &context, pal::LabelPosition *label, const QgsPalLayerSettings &settings) override
Add a label to the dxf output.
 
static QString dxfEncoding(const QString &name)
Returns DXF encoding for Qt encoding.
 
static int closestColorMatch(QRgb color)
Gets DXF palette index of nearest entry for given color.
 
void writePoint(const QString &layer, const QColor &color, const QgsPoint &pt)
Write point.
 
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
 
Q_DECL_DEPRECATED void registerDxfLayer(const QString &layerId, QgsFeatureId fid, const QString &layer)
Register name of layer for feature.
 
QgsDxfExport::Flags flags() const
Returns the export flags.
 
VAlign
Vertical alignments.
 
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
 
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
 
@ ContinuousPattern
The linetype pattern is generated continuously around the vertices of this polyline.
 
@ Closed
This is a closed polyline (or a polygon mesh closed in the M direction)
 
@ Curve
Curve-fit vertices have been added.
 
static QStringList encodings()
Returns list of available DXF encodings.
 
void setMapSettings(const QgsMapSettings &settings)
Set map settings and assign layer name attributes.
 
void writeGroupCode(int code)
Write a group code.
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the scope.
 
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
 
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
 
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
 
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
 
QList< QgsExpressionContextScope * > scopes()
Returns a list of scopes contained within the stack.
 
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
 
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
 
Handles parsing and evaluation of expressions (formerly called "search strings").
 
Wrapper for iterator of features from vector data provider or vector layer.
 
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
 
@ SymbolLevels
Rendering with symbol levels (i.e. implements symbols(), symbolForFeature())
 
Wraps a request for features to a vector layer (or directly its vector data provider).
 
QgsFeatureRequest & setFlags(Qgis::FeatureRequestFlags flags)
Sets flags that affect how features will be fetched.
 
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
 
QgsFeatureRequest & setFilterFids(const QgsFeatureIds &fids)
Sets the feature IDs that should be fetched.
 
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
 
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
 
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
 
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
 
bool hasGeometry() const
Returns true if the feature has an associated geometry.
 
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
 
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
 
Container of fields for a vector layer.
 
int size() const
Returns number of items.
 
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
 
int numGeometries() const
Returns the number of geometries within the collection.
 
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
 
A symbol layer subclass which alters rendered feature shapes through the use of QGIS expressions.
 
QString geometryExpression() const
Gets the expression to generate this geometry.
 
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
 
A geometry is the spatial representation of a feature.
 
Does vector analysis using the GEOS library and handles import, export, and exception handling.
 
Describes a feature that should be used within the labeling engine.
 
QgsPointXY anchorPosition() const
In case of quadrand or aligned positioning, this is set to the anchor point.
 
QString labelText() const
Text of the label.
 
bool reverseDirectionSymbol() const
Returns true if direction symbols should be reversed.
 
DirectionSymbolPlacement directionSymbolPlacement() const
Returns the placement for direction symbols.
 
QString leftDirectionSymbol() const
Returns the string to use for left direction arrows.
 
@ SymbolLeftRight
Place direction symbols on left/right of label.
 
@ SymbolAbove
Place direction symbols on above label.
 
@ SymbolBelow
Place direction symbols on below label.
 
QString rightDirectionSymbol() const
Returns the string to use for right direction arrows.
 
bool addDirectionSymbol() const
Returns true if '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) w...
 
Qgis::LabelQuadrantPosition quadrant() const
Returns the quadrant in which to offset labels from the point.
 
virtual void run(QgsRenderContext &context)=0
Runs the labeling job.
 
Line string geometry type, with support for z-dimension and m-values.
 
int numPoints() const override
Returns the number of points in the curve.
 
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
 
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
 
Base class for all map layer types.
 
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
 
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
 
QgsLayerMetadata metadata
 
Contains configuration for rendering maps.
 
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
 
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
 
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
 
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
 
const QgsMapToPixel & mapToPixel() const
 
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
 
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
 
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
 
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
 
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
 
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
 
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
 
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
 
Perform transforms between map coordinates and device coordinates.
 
double mapUnitsPerPixel() const
Returns the current map units per pixel.
 
Struct for storing maximum and minimum scales for measurements in map units.
 
bool minSizeMMEnabled
Whether the minimum size in mm should be respected.
 
double maxScale
The maximum scale, or 0.0 if unset.
 
double minScale
The minimum scale, or 0.0 if unset.
 
double maxSizeMM
The maximum size in millimeters, or 0.0 if unset.
 
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
 
double minSizeMM
The minimum size in millimeters, or 0.0 if unset.
 
Abstract base class for marker symbol layers.
 
double size() const
Returns the symbol size.
 
virtual double dxfAngle(QgsSymbolRenderContext &context) const override
Gets angle.
 
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets marker size.
 
Qgis::RenderUnit sizeUnit() const
Returns the units for the symbol's size.
 
Contains settings for how a map layer will be labeled.
 
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
 
QString wrapChar
Wrapping character string.
 
Qgis::LabelPlacement placement
Label placement mode.
 
bool drawLabels
Whether to draw labels for this layer.
 
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the label's property collection, used for data defined overrides.
 
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
 
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
 
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
 
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right)
 
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
 
const QgsLabelPointSettings & pointSettings() const
Returns the label point settings, which contain settings related to how the label engine places and f...
 
Point geometry type, with support for z-dimension and m-values.
 
static QgsProject * instance()
Returns the QgsProject singleton instance.
 
A grouped map of multiple QgsProperty objects, each referenced by an integer key value.
 
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
 
QSet< int > propertyKeys() const final
Returns a list of property keys contained within the collection.
 
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
 
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
 
QSet< QString > referencedFields(const QgsExpressionContext &context=QgsExpressionContext(), bool ignoreContext=false) const final
Returns the set of any fields referenced by the active properties from the collection.
 
A store for object properties.
 
A rectangle specified with double values.
 
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
 
Contains information about the context of a rendering operation.
 
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
 
QgsExpressionContext & expressionContext()
Gets the expression context.
 
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
 
void setExtent(const QgsRectangle &extent)
When rendering a map layer, calling this method sets the "clipping" extent for the layer (in the laye...
 
void setMapToPixel(const QgsMapToPixel &mtp)
Sets the context's map to pixel transform, which transforms between map coordinates and device coordi...
 
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
 
void setLabelingEngine(QgsLabelingEngine *engine)
Assigns the labeling engine.
 
void setRendererScale(double scale)
Sets the renderer map scale.
 
QgsLabelingEngine * labelingEngine() const
Gets access to new labeling engine (may be nullptr).
 
A simple line symbol layer, which renders lines using a line in a variety of styles (e....
 
bool useCustomDashPattern() const
Returns true if the line uses a custom dash pattern.
 
Abstract base class for symbol layers.
 
virtual double dxfSize(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets marker size.
 
virtual double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets offset.
 
virtual QColor dxfBrushColor(QgsSymbolRenderContext &context) const
Gets brush/fill color.
 
virtual Qt::PenStyle dxfPenStyle() const
Gets pen style.
 
virtual QColor dxfColor(QgsSymbolRenderContext &context) const
Gets color.
 
virtual QString layerType() const =0
Returns a string that represents this layer type.
 
virtual double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const
Gets line width.
 
virtual double dxfAngle(QgsSymbolRenderContext &context) const
Gets angle.
 
virtual bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const
write as DXF
 
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides.
 
virtual Qt::BrushStyle dxfBrushStyle() const
Gets brush/fill style.
 
virtual QVector< qreal > dxfCustomDashPattern(Qgis::RenderUnit &unit) const
Gets dash pattern.
 
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
 
Represents a symbol level during vector rendering operations.
 
Encapsulates the context in which a symbol is being rendered.
 
const QgsFeature * feature() const
Returns the current feature being rendered.
 
QgsExpressionContextScope * expressionContextScope()
This scope is always available when a symbol of this type is being rendered.
 
void setFeature(const QgsFeature *f)
 
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
 
Abstract base class for all rendered symbols.
 
QgsSymbolRenderContext * symbolRenderContext()
Returns the symbol render context.
 
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
 
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
 
Qgis::SymbolType type() const
Returns the symbol's type.
 
Container for all settings relating to text rendering.
 
void setFont(const QFont &font)
Sets the font used for rendering text.
 
QColor color() const
Returns the color that text will be rendered in.
 
QFont font() const
Returns the font used for rendering text.
 
Adds extra information to QgsLabelFeature for text labels.
 
QFont definedFont() const
Font to be used for rendering.
 
const QMap< QgsPalLayerSettings::Property, QVariant > & dataDefinedValues() const
Gets data-defined values.
 
static Q_INVOKABLE double fromUnitToUnitFactor(Qgis::DistanceUnit fromUnit, Qgis::DistanceUnit toUnit)
Returns the conversion factor between the specified distance units.
 
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) override
Gets an iterator for features matching the specified request.
 
QString id() const
Returns the layer id of the source layer.
 
QgsFields fields() const
Returns the fields that will be available for features that are retrieved from this source.
 
Represents a vector layer which manages a vector based dataset.
 
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
 
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
 
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
 
QgsRectangle extent() const FINAL
Returns the extent of the layer.
 
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
 
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
 
QgsFeatureId featureId() const
Returns the unique ID of the feature.
 
QgsLabelFeature * feature()
Returns the parent feature.
 
LabelPosition is a candidate feature label position.
 
double getAlpha() const
Returns the angle to rotate text (in radians).
 
bool isReversedFromLineDirection() const
Returns true if the label direction is the reversed from the line or polygon ring direction.
 
Qgis::LabelQuadrantPosition quadrant() const
Returns the quadrant associated with this label position.
 
FeaturePart * getFeaturePart() const
Returns the feature corresponding to this labelposition.
 
double getX(int i=0) const
Returns the down-left x coordinate.
 
double getY(int i=0) const
Returns the down-left y coordinate.
 
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
 
Contains geos related utilities and functions.
 
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
 
uint qHash(const QVariant &variant)
Hash for QVariant.
 
#define Q_NOWARN_DEPRECATED_POP
 
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
 
#define Q_NOWARN_DEPRECATED_PUSH
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
QVector< QgsRingSequence > QgsCoordinateSequence
 
QVector< QgsPointSequence > QgsRingSequence
 
QVector< QgsPoint > QgsPointSequence
 
#define DXF_HANDPLOTSTYLE
 
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
 
#define QgsDebugMsgLevel(str, level)
 
#define QgsDebugError(str)
 
QList< QgsSymbolLevel > QgsSymbolLevelOrder
 
QList< QgsSymbolLevelItem > QgsSymbolLevel
 
QList< QgsSymbol * > QgsSymbolList
 
QList< QgsSymbolLayer * > QgsSymbolLayerList
 
const QgsCoordinateReferenceSystem & crs
 
Holds information about each layer in a DXF job.
 
QSet< QString > attributes
 
std::unique_ptr< QgsFeatureRenderer > renderer
 
QgsRenderContext renderContext
 
QgsFeatureIds selectedFeatureIds
 
QgsCoordinateReferenceSystem crs
 
QgsVectorLayerFeatureSource featureSource
 
Layers and optional attribute index to split into multiple layers using attribute value as layer name...
 
QString splitLayerAttribute() const
If the split layer attribute is set, the vector layer will be split into several dxf layers,...