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, tzf;
344 float secondsPart = 0;
346 OGR_F_GetFieldAsDateTimeEx( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
347 float millisecondPart = std::modf( second, &secondsPart );
350 value = QDate( year, month, day );
351 else if (
field.
type() == QVariant::Time )
352 value = QTime( hour, minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) );
354 value = QDateTime( QDate( year, month, day ),
355 QTime( hour, minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) ) );
359 case QVariant::ByteArray:
362 const GByte *b = OGR_F_GetFieldAsBinary( ogrFet, attIndex, &size );
366 QByteArray ba = QByteArray::fromRawData(
reinterpret_cast<const char *
>( b ), size );
373 case QVariant::StringList:
376 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
377 const int count = CSLCount( lst );
380 list.reserve( count );
381 for (
int i = 0; i < count; i++ )
384 list << encoding->toUnicode( lst[i] );
386 list << QString::fromUtf8( lst[i] );
397 case QVariant::String:
400 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
401 const int count = CSLCount( lst );
404 list.reserve( count );
405 for (
int i = 0; i < count; i++ )
408 list << encoding->toUnicode( lst[i] );
410 list << QString::fromUtf8( lst[i] );
421 const int *lst = OGR_F_GetFieldAsIntegerList( ogrFet, attIndex, &count );
424 list.reserve( count );
425 for (
int i = 0; i < count; i++ )
434 case QVariant::Double:
438 const double *lst = OGR_F_GetFieldAsDoubleList( ogrFet, attIndex, &count );
441 list.reserve( count );
442 for (
int i = 0; i < count; i++ )
451 case QVariant::LongLong:
455 const long long *lst = OGR_F_GetFieldAsInteger64List( ogrFet, attIndex, &count );
458 list.reserve( count );
459 for (
int i = 0; i < count; i++ )
470 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
484 value = QJsonDocument::fromJson( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
486 value = QJsonDocument::fromJson( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
490 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
513 for (
int idx = 0; idx < fields.
count(); ++idx )
515 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
529 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
533 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
543 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
544 return std::make_unique< QgsPoint >( wkbType, x, y, z, m );
549 std::unique_ptr< QgsMultiPoint > mp = std::make_unique< QgsMultiPoint >();
551 const int count = OGR_G_GetGeometryCount( geom );
552 mp->reserve( count );
553 for (
int i = 0; i < count; ++i )
565 int count = OGR_G_GetPointCount( geom );
566 QVector< double > x( count );
567 QVector< double > y( count );
569 double *pz =
nullptr;
575 double *pm =
nullptr;
582 OGR_G_GetPointsZM( geom, x.data(),
sizeof(
double ), y.data(),
sizeof(
double ), pz,
sizeof(
double ), pm,
sizeof(
double ) );
589 std::unique_ptr< QgsMultiLineString > mp = std::make_unique< QgsMultiLineString >();
591 const int count = OGR_G_GetGeometryCount( geom );
592 mp->reserve( count );
593 for (
int i = 0; i < count; ++i )
603 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
605 const int count = OGR_G_GetGeometryCount( geom );
611 for (
int i = 1; i < count; ++i )
621 std::unique_ptr< QgsMultiPolygon > polygon = std::make_unique< QgsMultiPolygon >();
623 const int count = OGR_G_GetGeometryCount( geom );
624 polygon->reserve( count );
625 for (
int i = 0; i < count; ++i )
635 switch ( ogrGeomType )
637 case wkbUnknown:
return QgsWkbTypes::Type::Unknown;
638 case wkbPoint:
return QgsWkbTypes::Type::Point;
639 case wkbLineString:
return QgsWkbTypes::Type::LineString;
640 case wkbPolygon:
return QgsWkbTypes::Type::Polygon;
641 case wkbMultiPoint:
return QgsWkbTypes::Type::MultiPoint;
642 case wkbMultiLineString:
return QgsWkbTypes::Type::MultiLineString;
643 case wkbMultiPolygon:
return QgsWkbTypes::Type::MultiPolygon;
644 case wkbGeometryCollection:
return QgsWkbTypes::Type::GeometryCollection;
645 case wkbCircularString:
return QgsWkbTypes::Type::CircularString;
646 case wkbCompoundCurve:
return QgsWkbTypes::Type::CompoundCurve;
647 case wkbCurvePolygon:
return QgsWkbTypes::Type::CurvePolygon;
648 case wkbMultiCurve:
return QgsWkbTypes::Type::MultiCurve;
649 case wkbMultiSurface:
return QgsWkbTypes::Type::MultiSurface;
650 case wkbCurve:
return QgsWkbTypes::Type::Unknown;
651 case wkbSurface:
return QgsWkbTypes::Type::Unknown;
652 case wkbPolyhedralSurface:
return QgsWkbTypes::Type::Unknown;
653 case wkbTIN:
return QgsWkbTypes::Type::Unknown;
654 case wkbTriangle:
return QgsWkbTypes::Type::Triangle;
656 case wkbNone:
return QgsWkbTypes::Type::NoGeometry;
657 case wkbLinearRing:
return QgsWkbTypes::Type::LineString;
659 case wkbCircularStringZ:
return QgsWkbTypes::Type::CircularStringZ;
660 case wkbCompoundCurveZ:
return QgsWkbTypes::Type::CompoundCurveZ;
661 case wkbCurvePolygonZ:
return QgsWkbTypes::Type::CurvePolygonZ;
662 case wkbMultiCurveZ:
return QgsWkbTypes::Type::MultiCurveZ;
663 case wkbMultiSurfaceZ:
return QgsWkbTypes::Type::MultiSurfaceZ;
664 case wkbCurveZ:
return QgsWkbTypes::Type::Unknown;
665 case wkbSurfaceZ:
return QgsWkbTypes::Type::Unknown;
666 case wkbPolyhedralSurfaceZ:
return QgsWkbTypes::Type::Unknown;
667 case wkbTINZ:
return QgsWkbTypes::Type::Unknown;
668 case wkbTriangleZ:
return QgsWkbTypes::Type::TriangleZ;
670 case wkbPointM:
return QgsWkbTypes::Type::PointM;
671 case wkbLineStringM:
return QgsWkbTypes::Type::LineStringM;
672 case wkbPolygonM:
return QgsWkbTypes::Type::PolygonM;
673 case wkbMultiPointM:
return QgsWkbTypes::Type::MultiPointM;
674 case wkbMultiLineStringM:
return QgsWkbTypes::Type::MultiLineStringM;
675 case wkbMultiPolygonM:
return QgsWkbTypes::Type::MultiPolygonM;
676 case wkbGeometryCollectionM:
return QgsWkbTypes::Type::GeometryCollectionM;
677 case wkbCircularStringM:
return QgsWkbTypes::Type::CircularStringM;
678 case wkbCompoundCurveM:
return QgsWkbTypes::Type::CompoundCurveM;
679 case wkbCurvePolygonM:
return QgsWkbTypes::Type::CurvePolygonM;
680 case wkbMultiCurveM:
return QgsWkbTypes::Type::MultiCurveM;
681 case wkbMultiSurfaceM:
return QgsWkbTypes::Type::MultiSurfaceM;
682 case wkbCurveM:
return QgsWkbTypes::Type::Unknown;
683 case wkbSurfaceM:
return QgsWkbTypes::Type::Unknown;
684 case wkbPolyhedralSurfaceM:
return QgsWkbTypes::Type::Unknown;
685 case wkbTINM:
return QgsWkbTypes::Type::Unknown;
686 case wkbTriangleM:
return QgsWkbTypes::Type::TriangleM;
688 case wkbPointZM:
return QgsWkbTypes::Type::PointZM;
689 case wkbLineStringZM:
return QgsWkbTypes::Type::LineStringZM;
690 case wkbPolygonZM:
return QgsWkbTypes::Type::PolygonZM;
691 case wkbMultiPointZM:
return QgsWkbTypes::Type::MultiPointZM;
692 case wkbMultiLineStringZM:
return QgsWkbTypes::Type::MultiLineStringZM;
693 case wkbMultiPolygonZM:
return QgsWkbTypes::Type::MultiPolygonZM;
694 case wkbGeometryCollectionZM:
return QgsWkbTypes::Type::GeometryCollectionZM;
695 case wkbCircularStringZM:
return QgsWkbTypes::Type::CircularStringZM;
696 case wkbCompoundCurveZM:
return QgsWkbTypes::Type::CompoundCurveZM;
697 case wkbCurvePolygonZM:
return QgsWkbTypes::Type::CurvePolygonZM;
698 case wkbMultiCurveZM:
return QgsWkbTypes::Type::MultiCurveZM;
699 case wkbMultiSurfaceZM:
return QgsWkbTypes::Type::MultiSurfaceZM;
700 case wkbCurveZM:
return QgsWkbTypes::Type::Unknown;
701 case wkbSurfaceZM:
return QgsWkbTypes::Type::Unknown;
702 case wkbPolyhedralSurfaceZM:
return QgsWkbTypes::Type::Unknown;
703 case wkbTINZM:
return QgsWkbTypes::Type::Unknown;
704 case wkbTriangleZM:
return QgsWkbTypes::Type::TriangleZM;
706 case wkbPoint25D:
return QgsWkbTypes::Type::PointZ;
707 case wkbLineString25D:
return QgsWkbTypes::Type::LineStringZ;
708 case wkbPolygon25D:
return QgsWkbTypes::Type::PolygonZ;
709 case wkbMultiPoint25D:
return QgsWkbTypes::Type::MultiPointZ;
710 case wkbMultiLineString25D:
return QgsWkbTypes::Type::MultiLineStringZ;
711 case wkbMultiPolygon25D:
return QgsWkbTypes::Type::MultiPolygonZ;
712 case wkbGeometryCollection25D:
return QgsWkbTypes::Type::GeometryCollectionZ;
716 return QgsWkbTypes::Type::Unknown;
724 const auto ogrGeomType = OGR_G_GetGeometryType( geom );
767 if ( wkbFlatten( wkbType ) == wkbGeometryCollection )
770 if ( OGR_G_GetGeometryCount( geom ) >= 1 &&
771 wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
773 auto newGeom = OGR_G_ForceToMultiPolygon( OGR_G_Clone( geom ) );
774 auto ret = ogrGeometryToQgsGeometry( newGeom );
775 OGR_G_DestroyGeometry( newGeom );
781 int memorySize = OGR_G_WkbSize( geom );
782 unsigned char *wkb =
new unsigned char[memorySize];
786 uint32_t origGeomType;
787 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
788 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
789 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
792 if ( origGeomType % 1000 == 16 )
795 int nDims = 2 + hasZ + hasM;
798 unsigned char *wkbptr = wkb;
804 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
809 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
813 for ( uint32_t i = 0; i < numGeoms; ++i )
819 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
820 wkbptr +=
sizeof( uint32_t );
824 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
825 wkbptr +=
sizeof( uint32_t );
827 for ( uint32_t j = 0; j < nRings; ++j )
830 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
831 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
835 else if ( origGeomType % 1000 == 15 )
840 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
851 if (
string.isEmpty() )
854 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
857 QByteArray ba =
string.toUtf8();
858 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
859 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
864 VSIUnlink( randomFileName.toUtf8().constData() );
868 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
872 VSIUnlink( randomFileName.toUtf8().constData() );
877 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
879 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
885 VSIUnlink( randomFileName.toUtf8().constData() );
893 if (
string.isEmpty() )
896 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
899 QByteArray ba =
string.toUtf8();
900 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
901 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
906 VSIUnlink( randomFileName.toUtf8().constData() );
910 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
914 VSIUnlink( randomFileName.toUtf8().constData() );
920 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
922 fields = readOgrFields( oFeat.get(), encoding );
926 VSIUnlink( randomFileName.toUtf8().constData() );
935 for (
qgssize i = 0; stringList[i]; ++i )
937 strings.append( QString::fromUtf8( stringList[i] ) );
948 char *pszWkt =
nullptr;
949 const QByteArray multiLineOption = QStringLiteral(
"MULTILINE=NO" ).toLocal8Bit();
950 const QByteArray formatOption = QStringLiteral(
"FORMAT=WKT2" ).toLocal8Bit();
951 const char *
const options[] = {multiLineOption.constData(), formatOption.constData(),
nullptr};
952 OSRExportToWktEx( srs, &pszWkt, options );
954 const QString res( pszWkt );
961 const QString wkt = OGRSpatialReferenceToWkt( srs );
965 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
967 const double coordinateEpoch = OSRGetCoordinateEpoch( srs );
968 if ( coordinateEpoch > 0 )
984 OSRSetAxisMappingStrategy( ogrSrs, OAMS_TRADITIONAL_GIS_ORDER );
985 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
1000 const QString cpgEncoding = readShapefileEncodingFromCpg( path );
1001 if ( !cpgEncoding.isEmpty() )
1004 return readShapefileEncodingFromLdid( path );
1009 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1011 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1012 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_CPG" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1014 if ( !QFileInfo::exists( path ) )
1018 const QFileInfo fi( path );
1019 const QString baseName = fi.completeBaseName();
1020 const QString cpgPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"CPG" ) : QStringLiteral(
"cpg" ) ) );
1021 if ( QFile::exists( cpgPath ) )
1023 QFile cpgFile( cpgPath );
1024 if ( cpgFile.open( QIODevice::ReadOnly ) )
1026 QTextStream cpgStream( &cpgFile );
1027 const QString cpgString = cpgStream.readLine();
1030 if ( !cpgString.isEmpty() )
1035 int cpgCodePage = cpgString.toInt( &ok );
1036 if ( ok && ( ( cpgCodePage >= 437 && cpgCodePage <= 950 )
1037 || ( cpgCodePage >= 1250 && cpgCodePage <= 1258 ) ) )
1039 return QStringLiteral(
"CP%1" ).arg( cpgCodePage );
1041 else if ( cpgString.startsWith( QLatin1String(
"8859" ) ) )
1043 if ( cpgString.length() > 4 && cpgString.at( 4 ) ==
'-' )
1044 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 5 ) );
1046 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 4 ) );
1048 else if ( cpgString.startsWith( QLatin1String(
"UTF-8" ), Qt::CaseInsensitive ) ||
1049 cpgString.startsWith( QLatin1String(
"UTF8" ), Qt::CaseInsensitive ) )
1050 return QStringLiteral(
"UTF-8" );
1051 else if ( cpgString.startsWith( QLatin1String(
"ANSI 1251" ), Qt::CaseInsensitive ) )
1052 return QStringLiteral(
"CP1251" );
1065 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1067 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1068 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_LDID" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1073 if ( !QFileInfo::exists( path ) )
1077 const QFileInfo fi( path );
1078 const QString baseName = fi.completeBaseName();
1081 const QString dbfPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"DBF" ) : QStringLiteral(
"dbf" ) ) );
1082 if ( QFile::exists( dbfPath ) )
1084 QFile dbfFile( dbfPath );
1085 if ( dbfFile.open( QIODevice::ReadOnly ) )
1088 QDataStream dbfIn( &dbfFile );
1089 dbfIn.setByteOrder( QDataStream::LittleEndian );
1099 case 1: nCP = 437;
break;
1100 case 2: nCP = 850;
break;
1101 case 3: nCP = 1252;
break;
1102 case 4: nCP = 10000;
break;
1103 case 8: nCP = 865;
break;
1104 case 10: nCP = 850;
break;
1105 case 11: nCP = 437;
break;
1106 case 13: nCP = 437;
break;
1107 case 14: nCP = 850;
break;
1108 case 15: nCP = 437;
break;
1109 case 16: nCP = 850;
break;
1110 case 17: nCP = 437;
break;
1111 case 18: nCP = 850;
break;
1112 case 19: nCP = 932;
break;
1113 case 20: nCP = 850;
break;
1114 case 21: nCP = 437;
break;
1115 case 22: nCP = 850;
break;
1116 case 23: nCP = 865;
break;
1117 case 24: nCP = 437;
break;
1118 case 25: nCP = 437;
break;
1119 case 26: nCP = 850;
break;
1120 case 27: nCP = 437;
break;
1121 case 28: nCP = 863;
break;
1122 case 29: nCP = 850;
break;
1123 case 31: nCP = 852;
break;
1124 case 34: nCP = 852;
break;
1125 case 35: nCP = 852;
break;
1126 case 36: nCP = 860;
break;
1127 case 37: nCP = 850;
break;
1128 case 38: nCP = 866;
break;
1129 case 55: nCP = 850;
break;
1130 case 64: nCP = 852;
break;
1131 case 77: nCP = 936;
break;
1132 case 78: nCP = 949;
break;
1133 case 79: nCP = 950;
break;
1134 case 80: nCP = 874;
break;
1135 case 87:
return QStringLiteral(
"ISO-8859-1" );
1136 case 88: nCP = 1252;
break;
1137 case 89: nCP = 1252;
break;
1138 case 100: nCP = 852;
break;
1139 case 101: nCP = 866;
break;
1140 case 102: nCP = 865;
break;
1141 case 103: nCP = 861;
break;
1142 case 104: nCP = 895;
break;
1143 case 105: nCP = 620;
break;
1144 case 106: nCP = 737;
break;
1145 case 107: nCP = 857;
break;
1146 case 108: nCP = 863;
break;
1147 case 120: nCP = 950;
break;
1148 case 121: nCP = 949;
break;
1149 case 122: nCP = 936;
break;
1150 case 123: nCP = 932;
break;
1151 case 124: nCP = 874;
break;
1152 case 134: nCP = 737;
break;
1153 case 135: nCP = 852;
break;
1154 case 136: nCP = 857;
break;
1155 case 150: nCP = 10007;
break;
1156 case 151: nCP = 10029;
break;
1157 case 200: nCP = 1250;
break;
1158 case 201: nCP = 1251;
break;
1159 case 202: nCP = 1254;
break;
1160 case 203: nCP = 1253;
break;
1161 case 204: nCP = 1257;
break;
1167 return QStringLiteral(
"CP%1" ).arg( nCP );
1179 char **papszStyleString = CSLTokenizeString2(
string.toUtf8().constData(),
";",
1181 | CSLT_PRESERVEQUOTES
1182 | CSLT_PRESERVEESCAPES );
1183 for (
int i = 0; papszStyleString[i] !=
nullptr; ++i )
1189 const thread_local QRegularExpression sToolPartRx( QStringLiteral(
"^(.*?)\\((.*)\\)$" ) );
1190 const QString stylePart( papszStyleString[i] );
1191 const QRegularExpressionMatch match = sToolPartRx.match( stylePart );
1192 if ( !match.hasMatch() )
1195 const QString tool = match.captured( 1 );
1196 const QString params = match.captured( 2 );
1198 char **papszTokens = CSLTokenizeString2( params.toUtf8().constData(),
",", CSLT_HONOURSTRINGS
1199 | CSLT_PRESERVEESCAPES );
1201 QVariantMap toolParts;
1202 const thread_local QRegularExpression sToolParamRx( QStringLiteral(
"^(.*?):(.*)$" ) );
1203 for (
int j = 0; papszTokens[j] !=
nullptr; ++j )
1205 const QString toolPart( papszTokens[j] );
1206 const QRegularExpressionMatch toolMatch = sToolParamRx.match( toolPart );
1207 if ( !match.hasMatch() )
1211 toolParts.insert( toolMatch.captured( 1 ).toLower(), toolMatch.captured( 2 ) );
1213 CSLDestroy( papszTokens );
1216 styles.insert( tool.toLower(), toolParts );
1218 CSLDestroy( papszStyleString );
1224 const QVariantMap styles = parseStyleString(
string );
1228 const thread_local QRegularExpression sUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.]+)(g|px|pt|mm|cm|in)$" ) );
1229 const QRegularExpressionMatch match = sUnitRx.match( size );
1230 if ( match.hasMatch() )
1232 value = match.captured( 1 ).toDouble();
1233 const QString unitString = match.captured( 2 );
1234 if ( unitString.compare( QLatin1String(
"px" ), Qt::CaseInsensitive ) == 0 )
1238 static constexpr
double PT_TO_INCHES_FACTOR = 1 / 72.0;
1239 static constexpr
double PX_TO_PT_FACTOR = 1 / ( 96.0 * PT_TO_INCHES_FACTOR );
1241 value *= PX_TO_PT_FACTOR;
1244 else if ( unitString.compare( QLatin1String(
"pt" ), Qt::CaseInsensitive ) == 0 )
1249 else if ( unitString.compare( QLatin1String(
"mm" ), Qt::CaseInsensitive ) == 0 )
1254 else if ( unitString.compare( QLatin1String(
"cm" ), Qt::CaseInsensitive ) == 0 )
1260 else if ( unitString.compare( QLatin1String(
"in" ), Qt::CaseInsensitive ) == 0 )
1265 else if ( unitString.compare( QLatin1String(
"g" ), Qt::CaseInsensitive ) == 0 )
1270 QgsDebugMsg( QStringLiteral(
"Unknown unit %1" ).arg( unitString ) );
1274 QgsDebugMsg( QStringLiteral(
"Could not parse style size %1" ).arg( size ) );
1279 auto convertColor = [](
const QString & string ) -> QColor
1281 if (
string.isEmpty() )
1284 const thread_local QRegularExpression sColorWithAlphaRx = QRegularExpression( QStringLiteral(
"^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})$" ) );
1285 const QRegularExpressionMatch match = sColorWithAlphaRx.match(
string );
1286 if ( match.hasMatch() )
1289 return QColor( QStringLiteral(
"#%1%2" ).arg( match.captured( 2 ), match.captured( 1 ) ) );
1293 return QColor(
string );
1297 auto convertPen = [&convertColor, &convertSize, string](
const QVariantMap & lineStyle ) -> std::unique_ptr< QgsSymbol >
1299 QColor color = convertColor( lineStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1303 convertSize( lineStyle.value( QStringLiteral(
"w" ) ).toString(), lineWidth, lineWidthUnit );
1306 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-pen-(\\d+)" ) );
1307 const QRegularExpressionMatch match = sMapInfoId.match(
string );
1308 if ( match.hasMatch() )
1310 const int penId = match.captured( 1 ).toInt();
1317 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( color, lineWidth );
1318 simpleLine->setWidthUnit( lineWidthUnit );
1321 const QString pattern = lineStyle.value( QStringLiteral(
"p" ) ).toString();
1322 if ( !pattern.isEmpty() )
1324 const thread_local QRegularExpression sPatternUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.\\s]+)(g|px|pt|mm|cm|in)$" ) );
1325 const QRegularExpressionMatch match = sPatternUnitRx.match( pattern );
1326 if ( match.hasMatch() )
1328 const QStringList patternValues = match.captured( 1 ).split(
' ' );
1329 QVector< qreal > dashPattern;
1331 for (
const QString &val : patternValues )
1334 convertSize( val + match.captured( 2 ), length, patternUnits );
1335 dashPattern.push_back( length * lineWidth * 2 );
1338 simpleLine->setCustomDashVector( dashPattern );
1339 simpleLine->setCustomDashPatternUnit( patternUnits );
1340 simpleLine->setUseCustomDashPattern(
true );
1344 Qt::PenCapStyle capStyle = Qt::FlatCap;
1345 Qt::PenJoinStyle joinStyle = Qt::MiterJoin;
1347 const QString
id = lineStyle.value( QStringLiteral(
"id" ) ).toString();
1348 if (
id.contains( QLatin1String(
"mapinfo-pen" ), Qt::CaseInsensitive ) )
1353 capStyle = Qt::RoundCap;
1354 joinStyle = Qt::RoundJoin;
1358 const QString penCap = lineStyle.value( QStringLiteral(
"cap" ) ).toString();
1359 if ( penCap.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1361 capStyle = Qt::FlatCap;
1363 else if ( penCap.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1365 capStyle = Qt::RoundCap;
1367 else if ( penCap.compare( QLatin1String(
"p" ), Qt::CaseInsensitive ) == 0 )
1369 capStyle = Qt::SquareCap;
1371 simpleLine->setPenCapStyle( capStyle );
1374 const QString penJoin = lineStyle.value( QStringLiteral(
"j" ) ).toString();
1375 if ( penJoin.compare( QLatin1String(
"m" ), Qt::CaseInsensitive ) == 0 )
1377 joinStyle = Qt::MiterJoin;
1379 else if ( penJoin.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1381 joinStyle = Qt::RoundJoin;
1383 else if ( penJoin.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1385 joinStyle = Qt::BevelJoin;
1387 simpleLine->setPenJoinStyle( joinStyle );
1389 const QString priority = lineStyle.value( QStringLiteral(
"l" ) ).toString();
1390 if ( !priority.isEmpty() )
1392 simpleLine->setRenderingPass( priority.toInt() );
1394 return std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
1397 auto convertBrush = [&convertColor](
const QVariantMap & brushStyle ) -> std::unique_ptr< QgsSymbol >
1399 const QColor foreColor = convertColor( brushStyle.value( QStringLiteral(
"fc" ), QStringLiteral(
"#000000" ) ).toString() );
1400 const QColor backColor = convertColor( brushStyle.value( QStringLiteral(
"bc" ), QString() ).toString() );
1402 const QString
id = brushStyle.value( QStringLiteral(
"id" ) ).toString();
1405 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-brush-(\\d+)" ) );
1406 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1407 if ( match.hasMatch() )
1409 const int brushId = match.captured( 1 ).toInt();
1416 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-brush-(\\d+)" ) );
1417 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1419 Qt::BrushStyle style = Qt::SolidPattern;
1420 if ( ogrMatch.hasMatch() )
1422 const int brushId = ogrMatch.captured( 1 ).toInt();
1426 style = Qt::SolidPattern;
1430 style = Qt::NoBrush;
1434 style = Qt::HorPattern;
1438 style = Qt::VerPattern;
1442 style = Qt::FDiagPattern;
1446 style = Qt::BDiagPattern;
1450 style = Qt::CrossPattern;
1454 style = Qt::DiagCrossPattern;
1460 if ( backColor.isValid() && style != Qt::SolidPattern && style != Qt::NoBrush )
1462 std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1463 backgroundFill->setLocked(
true );
1464 backgroundFill->setStrokeStyle( Qt::NoPen );
1465 layers << backgroundFill.release();
1468 std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1469 foregroundFill->setBrushStyle( style );
1470 foregroundFill->setStrokeStyle( Qt::NoPen );
1472 const QString priority = brushStyle.value( QStringLiteral(
"l" ) ).toString();
1473 if ( !priority.isEmpty() )
1475 foregroundFill->setRenderingPass( priority.toInt() );
1477 layers << foregroundFill.release();
1478 return std::make_unique< QgsFillSymbol >( layers );
1481 auto convertSymbol = [&convertColor, &convertSize, string](
const QVariantMap & symbolStyle ) -> std::unique_ptr< QgsSymbol >
1483 const QColor color = convertColor( symbolStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1487 convertSize( symbolStyle.value( QStringLiteral(
"s" ) ).toString(), symbolSize, symbolSizeUnit );
1489 const double angle = symbolStyle.value( QStringLiteral(
"a" ), QStringLiteral(
"0" ) ).toDouble();
1491 const QString
id = symbolStyle.value( QStringLiteral(
"id" ) ).toString();
1494 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-sym-(\\d+)" ) );
1495 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1496 if ( match.hasMatch() )
1498 const int symbolId = match.captured( 1 ).toInt();
1509 std::unique_ptr< QgsMarkerSymbolLayer > markerLayer;
1511 const thread_local QRegularExpression sFontId = QRegularExpression( QStringLiteral(
"font-sym-(\\d+)" ) );
1512 const QRegularExpressionMatch fontMatch = sFontId.match(
id );
1513 if ( fontMatch.hasMatch() )
1515 const int symId = fontMatch.captured( 1 ).toInt();
1516 const QStringList families = symbolStyle.value( QStringLiteral(
"f" ), QString() ).toString().split(
',' );
1518 bool familyFound =
false;
1520 for (
const QString &family : std::as_const( families ) )
1525 fontFamily = family;
1532 std::unique_ptr< QgsFontMarkerSymbolLayer > fontMarker = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, QChar( symId ), symbolSize );
1533 fontMarker->setSizeUnit( symbolSizeUnit );
1534 fontMarker->setAngle( -
angle );
1536 fontMarker->setColor( color );
1538 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1539 if ( strokeColor.isValid() )
1541 fontMarker->setStrokeColor( strokeColor );
1542 fontMarker->setStrokeWidth( 1 );
1547 fontMarker->setStrokeWidth( 0 );
1550 markerLayer = std::move( fontMarker );
1552 else if ( !families.empty() )
1561 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-sym-(\\d+)" ) );
1562 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1565 bool isFilled =
true;
1566 if ( ogrMatch.hasMatch() )
1568 const int symId = ogrMatch.captured( 1 ).toInt();
1572 shape = QgsSimpleMarkerSymbolLayer::Shape::Cross;
1576 shape = QgsSimpleMarkerSymbolLayer::Shape::Cross2;
1581 shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1585 shape = QgsSimpleMarkerSymbolLayer::Shape::Circle;
1590 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1594 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1599 shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1603 shape = QgsSimpleMarkerSymbolLayer::Shape::Triangle;
1608 shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1612 shape = QgsSimpleMarkerSymbolLayer::Shape::Star;
1616 shape = QgsSimpleMarkerSymbolLayer::Shape::Line;
1621 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1628 shape = QgsSimpleMarkerSymbolLayer::Shape::Square;
1631 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, symbolSize, -
angle );
1632 simpleMarker->setSizeUnit( symbolSizeUnit );
1636 simpleMarker->setColor( color );
1637 simpleMarker->setStrokeStyle( Qt::NoPen );
1641 simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1642 simpleMarker->setStrokeColor( color );
1645 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1646 if ( strokeColor.isValid() )
1648 simpleMarker->setStrokeColor( strokeColor );
1649 simpleMarker->setStrokeStyle( Qt::SolidLine );
1652 markerLayer = std::move( simpleMarker );
1655 return std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << markerLayer.release() );
1661 if ( styles.contains( QStringLiteral(
"symbol" ) ) )
1663 const QVariantMap symbolStyle = styles.value( QStringLiteral(
"symbol" ) ).toMap();
1664 return convertSymbol( symbolStyle );
1672 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1675 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1676 return convertPen( lineStyle );
1685 std::unique_ptr< QgsSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1686 if ( styles.contains( QStringLiteral(
"brush" ) ) )
1688 const QVariantMap brushStyle = styles.value( QStringLiteral(
"brush" ) ).toMap();
1689 fillSymbol = convertBrush( brushStyle );
1693 std::unique_ptr< QgsSimpleFillSymbolLayer > emptyFill = std::make_unique< QgsSimpleFillSymbolLayer >();
1694 emptyFill->setBrushStyle( Qt::NoBrush );
1695 fillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << emptyFill.release() );
1698 std::unique_ptr< QgsSymbol > penSymbol;
1699 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1701 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1702 penSymbol = convertPen( lineStyle );
1707 const int count = penSymbol->symbolLayerCount();
1717 for (
int i = 0; i < count; ++i )
1719 std::unique_ptr< QgsSymbolLayer > layer( penSymbol->takeSymbolLayer( 0 ) );
1720 layer->setLocked(
true );
1721 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).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
void setCoordinateEpoch(double epoch)
Sets the coordinate epoch, as a decimal year.
@ WKT_PREFERRED_GDAL
Preferred format for conversion of CRS to WKT for use with the GDAL library.
static QgsCoordinateReferenceSystem fromWkt(const QString &wkt)
Creates a CRS from a WKT spatial ref sys definition string.
double coordinateEpoch() const
Returns the coordinate epoch, as a decimal year.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
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 OGRSpatialReferenceH crsToOGRSpatialReference(const QgsCoordinateReferenceSystem &crs)
Returns a OGRSpatialReferenceH corresponding to the specified crs 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
const QgsCoordinateReferenceSystem & crs
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.