25 #include <cpl_error.h> 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;
156 varType = QVariant::String;
165 if ( !ogrFet || attIndex < 0 || attIndex >= fields.
count() )
172 OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
179 QgsDebugMsg( QStringLiteral(
"ogrFet->GetFieldDefnRef(attindex) returns NULL" ) );
190 switch ( fields.
at( attIndex ).
type() )
192 case QVariant::String:
195 value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
197 value = QVariant( QString::fromUtf8( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
201 value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
204 value = QVariant(
bool( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) ) );
206 case QVariant::LongLong:
207 value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
209 case QVariant::Double:
210 value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
213 case QVariant::DateTime:
216 int year, month, day, hour, minute, second, tzf;
218 OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
219 if ( fields.
at( attIndex ).
type() == QVariant::Date )
220 value = QDate( year, month, day );
221 else if ( fields.
at( attIndex ).
type() == QVariant::Time )
222 value = QTime( hour, minute, second );
224 value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
228 Q_ASSERT_X(
false,
"QgsOgrUtils::getOgrFeatureAttribute",
"unsupported field type" );
235 value = QVariant( QString() );
251 for (
int idx = 0; idx < fields.
count(); ++idx )
253 QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
267 OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
271 feature.
setGeometry( ogrGeometryToQgsGeometry( geom ) );
281 OGR_G_GetPointZM( geom, 0, &x, &y, &z, &m );
282 return qgis::make_unique< QgsPoint >( wkbType, x, y, z, m );
287 std::unique_ptr< QgsMultiPoint > mp = qgis::make_unique< QgsMultiPoint >();
289 const int count = OGR_G_GetGeometryCount( geom );
290 for (
int i = 0; i < count; ++i )
302 int count = OGR_G_GetPointCount( geom );
303 QVector< double > x( count );
304 QVector< double > y( count );
306 double *pz =
nullptr;
312 double *pm =
nullptr;
319 OGR_G_GetPointsZM( geom, x.data(),
sizeof( double ), y.data(),
sizeof( double ), pz,
sizeof(
double ), pm,
sizeof( double ) );
326 switch ( ogrGeomType )
328 case wkbUnknown:
return QgsWkbTypes::Type::Unknown;
329 case wkbPoint:
return QgsWkbTypes::Type::Point;
330 case wkbLineString:
return QgsWkbTypes::Type::LineString;
331 case wkbPolygon:
return QgsWkbTypes::Type::Polygon;
332 case wkbMultiPoint:
return QgsWkbTypes::Type::MultiPoint;
333 case wkbMultiLineString:
return QgsWkbTypes::Type::MultiLineString;
334 case wkbMultiPolygon:
return QgsWkbTypes::Type::MultiPolygon;
335 case wkbGeometryCollection:
return QgsWkbTypes::Type::GeometryCollection;
336 case wkbCircularString:
return QgsWkbTypes::Type::CircularString;
337 case wkbCompoundCurve:
return QgsWkbTypes::Type::CompoundCurve;
338 case wkbCurvePolygon:
return QgsWkbTypes::Type::CurvePolygon;
339 case wkbMultiCurve:
return QgsWkbTypes::Type::MultiCurve;
340 case wkbMultiSurface:
return QgsWkbTypes::Type::MultiSurface;
341 case wkbCurve:
return QgsWkbTypes::Type::Unknown;
342 case wkbSurface:
return QgsWkbTypes::Type::Unknown;
343 case wkbPolyhedralSurface:
return QgsWkbTypes::Type::Unknown;
344 case wkbTIN:
return QgsWkbTypes::Type::Unknown;
345 case wkbTriangle:
return QgsWkbTypes::Type::Triangle;
347 case wkbNone:
return QgsWkbTypes::Type::NoGeometry;
348 case wkbLinearRing:
return QgsWkbTypes::Type::LineString;
350 case wkbCircularStringZ:
return QgsWkbTypes::Type::CircularStringZ;
351 case wkbCompoundCurveZ:
return QgsWkbTypes::Type::CompoundCurveZ;
352 case wkbCurvePolygonZ:
return QgsWkbTypes::Type::CurvePolygonZ;
353 case wkbMultiCurveZ:
return QgsWkbTypes::Type::MultiCurveZ;
354 case wkbMultiSurfaceZ:
return QgsWkbTypes::Type::MultiSurfaceZ;
355 case wkbCurveZ:
return QgsWkbTypes::Type::Unknown;
356 case wkbSurfaceZ:
return QgsWkbTypes::Type::Unknown;
357 case wkbPolyhedralSurfaceZ:
return QgsWkbTypes::Type::Unknown;
358 case wkbTINZ:
return QgsWkbTypes::Type::Unknown;
359 case wkbTriangleZ:
return QgsWkbTypes::Type::TriangleZ;
361 case wkbPointM:
return QgsWkbTypes::Type::PointM;
362 case wkbLineStringM:
return QgsWkbTypes::Type::LineStringM;
363 case wkbPolygonM:
return QgsWkbTypes::Type::PolygonM;
364 case wkbMultiPointM:
return QgsWkbTypes::Type::MultiPointM;
365 case wkbMultiLineStringM:
return QgsWkbTypes::Type::MultiLineStringM;
366 case wkbMultiPolygonM:
return QgsWkbTypes::Type::MultiPolygonM;
367 case wkbGeometryCollectionM:
return QgsWkbTypes::Type::GeometryCollectionM;
368 case wkbCircularStringM:
return QgsWkbTypes::Type::CircularStringM;
369 case wkbCompoundCurveM:
return QgsWkbTypes::Type::CompoundCurveM;
370 case wkbCurvePolygonM:
return QgsWkbTypes::Type::CurvePolygonM;
371 case wkbMultiCurveM:
return QgsWkbTypes::Type::MultiCurveM;
372 case wkbMultiSurfaceM:
return QgsWkbTypes::Type::MultiSurfaceM;
373 case wkbCurveM:
return QgsWkbTypes::Type::Unknown;
374 case wkbSurfaceM:
return QgsWkbTypes::Type::Unknown;
375 case wkbPolyhedralSurfaceM:
return QgsWkbTypes::Type::Unknown;
376 case wkbTINM:
return QgsWkbTypes::Type::Unknown;
377 case wkbTriangleM:
return QgsWkbTypes::Type::TriangleM;
379 case wkbPointZM:
return QgsWkbTypes::Type::PointZM;
380 case wkbLineStringZM:
return QgsWkbTypes::Type::LineStringZM;
381 case wkbPolygonZM:
return QgsWkbTypes::Type::PolygonZM;
382 case wkbMultiPointZM:
return QgsWkbTypes::Type::MultiPointZM;
383 case wkbMultiLineStringZM:
return QgsWkbTypes::Type::MultiLineStringZM;
384 case wkbMultiPolygonZM:
return QgsWkbTypes::Type::MultiPolygonZM;
385 case wkbGeometryCollectionZM:
return QgsWkbTypes::Type::GeometryCollectionZM;
386 case wkbCircularStringZM:
return QgsWkbTypes::Type::CircularStringZM;
387 case wkbCompoundCurveZM:
return QgsWkbTypes::Type::CompoundCurveZM;
388 case wkbCurvePolygonZM:
return QgsWkbTypes::Type::CurvePolygonZM;
389 case wkbMultiCurveZM:
return QgsWkbTypes::Type::MultiCurveZM;
390 case wkbMultiSurfaceZM:
return QgsWkbTypes::Type::MultiSurfaceZM;
391 case wkbCurveZM:
return QgsWkbTypes::Type::Unknown;
392 case wkbSurfaceZM:
return QgsWkbTypes::Type::Unknown;
393 case wkbPolyhedralSurfaceZM:
return QgsWkbTypes::Type::Unknown;
394 case wkbTINZM:
return QgsWkbTypes::Type::Unknown;
395 case wkbTriangleZM:
return QgsWkbTypes::Type::TriangleZM;
397 case wkbPoint25D:
return QgsWkbTypes::Type::PointZ;
398 case wkbLineString25D:
return QgsWkbTypes::Type::LineStringZ;
399 case wkbPolygon25D:
return QgsWkbTypes::Type::PolygonZ;
400 case wkbMultiPoint25D:
return QgsWkbTypes::Type::MultiPointZ;
401 case wkbMultiLineString25D:
return QgsWkbTypes::Type::MultiLineStringZ;
402 case wkbMultiPolygon25D:
return QgsWkbTypes::Type::MultiPolygonZ;
403 case wkbGeometryCollection25D:
return QgsWkbTypes::Type::GeometryCollectionZ;
407 return QgsWkbTypes::Type::Unknown;
415 const auto ogrGeomType = OGR_G_GetGeometryType( geom );
444 if ( wkbFlatten( wkbType ) == wkbGeometryCollection )
447 if ( OGR_G_GetGeometryCount( geom ) >= 1 &&
448 wkbFlatten( OGR_G_GetGeometryType( OGR_G_GetGeometryRef( geom, 0 ) ) ) == wkbTIN )
450 auto newGeom = OGR_G_ForceToMultiPolygon( OGR_G_Clone( geom ) );
451 auto ret = ogrGeometryToQgsGeometry( newGeom );
452 OGR_G_DestroyGeometry( newGeom );
458 int memorySize = OGR_G_WkbSize( geom );
459 unsigned char *wkb =
new unsigned char[memorySize];
463 uint32_t origGeomType;
464 memcpy( &origGeomType, wkb + 1,
sizeof( uint32_t ) );
465 bool hasZ = ( origGeomType >= 1000 && origGeomType < 2000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
466 bool hasM = ( origGeomType >= 2000 && origGeomType < 3000 ) || ( origGeomType >= 3000 && origGeomType < 4000 );
469 if ( origGeomType % 1000 == 16 )
472 int nDims = 2 + hasZ + hasM;
475 unsigned char *wkbptr = wkb;
481 memcpy( wkbptr, &newMultiType,
sizeof( uint32_t ) );
486 memcpy( &numGeoms, wkb + 5,
sizeof( uint32_t ) );
490 for ( uint32_t i = 0; i < numGeoms; ++i )
496 memcpy( wkbptr, &newSingleType,
sizeof( uint32_t ) );
497 wkbptr +=
sizeof( uint32_t );
501 memcpy( &nRings, wkbptr,
sizeof( uint32_t ) );
502 wkbptr +=
sizeof( uint32_t );
504 for ( uint32_t j = 0; j < nRings; ++j )
507 memcpy( &nPoints, wkbptr,
sizeof( uint32_t ) );
508 wkbptr +=
sizeof( uint32_t ) +
sizeof(
double ) * nDims * nPoints;
512 else if ( origGeomType % 1000 == 15 )
517 memcpy( wkb + 1, &newType,
sizeof( uint32_t ) );
528 if (
string.isEmpty() )
531 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
534 QByteArray ba =
string.toUtf8();
535 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
536 static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
541 VSIUnlink( randomFileName.toUtf8().constData() );
545 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
549 VSIUnlink( randomFileName.toUtf8().constData() );
554 while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
556 QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding );
562 VSIUnlink( randomFileName.toUtf8().constData() );
570 if (
string.isEmpty() )
573 QString randomFileName = QStringLiteral(
"/vsimem/%1" ).arg( QUuid::createUuid().toString() );
576 QByteArray ba =
string.toUtf8();
577 VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(),
reinterpret_cast< GByte *
>( ba.data() ),
578 static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
583 VSIUnlink( randomFileName.toUtf8().constData() );
587 OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 );
591 VSIUnlink( randomFileName.toUtf8().constData() );
597 if ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat )
599 fields = readOgrFields( oFeat.get(), encoding );
603 VSIUnlink( randomFileName.toUtf8().constData() );
612 for (
qgssize i = 0; stringList[i]; ++i )
614 strings.append( QString::fromUtf8( stringList[i] ) );
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.
bool isValid() const
Returns the validity of this 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...
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
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
static endian_t endian()
Returns whether this machine uses big or little endian.
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
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.
std::unique_ptr< QgsMultiPoint > ogrGeometryToQgsMultiPoint(OGRGeometryH geom)
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) ...
int count() const
Returns number of items.
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 QgsWkbTypes::Type ogrGeometryTypeToQgsWkbType(OGRwkbGeometryType ogrGeomType)
Converts a OGRwkbGeometryType to QgsWkbTypes::Type.
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.