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 const char *authorityName = OSRGetAuthorityName( srs,
nullptr );
966 const char *authorityCode = OSRGetAuthorityCode( srs,
nullptr );
968 if ( authorityName && authorityCode )
970 QString authId = QString( authorityName ) +
':' + QString( authorityCode );
973 if ( OSRSetFromUserInput( ogrSrsTmp, authId.toUtf8().constData() ) != OGRERR_NONE &&
974 OSRIsSame( srs, ogrSrsTmp ) )
979 OSRDestroySpatialReference( ogrSrsTmp );
984 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
985 const double coordinateEpoch = OSRGetCoordinateEpoch( srs );
986 if ( coordinateEpoch > 0 )
1004 if ( !authId.isEmpty() )
1006 ogrSrs = OSRNewSpatialReference(
nullptr );
1007 if ( OSRSetFromUserInput( ogrSrs, authId.toUtf8().constData() ) == OGRERR_NONE )
1011 if ( ogrSrsFromWkt )
1013 if ( !OSRIsSame( ogrSrs, ogrSrsFromWkt ) )
1015 OSRDestroySpatialReference( ogrSrs );
1016 ogrSrs = ogrSrsFromWkt;
1020 OSRDestroySpatialReference( ogrSrsFromWkt );
1026 OSRDestroySpatialReference( ogrSrs );
1032 ogrSrs = OSRNewSpatialReference( srsWkt.toUtf8().constData() );
1036 OSRSetAxisMappingStrategy( ogrSrs, OAMS_TRADITIONAL_GIS_ORDER );
1037 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
1052 const QString cpgEncoding = readShapefileEncodingFromCpg( path );
1053 if ( !cpgEncoding.isEmpty() )
1056 return readShapefileEncodingFromLdid( path );
1061 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1063 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1064 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_CPG" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1066 if ( !QFileInfo::exists( path ) )
1070 const QFileInfo fi( path );
1071 const QString baseName = fi.completeBaseName();
1072 const QString cpgPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"CPG" ) : QStringLiteral(
"cpg" ) ) );
1073 if ( QFile::exists( cpgPath ) )
1075 QFile cpgFile( cpgPath );
1076 if ( cpgFile.open( QIODevice::ReadOnly ) )
1078 QTextStream cpgStream( &cpgFile );
1079 const QString cpgString = cpgStream.readLine();
1082 if ( !cpgString.isEmpty() )
1087 int cpgCodePage = cpgString.toInt( &ok );
1088 if ( ok && ( ( cpgCodePage >= 437 && cpgCodePage <= 950 )
1089 || ( cpgCodePage >= 1250 && cpgCodePage <= 1258 ) ) )
1091 return QStringLiteral(
"CP%1" ).arg( cpgCodePage );
1093 else if ( cpgString.startsWith( QLatin1String(
"8859" ) ) )
1095 if ( cpgString.length() > 4 && cpgString.at( 4 ) ==
'-' )
1096 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 5 ) );
1098 return QStringLiteral(
"ISO-8859-%1" ).arg( cpgString.mid( 4 ) );
1100 else if ( cpgString.startsWith( QLatin1String(
"UTF-8" ), Qt::CaseInsensitive ) ||
1101 cpgString.startsWith( QLatin1String(
"UTF8" ), Qt::CaseInsensitive ) )
1102 return QStringLiteral(
"UTF-8" );
1103 else if ( cpgString.startsWith( QLatin1String(
"ANSI 1251" ), Qt::CaseInsensitive ) )
1104 return QStringLiteral(
"CP1251" );
1117 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,1,0)
1119 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1120 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_LDID" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1125 if ( !QFileInfo::exists( path ) )
1129 const QFileInfo fi( path );
1130 const QString baseName = fi.completeBaseName();
1133 const QString dbfPath = fi.dir().filePath( QStringLiteral(
"%1.%2" ).arg( baseName, fi.suffix() == QLatin1String(
"SHP" ) ? QStringLiteral(
"DBF" ) : QStringLiteral(
"dbf" ) ) );
1134 if ( QFile::exists( dbfPath ) )
1136 QFile dbfFile( dbfPath );
1137 if ( dbfFile.open( QIODevice::ReadOnly ) )
1140 QDataStream dbfIn( &dbfFile );
1141 dbfIn.setByteOrder( QDataStream::LittleEndian );
1151 case 1: nCP = 437;
break;
1152 case 2: nCP = 850;
break;
1153 case 3: nCP = 1252;
break;
1154 case 4: nCP = 10000;
break;
1155 case 8: nCP = 865;
break;
1156 case 10: nCP = 850;
break;
1157 case 11: nCP = 437;
break;
1158 case 13: nCP = 437;
break;
1159 case 14: nCP = 850;
break;
1160 case 15: nCP = 437;
break;
1161 case 16: nCP = 850;
break;
1162 case 17: nCP = 437;
break;
1163 case 18: nCP = 850;
break;
1164 case 19: nCP = 932;
break;
1165 case 20: nCP = 850;
break;
1166 case 21: nCP = 437;
break;
1167 case 22: nCP = 850;
break;
1168 case 23: nCP = 865;
break;
1169 case 24: nCP = 437;
break;
1170 case 25: nCP = 437;
break;
1171 case 26: nCP = 850;
break;
1172 case 27: nCP = 437;
break;
1173 case 28: nCP = 863;
break;
1174 case 29: nCP = 850;
break;
1175 case 31: nCP = 852;
break;
1176 case 34: nCP = 852;
break;
1177 case 35: nCP = 852;
break;
1178 case 36: nCP = 860;
break;
1179 case 37: nCP = 850;
break;
1180 case 38: nCP = 866;
break;
1181 case 55: nCP = 850;
break;
1182 case 64: nCP = 852;
break;
1183 case 77: nCP = 936;
break;
1184 case 78: nCP = 949;
break;
1185 case 79: nCP = 950;
break;
1186 case 80: nCP = 874;
break;
1187 case 87:
return QStringLiteral(
"ISO-8859-1" );
1188 case 88: nCP = 1252;
break;
1189 case 89: nCP = 1252;
break;
1190 case 100: nCP = 852;
break;
1191 case 101: nCP = 866;
break;
1192 case 102: nCP = 865;
break;
1193 case 103: nCP = 861;
break;
1194 case 104: nCP = 895;
break;
1195 case 105: nCP = 620;
break;
1196 case 106: nCP = 737;
break;
1197 case 107: nCP = 857;
break;
1198 case 108: nCP = 863;
break;
1199 case 120: nCP = 950;
break;
1200 case 121: nCP = 949;
break;
1201 case 122: nCP = 936;
break;
1202 case 123: nCP = 932;
break;
1203 case 124: nCP = 874;
break;
1204 case 134: nCP = 737;
break;
1205 case 135: nCP = 852;
break;
1206 case 136: nCP = 857;
break;
1207 case 150: nCP = 10007;
break;
1208 case 151: nCP = 10029;
break;
1209 case 200: nCP = 1250;
break;
1210 case 201: nCP = 1251;
break;
1211 case 202: nCP = 1254;
break;
1212 case 203: nCP = 1253;
break;
1213 case 204: nCP = 1257;
break;
1219 return QStringLiteral(
"CP%1" ).arg( nCP );
1231 char **papszStyleString = CSLTokenizeString2(
string.toUtf8().constData(),
";",
1233 | CSLT_PRESERVEQUOTES
1234 | CSLT_PRESERVEESCAPES );
1235 for (
int i = 0; papszStyleString[i] !=
nullptr; ++i )
1241 const thread_local QRegularExpression sToolPartRx( QStringLiteral(
"^(.*?)\\((.*)\\)$" ) );
1242 const QString stylePart( papszStyleString[i] );
1243 const QRegularExpressionMatch match = sToolPartRx.match( stylePart );
1244 if ( !match.hasMatch() )
1247 const QString tool = match.captured( 1 );
1248 const QString params = match.captured( 2 );
1250 char **papszTokens = CSLTokenizeString2( params.toUtf8().constData(),
",", CSLT_HONOURSTRINGS
1251 | CSLT_PRESERVEESCAPES );
1253 QVariantMap toolParts;
1254 const thread_local QRegularExpression sToolParamRx( QStringLiteral(
"^(.*?):(.*)$" ) );
1255 for (
int j = 0; papszTokens[j] !=
nullptr; ++j )
1257 const QString toolPart( papszTokens[j] );
1258 const QRegularExpressionMatch toolMatch = sToolParamRx.match( toolPart );
1259 if ( !match.hasMatch() )
1263 toolParts.insert( toolMatch.captured( 1 ).toLower(), toolMatch.captured( 2 ) );
1265 CSLDestroy( papszTokens );
1268 styles.insert( tool.toLower(), toolParts );
1270 CSLDestroy( papszStyleString );
1276 const QVariantMap styles = parseStyleString(
string );
1280 const thread_local QRegularExpression sUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.]+)(g|px|pt|mm|cm|in)$" ) );
1281 const QRegularExpressionMatch match = sUnitRx.match( size );
1282 if ( match.hasMatch() )
1284 value = match.captured( 1 ).toDouble();
1285 const QString unitString = match.captured( 2 );
1286 if ( unitString.compare( QLatin1String(
"px" ), Qt::CaseInsensitive ) == 0 )
1290 static constexpr
double PT_TO_INCHES_FACTOR = 1 / 72.0;
1291 static constexpr
double PX_TO_PT_FACTOR = 1 / ( 96.0 * PT_TO_INCHES_FACTOR );
1293 value *= PX_TO_PT_FACTOR;
1296 else if ( unitString.compare( QLatin1String(
"pt" ), Qt::CaseInsensitive ) == 0 )
1301 else if ( unitString.compare( QLatin1String(
"mm" ), Qt::CaseInsensitive ) == 0 )
1306 else if ( unitString.compare( QLatin1String(
"cm" ), Qt::CaseInsensitive ) == 0 )
1312 else if ( unitString.compare( QLatin1String(
"in" ), Qt::CaseInsensitive ) == 0 )
1317 else if ( unitString.compare( QLatin1String(
"g" ), Qt::CaseInsensitive ) == 0 )
1322 QgsDebugMsg( QStringLiteral(
"Unknown unit %1" ).arg( unitString ) );
1326 QgsDebugMsg( QStringLiteral(
"Could not parse style size %1" ).arg( size ) );
1331 auto convertColor = [](
const QString & string ) -> QColor
1333 if (
string.isEmpty() )
1336 const thread_local QRegularExpression sColorWithAlphaRx = QRegularExpression( QStringLiteral(
"^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})$" ) );
1337 const QRegularExpressionMatch match = sColorWithAlphaRx.match(
string );
1338 if ( match.hasMatch() )
1341 return QColor( QStringLiteral(
"#%1%2" ).arg( match.captured( 2 ), match.captured( 1 ) ) );
1345 return QColor(
string );
1349 auto convertPen = [&convertColor, &convertSize, string](
const QVariantMap & lineStyle ) -> std::unique_ptr< QgsSymbol >
1351 QColor color = convertColor( lineStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1355 convertSize( lineStyle.value( QStringLiteral(
"w" ) ).toString(), lineWidth, lineWidthUnit );
1358 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-pen-(\\d+)" ) );
1359 const QRegularExpressionMatch match = sMapInfoId.match(
string );
1360 if ( match.hasMatch() )
1362 const int penId = match.captured( 1 ).toInt();
1369 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( color, lineWidth );
1370 simpleLine->setWidthUnit( lineWidthUnit );
1373 const QString pattern = lineStyle.value( QStringLiteral(
"p" ) ).toString();
1374 if ( !pattern.isEmpty() )
1376 const thread_local QRegularExpression sPatternUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.\\s]+)(g|px|pt|mm|cm|in)$" ) );
1377 const QRegularExpressionMatch match = sPatternUnitRx.match( pattern );
1378 if ( match.hasMatch() )
1380 const QStringList patternValues = match.captured( 1 ).split(
' ' );
1381 QVector< qreal > dashPattern;
1383 for (
const QString &val : patternValues )
1386 convertSize( val + match.captured( 2 ), length, patternUnits );
1387 dashPattern.push_back( length * lineWidth * 2 );
1390 simpleLine->setCustomDashVector( dashPattern );
1391 simpleLine->setCustomDashPatternUnit( patternUnits );
1392 simpleLine->setUseCustomDashPattern(
true );
1396 Qt::PenCapStyle capStyle = Qt::FlatCap;
1397 Qt::PenJoinStyle joinStyle = Qt::MiterJoin;
1399 const QString
id = lineStyle.value( QStringLiteral(
"id" ) ).toString();
1400 if (
id.contains( QLatin1String(
"mapinfo-pen" ), Qt::CaseInsensitive ) )
1405 capStyle = Qt::RoundCap;
1406 joinStyle = Qt::RoundJoin;
1410 const QString penCap = lineStyle.value( QStringLiteral(
"cap" ) ).toString();
1411 if ( penCap.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1413 capStyle = Qt::FlatCap;
1415 else if ( penCap.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1417 capStyle = Qt::RoundCap;
1419 else if ( penCap.compare( QLatin1String(
"p" ), Qt::CaseInsensitive ) == 0 )
1421 capStyle = Qt::SquareCap;
1423 simpleLine->setPenCapStyle( capStyle );
1426 const QString penJoin = lineStyle.value( QStringLiteral(
"j" ) ).toString();
1427 if ( penJoin.compare( QLatin1String(
"m" ), Qt::CaseInsensitive ) == 0 )
1429 joinStyle = Qt::MiterJoin;
1431 else if ( penJoin.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1433 joinStyle = Qt::RoundJoin;
1435 else if ( penJoin.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1437 joinStyle = Qt::BevelJoin;
1439 simpleLine->setPenJoinStyle( joinStyle );
1441 const QString priority = lineStyle.value( QStringLiteral(
"l" ) ).toString();
1442 if ( !priority.isEmpty() )
1444 simpleLine->setRenderingPass( priority.toInt() );
1446 return std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
1449 auto convertBrush = [&convertColor](
const QVariantMap & brushStyle ) -> std::unique_ptr< QgsSymbol >
1451 const QColor foreColor = convertColor( brushStyle.value( QStringLiteral(
"fc" ), QStringLiteral(
"#000000" ) ).toString() );
1452 const QColor backColor = convertColor( brushStyle.value( QStringLiteral(
"bc" ), QString() ).toString() );
1454 const QString
id = brushStyle.value( QStringLiteral(
"id" ) ).toString();
1457 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-brush-(\\d+)" ) );
1458 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1459 if ( match.hasMatch() )
1461 const int brushId = match.captured( 1 ).toInt();
1468 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-brush-(\\d+)" ) );
1469 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1471 Qt::BrushStyle style = Qt::SolidPattern;
1472 if ( ogrMatch.hasMatch() )
1474 const int brushId = ogrMatch.captured( 1 ).toInt();
1478 style = Qt::SolidPattern;
1482 style = Qt::NoBrush;
1486 style = Qt::HorPattern;
1490 style = Qt::VerPattern;
1494 style = Qt::FDiagPattern;
1498 style = Qt::BDiagPattern;
1502 style = Qt::CrossPattern;
1506 style = Qt::DiagCrossPattern;
1512 if ( backColor.isValid() && style != Qt::SolidPattern && style != Qt::NoBrush )
1514 std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1515 backgroundFill->setLocked(
true );
1516 backgroundFill->setStrokeStyle( Qt::NoPen );
1517 layers << backgroundFill.release();
1520 std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1521 foregroundFill->setBrushStyle( style );
1522 foregroundFill->setStrokeStyle( Qt::NoPen );
1524 const QString priority = brushStyle.value( QStringLiteral(
"l" ) ).toString();
1525 if ( !priority.isEmpty() )
1527 foregroundFill->setRenderingPass( priority.toInt() );
1529 layers << foregroundFill.release();
1530 return std::make_unique< QgsFillSymbol >( layers );
1533 auto convertSymbol = [&convertColor, &convertSize, string](
const QVariantMap & symbolStyle ) -> std::unique_ptr< QgsSymbol >
1535 const QColor color = convertColor( symbolStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1539 convertSize( symbolStyle.value( QStringLiteral(
"s" ) ).toString(), symbolSize, symbolSizeUnit );
1541 const double angle = symbolStyle.value( QStringLiteral(
"a" ), QStringLiteral(
"0" ) ).toDouble();
1543 const QString
id = symbolStyle.value( QStringLiteral(
"id" ) ).toString();
1546 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-sym-(\\d+)" ) );
1547 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1548 if ( match.hasMatch() )
1550 const int symbolId = match.captured( 1 ).toInt();
1561 std::unique_ptr< QgsMarkerSymbolLayer > markerLayer;
1563 const thread_local QRegularExpression sFontId = QRegularExpression( QStringLiteral(
"font-sym-(\\d+)" ) );
1564 const QRegularExpressionMatch fontMatch = sFontId.match(
id );
1565 if ( fontMatch.hasMatch() )
1567 const int symId = fontMatch.captured( 1 ).toInt();
1568 const QStringList families = symbolStyle.value( QStringLiteral(
"f" ), QString() ).toString().split(
',' );
1570 bool familyFound =
false;
1572 for (
const QString &family : std::as_const( families ) )
1577 fontFamily = family;
1584 std::unique_ptr< QgsFontMarkerSymbolLayer > fontMarker = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, QChar( symId ), symbolSize );
1585 fontMarker->setSizeUnit( symbolSizeUnit );
1586 fontMarker->setAngle( -
angle );
1588 fontMarker->setColor( color );
1590 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1591 if ( strokeColor.isValid() )
1593 fontMarker->setStrokeColor( strokeColor );
1594 fontMarker->setStrokeWidth( 1 );
1599 fontMarker->setStrokeWidth( 0 );
1602 markerLayer = std::move( fontMarker );
1604 else if ( !families.empty() )
1613 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-sym-(\\d+)" ) );
1614 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1617 bool isFilled =
true;
1618 if ( ogrMatch.hasMatch() )
1620 const int symId = ogrMatch.captured( 1 ).toInt();
1683 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, symbolSize, -
angle );
1684 simpleMarker->setSizeUnit( symbolSizeUnit );
1688 simpleMarker->setColor( color );
1689 simpleMarker->setStrokeStyle( Qt::NoPen );
1693 simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1694 simpleMarker->setStrokeColor( color );
1697 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1698 if ( strokeColor.isValid() )
1700 simpleMarker->setStrokeColor( strokeColor );
1701 simpleMarker->setStrokeStyle( Qt::SolidLine );
1704 markerLayer = std::move( simpleMarker );
1707 return std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << markerLayer.release() );
1713 if ( styles.contains( QStringLiteral(
"symbol" ) ) )
1715 const QVariantMap symbolStyle = styles.value( QStringLiteral(
"symbol" ) ).toMap();
1716 return convertSymbol( symbolStyle );
1724 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1727 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1728 return convertPen( lineStyle );
1737 std::unique_ptr< QgsSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1738 if ( styles.contains( QStringLiteral(
"brush" ) ) )
1740 const QVariantMap brushStyle = styles.value( QStringLiteral(
"brush" ) ).toMap();
1741 fillSymbol = convertBrush( brushStyle );
1745 std::unique_ptr< QgsSimpleFillSymbolLayer > emptyFill = std::make_unique< QgsSimpleFillSymbolLayer >();
1746 emptyFill->setBrushStyle( Qt::NoBrush );
1747 fillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << emptyFill.release() );
1750 std::unique_ptr< QgsSymbol > penSymbol;
1751 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1753 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1754 penSymbol = convertPen( lineStyle );
1759 const int count = penSymbol->symbolLayerCount();
1769 for (
int i = 0; i < count; ++i )
1771 std::unique_ptr< QgsSymbolLayer > layer( penSymbol->takeSymbolLayer( 0 ) );
1772 layer->setLocked(
true );
1773 fillSymbol->appendSymbolLayer( layer.release() );
MarkerShape
Marker shapes.
@ Cross2
Rotated cross (lines only), 'x' shape.
@ Cross
Cross (lines only)
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.
bool createFromUserInput(const QString &definition)
Set up this CRS from various text formats.
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(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
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.