24 #include "qgsogrprovider.h"
41 #include <cpl_error.h>
42 #include <QJsonDocument>
45 #include <QTextStream>
46 #include <QDataStream>
47 #include <QRegularExpression>
49 #include "ogr_srs_api.h"
54 OGR_DS_Destroy( source );
60 OGR_G_DestroyGeometry( geometry );
65 OGR_Fld_Destroy( definition );
70 OGR_F_Destroy( feature );
87 CPLPushErrorHandler( CPLQuietErrorHandler );
88 GDALDeleteDataset( driver, path.toUtf8().constData() );
100 GDALDestroyWarpOptions( options );
105 if ( !value || OGR_RawField_IsUnset( value ) || OGR_RawField_IsNull( value ) )
111 return value->Integer;
114 return value->Integer64;
121 return QString::fromUtf8( value->String );
124 return QDate( value->Date.Year, value->Date.Month, value->Date.Day );
128 float secondsPart = 0;
129 float millisecondPart = std::modf( value->Date.Second, &secondsPart );
130 return QTime( value->Date.Hour, value->Date.Minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) );
135 float secondsPart = 0;
136 float millisecondPart = std::modf( value->Date.Second, &secondsPart );
137 return QDateTime( QDate( value->Date.Year, value->Date.Month, value->Date.Day ),
138 QTime( value->Date.Hour, value->Date.Minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) ) );
143 Q_ASSERT_X(
false,
"QgsOgrUtils::OGRFieldtoVariant",
"OFTBinary type not supported" );
149 res.reserve( value->IntegerList.nCount );
150 for (
int i = 0; i < value->IntegerList.nCount; ++i )
151 res << value->IntegerList.paList[ i ];
155 case OFTInteger64List:
158 res.reserve( value->Integer64List.nCount );
159 for (
int i = 0; i < value->Integer64List.nCount; ++i )
160 res << value->Integer64List.paList[ i ];
167 res.reserve( value->RealList.nCount );
168 for (
int i = 0; i < value->RealList.nCount; ++i )
169 res << value->RealList.paList[ i ];
174 case OFTWideStringList:
177 res.reserve( value->StringList.nCount );
178 for (
int i = 0; i < value->StringList.nCount; ++i )
179 res << QString::fromUtf8( value->StringList.paList[ i ] );
195 feature.
setId( OGR_F_GetFID( ogrFet ) );
198 if ( !readOgrFeatureGeometry( ogrFet, feature ) )
203 if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
218 int fieldCount = OGR_F_GetFieldCount( ogrFet );
219 for (
int i = 0; i < fieldCount; ++i )
221 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
228 QString name = encoding ? encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) ) : QString::fromUtf8( OGR_Fld_GetNameRef( fldDef ) );
229 QVariant::Type varType;
230 switch ( OGR_Fld_GetType( fldDef ) )
233 if ( OGR_Fld_GetSubType( fldDef ) == OFSTBoolean )
234 varType = QVariant::Bool;
236 varType = QVariant::Int;
239 varType = QVariant::LongLong;
242 varType = QVariant::Double;
245 varType = QVariant::Date;
248 varType = QVariant::Time;
251 varType = QVariant::DateTime;
254 if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON )
255 varType = QVariant::Map;
257 varType = QVariant::String;
260 varType = QVariant::String;
270 if ( attIndex < 0 || attIndex >= fields.
count() )
278 return getOgrFeatureAttribute( ogrFet,
field, attIndex, encoding, ok );
283 if ( !ogrFet || attIndex < 0 )
290 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
297 QgsDebugMsg( QStringLiteral(
"ogrFet->GetFieldDefnRef(attindex) returns NULL" ) );
306 if ( OGR_F_IsFieldSetAndNotNull( ogrFet, attIndex ) )
310 case QVariant::String:
313 value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
315 value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
320 if ( value.isNull() )
321 value = QVariant( QStringLiteral(
"" ) );
327 value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
330 value = QVariant(
bool( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ) );
332 case QVariant::LongLong:
333 value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
335 case QVariant::Double:
336 value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
339 case QVariant::DateTime:
342 int year, month, day, hour, minute, second, tzf;
344 OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
346 value = QDate( year, month, day );
347 else if (
field.
type() == QVariant::Time )
348 value = QTime( hour, minute, second );
350 value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
354 case QVariant::ByteArray:
357 const GByte *b = OGR_F_GetFieldAsBinary( ogrFet, attIndex, &size );
361 QByteArray ba = QByteArray::fromRawData(
reinterpret_cast<const char *
>( b ), size );
368 case QVariant::StringList:
371 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
372 const int count = CSLCount( lst );
375 list.reserve( count );
376 for (
int i = 0; i < count; i++ )
379 list << encoding->toUnicode( lst[i] );
381 list << QString::fromUtf8( lst[i] );
392 case QVariant::String:
395 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
396 const int count = CSLCount( lst );
399 list.reserve( count );
400 for (
int i = 0; i < count; i++ )
403 list << encoding->toUnicode( lst[i] );
405 list << QString::fromUtf8( lst[i] );
416 const int *lst = OGR_F_GetFieldAsIntegerList( ogrFet, attIndex, &count );
419 list.reserve( count );
420 for (
int i = 0; i < count; i++ )
429 case QVariant::Double:
433 const double *lst = OGR_F_GetFieldAsDoubleList( ogrFet, attIndex, &count );
436 list.reserve( count );
437 for (
int i = 0; i < count; i++ )
446 case QVariant::LongLong:
450 const long long *lst = OGR_F_GetFieldAsInteger64List( ogrFet, attIndex, &count );
453 list.reserve( count );
454 for (
int i = 0; i < count; i++ )
465 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
479 value = QJsonDocument::fromJson( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
481 value = QJsonDocument::fromJson( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
485 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
508 for (
int idx = 0; idx < fields.
count(); ++idx )
510 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
524 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
528 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
538 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
539 return std::make_unique< QgsPoint >( wkbType, x, y, z, m );
544 std::unique_ptr< QgsMultiPoint > mp = std::make_unique< QgsMultiPoint >();
546 const int count = OGR_G_GetGeometryCount( geom );
547 mp->reserve( count );
548 for (
int i = 0; i < count; ++i )
560 int count = OGR_G_GetPointCount( geom );
561 QVector< double > x( count );
562 QVector< double > y( count );
564 double *pz =
nullptr;
570 double *pm =
nullptr;
577 OGR_G_GetPointsZM( geom, x.data(),
sizeof(
double ), y.data(),
sizeof(
double ), pz,
sizeof(
double ), pm,
sizeof(
double ) );
584 std::unique_ptr< QgsMultiLineString > mp = std::make_unique< QgsMultiLineString >();
586 const int count = OGR_G_GetGeometryCount( geom );
587 mp->reserve( count );
588 for (
int i = 0; i < count; ++i )
598 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
600 const int count = OGR_G_GetGeometryCount( geom );
606 for (
int i = 1; i < count; ++i )
616 std::unique_ptr< QgsMultiPolygon > polygon = std::make_unique< QgsMultiPolygon >();
618 const int count = OGR_G_GetGeometryCount( geom );
619 polygon->reserve( count );
620 for (
int i = 0; i < count; ++i )
630 switch ( ogrGeomType )
632 case wkbUnknown:
return QgsWkbTypes::Type::Unknown;
633 case wkbPoint:
return QgsWkbTypes::Type::Point;
634 case wkbLineString:
return QgsWkbTypes::Type::LineString;
635 case wkbPolygon:
return QgsWkbTypes::Type::Polygon;
636 case wkbMultiPoint:
return QgsWkbTypes::Type::MultiPoint;
637 case wkbMultiLineString:
return QgsWkbTypes::Type::MultiLineString;
638 case wkbMultiPolygon:
return QgsWkbTypes::Type::MultiPolygon;
639 case wkbGeometryCollection:
return QgsWkbTypes::Type::GeometryCollection;
640 case wkbCircularString:
return QgsWkbTypes::Type::CircularString;
641 case wkbCompoundCurve:
return QgsWkbTypes::Type::CompoundCurve;
642 case wkbCurvePolygon:
return QgsWkbTypes::Type::CurvePolygon;
643 case wkbMultiCurve:
return QgsWkbTypes::Type::MultiCurve;
644 case wkbMultiSurface:
return QgsWkbTypes::Type::MultiSurface;
645 case wkbCurve:
return QgsWkbTypes::Type::Unknown;
646 case wkbSurface:
return QgsWkbTypes::Type::Unknown;
647 case wkbPolyhedralSurface:
return QgsWkbTypes::Type::Unknown;
648 case wkbTIN:
return QgsWkbTypes::Type::Unknown;
649 case wkbTriangle:
return QgsWkbTypes::Type::Triangle;
651 case wkbNone:
return QgsWkbTypes::Type::NoGeometry;
652 case wkbLinearRing:
return QgsWkbTypes::Type::LineString;
654 case wkbCircularStringZ:
return QgsWkbTypes::Type::CircularStringZ;
655 case wkbCompoundCurveZ:
return QgsWkbTypes::Type::CompoundCurveZ;
656 case wkbCurvePolygonZ:
return QgsWkbTypes::Type::CurvePolygonZ;
657 case wkbMultiCurveZ:
return QgsWkbTypes::Type::MultiCurveZ;
658 case wkbMultiSurfaceZ:
return QgsWkbTypes::Type::MultiSurfaceZ;
659 case wkbCurveZ:
return QgsWkbTypes::Type::Unknown;
660 case wkbSurfaceZ:
return QgsWkbTypes::Type::Unknown;
661 case wkbPolyhedralSurfaceZ:
return QgsWkbTypes::Type::Unknown;
662 case wkbTINZ:
return QgsWkbTypes::Type::Unknown;
663 case wkbTriangleZ:
return QgsWkbTypes::Type::TriangleZ;
665 case wkbPointM:
return QgsWkbTypes::Type::PointM;
666 case wkbLineStringM:
return QgsWkbTypes::Type::LineStringM;
667 case wkbPolygonM:
return QgsWkbTypes::Type::PolygonM;
668 case wkbMultiPointM:
return QgsWkbTypes::Type::MultiPointM;
669 case wkbMultiLineStringM:
return QgsWkbTypes::Type::MultiLineStringM;
670 case wkbMultiPolygonM:
return QgsWkbTypes::Type::MultiPolygonM;
671 case wkbGeometryCollectionM:
return QgsWkbTypes::Type::GeometryCollectionM;
672 case wkbCircularStringM:
return QgsWkbTypes::Type::CircularStringM;
673 case wkbCompoundCurveM:
return QgsWkbTypes::Type::CompoundCurveM;
674 case wkbCurvePolygonM:
return QgsWkbTypes::Type::CurvePolygonM;
675 case wkbMultiCurveM:
return QgsWkbTypes::Type::MultiCurveM;
676 case wkbMultiSurfaceM:
return QgsWkbTypes::Type::MultiSurfaceM;
677 case wkbCurveM:
return QgsWkbTypes::Type::Unknown;
678 case wkbSurfaceM:
return QgsWkbTypes::Type::Unknown;
679 case wkbPolyhedralSurfaceM:
return QgsWkbTypes::Type::Unknown;
680 case wkbTINM:
return QgsWkbTypes::Type::Unknown;
681 case wkbTriangleM:
return QgsWkbTypes::Type::TriangleM;
683 case wkbPointZM:
return QgsWkbTypes::Type::PointZM;
684 case wkbLineStringZM:
return QgsWkbTypes::Type::LineStringZM;
685 case wkbPolygonZM:
return QgsWkbTypes::Type::PolygonZM;
686 case wkbMultiPointZM:
return QgsWkbTypes::Type::MultiPointZM;
687 case wkbMultiLineStringZM:
return QgsWkbTypes::Type::MultiLineStringZM;
688 case wkbMultiPolygonZM:
return QgsWkbTypes::Type::MultiPolygonZM;
689 case wkbGeometryCollectionZM:
return QgsWkbTypes::Type::GeometryCollectionZM;
690 case wkbCircularStringZM:
return QgsWkbTypes::Type::CircularStringZM;
691 case wkbCompoundCurveZM:
return QgsWkbTypes::Type::CompoundCurveZM;
692 case wkbCurvePolygonZM:
return QgsWkbTypes::Type::CurvePolygonZM;
693 case wkbMultiCurveZM:
return QgsWkbTypes::Type::MultiCurveZM;
694 case wkbMultiSurfaceZM:
return QgsWkbTypes::Type::MultiSurfaceZM;
695 case wkbCurveZM:
return QgsWkbTypes::Type::Unknown;
696 case wkbSurfaceZM:
return QgsWkbTypes::Type::Unknown;
697 case wkbPolyhedralSurfaceZM:
return QgsWkbTypes::Type::Unknown;
698 case wkbTINZM:
return QgsWkbTypes::Type::Unknown;
699 case wkbTriangleZM:
return QgsWkbTypes::Type::TriangleZM;
701 case wkbPoint25D:
return QgsWkbTypes::Type::PointZ;
702 case wkbLineString25D:
return QgsWkbTypes::Type::LineStringZ;
703 case wkbPolygon25D:
return QgsWkbTypes::Type::PolygonZ;
704 case wkbMultiPoint25D:
return QgsWkbTypes::Type::MultiPointZ;
705 case wkbMultiLineString25D:
return QgsWkbTypes::Type::MultiLineStringZ;
706 case wkbMultiPolygon25D:
return QgsWkbTypes::Type::MultiPolygonZ;
707 case wkbGeometryCollection25D:
return QgsWkbTypes::Type::GeometryCollectionZ;
711 return QgsWkbTypes::Type::Unknown;
719 const auto ogrGeomType = OGR_G_GetGeometryType( geom );
762 if ( wkbFlatten( wkbType ) == wkbGeometryCollection )
765 if ( OGR_G_GetGeometryCount( geom ) >= 1 &&
766 wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
768 auto newGeom = OGR_G_ForceToMultiPolygon( OGR_G_Clone( geom ) );
769 auto ret = ogrGeometryToQgsGeometry( newGeom );
770 OGR_G_DestroyGeometry( newGeom );
776 int memorySize = OGR_G_WkbSize( geom );
777 unsigned char *wkb =
new unsigned char[memorySize];
781 uint32_t origGeomType;
782 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
783 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
784 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
787 if ( origGeomType % 1000 == 16 )
790 int nDims = 2 + hasZ + hasM;
793 unsigned char *wkbptr = wkb;
799 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
804 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
808 for ( uint32_t i = 0; i < numGeoms; ++i )
814 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
815 wkbptr +=
sizeof( uint32_t );
819 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
820 wkbptr +=
sizeof( uint32_t );
822 for ( uint32_t j = 0; j < nRings; ++j )
825 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
826 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
830 else if ( origGeomType % 1000 == 15 )
835 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
846 if (
string.isEmpty() )
849 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
852 QByteArray ba =
string.toUtf8();
853 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
854 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
859 VSIUnlink( randomFileName.toUtf8().constData() );
863 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
867 VSIUnlink( randomFileName.toUtf8().constData() );
872 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
874 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
880 VSIUnlink( randomFileName.toUtf8().constData() );
888 if (
string.isEmpty() )
891 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
894 QByteArray ba =
string.toUtf8();
895 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
896 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
901 VSIUnlink( randomFileName.toUtf8().constData() );
905 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
909 VSIUnlink( randomFileName.toUtf8().constData() );
915 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
917 fields = readOgrFields( oFeat.get(), encoding );
921 VSIUnlink( randomFileName.toUtf8().constData() );
930 for (
qgssize i = 0; stringList[i]; ++i )
932 strings.append( QString::fromUtf8( stringList[i] ) );
943 char *pszWkt =
nullptr;
944 const QByteArray multiLineOption = QStringLiteral(
"MULTILINE=NO" ).toLocal8Bit();
945 const QByteArray formatOption = QStringLiteral(
"FORMAT=WKT2" ).toLocal8Bit();
946 const char *
const options[] = {multiLineOption.constData(), formatOption.constData(),
nullptr};
947 OSRExportToWktEx( srs, &pszWkt, options );
949 const QString res( pszWkt );
956 const QString wkt = OGRSpatialReferenceToWkt( srs );
965 const QString cpgEncoding = readShapefileEncodingFromCpg( path );
966 if ( !cpgEncoding.isEmpty() )
969 return readShapefileEncodingFromLdid( path );
974 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
976 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
977 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_CPG" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
979 if ( !QFileInfo::exists( path ) )
983 const QFileInfo fi( path );
984 const QString baseName = fi.completeBaseName();
985 const QString cpgPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"CPG" ) : QStringLiteral(
"cpg" ) ) );
986 if ( QFile::exists( cpgPath ) )
988 QFile cpgFile( cpgPath );
989 if ( cpgFile.open( QIODevice::ReadOnly ) )
991 QTextStream cpgStream( &cpgFile );
992 const QString cpgString = cpgStream.readLine();
995 if ( !cpgString.isEmpty() )
1000 int cpgCodePage = cpgString.toInt( &ok );
1001 if ( ok && ( ( cpgCodePage >= 437 && cpgCodePage <= 950 )
1002 || ( cpgCodePage >= 1250 && cpgCodePage <= 1258 ) ) )
1004 return QStringLiteral(
"CP%1" ).arg( cpgCodePage );
1006 else if ( cpgString.startsWith( QLatin1String(
"8859" ) ) )
1008 if ( cpgString.length() > 4 && cpgString.at( 4 ) ==
'-' )
1009 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 5 ) );
1011 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 4 ) );
1013 else if ( cpgString.startsWith( QLatin1String(
"UTF-8" ), Qt::CaseInsensitive ) ||
1014 cpgString.startsWith( QLatin1String(
"UTF8" ), Qt::CaseInsensitive ) )
1015 return QStringLiteral(
"UTF-8" );
1016 else if ( cpgString.startsWith( QLatin1String(
"ANSI 1251" ), Qt::CaseInsensitive ) )
1017 return QStringLiteral(
"CP1251" );
1030 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1032 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1033 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_LDID" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1038 if ( !QFileInfo::exists( path ) )
1042 const QFileInfo fi( path );
1043 const QString baseName = fi.completeBaseName();
1046 const QString dbfPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"DBF" ) : QStringLiteral(
"dbf" ) ) );
1047 if ( QFile::exists( dbfPath ) )
1049 QFile dbfFile( dbfPath );
1050 if ( dbfFile.open( QIODevice::ReadOnly ) )
1053 QDataStream dbfIn( &dbfFile );
1054 dbfIn.setByteOrder( QDataStream::LittleEndian );
1064 case 1: nCP = 437;
break;
1065 case 2: nCP = 850;
break;
1066 case 3: nCP = 1252;
break;
1067 case 4: nCP = 10000;
break;
1068 case 8: nCP = 865;
break;
1069 case 10: nCP = 850;
break;
1070 case 11: nCP = 437;
break;
1071 case 13: nCP = 437;
break;
1072 case 14: nCP = 850;
break;
1073 case 15: nCP = 437;
break;
1074 case 16: nCP = 850;
break;
1075 case 17: nCP = 437;
break;
1076 case 18: nCP = 850;
break;
1077 case 19: nCP = 932;
break;
1078 case 20: nCP = 850;
break;
1079 case 21: nCP = 437;
break;
1080 case 22: nCP = 850;
break;
1081 case 23: nCP = 865;
break;
1082 case 24: nCP = 437;
break;
1083 case 25: nCP = 437;
break;
1084 case 26: nCP = 850;
break;
1085 case 27: nCP = 437;
break;
1086 case 28: nCP = 863;
break;
1087 case 29: nCP = 850;
break;
1088 case 31: nCP = 852;
break;
1089 case 34: nCP = 852;
break;
1090 case 35: nCP = 852;
break;
1091 case 36: nCP = 860;
break;
1092 case 37: nCP = 850;
break;
1093 case 38: nCP = 866;
break;
1094 case 55: nCP = 850;
break;
1095 case 64: nCP = 852;
break;
1096 case 77: nCP = 936;
break;
1097 case 78: nCP = 949;
break;
1098 case 79: nCP = 950;
break;
1099 case 80: nCP = 874;
break;
1100 case 87:
return QStringLiteral(
"ISO-8859-1" );
1101 case 88: nCP = 1252;
break;
1102 case 89: nCP = 1252;
break;
1103 case 100: nCP = 852;
break;
1104 case 101: nCP = 866;
break;
1105 case 102: nCP = 865;
break;
1106 case 103: nCP = 861;
break;
1107 case 104: nCP = 895;
break;
1108 case 105: nCP = 620;
break;
1109 case 106: nCP = 737;
break;
1110 case 107: nCP = 857;
break;
1111 case 108: nCP = 863;
break;
1112 case 120: nCP = 950;
break;
1113 case 121: nCP = 949;
break;
1114 case 122: nCP = 936;
break;
1115 case 123: nCP = 932;
break;
1116 case 124: nCP = 874;
break;
1117 case 134: nCP = 737;
break;
1118 case 135: nCP = 852;
break;
1119 case 136: nCP = 857;
break;
1120 case 150: nCP = 10007;
break;
1121 case 151: nCP = 10029;
break;
1122 case 200: nCP = 1250;
break;
1123 case 201: nCP = 1251;
break;
1124 case 202: nCP = 1254;
break;
1125 case 203: nCP = 1253;
break;
1126 case 204: nCP = 1257;
break;
1132 return QStringLiteral(
"CP%1" ).arg( nCP );
1144 char **papszStyleString = CSLTokenizeString2(
string.toUtf8().constData(),
";",
1146 | CSLT_PRESERVEQUOTES
1147 | CSLT_PRESERVEESCAPES );
1148 for (
int i = 0; papszStyleString[i] !=
nullptr; ++i )
1154 const thread_local QRegularExpression sToolPartRx( QStringLiteral(
"^(.*?)\\((.*)\\)$" ) );
1155 const QString stylePart( papszStyleString[i] );
1156 const QRegularExpressionMatch match = sToolPartRx.match( stylePart );
1157 if ( !match.hasMatch() )
1160 const QString tool = match.captured( 1 );
1161 const QString params = match.captured( 2 );
1163 char **papszTokens = CSLTokenizeString2( params.toUtf8().constData(),
",", CSLT_HONOURSTRINGS
1164 | CSLT_PRESERVEESCAPES );
1166 QVariantMap toolParts;
1167 const thread_local QRegularExpression sToolParamRx( QStringLiteral(
"^(.*?):(.*)$" ) );
1168 for (
int j = 0; papszTokens[j] !=
nullptr; ++j )
1170 const QString toolPart( papszTokens[j] );
1171 const QRegularExpressionMatch toolMatch = sToolParamRx.match( toolPart );
1172 if ( !match.hasMatch() )
1176 toolParts.insert( toolMatch.captured( 1 ).toLower(), toolMatch.captured( 2 ) );
1178 CSLDestroy( papszTokens );
1181 styles.insert( tool.toLower(), toolParts );
1183 CSLDestroy( papszStyleString );
1189 const QVariantMap styles = parseStyleString(
string );
1193 const thread_local QRegularExpression sUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.]+)(g|px|pt|mm|cm|in)$" ) );
1194 const QRegularExpressionMatch match = sUnitRx.match( size );
1195 if ( match.hasMatch() )
1197 value = match.captured( 1 ).toDouble();
1198 const QString unitString = match.captured( 2 );
1199 if ( unitString.compare( QLatin1String(
"px" ), Qt::CaseInsensitive ) == 0 )
1203 static constexpr
double PT_TO_INCHES_FACTOR = 1 / 72.0;
1204 static constexpr
double PX_TO_PT_FACTOR = 1 / ( 96.0 * PT_TO_INCHES_FACTOR );
1206 value *= PX_TO_PT_FACTOR;
1209 else if ( unitString.compare( QLatin1String(
"pt" ), Qt::CaseInsensitive ) == 0 )
1214 else if ( unitString.compare( QLatin1String(
"mm" ), Qt::CaseInsensitive ) == 0 )
1219 else if ( unitString.compare( QLatin1String(
"cm" ), Qt::CaseInsensitive ) == 0 )
1225 else if ( unitString.compare( QLatin1String(
"in" ), Qt::CaseInsensitive ) == 0 )
1230 else if ( unitString.compare( QLatin1String(
"g" ), Qt::CaseInsensitive ) == 0 )
1235 QgsDebugMsg( QStringLiteral(
"Unknown unit %1" ).arg( unitString ) );
1239 QgsDebugMsg( QStringLiteral(
"Could not parse style size %1" ).arg( size ) );
1244 auto convertColor = [](
const QString & string ) -> QColor
1246 if (
string.isEmpty() )
1249 const thread_local QRegularExpression sColorWithAlphaRx = QRegularExpression( QStringLiteral(
"^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})$" ) );
1250 const QRegularExpressionMatch match = sColorWithAlphaRx.match(
string );
1251 if ( match.hasMatch() )
1254 return QColor( QStringLiteral(
"#%1%2" ).arg( match.captured( 2 ), match.captured( 1 ) ) );
1258 return QColor(
string );
1262 auto convertPen = [&convertColor, &convertSize, string](
const QVariantMap & lineStyle ) -> std::unique_ptr< QgsSymbol >
1264 QColor color = convertColor( lineStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1268 convertSize( lineStyle.value( QStringLiteral(
"w" ) ).toString(), lineWidth, lineWidthUnit );
1271 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-pen-(\\d+)" ) );
1272 const QRegularExpressionMatch match = sMapInfoId.match(
string );
1273 if ( match.hasMatch() )
1275 const int penId = match.captured( 1 ).toInt();
1282 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( color, lineWidth );
1283 simpleLine->setWidthUnit( lineWidthUnit );
1286 const QString pattern = lineStyle.value( QStringLiteral(
"p" ) ).toString();
1287 if ( !pattern.isEmpty() )
1289 const thread_local QRegularExpression sPatternUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.\\s]+)(g|px|pt|mm|cm|in)$" ) );
1290 const QRegularExpressionMatch match = sPatternUnitRx.match( pattern );
1291 if ( match.hasMatch() )
1293 const QStringList patternValues = match.captured( 1 ).split(
' ' );
1294 QVector< qreal > dashPattern;
1296 for (
const QString &val : patternValues )
1299 convertSize( val + match.captured( 2 ), length, patternUnits );
1300 dashPattern.push_back( length * lineWidth * 2 );
1303 simpleLine->setCustomDashVector( dashPattern );
1304 simpleLine->setCustomDashPatternUnit( patternUnits );
1305 simpleLine->setUseCustomDashPattern(
true );
1309 Qt::PenCapStyle capStyle = Qt::FlatCap;
1310 Qt::PenJoinStyle joinStyle = Qt::MiterJoin;
1312 const QString
id = lineStyle.value( QStringLiteral(
"id" ) ).toString();
1313 if (
id.contains( QLatin1String(
"mapinfo-pen" ), Qt::CaseInsensitive ) )
1318 capStyle = Qt::RoundCap;
1319 joinStyle = Qt::RoundJoin;
1323 const QString penCap = lineStyle.value( QStringLiteral(
"cap" ) ).toString();
1324 if ( penCap.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1326 capStyle = Qt::FlatCap;
1328 else if ( penCap.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1330 capStyle = Qt::RoundCap;
1332 else if ( penCap.compare( QLatin1String(
"p" ), Qt::CaseInsensitive ) == 0 )
1334 capStyle = Qt::SquareCap;
1336 simpleLine->setPenCapStyle( capStyle );
1339 const QString penJoin = lineStyle.value( QStringLiteral(
"j" ) ).toString();
1340 if ( penJoin.compare( QLatin1String(
"m" ), Qt::CaseInsensitive ) == 0 )
1342 joinStyle = Qt::MiterJoin;
1344 else if ( penJoin.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1346 joinStyle = Qt::RoundJoin;
1348 else if ( penJoin.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1350 joinStyle = Qt::BevelJoin;
1352 simpleLine->setPenJoinStyle( joinStyle );
1354 const QString priority = lineStyle.value( QStringLiteral(
"l" ) ).toString();
1355 if ( !priority.isEmpty() )
1357 simpleLine->setRenderingPass( priority.toInt() );
1359 return std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
1362 auto convertBrush = [&convertColor](
const QVariantMap & brushStyle ) -> std::unique_ptr< QgsSymbol >
1364 const QColor foreColor = convertColor( brushStyle.value( QStringLiteral(
"fc" ), QStringLiteral(
"#000000" ) ).toString() );
1365 const QColor backColor = convertColor( brushStyle.value( QStringLiteral(
"bc" ), QString() ).toString() );
1367 const QString
id = brushStyle.value( QStringLiteral(
"id" ) ).toString();
1370 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-brush-(\\d+)" ) );
1371 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1372 if ( match.hasMatch() )
1374 const int brushId = match.captured( 1 ).toInt();
1381 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-brush-(\\d+)" ) );
1382 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1384 Qt::BrushStyle style = Qt::SolidPattern;
1385 if ( ogrMatch.hasMatch() )
1387 const int brushId = ogrMatch.captured( 1 ).toInt();
1391 style = Qt::SolidPattern;
1395 style = Qt::NoBrush;
1399 style = Qt::HorPattern;
1403 style = Qt::VerPattern;
1407 style = Qt::FDiagPattern;
1411 style = Qt::BDiagPattern;
1415 style = Qt::CrossPattern;
1419 style = Qt::DiagCrossPattern;
1425 if ( backColor.isValid() && style != Qt::SolidPattern && style != Qt::NoBrush )
1427 std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1428 backgroundFill->setLocked(
true );
1429 backgroundFill->setStrokeStyle( Qt::NoPen );
1430 layers << backgroundFill.release();
1433 std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1434 foregroundFill->setBrushStyle( style );
1435 foregroundFill->setStrokeStyle( Qt::NoPen );
1437 const QString priority = brushStyle.value( QStringLiteral(
"l" ) ).toString();
1438 if ( !priority.isEmpty() )
1440 foregroundFill->setRenderingPass( priority.toInt() );
1442 layers << foregroundFill.release();
1443 return std::make_unique< QgsFillSymbol >( layers );
1446 auto convertSymbol = [&convertColor, &convertSize, string](
const QVariantMap & symbolStyle ) -> std::unique_ptr< QgsSymbol >
1448 const QColor color = convertColor( symbolStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1452 convertSize( symbolStyle.value( QStringLiteral(
"s" ) ).toString(), symbolSize, symbolSizeUnit );
1454 const double angle = symbolStyle.value( QStringLiteral(
"a" ), QStringLiteral(
"0" ) ).toDouble();
1456 const QString
id = symbolStyle.value( QStringLiteral(
"id" ) ).toString();
1459 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-sym-(\\d+)" ) );
1460 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1461 if ( match.hasMatch() )
1463 const int symbolId = match.captured( 1 ).toInt();
1474 std::unique_ptr< QgsMarkerSymbolLayer > markerLayer;
1476 const thread_local QRegularExpression sFontId = QRegularExpression( QStringLiteral(
"font-sym-(\\d+)" ) );
1477 const QRegularExpressionMatch fontMatch = sFontId.match(
id );
1478 if ( fontMatch.hasMatch() )
1480 const int symId = fontMatch.captured( 1 ).toInt();
1481 const QStringList families = symbolStyle.value( QStringLiteral(
"f" ), QString() ).toString().split(
',' );
1483 bool familyFound =
false;
1485 for (
const QString &family : std::as_const( families ) )
1490 fontFamily = family;
1497 std::unique_ptr< QgsFontMarkerSymbolLayer > fontMarker = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, QChar( symId ), symbolSize );
1498 fontMarker->setSizeUnit( symbolSizeUnit );
1499 fontMarker->setAngle( -
angle );
1501 fontMarker->setColor( color );
1503 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1504 if ( strokeColor.isValid() )
1506 fontMarker->setStrokeColor( strokeColor );
1507 fontMarker->setStrokeWidth( 1 );
1512 fontMarker->setStrokeWidth( 0 );
1515 markerLayer = std::move( fontMarker );
1517 else if ( !families.empty() )
1526 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-sym-(\\d+)" ) );
1527 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1530 bool isFilled =
true;
1531 if ( ogrMatch.hasMatch() )
1533 const int symId = ogrMatch.captured( 1 ).toInt();
1537 shape = QgsSimpleMarkerSymbolLayer::Shape::Cross;
1541 shape = QgsSimpleMarkerSymbolLayer::Shape::Cross2;
1546 shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1550 shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1555 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1559 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1564 shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1568 shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1573 shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1577 shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1581 shape = QgsSimpleMarkerSymbolLayer::Shape::Line;
1586 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1593 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1596 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, symbolSize, -
angle );
1597 simpleMarker->setSizeUnit( symbolSizeUnit );
1601 simpleMarker->setColor( color );
1602 simpleMarker->setStrokeStyle( Qt::NoPen );
1606 simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1607 simpleMarker->setStrokeColor( color );
1610 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1611 if ( strokeColor.isValid() )
1613 simpleMarker->setStrokeColor( strokeColor );
1614 simpleMarker->setStrokeStyle( Qt::SolidLine );
1617 markerLayer = std::move( simpleMarker );
1620 return std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << markerLayer.release() );
1626 if ( styles.contains( QStringLiteral(
"symbol" ) ) )
1628 const QVariantMap symbolStyle = styles.value( QStringLiteral(
"symbol" ) ).toMap();
1629 return convertSymbol( symbolStyle );
1637 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1640 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1641 return convertPen( lineStyle );
1650 std::unique_ptr< QgsSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1651 if ( styles.contains( QStringLiteral(
"brush" ) ) )
1653 const QVariantMap brushStyle = styles.value( QStringLiteral(
"brush" ) ).toMap();
1654 fillSymbol = convertBrush( brushStyle );
1658 std::unique_ptr< QgsSimpleFillSymbolLayer > emptyFill = std::make_unique< QgsSimpleFillSymbolLayer >();
1659 emptyFill->setBrushStyle( Qt::NoBrush );
1660 fillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << emptyFill.release() );
1663 std::unique_ptr< QgsSymbol > penSymbol;
1664 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1666 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1667 penSymbol = convertPen( lineStyle );
1672 const int count = penSymbol->symbolLayerCount();
1682 for (
int i = 0; i < count; ++i )
1684 std::unique_ptr< QgsSymbolLayer > layer( penSymbol->takeSymbolLayer( 0 ) );
1685 layer->setLocked(
true );
1686 fillSymbol->appendSymbolLayer( layer.release() );
static endian_t endian()
Returns whether this machine uses big or little endian.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool setAttribute(int field, const QVariant &attr)
Sets an attribute's value by field index.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assigns a field map with the feature to allow attribute access by attribute name.
void setId(QgsFeatureId id)
Sets the feature id for this feature.
void clearGeometry()
Removes any geometry associated with the feature.
void setValid(bool validity)
Sets the validity of the feature.
bool isValid() const
Returns the validity of this feature.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Encapsulate a field in an attribute table or data source.
QVariant::Type subType() const
If the field is a collection, gets its element's type.
Container of fields for a vector layer.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
A geometry is the spatial representation of a feature.
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length.
Context for a MapInfo symbol conversion operation.
static QgsFillSymbol * convertFillSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, const QColor &backColor=QColor())
Converts the MapInfo fill symbol with the specified identifier to a QgsFillSymbol.
static QgsLineSymbol * convertLineSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &foreColor, double size, QgsUnitTypes::RenderUnit sizeUnit, bool interleaved=false)
Converts the MapInfo line symbol with the specified identifier to a QgsLineSymbol.
static QgsMarkerSymbol * convertMarkerSymbol(int identifier, QgsMapInfoSymbolConversionContext &context, const QColor &color, double size, QgsUnitTypes::RenderUnit sizeUnit)
Converts the MapInfo marker symbol with the specified identifier to a QgsMarkerSymbol.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
static QString readShapefileEncoding(const QString &path)
Reads the encoding of the shapefile at the specified path (where path is the location of the "....
static bool readOgrFeatureAttributes(OGRFeatureH ogrFet, const QgsFields &fields, QgsFeature &feature, QTextCodec *encoding)
Reads all attributes from an OGR feature into a QgsFeature.
static QgsGeometry ogrGeometryToQgsGeometry(OGRGeometryH geom)
Converts an OGR geometry representation to a QgsGeometry object.
static QString OGRSpatialReferenceToWkt(OGRSpatialReferenceH srs)
Returns a WKT string corresponding to the specified OGR srs object.
static QVariant OGRFieldtoVariant(const OGRField *value, OGRFieldType type)
Converts an OGRField value of the specified type into a QVariant.
static QgsFeature readOgrFeature(OGRFeatureH ogrFet, const QgsFields &fields, QTextCodec *encoding)
Reads an OGR feature and converts it to a QgsFeature.
static QStringList cStringListToQStringList(char **stringList)
Converts a c string list to a QStringList.
static QgsFields readOgrFields(OGRFeatureH ogrFet, QTextCodec *encoding)
Reads an OGR feature and returns a corresponding fields collection.
static QgsWkbTypes::Type ogrGeometryTypeToQgsWkbType(OGRwkbGeometryType ogrGeomType)
Converts a OGRwkbGeometryType to QgsWkbTypes::Type.
static QgsCoordinateReferenceSystem OGRSpatialReferenceToCrs(OGRSpatialReferenceH srs)
Returns a QgsCoordinateReferenceSystem corresponding to the specified OGR srs object,...
static QgsFeatureList stringToFeatureList(const QString &string, const QgsFields &fields, QTextCodec *encoding)
Attempts to parse a string representing a collection of features using OGR.
static QString readShapefileEncodingFromCpg(const QString &path)
Reads the encoding of the shapefile at the specified path (where path is the location of the "....
static bool readOgrFeatureGeometry(OGRFeatureH ogrFet, QgsFeature &feature)
Reads the geometry from an OGR feature into a QgsFeature.
static QgsFields stringToFields(const QString &string, QTextCodec *encoding)
Attempts to retrieve the fields from a string representing a collection of features using OGR.
static QString readShapefileEncodingFromLdid(const QString &path)
Reads the encoding of the shapefile at the specified path (where path is the location of the "....
static std::unique_ptr< QgsSymbol > symbolFromStyleString(const QString &string, Qgis::SymbolType type)
Creates a new QgsSymbol matching an OGR style string.
static QVariantMap parseStyleString(const QString &string)
Parses an OGR style string to a variant map containing the style string components.
static QVariant getOgrFeatureAttribute(OGRFeatureH ogrFet, const QgsFields &fields, int attIndex, QTextCodec *encoding, bool *ok=nullptr)
Retrieves an attribute value from an OGR feature.
static bool shapeIsFilled(QgsSimpleMarkerSymbolLayerBase::Shape shape)
Returns true if a symbol shape has a fill.
Shape
Marker symbol shapes.
static bool condenseFillAndOutline(QgsFillSymbolLayer *fill, QgsLineSymbolLayer *outline)
Attempts to condense a fill and outline layer, by moving the outline layer to the fill symbol's strok...
RenderUnit
Rendering size units.
@ RenderPoints
Points (e.g., for font sizes)
@ RenderMillimeters
Millimeters.
@ RenderMapUnits
Map units.
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Type
The WKB type describes the number of dimensions a geometry has.
static Type zmType(Type type, bool hasZ, bool hasM) SIP_HOLDGIL
Returns the modified input geometry type according to hasZ / hasM.
static Type flatType(Type type) SIP_HOLDGIL
Returns the flat type for a WKB type.
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
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)
void CORE_EXPORT fast_delete_and_close(dataset_unique_ptr &dataset, GDALDriverH driver, const QString &path)
Performs a fast close of an unwanted GDAL dataset handle by deleting the underlying data store.
std::unique_ptr< std::remove_pointer< OGRFeatureH >::type, OGRFeatureDeleter > ogr_feature_unique_ptr
Scoped OGR feature.
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
std::unique_ptr< std::remove_pointer< OGRDataSourceH >::type, OGRDataSourceDeleter > ogr_datasource_unique_ptr
Scoped OGR data source.
unsigned long long qgssize
Qgssize is used instead of size_t, because size_t is stdlib type, unknown by SIP, and it would be har...
void * OGRSpatialReferenceH
QList< QgsFeature > QgsFeatureList
#define DEFAULT_SIMPLELINE_WIDTH
#define DEFAULT_SIMPLEMARKER_SIZE
std::unique_ptr< QgsLineString > ogrGeometryToQgsLineString(OGRGeometryH geom)
std::unique_ptr< QgsMultiLineString > ogrGeometryToQgsMultiLineString(OGRGeometryH geom)
std::unique_ptr< QgsMultiPoint > ogrGeometryToQgsMultiPoint(OGRGeometryH geom)
std::unique_ptr< QgsPolygon > ogrGeometryToQgsPolygon(OGRGeometryH geom)
std::unique_ptr< QgsPoint > ogrGeometryToQgsPoint(OGRGeometryH geom)
std::unique_ptr< QgsMultiPolygon > ogrGeometryToQgsMultiPolygon(OGRGeometryH geom)
QList< QgsSymbolLayer * > QgsSymbolLayerList
void CORE_EXPORT operator()(GDALDatasetH datasource)
Destroys an gdal dataset, using the correct gdal calls.
void CORE_EXPORT operator()(GDALWarpOptions *options)
Destroys GDAL warp options, using the correct gdal calls.
void CORE_EXPORT operator()(OGRDataSourceH source)
Destroys an OGR data source, using the correct gdal calls.
void CORE_EXPORT operator()(OGRFeatureH feature)
Destroys an OGR feature, using the correct gdal calls.
void CORE_EXPORT operator()(OGRFieldDefnH definition)
Destroys an OGR field definition, using the correct gdal calls.
void CORE_EXPORT operator()(OGRGeometryH geometry)
Destroys an OGR geometry, using the correct gdal calls.