24 #include <cpl_error.h> 25 #include <QJsonDocument> 31 #define OGR_F_IsFieldSetAndNotNull OGR_F_IsFieldSet 38 OGR_DS_Destroy( source );
44 OGR_G_DestroyGeometry( geometry );
49 OGR_Fld_Destroy( definition );
54 OGR_F_Destroy( feature );
71 CPLPushErrorHandler( CPLQuietErrorHandler );
72 GDALDeleteDataset( driver, path.toUtf8().constData() );
84 GDALDestroyWarpOptions( options );
96 feature.
setId( OGR_F_GetFID( ogrFet ) );
99 if ( !readOgrFeatureGeometry( ogrFet, feature ) )
104 if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
119 int fieldCount = OGR_F_GetFieldCount( ogrFet );
120 for (
int i = 0; i < fieldCount; ++i )
122 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
129 QString name = encoding ? encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) ) : QString::fromUtf8( OGR_Fld_GetNameRef( fldDef ) );
130 QVariant::Type varType;
131 switch ( OGR_Fld_GetType( fldDef ) )
134 if ( OGR_Fld_GetSubType( fldDef ) == OFSTBoolean )
135 varType = QVariant::Bool;
137 varType = QVariant::Int;
140 varType = QVariant::LongLong;
143 varType = QVariant::Double;
146 varType = QVariant::Date;
149 varType = QVariant::Time;
152 varType = QVariant::DateTime;
155 #if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(2,4,0) 156 if ( OGR_Fld_GetSubType( fldDef ) == OFSTJSON )
157 varType = QVariant::Map;
159 varType = QVariant::String;
163 varType = QVariant::String;
172 if ( !ogrFet || attIndex < 0 || attIndex >= fields.
count() )
179 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
186 QgsDebugMsg( QStringLiteral(
"ogrFet->GetFieldDefnRef(attindex) returns NULL" ) );
197 switch ( fields.
at( attIndex ).
type() )
199 case QVariant::String:
202 value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
204 value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
208 value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
211 value = QVariant(
bool( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ) );
213 case QVariant::LongLong:
214 value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
216 case QVariant::Double:
217 value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
220 case QVariant::DateTime:
223 int year, month, day, hour, minute, second, tzf;
225 OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
226 if ( fields.
at( attIndex ).
type() == QVariant::Date )
227 value = QDate( year, month, day );
228 else if ( fields.
at( attIndex ).
type() == QVariant::Time )
229 value = QTime( hour, minute, second );
231 value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
235 case QVariant::ByteArray:
238 const GByte *b = OGR_F_GetFieldAsBinary( ogrFet, attIndex, &size );
242 QByteArray ba = QByteArray::fromRawData( reinterpret_cast<const char *>( b ), size );
254 value = QJsonDocument::fromJson( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
256 value = QJsonDocument::fromJson( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ).toUtf8() ).toVariant();
260 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
267 value = QVariant( QString() );
283 for (
int idx = 0; idx < fields.
count(); ++idx )
285 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
299 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
303 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
313 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
314 return qgis::make_unique< QgsPoint >( wkbType, x, y, z, m );
321 int count = OGR_G_GetPointCount( geom );
322 QVector< double > x( count );
323 QVector< double > y( count );
325 double *pz =
nullptr;
331 double *pm =
nullptr;
338 OGR_G_GetPointsZM( geom, x.data(),
sizeof( double ), y.data(),
sizeof( double ), pz,
sizeof(
double ), pm,
sizeof( double ) );
371 int memorySize = OGR_G_WkbSize( geom );
372 unsigned char *wkb =
new unsigned char[memorySize];
376 uint32_t origGeomType;
377 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
378 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
379 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
382 if ( origGeomType % 1000 == 16 )
385 int nDims = 2 + hasZ + hasM;
388 unsigned char *wkbptr = wkb;
394 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
399 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
403 for ( uint32_t i = 0; i < numGeoms; ++i )
409 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
410 wkbptr +=
sizeof( uint32_t );
414 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
415 wkbptr +=
sizeof( uint32_t );
417 for ( uint32_t j = 0; j < nRings; ++j )
420 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
421 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
425 else if ( origGeomType % 1000 == 15 )
430 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
441 if (
string.isEmpty() )
444 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
447 QByteArray ba =
string.toUtf8();
448 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
449 static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
454 VSIUnlink( randomFileName.toUtf8().constData() );
458 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
462 VSIUnlink( randomFileName.toUtf8().constData() );
467 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
469 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
475 VSIUnlink( randomFileName.toUtf8().constData() );
483 if (
string.isEmpty() )
486 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
489 QByteArray ba =
string.toUtf8();
490 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
491 static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
496 VSIUnlink( randomFileName.toUtf8().constData() );
500 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
504 VSIUnlink( randomFileName.toUtf8().constData() );
510 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
512 fields = readOgrFields( oFeat.get(), encoding );
516 VSIUnlink( randomFileName.toUtf8().constData() );
525 for (
qgssize i = 0; stringList[i]; ++i )
527 strings.append( QString::fromUtf8( stringList[i] ) );
bool isValid() const
Returns the validity of this feature.
void CORE_EXPORT operator()(OGRFeatureH feature)
Destroys an OGR feature, using the correct gdal calls.
static bool readOgrFeatureAttributes(OGRFeatureH ogrFet, const QgsFields &fields, QgsFeature &feature, QTextCodec *encoding)
Reads all attributes from an OGR feature into a QgsFeature.
void setFields(const QgsFields &fields, bool initAttributes=false)
Assign a field map with the feature to allow attribute access by attribute name.
void fromWkb(unsigned char *wkb, int length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
QList< QgsFeature > QgsFeatureList
static bool readOgrFeatureGeometry(OGRFeatureH ogrFet, QgsFeature &feature)
Reads the geometry from an OGR feature into a QgsFeature.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
void CORE_EXPORT operator()(OGRDataSourceH source)
Destroys an OGR data source, using the correct gdal calls.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static QgsFields readOgrFields(OGRFeatureH ogrFet, QTextCodec *encoding)
Reads an OGR feature and returns a corresponding fields collection.
#define OGR_F_IsFieldSetAndNotNull
static endian_t endian()
Returns whether this machine uses big or little endian.
int count() const
Returns number of items.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Type
The WKB type describes the number of dimensions a geometry has.
std::unique_ptr< QgsPoint > ogrGeometryToQgsPoint(OGRGeometryH geom)
static QgsFeatureList stringToFeatureList(const QString &string, const QgsFields &fields, QTextCodec *encoding)
Attempts to parse a string representing a collection of features using OGR.
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.
void CORE_EXPORT operator()(GDALDatasetH datasource)
Destroys an gdal dataset, using the correct gdal calls.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
static QgsFeature readOgrFeature(OGRFeatureH ogrFet, const QgsFields &fields, QTextCodec *encoding)
Reads an OGR feature and converts it to a QgsFeature.
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) ...
static QgsFields stringToFields(const QString &string, QTextCodec *encoding)
Attempts to retrieve the fields from a string representing a collection of features using OGR...
Encapsulate a field in an attribute table or data source.
void setId(QgsFeatureId id)
Sets the feature ID for this feature.
static QgsGeometry ogrGeometryToQgsGeometry(OGRGeometryH geom)
Converts an OGR geometry representation to a QgsGeometry object.
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 CORE_EXPORT operator()(GDALWarpOptions *options)
Destroys GDAL warp options, using the correct gdal calls.
void setValid(bool validity)
Sets the validity of the feature.
void clearGeometry()
Removes any geometry associated with the feature.
static QVariant getOgrFeatureAttribute(OGRFeatureH ogrFet, const QgsFields &fields, int attIndex, QTextCodec *encoding, bool *ok=nullptr)
Retrieves an attribute value from an OGR feature.
std::unique_ptr< QgsLineString > ogrGeometryToQgsLineString(OGRGeometryH geom)
void CORE_EXPORT operator()(OGRGeometryH geometry)
Destroys an OGR geometry, using the correct gdal calls.
void CORE_EXPORT operator()(OGRFieldDefnH definition)
Destroys an OGR field definition, using the correct gdal calls.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
static Type zmType(Type type, bool hasZ, bool hasM)
Returns the modified input geometry type according to hasZ / hasM.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
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.
static QStringList cStringListToQStringList(char **stringList)
Converts a c string list to a QStringList.
static Type flatType(Type type)
Returns the flat type for a WKB type.