24#include "qgsogrprovider.h"
45#include <QJsonDocument>
50#include <QRegularExpression>
52#include "ogr_srs_api.h"
57 OGR_DS_Destroy( source );
63 OGR_G_DestroyGeometry( geometry );
68 OGR_Fld_Destroy( definition );
73 OGR_F_Destroy( feature );
90 CPLPushErrorHandler( CPLQuietErrorHandler );
91 GDALDeleteDataset( driver, path.toUtf8().constData() );
103 GDALDestroyWarpOptions( options );
108 if ( !value || OGR_RawField_IsUnset( value ) || OGR_RawField_IsNull( value ) )
114 return value->Integer;
117 return value->Integer64;
124 return QString::fromUtf8( value->String );
127 return QDate( value->Date.Year, value->Date.Month, value->Date.Day );
131 float secondsPart = 0;
132 float millisecondPart = std::modf( value->Date.Second, &secondsPart );
133 return QTime( value->Date.Hour, value->Date.Minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) );
138 float secondsPart = 0;
139 float millisecondPart = std::modf( value->Date.Second, &secondsPart );
140 return QDateTime( QDate( value->Date.Year, value->Date.Month, value->Date.Day ),
141 QTime( value->Date.Hour, value->Date.Minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) ) );
146 Q_ASSERT_X(
false,
"QgsOgrUtils::OGRFieldtoVariant",
"OFTBinary type not supported" );
152 res.reserve( value->IntegerList.nCount );
153 for (
int i = 0; i < value->IntegerList.nCount; ++i )
154 res << value->IntegerList.paList[ i ];
158 case OFTInteger64List:
161 res.reserve( value->Integer64List.nCount );
162 for (
int i = 0; i < value->Integer64List.nCount; ++i )
163 res << value->Integer64List.paList[ i ];
170 res.reserve( value->RealList.nCount );
171 for (
int i = 0; i < value->RealList.nCount; ++i )
172 res << value->RealList.paList[ i ];
177 case OFTWideStringList:
180 res.reserve( value->StringList.nCount );
181 for (
int i = 0; i < value->StringList.nCount; ++i )
182 res << QString::fromUtf8( value->StringList.paList[ i ] );
191 std::unique_ptr< OGRField > res = std::make_unique< OGRField >();
193 switch ( value.type() )
195 case QVariant::Invalid:
196 OGR_RawField_SetUnset( res.get() );
199 res->Integer = value.toBool() ? 1 : 0;
202 res->Integer = value.toInt();
204 case QVariant::LongLong:
205 res->Integer64 = value.toLongLong();
207 case QVariant::Double:
208 res->Real = value.toDouble();
211 case QVariant::String:
212 res->String = CPLStrdup( value.toString().toUtf8().constData() );
216 const QDate date = value.toDate();
217 res->Date.Day = date.day();
218 res->Date.Month = date.month();
219 res->Date.Year = date.year();
220 res->Date.TZFlag = 0;
225 const QTime time = value.toTime();
226 res->Date.Hour = time.hour();
227 res->Date.Minute = time.minute();
228 res->Date.Second = time.second() +
static_cast< double >( time.msec() ) / 1000;
229 res->Date.TZFlag = 0;
232 case QVariant::DateTime:
234 const QDateTime dateTime = value.toDateTime();
235 res->Date.Day = dateTime.date().day();
236 res->Date.Month = dateTime.date().month();
237 res->Date.Year = dateTime.date().year();
238 res->Date.Hour = dateTime.time().hour();
239 res->Date.Minute = dateTime.time().minute();
240 res->Date.Second = dateTime.time().second() +
static_cast< double >( dateTime.time().msec() ) / 1000;
241 res->Date.TZFlag = 0;
246 QgsDebugMsg(
"Unhandled variant type in variantToOGRField" );
247 OGR_RawField_SetUnset( res.get() );
263 feature.
setId( OGR_F_GetFID( ogrFet ) );
266 if ( !readOgrFeatureGeometry( ogrFet, feature ) )
271 if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
286 int fieldCount = OGR_F_GetFieldCount( ogrFet );
287 for (
int i = 0; i < fieldCount; ++i )
289 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
296 QString name = encoding ? encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) ) : QString::fromUtf8( OGR_Fld_GetNameRef( fldDef ) );
297 QVariant::Type varType;
298 switch ( OGR_Fld_GetType( fldDef ) )
301 if ( OGR_Fld_GetSubType( fldDef ) == OFSTBoolean )
302 varType = QVariant::Bool;
304 varType = QVariant::Int;
307 varType = QVariant::LongLong;
310 varType = QVariant::Double;
313 varType = QVariant::Date;
316 varType = QVariant::Time;
319 varType = QVariant::DateTime;
322 if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON )
323 varType = QVariant::Map;
325 varType = QVariant::String;
328 varType = QVariant::String;
338 if ( attIndex < 0 || attIndex >= fields.
count() )
346 return getOgrFeatureAttribute( ogrFet,
field, attIndex, encoding, ok );
351 if ( !ogrFet || attIndex < 0 )
358 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
365 QgsDebugMsg( QStringLiteral(
"ogrFet->GetFieldDefnRef(attindex) returns NULL" ) );
374 if ( OGR_F_IsFieldSetAndNotNull( ogrFet, attIndex ) )
378 case QVariant::String:
381 value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
383 value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
388 if ( value.isNull() )
389 value = QVariant( QStringLiteral(
"" ) );
395 value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
398 value = QVariant(
bool( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ) );
400 case QVariant::LongLong:
401 value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
403 case QVariant::Double:
404 value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
407 case QVariant::DateTime:
410 int year, month, day, hour, minute, tzf;
412 float secondsPart = 0;
414 OGR_F_GetFieldAsDateTimeEx( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
415 float millisecondPart = std::modf( second, &secondsPart );
418 value = QDate( year, month, day );
419 else if (
field.
type() == QVariant::Time )
420 value = QTime( hour, minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) );
422 value = QDateTime( QDate( year, month, day ),
423 QTime( hour, minute,
static_cast< int >( secondsPart ),
static_cast< int >( 1000 * millisecondPart ) ) );
427 case QVariant::ByteArray:
430 const GByte *b = OGR_F_GetFieldAsBinary( ogrFet, attIndex, &size );
434 QByteArray ba = QByteArray::fromRawData(
reinterpret_cast<const char *
>( b ), size );
441 case QVariant::StringList:
444 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
445 const int count = CSLCount( lst );
448 list.reserve( count );
449 for (
int i = 0; i < count; i++ )
452 list << encoding->toUnicode( lst[i] );
454 list << QString::fromUtf8( lst[i] );
465 case QVariant::String:
468 char **lst = OGR_F_GetFieldAsStringList( ogrFet, attIndex );
469 const int count = CSLCount( lst );
472 list.reserve( count );
473 for (
int i = 0; i < count; i++ )
476 list << encoding->toUnicode( lst[i] );
478 list << QString::fromUtf8( lst[i] );
489 const int *lst = OGR_F_GetFieldAsIntegerList( ogrFet, attIndex, &count );
492 list.reserve( count );
493 for (
int i = 0; i < count; i++ )
502 case QVariant::Double:
506 const double *lst = OGR_F_GetFieldAsDoubleList( ogrFet, attIndex, &count );
509 list.reserve( count );
510 for (
int i = 0; i < count; i++ )
519 case QVariant::LongLong:
523 const long long *lst = OGR_F_GetFieldAsInteger64List( ogrFet, attIndex, &count );
526 list.reserve( count );
527 for (
int i = 0; i < count; i++ )
538 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
552 value = QJsonDocument::fromJson( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
554 value = QJsonDocument::fromJson( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
558 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
581 for (
int idx = 0; idx < fields.
count(); ++idx )
583 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
597 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
601 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
611 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
612 return std::make_unique< QgsPoint >( wkbType, x, y, z, m );
617 std::unique_ptr< QgsMultiPoint > mp = std::make_unique< QgsMultiPoint >();
619 const int count = OGR_G_GetGeometryCount( geom );
620 mp->reserve( count );
621 for (
int i = 0; i < count; ++i )
633 int count = OGR_G_GetPointCount( geom );
634 QVector< double > x( count );
635 QVector< double > y( count );
637 double *pz =
nullptr;
643 double *pm =
nullptr;
650 OGR_G_GetPointsZM( geom, x.data(),
sizeof(
double ), y.data(),
sizeof(
double ), pz,
sizeof(
double ), pm,
sizeof(
double ) );
657 std::unique_ptr< QgsMultiLineString > mp = std::make_unique< QgsMultiLineString >();
659 const int count = OGR_G_GetGeometryCount( geom );
660 mp->reserve( count );
661 for (
int i = 0; i < count; ++i )
671 std::unique_ptr< QgsPolygon > polygon = std::make_unique< QgsPolygon >();
673 const int count = OGR_G_GetGeometryCount( geom );
679 for (
int i = 1; i < count; ++i )
689 std::unique_ptr< QgsMultiPolygon > polygon = std::make_unique< QgsMultiPolygon >();
691 const int count = OGR_G_GetGeometryCount( geom );
692 polygon->reserve( count );
693 for (
int i = 0; i < count; ++i )
703 switch ( ogrGeomType )
705 case wkbUnknown:
return QgsWkbTypes::Type::Unknown;
706 case wkbPoint:
return QgsWkbTypes::Type::Point;
707 case wkbLineString:
return QgsWkbTypes::Type::LineString;
708 case wkbPolygon:
return QgsWkbTypes::Type::Polygon;
709 case wkbMultiPoint:
return QgsWkbTypes::Type::MultiPoint;
710 case wkbMultiLineString:
return QgsWkbTypes::Type::MultiLineString;
711 case wkbMultiPolygon:
return QgsWkbTypes::Type::MultiPolygon;
712 case wkbGeometryCollection:
return QgsWkbTypes::Type::GeometryCollection;
713 case wkbCircularString:
return QgsWkbTypes::Type::CircularString;
714 case wkbCompoundCurve:
return QgsWkbTypes::Type::CompoundCurve;
715 case wkbCurvePolygon:
return QgsWkbTypes::Type::CurvePolygon;
716 case wkbMultiCurve:
return QgsWkbTypes::Type::MultiCurve;
717 case wkbMultiSurface:
return QgsWkbTypes::Type::MultiSurface;
718 case wkbCurve:
return QgsWkbTypes::Type::Unknown;
719 case wkbSurface:
return QgsWkbTypes::Type::Unknown;
720 case wkbPolyhedralSurface:
return QgsWkbTypes::Type::Unknown;
721 case wkbTIN:
return QgsWkbTypes::Type::Unknown;
722 case wkbTriangle:
return QgsWkbTypes::Type::Triangle;
724 case wkbNone:
return QgsWkbTypes::Type::NoGeometry;
725 case wkbLinearRing:
return QgsWkbTypes::Type::LineString;
727 case wkbCircularStringZ:
return QgsWkbTypes::Type::CircularStringZ;
728 case wkbCompoundCurveZ:
return QgsWkbTypes::Type::CompoundCurveZ;
729 case wkbCurvePolygonZ:
return QgsWkbTypes::Type::CurvePolygonZ;
730 case wkbMultiCurveZ:
return QgsWkbTypes::Type::MultiCurveZ;
731 case wkbMultiSurfaceZ:
return QgsWkbTypes::Type::MultiSurfaceZ;
732 case wkbCurveZ:
return QgsWkbTypes::Type::Unknown;
733 case wkbSurfaceZ:
return QgsWkbTypes::Type::Unknown;
734 case wkbPolyhedralSurfaceZ:
return QgsWkbTypes::Type::Unknown;
735 case wkbTINZ:
return QgsWkbTypes::Type::Unknown;
736 case wkbTriangleZ:
return QgsWkbTypes::Type::TriangleZ;
738 case wkbPointM:
return QgsWkbTypes::Type::PointM;
739 case wkbLineStringM:
return QgsWkbTypes::Type::LineStringM;
740 case wkbPolygonM:
return QgsWkbTypes::Type::PolygonM;
741 case wkbMultiPointM:
return QgsWkbTypes::Type::MultiPointM;
742 case wkbMultiLineStringM:
return QgsWkbTypes::Type::MultiLineStringM;
743 case wkbMultiPolygonM:
return QgsWkbTypes::Type::MultiPolygonM;
744 case wkbGeometryCollectionM:
return QgsWkbTypes::Type::GeometryCollectionM;
745 case wkbCircularStringM:
return QgsWkbTypes::Type::CircularStringM;
746 case wkbCompoundCurveM:
return QgsWkbTypes::Type::CompoundCurveM;
747 case wkbCurvePolygonM:
return QgsWkbTypes::Type::CurvePolygonM;
748 case wkbMultiCurveM:
return QgsWkbTypes::Type::MultiCurveM;
749 case wkbMultiSurfaceM:
return QgsWkbTypes::Type::MultiSurfaceM;
750 case wkbCurveM:
return QgsWkbTypes::Type::Unknown;
751 case wkbSurfaceM:
return QgsWkbTypes::Type::Unknown;
752 case wkbPolyhedralSurfaceM:
return QgsWkbTypes::Type::Unknown;
753 case wkbTINM:
return QgsWkbTypes::Type::Unknown;
754 case wkbTriangleM:
return QgsWkbTypes::Type::TriangleM;
756 case wkbPointZM:
return QgsWkbTypes::Type::PointZM;
757 case wkbLineStringZM:
return QgsWkbTypes::Type::LineStringZM;
758 case wkbPolygonZM:
return QgsWkbTypes::Type::PolygonZM;
759 case wkbMultiPointZM:
return QgsWkbTypes::Type::MultiPointZM;
760 case wkbMultiLineStringZM:
return QgsWkbTypes::Type::MultiLineStringZM;
761 case wkbMultiPolygonZM:
return QgsWkbTypes::Type::MultiPolygonZM;
762 case wkbGeometryCollectionZM:
return QgsWkbTypes::Type::GeometryCollectionZM;
763 case wkbCircularStringZM:
return QgsWkbTypes::Type::CircularStringZM;
764 case wkbCompoundCurveZM:
return QgsWkbTypes::Type::CompoundCurveZM;
765 case wkbCurvePolygonZM:
return QgsWkbTypes::Type::CurvePolygonZM;
766 case wkbMultiCurveZM:
return QgsWkbTypes::Type::MultiCurveZM;
767 case wkbMultiSurfaceZM:
return QgsWkbTypes::Type::MultiSurfaceZM;
768 case wkbCurveZM:
return QgsWkbTypes::Type::Unknown;
769 case wkbSurfaceZM:
return QgsWkbTypes::Type::Unknown;
770 case wkbPolyhedralSurfaceZM:
return QgsWkbTypes::Type::Unknown;
771 case wkbTINZM:
return QgsWkbTypes::Type::Unknown;
772 case wkbTriangleZM:
return QgsWkbTypes::Type::TriangleZM;
774 case wkbPoint25D:
return QgsWkbTypes::Type::PointZ;
775 case wkbLineString25D:
return QgsWkbTypes::Type::LineStringZ;
776 case wkbPolygon25D:
return QgsWkbTypes::Type::PolygonZ;
777 case wkbMultiPoint25D:
return QgsWkbTypes::Type::MultiPointZ;
778 case wkbMultiLineString25D:
return QgsWkbTypes::Type::MultiLineStringZ;
779 case wkbMultiPolygon25D:
return QgsWkbTypes::Type::MultiPolygonZ;
780 case wkbGeometryCollection25D:
return QgsWkbTypes::Type::GeometryCollectionZ;
784 return QgsWkbTypes::Type::Unknown;
792 const auto ogrGeomType = OGR_G_GetGeometryType( geom );
835 if ( wkbFlatten( wkbType ) == wkbGeometryCollection )
838 if ( OGR_G_GetGeometryCount( geom ) >= 1 &&
839 wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
841 auto newGeom = OGR_G_ForceToMultiPolygon( OGR_G_Clone( geom ) );
842 auto ret = ogrGeometryToQgsGeometry( newGeom );
843 OGR_G_DestroyGeometry( newGeom );
849 int memorySize = OGR_G_WkbSize( geom );
850 unsigned char *wkb =
new unsigned char[memorySize];
854 uint32_t origGeomType;
855 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
856 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
857 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
860 if ( origGeomType % 1000 == 16 )
863 int nDims = 2 + hasZ + hasM;
866 unsigned char *wkbptr = wkb;
872 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
877 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
881 for ( uint32_t i = 0; i < numGeoms; ++i )
887 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
888 wkbptr +=
sizeof( uint32_t );
892 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
893 wkbptr +=
sizeof( uint32_t );
895 for ( uint32_t j = 0; j < nRings; ++j )
898 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
899 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
903 else if ( origGeomType % 1000 == 15 )
908 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
919 if (
string.isEmpty() )
922 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
925 QByteArray ba =
string.toUtf8();
926 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
927 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
932 VSIUnlink( randomFileName.toUtf8().constData() );
936 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
940 VSIUnlink( randomFileName.toUtf8().constData() );
945 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
947 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
953 VSIUnlink( randomFileName.toUtf8().constData() );
961 if (
string.isEmpty() )
964 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
967 QByteArray ba =
string.toUtf8();
968 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
969 static_cast< vsi_l_offset
>( ba.size() ), FALSE ) );
974 VSIUnlink( randomFileName.toUtf8().constData() );
978 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
982 VSIUnlink( randomFileName.toUtf8().constData() );
988 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
990 fields = readOgrFields( oFeat.get(), encoding );
994 VSIUnlink( randomFileName.toUtf8().constData() );
1003 QStringList strings;
1005 for (
qgssize i = 0; stringList[i]; ++i )
1007 strings.append( QString::fromUtf8( stringList[i] ) );
1018 char *pszWkt =
nullptr;
1019 const QByteArray multiLineOption = QStringLiteral(
"MULTILINE=NO" ).toLocal8Bit();
1020 const QByteArray formatOption = QStringLiteral(
"FORMAT=WKT2" ).toLocal8Bit();
1021 const char *
const options[] = {multiLineOption.constData(), formatOption.constData(),
nullptr};
1022 OSRExportToWktEx( srs, &pszWkt, options );
1024 const QString res( pszWkt );
1031 const QString wkt = OGRSpatialReferenceToWkt( srs );
1032 if ( wkt.isEmpty() )
1035 const char *authorityName = OSRGetAuthorityName( srs,
nullptr );
1036 const char *authorityCode = OSRGetAuthorityCode( srs,
nullptr );
1038 if ( authorityName && authorityCode )
1040 QString authId = QString( authorityName ) +
':' + QString( authorityCode );
1043 if ( OSRSetFromUserInput( ogrSrsTmp, authId.toUtf8().constData() ) != OGRERR_NONE &&
1044 OSRIsSame( srs, ogrSrsTmp ) )
1049 OSRDestroySpatialReference( ogrSrsTmp );
1054#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
1055 const double coordinateEpoch = OSRGetCoordinateEpoch( srs );
1056 if ( coordinateEpoch > 0 )
1074 if ( !authId.isEmpty() )
1076 ogrSrs = OSRNewSpatialReference(
nullptr );
1077 if ( OSRSetFromUserInput( ogrSrs, authId.toUtf8().constData() ) == OGRERR_NONE )
1081 if ( ogrSrsFromWkt )
1083 if ( !OSRIsSame( ogrSrs, ogrSrsFromWkt ) )
1085 OSRDestroySpatialReference( ogrSrs );
1086 ogrSrs = ogrSrsFromWkt;
1090 OSRDestroySpatialReference( ogrSrsFromWkt );
1096 OSRDestroySpatialReference( ogrSrs );
1102 ogrSrs = OSRNewSpatialReference( srsWkt.toUtf8().constData() );
1106 OSRSetAxisMappingStrategy( ogrSrs, OAMS_TRADITIONAL_GIS_ORDER );
1107#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
1122 const QString cpgEncoding = readShapefileEncodingFromCpg( path );
1123 if ( !cpgEncoding.isEmpty() )
1126 return readShapefileEncodingFromLdid( path );
1132 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1133 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_CPG" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1139 QgsOgrLayerUniquePtr layer = QgsOgrProviderUtils::getLayer( path,
false, QStringList(), 0, errCause,
false );
1140 return layer ? layer->GetMetadataItem( QStringLiteral(
"ENCODING_FROM_LDID" ), QStringLiteral(
"SHAPEFILE" ) ) : QString();
1147 char **papszStyleString = CSLTokenizeString2(
string.toUtf8().constData(),
";",
1149 | CSLT_PRESERVEQUOTES
1150 | CSLT_PRESERVEESCAPES );
1151 for (
int i = 0; papszStyleString[i] !=
nullptr; ++i )
1157 const thread_local QRegularExpression sToolPartRx( QStringLiteral(
"^(.*?)\\((.*)\\)$" ) );
1158 const QString stylePart( papszStyleString[i] );
1159 const QRegularExpressionMatch match = sToolPartRx.match( stylePart );
1160 if ( !match.hasMatch() )
1163 const QString tool = match.captured( 1 );
1164 const QString params = match.captured( 2 );
1166 char **papszTokens = CSLTokenizeString2( params.toUtf8().constData(),
",", CSLT_HONOURSTRINGS
1167 | CSLT_PRESERVEESCAPES );
1169 QVariantMap toolParts;
1170 const thread_local QRegularExpression sToolParamRx( QStringLiteral(
"^(.*?):(.*)$" ) );
1171 for (
int j = 0; papszTokens[j] !=
nullptr; ++j )
1173 const QString toolPart( papszTokens[j] );
1174 const QRegularExpressionMatch toolMatch = sToolParamRx.match( toolPart );
1175 if ( !match.hasMatch() )
1179 toolParts.insert( toolMatch.captured( 1 ).toLower(), toolMatch.captured( 2 ) );
1181 CSLDestroy( papszTokens );
1184 styles.insert( tool.toLower(), toolParts );
1186 CSLDestroy( papszStyleString );
1192 const QVariantMap styles = parseStyleString(
string );
1196 const thread_local QRegularExpression sUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.]+)(g|px|pt|mm|cm|in)$" ) );
1197 const QRegularExpressionMatch match = sUnitRx.match( size );
1198 if ( match.hasMatch() )
1200 value = match.captured( 1 ).toDouble();
1201 const QString unitString = match.captured( 2 );
1202 if ( unitString.compare( QLatin1String(
"px" ), Qt::CaseInsensitive ) == 0 )
1206 static constexpr double PT_TO_INCHES_FACTOR = 1 / 72.0;
1207 static constexpr double PX_TO_PT_FACTOR = 1 / ( 96.0 * PT_TO_INCHES_FACTOR );
1209 value *= PX_TO_PT_FACTOR;
1212 else if ( unitString.compare( QLatin1String(
"pt" ), Qt::CaseInsensitive ) == 0 )
1217 else if ( unitString.compare( QLatin1String(
"mm" ), Qt::CaseInsensitive ) == 0 )
1222 else if ( unitString.compare( QLatin1String(
"cm" ), Qt::CaseInsensitive ) == 0 )
1228 else if ( unitString.compare( QLatin1String(
"in" ), Qt::CaseInsensitive ) == 0 )
1233 else if ( unitString.compare( QLatin1String(
"g" ), Qt::CaseInsensitive ) == 0 )
1238 QgsDebugMsg( QStringLiteral(
"Unknown unit %1" ).arg( unitString ) );
1242 QgsDebugMsg( QStringLiteral(
"Could not parse style size %1" ).arg( size ) );
1247 auto convertColor = [](
const QString & string ) -> QColor
1249 if (
string.isEmpty() )
1252 const thread_local QRegularExpression sColorWithAlphaRx = QRegularExpression( QStringLiteral(
"^#([0-9a-fA-F]{6})([0-9a-fA-F]{2})$" ) );
1253 const QRegularExpressionMatch match = sColorWithAlphaRx.match(
string );
1254 if ( match.hasMatch() )
1257 return QColor( QStringLiteral(
"#%1%2" ).arg( match.captured( 2 ), match.captured( 1 ) ) );
1261 return QColor(
string );
1265 auto convertPen = [&convertColor, &convertSize, string](
const QVariantMap & lineStyle ) -> std::unique_ptr< QgsSymbol >
1267 QColor color = convertColor( lineStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1271 convertSize( lineStyle.value( QStringLiteral(
"w" ) ).toString(), lineWidth, lineWidthUnit );
1274 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-pen-(\\d+)" ) );
1275 const QRegularExpressionMatch match = sMapInfoId.match(
string );
1276 if ( match.hasMatch() )
1278 const int penId = match.captured( 1 ).toInt();
1285 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( color, lineWidth );
1286 simpleLine->setWidthUnit( lineWidthUnit );
1289 const QString pattern = lineStyle.value( QStringLiteral(
"p" ) ).toString();
1290 if ( !pattern.isEmpty() )
1292 const thread_local QRegularExpression sPatternUnitRx = QRegularExpression( QStringLiteral(
"^([\\d\\.\\s]+)(g|px|pt|mm|cm|in)$" ) );
1293 const QRegularExpressionMatch match = sPatternUnitRx.match( pattern );
1294 if ( match.hasMatch() )
1296 const QStringList patternValues = match.captured( 1 ).split(
' ' );
1297 QVector< qreal > dashPattern;
1299 for (
const QString &val : patternValues )
1302 convertSize( val + match.captured( 2 ), length, patternUnits );
1303 dashPattern.push_back( length * lineWidth * 2 );
1306 simpleLine->setCustomDashVector( dashPattern );
1307 simpleLine->setCustomDashPatternUnit( patternUnits );
1308 simpleLine->setUseCustomDashPattern(
true );
1312 Qt::PenCapStyle capStyle = Qt::FlatCap;
1313 Qt::PenJoinStyle joinStyle = Qt::MiterJoin;
1315 const QString
id = lineStyle.value( QStringLiteral(
"id" ) ).toString();
1316 if (
id.contains( QLatin1String(
"mapinfo-pen" ), Qt::CaseInsensitive ) )
1321 capStyle = Qt::RoundCap;
1322 joinStyle = Qt::RoundJoin;
1326 const QString penCap = lineStyle.value( QStringLiteral(
"cap" ) ).toString();
1327 if ( penCap.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1329 capStyle = Qt::FlatCap;
1331 else if ( penCap.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1333 capStyle = Qt::RoundCap;
1335 else if ( penCap.compare( QLatin1String(
"p" ), Qt::CaseInsensitive ) == 0 )
1337 capStyle = Qt::SquareCap;
1339 simpleLine->setPenCapStyle( capStyle );
1342 const QString penJoin = lineStyle.value( QStringLiteral(
"j" ) ).toString();
1343 if ( penJoin.compare( QLatin1String(
"m" ), Qt::CaseInsensitive ) == 0 )
1345 joinStyle = Qt::MiterJoin;
1347 else if ( penJoin.compare( QLatin1String(
"r" ), Qt::CaseInsensitive ) == 0 )
1349 joinStyle = Qt::RoundJoin;
1351 else if ( penJoin.compare( QLatin1String(
"b" ), Qt::CaseInsensitive ) == 0 )
1353 joinStyle = Qt::BevelJoin;
1355 simpleLine->setPenJoinStyle( joinStyle );
1357 const QString priority = lineStyle.value( QStringLiteral(
"l" ) ).toString();
1358 if ( !priority.isEmpty() )
1360 simpleLine->setRenderingPass( priority.toInt() );
1362 return std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
1365 auto convertBrush = [&convertColor](
const QVariantMap & brushStyle ) -> std::unique_ptr< QgsSymbol >
1367 const QColor foreColor = convertColor( brushStyle.value( QStringLiteral(
"fc" ), QStringLiteral(
"#000000" ) ).toString() );
1368 const QColor backColor = convertColor( brushStyle.value( QStringLiteral(
"bc" ), QString() ).toString() );
1370 const QString
id = brushStyle.value( QStringLiteral(
"id" ) ).toString();
1373 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-brush-(\\d+)" ) );
1374 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1375 if ( match.hasMatch() )
1377 const int brushId = match.captured( 1 ).toInt();
1384 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-brush-(\\d+)" ) );
1385 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1387 Qt::BrushStyle style = Qt::SolidPattern;
1388 if ( ogrMatch.hasMatch() )
1390 const int brushId = ogrMatch.captured( 1 ).toInt();
1394 style = Qt::SolidPattern;
1398 style = Qt::NoBrush;
1402 style = Qt::HorPattern;
1406 style = Qt::VerPattern;
1410 style = Qt::FDiagPattern;
1414 style = Qt::BDiagPattern;
1418 style = Qt::CrossPattern;
1422 style = Qt::DiagCrossPattern;
1428 if ( backColor.isValid() && style != Qt::SolidPattern && style != Qt::NoBrush )
1430 std::unique_ptr< QgsSimpleFillSymbolLayer > backgroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( backColor );
1431 backgroundFill->setLocked(
true );
1432 backgroundFill->setStrokeStyle( Qt::NoPen );
1433 layers << backgroundFill.release();
1436 std::unique_ptr< QgsSimpleFillSymbolLayer > foregroundFill = std::make_unique< QgsSimpleFillSymbolLayer >( foreColor );
1437 foregroundFill->setBrushStyle( style );
1438 foregroundFill->setStrokeStyle( Qt::NoPen );
1440 const QString priority = brushStyle.value( QStringLiteral(
"l" ) ).toString();
1441 if ( !priority.isEmpty() )
1443 foregroundFill->setRenderingPass( priority.toInt() );
1445 layers << foregroundFill.release();
1446 return std::make_unique< QgsFillSymbol >( layers );
1449 auto convertSymbol = [&convertColor, &convertSize, string](
const QVariantMap & symbolStyle ) -> std::unique_ptr< QgsSymbol >
1451 const QColor color = convertColor( symbolStyle.value( QStringLiteral(
"c" ), QStringLiteral(
"#000000" ) ).toString() );
1455 convertSize( symbolStyle.value( QStringLiteral(
"s" ) ).toString(), symbolSize, symbolSizeUnit );
1457 const double angle = symbolStyle.value( QStringLiteral(
"a" ), QStringLiteral(
"0" ) ).toDouble();
1459 const QString
id = symbolStyle.value( QStringLiteral(
"id" ) ).toString();
1462 const thread_local QRegularExpression sMapInfoId = QRegularExpression( QStringLiteral(
"mapinfo-sym-(\\d+)" ) );
1463 const QRegularExpressionMatch match = sMapInfoId.match(
id );
1464 if ( match.hasMatch() )
1466 const int symbolId = match.captured( 1 ).toInt();
1477 std::unique_ptr< QgsMarkerSymbolLayer > markerLayer;
1479 const thread_local QRegularExpression sFontId = QRegularExpression( QStringLiteral(
"font-sym-(\\d+)" ) );
1480 const QRegularExpressionMatch fontMatch = sFontId.match(
id );
1481 if ( fontMatch.hasMatch() )
1483 const int symId = fontMatch.captured( 1 ).toInt();
1484 const QStringList families = symbolStyle.value( QStringLiteral(
"f" ), QString() ).toString().split(
',' );
1486 bool familyFound =
false;
1489 for (
const QString &family : std::as_const( families ) )
1497 fontFamily = processedFamily;
1504 std::unique_ptr< QgsFontMarkerSymbolLayer > fontMarker = std::make_unique< QgsFontMarkerSymbolLayer >( fontFamily, QChar( symId ), symbolSize );
1505 fontMarker->setSizeUnit( symbolSizeUnit );
1506 fontMarker->setAngle( -
angle );
1508 fontMarker->setColor( color );
1510 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1511 if ( strokeColor.isValid() )
1513 fontMarker->setStrokeColor( strokeColor );
1514 fontMarker->setStrokeWidth( 1 );
1519 fontMarker->setStrokeWidth( 0 );
1522 markerLayer = std::move( fontMarker );
1524 else if ( !families.empty() )
1533 const thread_local QRegularExpression sOgrId = QRegularExpression( QStringLiteral(
"ogr-sym-(\\d+)" ) );
1534 const QRegularExpressionMatch ogrMatch = sOgrId.match(
id );
1537 bool isFilled =
true;
1538 if ( ogrMatch.hasMatch() )
1540 const int symId = ogrMatch.captured( 1 ).toInt();
1603 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >( shape, symbolSize, -
angle );
1604 simpleMarker->setSizeUnit( symbolSizeUnit );
1608 simpleMarker->setColor( color );
1609 simpleMarker->setStrokeStyle( Qt::NoPen );
1613 simpleMarker->setFillColor( QColor( 0, 0, 0, 0 ) );
1614 simpleMarker->setStrokeColor( color );
1617 const QColor strokeColor = convertColor( symbolStyle.value( QStringLiteral(
"o" ), QString() ).toString() );
1618 if ( strokeColor.isValid() )
1620 simpleMarker->setStrokeColor( strokeColor );
1621 simpleMarker->setStrokeStyle( Qt::SolidLine );
1624 markerLayer = std::move( simpleMarker );
1627 return std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << markerLayer.release() );
1633 if ( styles.contains( QStringLiteral(
"symbol" ) ) )
1635 const QVariantMap symbolStyle = styles.value( QStringLiteral(
"symbol" ) ).toMap();
1636 return convertSymbol( symbolStyle );
1644 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1647 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1648 return convertPen( lineStyle );
1657 std::unique_ptr< QgsSymbol > fillSymbol = std::make_unique< QgsFillSymbol >();
1658 if ( styles.contains( QStringLiteral(
"brush" ) ) )
1660 const QVariantMap brushStyle = styles.value( QStringLiteral(
"brush" ) ).toMap();
1661 fillSymbol = convertBrush( brushStyle );
1665 std::unique_ptr< QgsSimpleFillSymbolLayer > emptyFill = std::make_unique< QgsSimpleFillSymbolLayer >();
1666 emptyFill->setBrushStyle( Qt::NoBrush );
1667 fillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << emptyFill.release() );
1670 std::unique_ptr< QgsSymbol > penSymbol;
1671 if ( styles.contains( QStringLiteral(
"pen" ) ) )
1673 const QVariantMap lineStyle = styles.value( QStringLiteral(
"pen" ) ).toMap();
1674 penSymbol = convertPen( lineStyle );
1679 const int count = penSymbol->symbolLayerCount();
1689 for (
int i = 0; i < count; ++i )
1691 std::unique_ptr< QgsSymbolLayer > layer( penSymbol->takeSymbolLayer( 0 ) );
1692 layer->setLocked(
true );
1693 fillSymbol->appendSymbolLayer( layer.release() );
1709 variantType = QVariant::Type::Invalid;
1710 variantSubType = QVariant::Type::Invalid;
1715 if ( ogrSubType == OFSTBoolean )
1717 variantType = QVariant::Bool;
1718 ogrSubType = OFSTBoolean;
1721 variantType = QVariant::Int;
1724 variantType = QVariant::LongLong;
1727 variantType = QVariant::Double;
1730 variantType = QVariant::Date;
1733 variantType = QVariant::Time;
1736 variantType = QVariant::DateTime;
1740 variantType = QVariant::ByteArray;
1745 if ( ogrSubType == OFSTJSON )
1747 ogrSubType = OFSTJSON;
1748 variantType = QVariant::Map;
1749 variantSubType = QVariant::String;
1753 variantType = QVariant::String;
1758 case OFTWideStringList:
1759 variantType = QVariant::StringList;
1760 variantSubType = QVariant::String;
1763 case OFTIntegerList:
1764 variantType = QVariant::List;
1765 variantSubType = QVariant::Int;
1769 variantType = QVariant::List;
1770 variantSubType = QVariant::Double;
1773 case OFTInteger64List:
1774 variantType = QVariant::List;
1775 variantSubType = QVariant::LongLong;
1782 ogrSubType = OFSTNone;
1783 switch ( variantType )
1785 case QVariant::Bool:
1786 ogrType = OFTInteger;
1787 ogrSubType = OFSTBoolean;
1791 ogrType = OFTInteger;
1794 case QVariant::LongLong:
1795 ogrType = OFTInteger64;
1798 case QVariant::Double:
1802 case QVariant::Char:
1803 ogrType = OFTString;
1806 case QVariant::String:
1807 ogrType = OFTString;
1810 case QVariant::StringList:
1811 ogrType = OFTStringList;
1814 case QVariant::ByteArray:
1815 ogrType = OFTBinary;
1818 case QVariant::Date:
1822 case QVariant::Time:
1825 case QVariant::DateTime:
1826 ogrType = OFTDateTime;
1830 ogrType = OFTString;
1837 if (
string.isEmpty() )
1845 res =
string.toInt( &ok );
1849 res =
string.toLongLong( &ok );
1853 res =
string.toDouble( &ok );
1863 res = QDate::fromString(
string, Qt::ISODate );
1868 res = QTime::fromString(
string, Qt::ISODate );
1873 res = QDateTime::fromString(
string, Qt::ISODate );
1883 return ok ? res : QVariant();
1891 const QString driverName = QString::fromUtf8( GDALGetDriverShortName( driver ) );
1893 int nMaxIntLen = 11;
1894 int nMaxInt64Len = 21;
1895 int nMaxDoubleLen = 20;
1896 int nMaxDoublePrec = 15;
1898 if ( driverName == QLatin1String(
"GPKG" ) )
1908 QList<QgsVectorDataProvider::NativeType> nativeTypes;
1912 <<
QgsVectorDataProvider::NativeType( QObject::tr(
"Decimal number (real)" ), QStringLiteral(
"double" ), QVariant::Double, 0, nMaxDoubleLen, 0, nMaxDoublePrec )
1915 if ( driverName == QLatin1String(
"GPKG" ) )
1918 bool supportsDate =
true;
1919 bool supportsTime =
true;
1920 bool supportsDateTime =
true;
1921 bool supportsBinary =
false;
1922 bool supportIntegerList =
false;
1923 bool supportInteger64List =
false;
1924 bool supportRealList =
false;
1925 bool supportsStringList =
false;
1929 if (
const char *pszDataTypes = GDALGetMetadataItem( driver, GDAL_DMD_CREATIONFIELDDATATYPES,
nullptr ) )
1931 char **papszTokens = CSLTokenizeString2( pszDataTypes,
" ", 0 );
1932 supportsDate = CSLFindString( papszTokens,
"Date" ) >= 0;
1933 supportsTime = CSLFindString( papszTokens,
"Time" ) >= 0;
1934 supportsDateTime = CSLFindString( papszTokens,
"DateTime" ) >= 0;
1935 supportsBinary = CSLFindString( papszTokens,
"Binary" ) >= 0;
1936 supportIntegerList = CSLFindString( papszTokens,
"IntegerList" ) >= 0;
1937 supportInteger64List = CSLFindString( papszTokens,
"Integer64List" ) >= 0;
1938 supportRealList = CSLFindString( papszTokens,
"RealList" ) >= 0;
1939 supportsStringList = CSLFindString( papszTokens,
"StringList" ) >= 0;
1940 CSLDestroy( papszTokens );
1945#if GDAL_VERSION_NUM < GDAL_COMPUTE_VERSION(3,2,0)
1946 if ( driverName == QLatin1String(
"ESRI Shapefile" ) )
1948 supportsDateTime =
false;
1962 if ( supportsDateTime )
1967 if ( supportsBinary )
1972 if ( supportIntegerList )
1977 if ( supportInteger64List )
1982 if ( supportRealList )
1987 if ( supportsStringList )
1993 const char *pszDataSubTypes = GDALGetMetadataItem( driver, GDAL_DMD_CREATIONFIELDDATASUBTYPES,
nullptr );
1994 if ( pszDataSubTypes && strstr( pszDataSubTypes,
"Boolean" ) )
2005#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,3,0)
2011 const QString name{ OGR_FldDomain_GetName( domain ) };
2012 const QString description{ OGR_FldDomain_GetDescription( domain ) };
2014 QVariant::Type fieldType = QVariant::Type::Invalid;
2015 QVariant::Type fieldSubType = QVariant::Type::Invalid;
2016 const OGRFieldType domainFieldType = OGR_FldDomain_GetFieldType( domain );
2017 const OGRFieldSubType domainFieldSubType = OGR_FldDomain_GetFieldSubType( domain );
2018 ogrFieldTypeToQVariantType( domainFieldType, domainFieldSubType, fieldType, fieldSubType );
2020 std::unique_ptr< QgsFieldDomain > res;
2021 switch ( OGR_FldDomain_GetDomainType( domain ) )
2025 QList< QgsCodedValue > values;
2026 const OGRCodedValue *codedValue = OGR_CodedFldDomain_GetEnumeration( domain );
2027 while ( codedValue && codedValue->pszCode )
2029 const QString code( codedValue->pszCode );
2034 const QString value( codedValue->pszValue ? codedValue->pszValue : codedValue->pszCode );
2035 values.append(
QgsCodedValue( stringToVariant( domainFieldType, domainFieldSubType, code ), value ) );
2040 res = std::make_unique< QgsCodedFieldDomain >( name, description, fieldType, values );
2047 bool minIsInclusive =
false;
2048 if (
const OGRField *min = OGR_RangeFldDomain_GetMin( domain, &minIsInclusive ) )
2053 bool maxIsInclusive =
false;
2054 if (
const OGRField *max = OGR_RangeFldDomain_GetMax( domain, &maxIsInclusive ) )
2059 res = std::make_unique< QgsRangeFieldDomain >( name, description, fieldType,
2060 minValue, minIsInclusive,
2061 maxValue, maxIsInclusive );
2066 res = std::make_unique< QgsGlobFieldDomain >( name, description, fieldType,
2067 QString( OGR_GlobFldDomain_GetGlob( domain ) ) );
2071 switch ( OGR_FldDomain_GetMergePolicy( domain ) )
2073 case OFDMP_DEFAULT_VALUE:
2079 case OFDMP_GEOMETRY_WEIGHTED:
2084 switch ( OGR_FldDomain_GetSplitPolicy( domain ) )
2086 case OFDSP_DEFAULT_VALUE:
2089 case OFDSP_DUPLICATE:
2092 case OFDSP_GEOMETRY_RATIO:
2104 OGRFieldType domainFieldType = OFTInteger;
2105 OGRFieldSubType domainFieldSubType = OFSTNone;
2106 variantTypeToOgrFieldType( domain->
fieldType(), domainFieldType, domainFieldSubType );
2108 OGRFieldDomainH res =
nullptr;
2109 switch ( domain->
type() )
2113 std::vector< OGRCodedValue > enumeration;
2114 const QList< QgsCodedValue> values = qgis::down_cast< const QgsCodedFieldDomain * >( domain )->values();
2115 enumeration.reserve( values.size() );
2118 OGRCodedValue codedValue;
2119 codedValue.pszCode = CPLStrdup( value.code().toString().toUtf8().constData() );
2120 codedValue.pszValue = CPLStrdup( value.value().toUtf8().constData() );
2121 enumeration.push_back( codedValue );
2124 last.pszCode =
nullptr;
2125 last.pszValue =
nullptr;
2126 enumeration.push_back( last );
2127 res = OGR_CodedFldDomain_Create(
2128 domain->
name().toUtf8().constData(),
2135 for (
const OGRCodedValue &value : std::as_const( enumeration ) )
2137 CPLFree( value.pszCode );
2138 CPLFree( value.pszValue );
2145 std::unique_ptr< OGRField > min = variantToOGRField( qgis::down_cast< const QgsRangeFieldDomain * >( domain )->minimum() );
2146 std::unique_ptr< OGRField > max = variantToOGRField( qgis::down_cast< const QgsRangeFieldDomain * >( domain )->maximum() );
2147 res = OGR_RangeFldDomain_Create(
2148 domain->
name().toUtf8().constData(),
2153 qgis::down_cast< const QgsRangeFieldDomain * >( domain )->minimumIsInclusive(),
2155 qgis::down_cast< const QgsRangeFieldDomain * >( domain )->maximumIsInclusive()
2162 res = OGR_GlobFldDomain_Create(
2163 domain->
name().toUtf8().constData(),
2167 qgis::down_cast< const QgsGlobFieldDomain * >( domain )->glob().toUtf8().constData()
2176 OGR_FldDomain_SetMergePolicy( res, OFDMP_DEFAULT_VALUE );
2179 OGR_FldDomain_SetMergePolicy( res, OFDMP_GEOMETRY_WEIGHTED );
2182 OGR_FldDomain_SetMergePolicy( res, OFDMP_SUM );
2189 OGR_FldDomain_SetSplitPolicy( res, OFDSP_DEFAULT_VALUE );
2192 OGR_FldDomain_SetSplitPolicy( res, OFDSP_GEOMETRY_RATIO );
2195 OGR_FldDomain_SetSplitPolicy( res, OFDSP_DUPLICATE );
@ GeometryWeighted
New values are computed as the weighted average of the source values.
@ DefaultValue
Use default field value.
@ GeometryRatio
New values are computed by the ratio of their area/length compared to the area/length of the original...
@ DefaultValue
Use default field value.
@ Duplicate
Duplicate original value.
MarkerShape
Marker shapes.
@ Cross2
Rotated cross (lines only), 'x' shape.
@ Cross
Cross (lines only)
@ Coded
Coded field domain.
@ Range
Numeric range field domain (min/max)
@ Glob
Glob string pattern field domain.
static QgsFontManager * fontManager()
Returns the application font manager, which manages available fonts and font installation for the QGI...
static endian_t endian()
Returns whether this machine uses big or little endian.
Associates a code and a value.
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.
Base class for field domains.
Qgis::FieldDomainMergePolicy mergePolicy() const
Returns the merge policy.
Qgis::FieldDomainSplitPolicy splitPolicy() const
Returns the split policy.
virtual Qgis::FieldDomainType type() const =0
Returns the type of field domain.
QString name() const
Returns the name of the field domain.
QVariant::Type fieldType() const
Returns the associated field type.
QString description() const
Returns the description of the field domain.
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).
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
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 QVariant stringToVariant(OGRFieldType type, OGRFieldSubType subType, const QString &string)
Converts a string to a variant, using the provider OGR field type and subType to determine the most a...
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 void variantTypeToOgrFieldType(QVariant::Type variantType, OGRFieldType &ogrType, OGRFieldSubType &ogrSubType)
Converts an QVariant type to the best matching OGR field type and sub type.
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 std::unique_ptr< OGRField > variantToOGRField(const QVariant &value)
Converts a QVariant to an OGRField value.
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 QList< QgsVectorDataProvider::NativeType > nativeFieldTypesForDriver(GDALDriverH driver)
Returns the list of native field types supported for a driver.
static QgsWkbTypes::Type ogrGeometryTypeToQgsWkbType(OGRwkbGeometryType ogrGeomType)
Converts a OGRwkbGeometryType to QgsWkbTypes::Type.
static std::unique_ptr< QgsFieldDomain > convertFieldDomain(OGRFieldDomainH domain)
Converts an OGR field domain definition to a QgsFieldDomain equivalent.
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 void ogrFieldTypeToQVariantType(OGRFieldType ogrType, OGRFieldSubType ogrSubType, QVariant::Type &variantType, QVariant::Type &variantSubType)
Converts an OGR field type and sub type to the best matching QVariant::Type equivalent.
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 QString typeToDisplayString(QVariant::Type type, QVariant::Type subType=QVariant::Type::Invalid)
Returns a user-friendly translated string representing a QVariant type.
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) const
Destroys an gdal dataset, using the correct gdal calls.
void CORE_EXPORT operator()(GDALWarpOptions *options) const
Destroys GDAL warp options, using the correct gdal calls.
void CORE_EXPORT operator()(OGRDataSourceH source) const
Destroys an OGR data source, using the correct gdal calls.
void CORE_EXPORT operator()(OGRFeatureH feature) const
Destroys an OGR feature, using the correct gdal calls.
void CORE_EXPORT operator()(OGRFieldDefnH definition) const
Destroys an OGR field definition, using the correct gdal calls.
void CORE_EXPORT operator()(OGRGeometryH geometry) const
Destroys an OGR geometry, using the correct gdal calls.