63#define strcasecmp( a, b ) stricmp( a, b )
75 mMapSettings = settings;
91 mLayerNameAttribute.clear();
93 mLayerList.reserve( layers.size() );
94 for (
const DxfLayer &dxfLayer : layers )
96 mLayerList << dxfLayer.layer();
97 if ( dxfLayer.layerOutputAttributeIndex() >= 0 )
98 mLayerNameAttribute.insert( dxfLayer.layer()->id(), dxfLayer.layerOutputAttributeIndex() );
99 if ( dxfLayer.buildDataDefinedBlocks() )
101 mLayerDDBlockMaxNumberOfClasses.insert( dxfLayer.layer()->id(), dxfLayer.dataDefinedBlocksMaximumNumberOfClasses() );
134 if ( !mForce2d && p.
is3D() && std::isfinite( p.
z() ) )
141 int minDist = std::numeric_limits<int>::max();
143 for (
int i = 1; i < static_cast< int >(
sizeof( sDxfColors ) /
sizeof( *sDxfColors ) ) && minDist > 0; ++i )
145 int dist = color_distance( color.rgba(), i );
146 if ( dist >= minDist )
153 if ( minDist == 0 && minDistAt != 7 )
157 if ( color.alpha() == 255 )
161 int c = ( color.red() & 0xff ) * 0x10000 + ( color.green() & 0xff ) * 0x100 + ( color.blue() & 0xff );
163 if ( transparencyCode != -1 && color.alpha() < 255 )
164 writeGroup( transparencyCode, 0x2000000 | color.alpha() );
169 mTextStream << QStringLiteral(
"%1\n" ).arg( code, 3, 10, QChar(
' ' ) );
174 mTextStream << QStringLiteral(
"%1\n" ).arg( i, 6, 10, QChar(
' ' ) );
180 if ( !s.contains(
'.' ) )
181 s += QLatin1String(
".0" );
182 mTextStream << s <<
'\n';
187 mTextStream << s <<
'\n';
197 if ( !d->isOpen() && !d->open( QIODevice::WriteOnly | QIODevice::Truncate ) )
202 mTextStream.setDevice( d );
203#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
204 mTextStream.setCodec( encoding.toLocal8Bit() );
206 mTextStream.setEncoding( QStringConverter::encodingForName( encoding.toLocal8Bit() ).value_or( QStringConverter::Utf8 ) );
215 for (
QgsMapLayer *ml : std::as_const( mLayerList ) )
249 QList<QgsMapLayer *> layers;
250 QStringList skippedLayers;
251 for (
QgsMapLayer *ml : std::as_const( mLayerList ) )
274 skippedLayers << ml->name();
293 if ( !skippedLayers.isEmpty() )
295 mFeedbackMessage = QObject::tr(
"The following empty layers were skipped: %1" ).arg( skippedLayers.join( QLatin1String(
", " ) ) );
306void QgsDxfExport::writeHeader(
const QString &codepage )
308 writeGroup( 999, QStringLiteral(
"DXF created from QGIS" ) );
314 writeGroup( 9, QStringLiteral(
"$ACADVER" ) );
326 writeGroup( 9, QStringLiteral(
"$LTSCALE" ) );
338 writeGroup( 9, QStringLiteral(
"$PSLTSCALE" ) );
341 writeGroup( 9, QStringLiteral(
"$HANDSEED" ) );
344 writeGroup( 9, QStringLiteral(
"$DWGCODEPAGE" ) );
353 handle = mNextHandleId++;
355 Q_ASSERT_X( handle <
DXF_HANDMAX,
"QgsDxfExport::writeHandle(int, int)",
"DXF handle too large" );
357 writeGroup( code, QString::number( handle, 16 ) );
361void QgsDxfExport::writeTables()
368 QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
369 switch ( mSymbologyExport )
374 slList = symbolLayers( context );
387 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
390 writeDefaultLinetypes();
393 for (
const auto &symbolLayer : std::as_const( slList ) )
395 writeSymbolLayerLinetype( symbolLayer.first );
402 writeGroup( 2, QStringLiteral(
"BLOCK_RECORD" ) );
405 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
408 const QStringList blockStrings = QStringList() << QStringLiteral(
"*Model_Space" ) << QStringLiteral(
"*Paper_Space" ) << QStringLiteral(
"*Paper_Space0" );
409 for (
const QString &block : blockStrings )
411 writeGroup( 0, QStringLiteral(
"BLOCK_RECORD" ) );
413 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
414 writeGroup( 100, QStringLiteral(
"AcDbBlockTableRecord" ) );
419 for (
const auto &symbolLayer : std::as_const( slList ) )
425 if ( hasBlockBreakingDataDefinedProperties( ml, symbolLayer.second ) )
428 if ( !mDataDefinedBlockInfo.contains( ml ) )
433 const QHash <uint, DataDefinedBlockInfo> &symbolClasses = mDataDefinedBlockInfo[ml];
434 for (
const auto &blockInfo : symbolClasses )
436 writeSymbolTableBlockRef( blockInfo.blockName );
443 QString name = QStringLiteral(
"symbolLayer%1" ).arg( i++ );
444 writeSymbolTableBlockRef( name );
453 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
457 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
458 writeGroup( 100, QStringLiteral(
"AcDbRegAppTableRecord" ) );
467 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
475 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
483 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
487 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
488 writeGroup( 100, QStringLiteral(
"AcDbViewportTableRecord" ) );
527 writeGroup( 2, QStringLiteral(
"DIMSTYLE" ) );
529 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
530 writeGroup( 100, QStringLiteral(
"AcDbDimStyleTable" ) );
534 QSet<QString> layerNames;
535 const QList< QgsMapLayer * > layers = mMapSettings.
layers();
538 if ( !layerIsScaleBasedVisible( ml ) )
545 int attrIdx = mLayerNameAttribute.value( vl->
id(), -1 );
552 const QSet<QVariant> values = vl->
uniqueValues( attrIdx );
553 for (
const QVariant &v : values )
565 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
570 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
571 writeGroup( 100, QStringLiteral(
"AcDbLayerTableRecord" ) );
575 writeGroup( 6, QStringLiteral(
"CONTINUOUS" ) );
578 for (
const QString &
layerName : std::as_const( layerNames ) )
582 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
583 writeGroup( 100, QStringLiteral(
"AcDbLayerTableRecord" ) );
587 writeGroup( 6, QStringLiteral(
"CONTINUOUS" ) );
596 writeGroup( 100, QStringLiteral(
"AcDbSymbolTable" ) );
602 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
603 writeGroup( 100, QStringLiteral(
"AcDbTextStyleTableRecord" ) );
604 writeGroup( 2, QStringLiteral(
"STANDARD" ) );
611 writeGroup( 3, QStringLiteral(
"romans.shx" ) );
619void QgsDxfExport::writeSymbolTableBlockRef(
const QString &blockName )
621 writeGroup( 0, QStringLiteral(
"BLOCK_RECORD" ) );
623 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
624 writeGroup( 100, QStringLiteral(
"AcDbBlockTableRecord" ) );
628void QgsDxfExport::writeBlocks()
633 static const QStringList blockStrings = QStringList() << QStringLiteral(
"*Model_Space" ) << QStringLiteral(
"*Paper_Space" ) << QStringLiteral(
"*Paper_Space0" );
634 for (
const QString &block : blockStrings )
638 writeGroup( 330, QString::number( mBlockHandles[ block ], 16 ) );
639 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
641 writeGroup( 100, QStringLiteral(
"AcDbBlockBegin" ) );
649 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
651 writeGroup( 100, QStringLiteral(
"AcDbBlockEnd" ) );
657 QList< QPair< QgsSymbolLayer *, QgsSymbol * > > slList;
658 switch ( mSymbologyExport )
663 slList = symbolLayers( ct );
670 for (
const auto &symbolLayer : std::as_const( slList ) )
680 if ( hasBlockBreakingDataDefinedProperties( ml, symbolLayer.second ) )
682 if ( !mDataDefinedBlockInfo.contains( ml ) )
688 const QHash <uint, DataDefinedBlockInfo> &symbolClasses = mDataDefinedBlockInfo[ml];
689 for (
const auto &blockInfo : symbolClasses )
691 ctx.setFeature( &blockInfo.feature );
692 ctx.renderContext().expressionContext().setFeature( blockInfo.feature );
693 writeSymbolLayerBlock( blockInfo.blockName, ml, ctx );
700 QString block( QStringLiteral(
"symbolLayer%1" ).arg( mBlockCounter++ ) );
701 writeSymbolLayerBlock( block, ml, ctx );
703 mPointSymbolBlocks.insert( ml, block );
704 mPointSymbolBlockSizes.insert( ml, ml->
dxfSize( *
this, ctx ) );
705 mPointSymbolBlockAngles.insert( ml, ml->
dxfAngle( ctx ) );
712 mBlockHandle = QString::number( mBlockHandles[ blockName ], 16 );
716 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
718 writeGroup( 100, QStringLiteral(
"AcDbBlockBegin" ) );
736 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
738 writeGroup( 100, QStringLiteral(
"AcDbBlockEnd" ) );
741void QgsDxfExport::writeEntities()
744 writeGroup( 2, QStringLiteral(
"ENTITIES" ) );
746 mBlockHandle = QString::number( mBlockHandles[ QStringLiteral(
"*Model_Space" )], 16 );
755 job->renderer->usingSymbolLevels() )
757 writeEntitiesSymbolLevels( job );
779 QString lName(
dxfLayerName( job->splitLayerAttribute.isNull() ? job->layerTitle : fet.
attribute( job->splitLayerAttribute ).toString() ) );
781 sctx.setFeature( &fet );
783 if ( !job->renderer->willRenderFeature( fet, mRenderContext ) )
788 addFeature( sctx, ct, lName,
nullptr,
nullptr );
792 const QgsSymbolList symbolList = job->renderer->symbolsForFeature( fet, mRenderContext );
793 bool hasSymbology = symbolList.size() > 0;
805 bool isGeometryGenerator = ( symbolLayer->layerType() == QLatin1String(
"GeometryGenerator" ) );
806 if ( isGeometryGenerator )
808 addGeometryGeneratorSymbolLayer( sctx, ct, lName, symbolLayer,
true );
812 addFeature( sctx, ct, lName, symbolLayer, symbol );
817 else if ( hasSymbology )
828 addGeometryGeneratorSymbolLayer( sctx, ct, lName, s->
symbolLayer( 0 ),
false );
832 addFeature( sctx, ct, lName, s->
symbolLayer( 0 ), s );
836 if ( job->labelProvider )
838 job->labelProvider->registerFeature( fet, mRenderContext );
843 else if ( job->ruleBasedLabelProvider )
845 job->ruleBasedLabelProvider->registerFeature( fet, mRenderContext );
854 QImage image( 10, 10, QImage::Format_ARGB32_Premultiplied );
855 image.setDotsPerMeterX( 96 / 25.4 * 1000 );
856 image.setDotsPerMeterY( 96 / 25.4 * 1000 );
857 QPainter painter( &image );
865void QgsDxfExport::prepareRenderers()
867 Q_ASSERT( mJobs.empty() );
877 std::floor( mMapSettings.
extent().
width() * mFactor ),
878 std::floor( mMapSettings.
extent().
height() * mFactor ), 0 ) );
884 mLabelingEngine = std::make_unique<QgsDefaultLabelingEngine>();
885 mLabelingEngine->setMapSettings( mMapSettings );
888 const QList< QgsMapLayer * > layers = mMapSettings.
layers();
898 if ( !layerIsScaleBasedVisible( vl ) )
901 QString splitLayerAttribute;
902 int splitLayerAttributeIndex = mLayerNameAttribute.value( vl->
id(), -1 );
904 if ( splitLayerAttributeIndex >= 0 && splitLayerAttributeIndex < fields.
size() )
905 splitLayerAttribute = fields.
at( splitLayerAttributeIndex ).
name();
911void QgsDxfExport::writeEntitiesSymbolLevels(
DxfLayerJob *job )
913 QHash< QgsSymbol *, QList<QgsFeature> > features;
931 QgsDebugError( QStringLiteral(
"QgsDxfExport::writeEntitiesSymbolLevels(): extent reprojection failed" ) );
947 featureSymbol = job->
renderer->symbolForFeature( fet, ctx );
948 if ( !featureSymbol )
953 QHash< QgsSymbol *, QList<QgsFeature> >::iterator it = features.find( featureSymbol );
954 if ( it == features.end() )
956 it = features.insert( featureSymbol, QList<QgsFeature>() );
958 it.value().append( fet );
966 for (
int j = 0; j < symbol->symbolLayerCount(); j++ )
968 int level = symbol->symbolLayer( j )->renderingPass();
969 if ( level < 0 || level >= 1000 )
972 while ( level >= levels.count() )
974 levels[level].append( item );
983 QHash< QgsSymbol *, QList<QgsFeature> >::iterator levelIt = features.find( item.symbol() );
984 if ( levelIt == features.end() )
989 int llayer = item.layer();
990 const QList<QgsFeature> &featureList = levelIt.value();
991 for (
const QgsFeature &feature : featureList )
993 sctx.setFeature( &feature );
994 addFeature( sctx, ct, job->
layerName, levelIt.key()->symbolLayer( llayer ), levelIt.key() );
1000void QgsDxfExport::stopRenderers()
1002 qDeleteAll( mJobs );
1006void QgsDxfExport::writeEndFile()
1013void QgsDxfExport::startSection()
1015 writeGroup( 0, QStringLiteral(
"SECTION" ) );
1018void QgsDxfExport::endSection()
1031 msl->
sizeUnit(), mMapUnits ) / 2.0;
1043 QHash< const QgsSymbolLayer *, QString >::const_iterator blockIt = mPointSymbolBlocks.constFind( symbolLayer );
1044 if ( symbolLayer && blockIt != mPointSymbolBlocks.constEnd() )
1046 writePointBlockReference( pt, symbolLayer, ctx, layer,
angle, blockIt.value(), mPointSymbolBlockAngles.value( symbolLayer ), mPointSymbolBlockSizes.value( symbolLayer ) );
1051 QHash< const QgsSymbolLayer *, QHash <uint, DataDefinedBlockInfo> >::const_iterator ddBlockIt = mDataDefinedBlockInfo.constFind( symbolLayer );
1052 if ( symbolLayer && ctx.
feature() && ddBlockIt != mDataDefinedBlockInfo.constEnd() )
1054 const QHash <uint, DataDefinedBlockInfo> &symbolLayerDDBlocks = ddBlockIt.value();
1058 uint ddSymbolHash = dataDefinedSymbolClassHash( *( ctx.
feature() ), props );
1059 if ( symbolLayerDDBlocks.contains( ddSymbolHash ) )
1061 const DataDefinedBlockInfo &info = symbolLayerDDBlocks[ddSymbolHash];
1062 writePointBlockReference( pt, symbolLayer, ctx, layer,
angle, info.blockName, info.angle, info.size );
1069 if ( msl && symbol )
1081 const double scale = symbolLayer->
dxfSize( *
this, ctx ) / blockSize;
1086 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1087 writeGroup( 100, QStringLiteral(
"AcDbBlockReference" ) );
1091 if ( std::isfinite( scale ) && scale != 1.0 )
1107 std::sort( fields.begin(), fields.end() );
1109 for (
const auto &field : std::as_const( fields ) )
1111 QVariant attValue = fet.
attribute( field );
1114 hashValue =
qHash( attValue );
1118 hashValue = hashValue ^
qHash( attValue );
1128 int n = line.size();
1131 QgsDebugError( QStringLiteral(
"writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
1137 QgsDebugError( QStringLiteral(
"writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
1141 if ( mForce2d || !line.at( 0 ).is3D() )
1143 bool polygon = line[0] == line[ line.size() - 1 ];
1147 writeGroup( 0, QStringLiteral(
"LWPOLYLINE" ) );
1150 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1151 writeGroup( 100, QStringLiteral(
"AcDbPolyline" ) );
1159 for (
int i = 0; i < n; i++ )
1164 writeGroup( 0, QStringLiteral(
"POLYLINE" ) );
1167 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1171 writeGroup( 100, QStringLiteral(
"AcDb3dPolyline" ) );
1175 for (
int i = 0; i < n; i++ )
1180 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1183 writeGroup( 100, QStringLiteral(
"AcDbVertex" ) );
1184 writeGroup( 100, QStringLiteral(
"AcDb3dPolylineVertex" ) );
1192 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1198void QgsDxfExport::appendCurve(
const QgsCurve &
c, QVector<QgsPoint> &points, QVector<double> &bulges )
1203 appendLineString( *
dynamic_cast<const QgsLineString *
>( &
c ), points, bulges );
1207 appendCircularString( *
dynamic_cast<const QgsCircularString *
>( &
c ), points, bulges );
1211 appendCompoundCurve( *
dynamic_cast<const QgsCompoundCurve *
>( &
c ), points, bulges );
1215 QgsDebugError( QStringLiteral(
"Unexpected curve type %1" ).arg(
c.wktTypeStr() ) );
1220void QgsDxfExport::appendLineString(
const QgsLineString &ls, QVector<QgsPoint> &points, QVector<double> &bulges )
1222 for (
int i = 0; i < ls.
numPoints(); i++ )
1225 if ( !points.isEmpty() && points.last() == p )
1233void QgsDxfExport::appendCircularString(
const QgsCircularString &cs, QVector<QgsPoint> &points, QVector<double> &bulges )
1235 for (
int i = 0; i < cs.
numPoints() - 2; i += 2 )
1241 if ( points.isEmpty() || points.last() != p1 )
1243 else if ( !bulges.isEmpty() )
1244 bulges.removeLast();
1246 double a = ( M_PI - ( p1 - p2 ).
angle() + ( p3 - p2 ).
angle() ) / 2.0;
1247 bulges << sin( a ) / cos( a );
1254void QgsDxfExport::appendCompoundCurve(
const QgsCompoundCurve &cc, QVector<QgsPoint> &points, QVector<double> &bulges )
1256 for (
int i = 0; i < cc.
nCurves(); i++ )
1260 appendCurve( *
c, points, bulges );
1269 QgsDebugError( QStringLiteral(
"writePolyline: empty line layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
1275 QgsDebugError( QStringLiteral(
"writePolyline: line too short layer=%1 lineStyleName=%2" ).arg( layer, lineStyleName ) );
1279 QVector<QgsPoint> points;
1280 QVector<double> bulges;
1281 appendCurve( curve, points, bulges );
1283 if ( mForce2d || !curve.
is3D() )
1285 writeGroup( 0, QStringLiteral(
"LWPOLYLINE" ) );
1288 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1289 writeGroup( 100, QStringLiteral(
"AcDbPolyline" ) );
1296 polylineFlags.setFlag( QgsDxfExport::DxfPolylineFlag::Closed );
1298 polylineFlags.setFlag( QgsDxfExport::DxfPolylineFlag::Curve );
1302 polylineFlags.setFlag( QgsDxfExport::DxfPolylineFlag::ContinuousPattern );
1304 writeGroup( 70,
static_cast<int>( polylineFlags ) );
1307 for (
int i = 0; i < points.size(); i++ )
1310 if ( bulges[i] != 0.0 )
1316 writeGroup( 0, QStringLiteral(
"POLYLINE" ) );
1319 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1323 writeGroup( 100, QStringLiteral(
"AcDb3dPolyline" ) );
1327 for (
int i = 0; i < points.size(); i++ )
1332 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1335 writeGroup( 100, QStringLiteral(
"AcDbVertex" ) );
1336 writeGroup( 100, QStringLiteral(
"AcDb3dPolylineVertex" ) );
1338 if ( bulges[i] != 0.0 )
1346 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1357 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1360 writeGroup( 100, QStringLiteral(
"AcDbHatch" ) );
1366 writeGroup( 70, hatchPattern == QLatin1String(
"SOLID" ) );
1370 for (
int i = 0; i < polygon.size(); ++i )
1377 for (
int j = 0; j < polygon[i].size(); ++j )
1396 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1399 writeGroup( 100, QStringLiteral(
"AcDbHatch" ) );
1405 writeGroup( 70, hatchPattern == QLatin1String(
"SOLID" ) );
1408 QVector<QVector<QgsPoint>> points;
1409 QVector<QVector<double>> bulges;
1412 points.reserve( ringCount + 1 );
1413 bulges.reserve( ringCount + 1 );
1415 points << QVector<QgsPoint>();
1416 bulges << QVector<double>();
1417 appendCurve( *polygon.
exteriorRing(), points.last(), bulges.last() );
1419 for (
int i = 0; i < ringCount; i++ )
1421 points << QVector<QgsPoint>();
1422 bulges << QVector<double>();
1423 appendCurve( *polygon.
interiorRing( i ), points.last(), bulges.last() );
1426 bool hasBulges =
false;
1427 for (
int i = 0; i < points.size() && !hasBulges; ++i )
1428 for (
int j = 0; j < points[i].size() && !hasBulges; ++j )
1429 hasBulges = bulges[i][j] != 0.0;
1433 for (
int i = 0; i < points.size(); ++i )
1440 for (
int j = 0; j < points[i].size(); ++j )
1464 double lblX = label->
getX();
1465 double lblY = label->
getY();
1490 switch ( offsetQuad )
1540 const QString haliString = exprVal.toString();
1541 if ( haliString.compare( QLatin1String(
"Center" ), Qt::CaseInsensitive ) == 0 )
1545 else if ( haliString.compare( QLatin1String(
"Right" ), Qt::CaseInsensitive ) == 0 )
1559 const QString valiString = exprVal.toString();
1560 if ( valiString.compare( QLatin1String(
"Bottom" ), Qt::CaseInsensitive ) != 0 )
1562 if ( valiString.compare( QLatin1String(
"Base" ), Qt::CaseInsensitive ) == 0 )
1566 else if ( valiString.compare( QLatin1String(
"Half" ), Qt::CaseInsensitive ) == 0 )
1585 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1586 writeGroup( 100, QStringLiteral(
"AcDbPoint" ) );
1597 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1600 writeGroup( 100, QStringLiteral(
"AcDbHatch" ) );
1631 writeGroup( 0, QStringLiteral(
"LWPOLYLINE" ) );
1635 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1636 writeGroup( 100, QStringLiteral(
"AcDbPolyline" ) );
1655 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1658 writeGroup( 100, QStringLiteral(
"AcDbText" ) );
1669 writeGroup( 7, QStringLiteral(
"STANDARD" ) );
1670 writeGroup( 100, QStringLiteral(
"AcDbText" ) );
1679#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1680 if ( !mTextStream.codec()->canEncode( text ) )
1683 QgsDebugError( QStringLiteral(
"could not encode:%1" ).arg( text ) );
1690 writeGroup( 100, QStringLiteral(
"AcDbEntity" ) );
1691 writeGroup( 100, QStringLiteral(
"AcDbMText" ) );
1698 while ( t.length() > 250 )
1714 writeGroup( 7, QStringLiteral(
"STANDARD" ) );
1729 geom.transform( ct );
1738 penColor = colorFromSymbolLayer( symbolLayer, ctx );
1742 Qt::PenStyle penStyle( Qt::SolidLine );
1743 Qt::BrushStyle brushStyle( Qt::NoBrush );
1745 double offset = 0.0;
1749 width = symbolLayer->
dxfWidth( *
this, ctx );
1750 offset = symbolLayer->
dxfOffset( *
this, ctx );
1759 QString lineStyleName = QStringLiteral(
"CONTINUOUS" );
1762 lineStyleName = lineStyleFromSymbolLayer( symbolLayer );
1768 writePoint( geom.constGet()->coordinateSequence().at( 0 ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol,
angle );
1775 for (
int i = 0; i < cs.size(); i++ )
1777 writePoint( cs.at( i ).at( 0 ).at( 0 ), layer, penColor, ctx, symbolLayer, symbol,
angle );
1782 if ( penStyle != Qt::NoPen )
1785 std::unique_ptr< QgsAbstractGeometry > tempGeom;
1800 sourceGeom = tempGeom.get();
1802 sourceGeom = geom.constGet();
1808 writePolyline( *curve, layer, lineStyleName, penColor, width );
1820 writePolyline( *curve, layer, lineStyleName, penColor, width );
1837 sourceGeom = tempGeom.get();
1839 sourceGeom = geom.constGet();
1858 Q_ASSERT( polygon );
1876 if ( brushStyle != Qt::NoBrush )
1886 Q_ASSERT( polygon );
1887 writePolygon( *polygon, layer, QStringLiteral(
"SOLID" ), brushColor );
1900 Q_ASSERT( polygon );
1901 writePolygon( *polygon, layer, QStringLiteral(
"SOLID" ), brushColor );
1918 return symbolLayer->
dxfColor( ctx );
1921QString QgsDxfExport::lineStyleFromSymbolLayer(
const QgsSymbolLayer *symbolLayer )
1923 QString lineStyleName = QStringLiteral(
"CONTINUOUS" );
1926 return lineStyleName;
1929 QHash< const QgsSymbolLayer *, QString >::const_iterator lineTypeIt = mLineStyles.constFind( symbolLayer );
1930 if ( lineTypeIt != mLineStyles.constEnd() )
1932 lineStyleName = lineTypeIt.value();
1933 return lineStyleName;
1937 return lineNameFromPenStyle( symbolLayer->
dxfPenStyle() );
1944 int current_distance = std::numeric_limits<int>::max();
1945 for (
int i = 1; i < static_cast< int >(
sizeof( sDxfColors ) /
sizeof( *sDxfColors ) ); ++i )
1947 int dist = color_distance( pixel, i );
1948 if ( dist < current_distance )
1950 current_distance = dist;
1959int QgsDxfExport::color_distance( QRgb p1,
int index )
1961 if ( index > 255 || index < 0 )
1966 double redDiff = qRed( p1 ) - sDxfColors[index][0];
1967 double greenDiff = qGreen( p1 ) - sDxfColors[index][1];
1968 double blueDiff = qBlue( p1 ) - sDxfColors[index][2];
1970 QgsDebugMsgLevel( QStringLiteral(
"color_distance( r:%1 g:%2 b:%3 <=> i:%4 r:%5 g:%6 b:%7 ) => %8" )
1971 .arg( qRed( p1 ) ).arg( qGreen( p1 ) ).arg( qBlue( p1 ) )
1973 .arg( mDxfColors[index][0] )
1974 .arg( mDxfColors[index][1] )
1975 .arg( mDxfColors[index][2] )
1976 .arg( redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff ), 2 );
1978 return redDiff * redDiff + greenDiff * greenDiff + blueDiff * blueDiff;
1981QRgb QgsDxfExport::createRgbEntry( qreal r, qreal g, qreal b )
1983 return QColor::fromRgbF( r, g, b ).rgb();
1988 return mRenderContext;
2003 return mapUnitsPerPixel;
2017 double minSizeMU = std::numeric_limits<double>::lowest();
2020 minSizeMU = scale.
minSizeMM * pixelToMMFactor * mapUnitsPerPixel;
2024 minSizeMU = std::max( minSizeMU, value );
2026 value = std::max( value, minSizeMU );
2028 double maxSizeMU = std::numeric_limits<double>::max();
2031 maxSizeMU = scale.
maxSizeMM * pixelToMMFactor * mapUnitsPerPixel;
2035 maxSizeMU = std::min( maxSizeMU, value );
2037 value = std::min( value, maxSizeMU );
2040QList< QPair< QgsSymbolLayer *, QgsSymbol * > > QgsDxfExport::symbolLayers(
QgsRenderContext &context )
2042 QList< QPair< QgsSymbolLayer *, QgsSymbol * > > symbolLayers;
2053 maxSymbolLayers = 1;
2055 for (
int i = 0; i < maxSymbolLayers; ++i )
2057 symbolLayers.append( qMakePair( symbol->
symbolLayer( i ), symbol ) );
2062 return symbolLayers;
2065void QgsDxfExport::writeDefaultLinetypes()
2068 for (
const QString <ype : { QStringLiteral(
"ByLayer" ), QStringLiteral(
"ByBlock" ), QStringLiteral(
"CONTINUOUS" ) } )
2072 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
2073 writeGroup( 100, QStringLiteral(
"AcDbLinetypeTableRecord" ) );
2076 writeGroup( 3, QStringLiteral(
"Defaultstyle" ) );
2082 double das = dashSize();
2083 double dss = dashSeparatorSize();
2084 double dos = dotSize();
2086 QVector<qreal> dashVector( 2 );
2087 dashVector[0] = das;
2088 dashVector[1] = dss;
2091 QVector<qreal> dotVector( 2 );
2096 QVector<qreal> dashDotVector( 4 );
2097 dashDotVector[0] = das;
2098 dashDotVector[1] = dss;
2099 dashDotVector[2] = dos;
2100 dashDotVector[3] = dss;
2103 QVector<qreal> dashDotDotVector( 6 );
2104 dashDotDotVector[0] = das;
2105 dashDotDotVector[1] = dss;
2106 dashDotDotVector[2] = dos;
2107 dashDotDotVector[3] = dss;
2108 dashDotDotVector[4] = dos;
2109 dashDotDotVector[5] = dss;
2113void QgsDxfExport::writeSymbolLayerLinetype(
const QgsSymbolLayer *symbolLayer )
2122 if ( !customLinestyle.isEmpty() )
2124 QString name = QStringLiteral(
"symbolLayer%1" ).arg( mSymbolLayerCounter++ );
2125 writeLinetype( name, customLinestyle, unit );
2126 mLineStyles.insert( symbolLayer, name );
2130int QgsDxfExport::nLineTypes(
const QList< QPair< QgsSymbolLayer *, QgsSymbol * > > &symbolLayers )
2133 for (
const auto &symbolLayer : symbolLayers )
2147void QgsDxfExport::writeLinetype(
const QString &styleName,
const QVector<qreal> &pattern,
Qgis::RenderUnit u )
2150 for ( qreal size : pattern )
2158 writeGroup( 100, QStringLiteral(
"AcDbSymbolTableRecord" ) );
2159 writeGroup( 100, QStringLiteral(
"AcDbLinetypeTableRecord" ) );
2168 for ( qreal size : pattern )
2171 double segmentLength = ( isGap ? -size : size );
2197 geomExpr.prepare( &expressionContext );
2205 symbolExpressionContextScope->
setFeature( f );
2210 for (
int i = 0; i < nSymbolLayers; ++i )
2212 addFeature( ctx, ct, layer, symbol->
symbolLayer( i ), symbol );
2221 if ( !sl || !symbol )
2226 bool blockBreak =
false;
2233 blockBreak = !properties.isEmpty();
2239double QgsDxfExport::dashSize()
const
2241 double size = mSymbologyScale * 0.002;
2242 return sizeToMapUnits( size );
2245double QgsDxfExport::dotSize()
const
2247 double size = mSymbologyScale * 0.0006;
2248 return sizeToMapUnits( size );
2251double QgsDxfExport::dashSeparatorSize()
const
2253 double size = mSymbologyScale * 0.0006;
2254 return sizeToMapUnits( size );
2257double QgsDxfExport::sizeToMapUnits(
double s )
const
2263QString QgsDxfExport::lineNameFromPenStyle( Qt::PenStyle style )
2268 return QStringLiteral(
"DASH" );
2270 return QStringLiteral(
"DOT" );
2271 case Qt::DashDotLine:
2272 return QStringLiteral(
"DASHDOT" );
2273 case Qt::DashDotDotLine:
2274 return QStringLiteral(
"DASHDOTDOT" );
2277 return QStringLiteral(
"CONTINUOUS" );
2283 if ( name.isEmpty() )
2284 return QStringLiteral(
"0" );
2309 layerName.replace( QLatin1String(
"\r\n" ), QLatin1String(
"_" ) );
2316bool QgsDxfExport::layerIsScaleBasedVisible(
const QgsMapLayer *layer )
const
2330 for (
QgsMapLayer *ml : std::as_const( mLayerList ) )
2333 if ( vl && vl->
id() ==
id )
2335 int attrIdx = mLayerNameAttribute.value( vl->
id(), -1 );
2340 return QStringLiteral(
"0" );
2345 const QList< QByteArray > codecs = QTextCodec::availableCodecs();
2346 for (
const QByteArray &codec : codecs )
2348 if ( name != codec )
2352 for ( i = 0; i < static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) && name != DXF_ENCODINGS[i][1]; ++i )
2355 if ( i ==
static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) )
2358 return DXF_ENCODINGS[i][0];
2367 const QList< QByteArray > codecs = QTextCodec::availableCodecs();
2369 for (
const QByteArray &codec : codecs )
2372 for ( i = 0; i < static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) && strcasecmp( codec.data(), DXF_ENCODINGS[i][1] ) != 0; ++i )
2375 if ( i <
static_cast< int >(
sizeof( DXF_ENCODINGS ) /
sizeof( *DXF_ENCODINGS ) ) )
2387 return mLayerTitleAsName && !vl->
title().isEmpty() ? vl->
title() : vl->
name();
2405 const QMap< QgsPalLayerSettings::Property, QVariant > &ddValues = lf->
dataDefinedValues();
2410 QgsDebugMsgLevel( QStringLiteral(
"PAL font definedFont: %1, Style: %2" ).arg( dFont.toString(), dFont.styleName() ), 4 );
2440 QgsPalLabeling::dataDefinedTextStyle( tmpLyr, ddValues );
2443 QgsPalLabeling::dataDefinedTextBuffer( tmpLyr, ddValues );
2446 QgsPalLabeling::dataDefinedTextFormatting( tmpLyr, ddValues );
2452 QString dxfLayer = mDxfLayerNames[layerId][fid];
2454 QString wrapchr = tmpLyr.
wrapChar.isEmpty() ? QStringLiteral(
"\n" ) : tmpLyr.
wrapChar;
2459 bool prependSymb =
false;
2477 prependSymb =
false;
2486 symb = symb + wrapchr;
2490 prependSymb =
false;
2491 symb = wrapchr + symb;
2500 txt.prepend( symb );
2510 txt.replace( QChar( QChar::LineFeed ),
' ' );
2511 txt.replace( QChar( QChar::CarriageReturn ),
' ' );
2516 txt.replace( QString( QChar( QChar::CarriageReturn ) ) + QString( QChar( QChar::LineFeed ) ), QStringLiteral(
"\\P" ) );
2517 txt.replace( QChar( QChar::CarriageReturn ), QStringLiteral(
"\\P" ) );
2518 txt = txt.replace( wrapchr, QLatin1String(
"\\P" ) );
2519 txt.replace( QLatin1String(
" " ), QLatin1String(
"\\~" ) );
2523 txt.prepend(
"\\L" ).append(
"\\l" );
2528 txt.prepend(
"\\O" ).append(
"\\o" );
2533 txt.prepend(
"\\K" ).append(
"\\k" );
2536 txt.prepend( QStringLiteral(
"\\f%1|i%2|b%3;\\H%4;" )
2538 .arg( tmpLyr.
format().
font().italic() ? 1 : 0 )
2539 .arg( tmpLyr.
format().
font().bold() ? 1 : 0 )
2540 .arg( label->
getHeight() / ( 1 + txt.count( QStringLiteral(
"\\P" ) ) ) * 0.75 ) );
2548 if ( !mDxfLayerNames.contains( layerId ) )
2549 mDxfLayerNames[ layerId ] = QMap<QgsFeatureId, QString>();
2551 mDxfLayerNames[layerId][fid] =
layerName;
2567 QString splitLayerFieldName;
2569 if ( mLayerOutputAttributeIndex >= 0 && mLayerOutputAttributeIndex < fields.
size() )
2571 splitLayerFieldName = fields.
at( mLayerOutputAttributeIndex ).
name();
2574 return splitLayerFieldName;
2577void QgsDxfExport::createDDBlockInfo()
2579 int symbolLayerNr = 0;
2582 int ddMaxNumberOfClasses = -1;
2583 bool createDDBlocks = mLayerDDBlockMaxNumberOfClasses.contains( job->
featureSource.
id() );
2584 if ( createDDBlocks )
2586 ddMaxNumberOfClasses = mLayerDDBlockMaxNumberOfClasses[job->
featureSource.
id()];
2595 for (
const QgsSymbol *symbol : symbols )
2606 maxSymbolLayers = 1;
2609 for (
int i = 0; i < maxSymbolLayers; ++i )
2619 if ( !hasBlockBreakingDataDefinedProperties( sl, symbol ) || !createDDBlocks )
2634 QHash <uint, QPair<int, DataDefinedBlockInfo> > blockSymbolMap;
2639 uint symbolHash = dataDefinedSymbolClassHash( fet, properties );
2640 if ( blockSymbolMap.contains( symbolHash ) )
2642 blockSymbolMap[symbolHash].first += 1;
2646 sctx.setFeature( &fet );
2648 DataDefinedBlockInfo blockInfo;
2649 blockInfo.blockName = QStringLiteral(
"symbolLayer%1class%2" ).arg( symbolLayerNr ).arg( symbolHash );
2650 blockInfo.angle = sl->
dxfAngle( sctx );
2651 blockInfo.size = sl->
dxfSize( *
this, sctx );
2652 blockInfo.feature = fet;
2654 blockSymbolMap.insert( symbolHash, qMakePair( 1, blockInfo ) );
2659 QMultiMap<int, uint> occurrences;
2660 QHash <uint, QPair<int, DataDefinedBlockInfo> >::const_iterator blockSymbolIt = blockSymbolMap.constBegin();
2661 for ( ; blockSymbolIt != blockSymbolMap.constEnd(); ++blockSymbolIt )
2663 occurrences.insert( blockSymbolIt.value().first, blockSymbolIt.key() );
2666 QHash <uint, DataDefinedBlockInfo > applyBlockSymbolMap;
2667 int nInsertedClasses = 0;
2668 QMultiMap<int, uint>::const_iterator occIt = occurrences.constEnd();
2669 while ( occurrences.size() > 0 && occIt != occurrences.constBegin() )
2672 applyBlockSymbolMap.insert( occIt.value(), blockSymbolMap[occIt.value()].second );
2674 if ( ddMaxNumberOfClasses != -1 && nInsertedClasses >= ddMaxNumberOfClasses )
2681 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.
Q_GADGET 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.
@ 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)
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.
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.
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...
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.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString title() const
Returns the title of the layer used by QGIS Server in GetCapabilities request.
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.
Qgis::LabelQuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
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.
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.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double width() const
Returns the width of the rectangle.
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
QgsPointXY center() const
Returns the center point of the rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
bool isEmpty() const
Returns true if the rectangle has no area.
double height() const
Returns the height of the 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.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
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).
Quadrant getQuadrant() const
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,...