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 QList< QByteArray > codecs = QTextCodec::availableCodecs();
2358 for (
const QByteArray &codec : codecs )
2360 if ( name != codec )
2364 for ( i = 0; i < static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) && name != DXF_ENCODINGS[i][1]; ++i )
2367 if ( i ==
static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) )
2370 return DXF_ENCODINGS[i][0];
2379 const QList< QByteArray > codecs = QTextCodec::availableCodecs();
2381 for (
const QByteArray &codec : codecs )
2384 for ( i = 0; i < static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) && strcasecmp( codec.data(), DXF_ENCODINGS[i][1] ) != 0; ++i )
2387 if ( i <
static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) )
2399 if ( !mLayerOverriddenName.value( vl->
id(), QString() ).isEmpty() )
2401 return mLayerOverriddenName.value( vl->
id() );
2428 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->
dataDefinedValues();
2433 QgsDebugMsgLevel( QStringLiteral(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
2463 QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
2466 QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
2469 QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
2475 QString dxfLayer = mDxfLayerNames[layerId][fid];
2477 QString wrapchr = tmpLyr.
wrapChar.isEmpty() ? QStringLiteral(
"\n" ) : tmpLyr.
wrapChar;
2482 bool prependSymb =
false;
2500 prependSymb =
false;
2509 symb = symb + wrapchr;
2513 prependSymb =
false;
2514 symb = wrapchr + symb;
2523 txt.prepend( symb );
2533 txt.replace( QChar( QChar::LineFeed ),
' ' );
2534 txt.replace( QChar( QChar::CarriageReturn ),
' ' );
2539 txt.replace( QString( QChar( QChar::CarriageReturn ) ) + QString( QChar( QChar::LineFeed ) ), QStringLiteral(
"\\P" ) );
2540 txt.replace( QChar( QChar::CarriageReturn ), QStringLiteral(
"\\P" ) );
2541 txt = txt.replace( wrapchr, QLatin1String(
"\\P" ) );
2542 txt.replace( QLatin1String(
" " ), QLatin1String(
"\\~" ) );
2546 txt.prepend(
"\\L" ).append(
"\\l" );
2551 txt.prepend(
"\\O" ).append(
"\\o" );
2556 txt.prepend(
"\\K" ).append(
"\\k" );
2559 txt.prepend( QStringLiteral(
"\\f%1|i%2|b%3;\\H%4;" )
2561 .arg( tmpLyr.
format().
font().italic() ? 1 : 0 )
2562 .arg( tmpLyr.
format().
font().bold() ? 1 : 0 )
2563 .arg( label->
getHeight() / ( 1 + txt.count( QStringLiteral(
"\\P" ) ) ) * 0.75 ) );
2571 if ( !mDxfLayerNames.contains( layerId ) )
2572 mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
2574 mDxfLayerNames[layerId][fid] =
layerName;
2590 QString splitLayerFieldName;
2592 if ( mLayerOutputAttributeIndex >= 0 && mLayerOutputAttributeIndex < fields.
size() )
2594 splitLayerFieldName = fields.
at( mLayerOutputAttributeIndex ).
name();
2597 return splitLayerFieldName;
2600void QgsDxfExport::createDDBlockInfo()
2602 int symbolLayerNr = 0;
2605 int ddMaxNumberOfClasses = -1;
2606 bool createDDBlocks = mLayerDDBlockMaxNumberOfClasses.contains( job->
featureSource.
id() );
2607 if ( createDDBlocks )
2609 ddMaxNumberOfClasses = mLayerDDBlockMaxNumberOfClasses[job->
featureSource.
id()];
2618 for (
const QgsSymbol *symbol : symbols )
2629 maxSymbolLayers = 1;
2632 for (
int i = 0; i < maxSymbolLayers; ++i )
2642 if ( !hasBlockBreakingDataDefinedProperties( sl, symbol ) || !createDDBlocks )
2657 QHash <uint, QPair<int, DataDefinedBlockInfo> > blockSymbolMap;
2662 uint symbolHash = dataDefinedSymbolClassHash( fet, properties );
2663 if ( blockSymbolMap.contains( symbolHash ) )
2665 blockSymbolMap[symbolHash].first += 1;
2669 sctx.setFeature( &fet );
2670 sctx.renderContext().expressionContext().setFeature( fet );
2672 DataDefinedBlockInfo blockInfo;
2673 blockInfo.blockName = QStringLiteral(
"symbolLayer%1class%2" ).arg( symbolLayerNr ).arg( symbolHash );
2674 blockInfo.angle = sl->
dxfAngle( sctx );
2675 blockInfo.size = sl->
dxfSize( *
this, sctx );
2676 blockInfo.feature = fet;
2678 blockSymbolMap.insert( symbolHash, qMakePair( 1, blockInfo ) );
2683 QMultiMap<int, uint> occurrences;
2684 QHash <uint, QPair<int, DataDefinedBlockInfo> >::const_iterator blockSymbolIt = blockSymbolMap.constBegin();
2685 for ( ; blockSymbolIt != blockSymbolMap.constEnd(); ++blockSymbolIt )
2687 occurrences.insert( blockSymbolIt.value().first, blockSymbolIt.key() );
2690 QHash <uint, DataDefinedBlockInfo > applyBlockSymbolMap;
2691 int nInsertedClasses = 0;
2692 QMultiMap<int, uint>::const_iterator occIt = occurrences.constEnd();
2693 while ( occurrences.size() > 0 && occIt != occurrences.constBegin() )
2696 applyBlockSymbolMap.insert( occIt.value(), blockSymbolMap[occIt.value()].second );
2698 if ( ddMaxNumberOfClasses != -1 && nInsertedClasses >= ddMaxNumberOfClasses )
2705 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.
This class 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.
Class for 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())
This class 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, exception handling*.
The QgsLabelFeature class 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
The QgsMapSettings class contains configuration for rendering of the map.
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 a 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.
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.
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.
Class that 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 data sets.
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,...