mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
New class QgsOgrUtils w/helper functions for working with OGR features
Also includes handy function for converting a string to a QgsFeatureList or QgsFields by using OGR to parse the string. This allows eg conversion of GeoJSON to QgsFeatures.
This commit is contained in:
parent
3f80649b58
commit
3f62cd46e7
@ -154,6 +154,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgsobjectcustomproperties.cpp
|
||||
qgsofflineediting.cpp
|
||||
qgsogcutils.cpp
|
||||
qgsogrutils.cpp
|
||||
qgsowsconnection.cpp
|
||||
qgspaintenginehack.cpp
|
||||
qgspallabeling.cpp
|
||||
|
315
src/core/qgsogrutils.cpp
Normal file
315
src/core/qgsogrutils.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/***************************************************************************
|
||||
qgsogrutils.cpp
|
||||
---------------
|
||||
begin : February 2016
|
||||
copyright : (C) 2016 Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsogrutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include <QTextCodec>
|
||||
#include <QUuid>
|
||||
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
|
||||
#define TO8(x) (x).toUtf8().constData()
|
||||
#define TO8F(x) (x).toUtf8().constData()
|
||||
#define FROM8(x) QString::fromUtf8(x)
|
||||
#else
|
||||
#define TO8(x) (x).toLocal8Bit().constData()
|
||||
#define TO8F(x) QFile::encodeName( x ).constData()
|
||||
#define FROM8(x) QString::fromLocal8Bit(x)
|
||||
#endif
|
||||
|
||||
QgsFeature QgsOgrUtils::readOgrFeature( OGRFeatureH ogrFet, const QgsFields& fields, QTextCodec* encoding )
|
||||
{
|
||||
QgsFeature feature;
|
||||
if ( !ogrFet )
|
||||
{
|
||||
feature.setValid( false );
|
||||
return feature;
|
||||
}
|
||||
|
||||
feature.setFeatureId( OGR_F_GetFID( ogrFet ) );
|
||||
feature.setValid( true );
|
||||
|
||||
if ( !readOgrFeatureGeometry( ogrFet, feature ) )
|
||||
{
|
||||
feature.setValid( false );
|
||||
}
|
||||
|
||||
if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
|
||||
{
|
||||
feature.setValid( false );
|
||||
}
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
QgsFields QgsOgrUtils::readOgrFields( OGRFeatureH ogrFet, QTextCodec* encoding )
|
||||
{
|
||||
QgsFields fields;
|
||||
|
||||
if ( !ogrFet )
|
||||
return fields;
|
||||
|
||||
int fieldCount = OGR_F_GetFieldCount( ogrFet );
|
||||
for ( int i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
|
||||
if ( !fldDef )
|
||||
{
|
||||
fields.append( QgsField() );
|
||||
continue;
|
||||
}
|
||||
|
||||
QString name = encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) );
|
||||
QVariant::Type varType;
|
||||
switch ( OGR_Fld_GetType( fldDef ) )
|
||||
{
|
||||
case OFTInteger:
|
||||
varType = QVariant::Int;
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
|
||||
case OFTInteger64:
|
||||
varType = QVariant::LongLong;
|
||||
break;
|
||||
#endif
|
||||
case OFTReal:
|
||||
varType = QVariant::Double;
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1400
|
||||
case OFTDate:
|
||||
varType = QVariant::Date;
|
||||
break;
|
||||
case OFTTime:
|
||||
varType = QVariant::Time;
|
||||
break;
|
||||
case OFTDateTime:
|
||||
varType = QVariant::DateTime;
|
||||
break;
|
||||
case OFTString:
|
||||
#endif
|
||||
default:
|
||||
varType = QVariant::String; // other unsupported, leave it as a string
|
||||
}
|
||||
fields.append( QgsField( name, varType ) );
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
QVariant QgsOgrUtils::getOgrFeatureAttribute( OGRFeatureH ogrFet, const QgsFields& fields, int attIndex, QTextCodec* encoding , bool* ok )
|
||||
{
|
||||
if ( !ogrFet || attIndex < 0 || attIndex >= fields.count() )
|
||||
{
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
|
||||
|
||||
if ( ! fldDef )
|
||||
{
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
|
||||
QgsDebugMsg( "ogrFet->GetFieldDefnRef(attindex) returns NULL" );
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant value;
|
||||
|
||||
if ( ok )
|
||||
*ok = true;
|
||||
|
||||
if ( OGR_F_IsFieldSet( ogrFet, attIndex ) )
|
||||
{
|
||||
switch ( fields.at( attIndex ).type() )
|
||||
{
|
||||
case QVariant::String:
|
||||
value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
|
||||
break;
|
||||
case QVariant::Int:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
|
||||
case QVariant::LongLong:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
|
||||
break;
|
||||
#endif
|
||||
case QVariant::Double:
|
||||
value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
|
||||
break;
|
||||
case QVariant::Date:
|
||||
case QVariant::DateTime:
|
||||
case QVariant::Time:
|
||||
{
|
||||
int year, month, day, hour, minute, second, tzf;
|
||||
|
||||
OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
|
||||
if ( fields.at( attIndex ).type() == QVariant::Date )
|
||||
value = QDate( year, month, day );
|
||||
else if ( fields.at( attIndex ).type() == QVariant::Time )
|
||||
value = QTime( hour, minute, second );
|
||||
else
|
||||
value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT_X( false, "QgsOgrUtils::getOgrFeatureAttribute", "unsupported field type" );
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = QVariant( QString::null );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool QgsOgrUtils::readOgrFeatureAttributes( OGRFeatureH ogrFet, const QgsFields& fields, QgsFeature& feature, QTextCodec* encoding )
|
||||
{
|
||||
// read all attributes
|
||||
feature.initAttributes( fields.count() );
|
||||
feature.setFields( fields );
|
||||
|
||||
if ( !ogrFet )
|
||||
return false;
|
||||
|
||||
bool ok = false;
|
||||
for ( int idx = 0; idx < fields.count(); ++idx )
|
||||
{
|
||||
QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
|
||||
if ( ok )
|
||||
{
|
||||
feature.setAttribute( idx, value );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsOgrUtils::readOgrFeatureGeometry( OGRFeatureH ogrFet, QgsFeature& feature )
|
||||
{
|
||||
if ( !ogrFet )
|
||||
return false;
|
||||
|
||||
OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
|
||||
if ( !geom )
|
||||
feature.setGeometry( nullptr );
|
||||
else
|
||||
feature.setGeometry( ogrGeometryToQgsGeometry( geom ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsGeometry* QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom )
|
||||
{
|
||||
if ( !geom )
|
||||
return nullptr;
|
||||
|
||||
// get the wkb representation
|
||||
int memorySize = OGR_G_WkbSize( geom );
|
||||
unsigned char *wkb = new unsigned char[memorySize];
|
||||
OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( wkb, memorySize );
|
||||
return g;
|
||||
}
|
||||
|
||||
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding )
|
||||
{
|
||||
QgsFeatureList features;
|
||||
if ( string.isEmpty() )
|
||||
return features;
|
||||
|
||||
QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid() );
|
||||
|
||||
// create memory file system object from string buffer
|
||||
QByteArray ba = string.toUtf8();
|
||||
VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ),
|
||||
static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
|
||||
|
||||
OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr );
|
||||
if ( !hDS )
|
||||
{
|
||||
VSIUnlink( TO8( randomFileName ) );
|
||||
return features;
|
||||
}
|
||||
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
if ( !ogrLayer )
|
||||
{
|
||||
OGR_DS_Destroy( hDS );
|
||||
VSIUnlink( TO8( randomFileName ) );
|
||||
return features;
|
||||
}
|
||||
|
||||
OGRFeatureH oFeat;
|
||||
while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) )
|
||||
{
|
||||
QgsFeature feat = readOgrFeature( oFeat, fields, encoding );
|
||||
if ( feat.isValid() )
|
||||
features << feat;
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
}
|
||||
|
||||
OGR_DS_Destroy( hDS );
|
||||
VSIUnlink( "/vsimem/clipboard.dat" );
|
||||
|
||||
return features;
|
||||
}
|
||||
|
||||
QgsFields QgsOgrUtils::stringToFields( const QString& string, QTextCodec* encoding )
|
||||
{
|
||||
QgsFields fields;
|
||||
if ( string.isEmpty() )
|
||||
return fields;
|
||||
|
||||
QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid() );
|
||||
|
||||
// create memory file system object from buffer
|
||||
QByteArray ba = string.toUtf8();
|
||||
VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ),
|
||||
static_cast< vsi_l_offset >( ba.size() ), FALSE ) );
|
||||
|
||||
OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr );
|
||||
if ( !hDS )
|
||||
{
|
||||
VSIUnlink( TO8( randomFileName ) );
|
||||
return fields;
|
||||
}
|
||||
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
if ( !ogrLayer )
|
||||
{
|
||||
OGR_DS_Destroy( hDS );
|
||||
VSIUnlink( TO8( randomFileName ) );
|
||||
return fields;
|
||||
}
|
||||
|
||||
OGRFeatureH oFeat;
|
||||
//read in the first feature only
|
||||
if (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) )
|
||||
{
|
||||
fields = readOgrFields( oFeat, encoding );
|
||||
OGR_F_Destroy( oFeat );
|
||||
}
|
||||
|
||||
OGR_DS_Destroy( hDS );
|
||||
VSIUnlink( TO8( randomFileName ) );
|
||||
return fields;
|
||||
}
|
203
src/core/qgsogrutils.cpp.bom
Normal file
203
src/core/qgsogrutils.cpp.bom
Normal file
@ -0,0 +1,203 @@
|
||||
/***************************************************************************
|
||||
qgsogrutils.cpp
|
||||
---------------
|
||||
begin : February 2016
|
||||
copyright : (C) 2016 Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsogrutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include <QTextCodec>
|
||||
|
||||
QgsFeature QgsOgrUtils::readOgrFeature(OGRFeatureH ogrFet, const QgsFields& fields, QTextCodec* encoding)
|
||||
{
|
||||
QgsFeature feature;
|
||||
feature.setFeatureId( OGR_F_GetFID( ogrFet ) );
|
||||
feature.setValid( true );
|
||||
|
||||
if ( !readOgrFeatureGeometry( ogrFet, feature ) )
|
||||
{
|
||||
feature.setValid( false );
|
||||
}
|
||||
|
||||
if ( !readOgrFeatureAttributes( ogrFet, fields, feature, encoding ) )
|
||||
{
|
||||
feature.setValid( false );
|
||||
}
|
||||
|
||||
return feature;
|
||||
}
|
||||
|
||||
QgsFields QgsOgrUtils::readOgrFields( OGRFeatureH ogrFet, QTextCodec* encoding )
|
||||
{
|
||||
QgsFields fields;
|
||||
|
||||
if ( !ogrFet )
|
||||
return fields;
|
||||
|
||||
int fieldCount = OGR_F_GetFieldCount( fet );
|
||||
for ( int i = 0; i < fieldCount; ++i )
|
||||
{
|
||||
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, i );
|
||||
if ( !fldDef )
|
||||
{
|
||||
fields.append( QgsField() );
|
||||
continue;
|
||||
}
|
||||
|
||||
QString name = encoding->toUnicode( OGR_Fld_GetNameRef( fldDef ) );
|
||||
QVariant::Type varType;
|
||||
switch ( OGR_Fld_GetType( fldDef ) )
|
||||
{
|
||||
case OFTInteger:
|
||||
varType = QVariant::Int;
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
|
||||
case OFTInteger64:
|
||||
varType = QVariant::LongLong;
|
||||
break;
|
||||
#endif
|
||||
case OFTReal:
|
||||
varType = QVariant::Double;
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1400
|
||||
case OFTDate:
|
||||
varType = QVariant::Date;
|
||||
break;
|
||||
case OFTTime:
|
||||
varType = QVariant::Time;
|
||||
break;
|
||||
case OFTDateTime:
|
||||
varType = QVariant::DateTime;
|
||||
break;
|
||||
case OFTString:
|
||||
#endif
|
||||
default:
|
||||
varType = QVariant::String; // other unsupported, leave it as a string
|
||||
}
|
||||
fields.append( QgsField( name, varType ) );
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
QVariant QgsOgrUtils::getOgrFeatureAttribute(OGRFeatureH ogrFet, const QgsFields& fields, int attIndex, QTextCodec* encoding , bool* ok)
|
||||
{
|
||||
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attIndex );
|
||||
|
||||
if ( ! fldDef )
|
||||
{
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
|
||||
QgsDebugMsg( "ogrFet->GetFieldDefnRef(attindex) returns NULL" );
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant value;
|
||||
|
||||
if ( ok )
|
||||
*ok = true;
|
||||
|
||||
if ( OGR_F_IsFieldSet( ogrFet, attIndex ) )
|
||||
{
|
||||
switch ( fields.at( attIndex ).type() )
|
||||
{
|
||||
case QVariant::String:
|
||||
value = QVariant( encoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attIndex ) ) );
|
||||
break;
|
||||
case QVariant::Int:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attIndex ) );
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
|
||||
case QVariant::LongLong:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attIndex ) );
|
||||
break;
|
||||
#endif
|
||||
case QVariant::Double:
|
||||
value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attIndex ) );
|
||||
break;
|
||||
case QVariant::Date:
|
||||
case QVariant::DateTime:
|
||||
case QVariant::Time:
|
||||
{
|
||||
int year, month, day, hour, minute, second, tzf;
|
||||
|
||||
OGR_F_GetFieldAsDateTime( ogrFet, attIndex, &year, &month, &day, &hour, &minute, &second, &tzf );
|
||||
if ( fields.at( attIndex ).type() == QVariant::Date )
|
||||
value = QDate( year, month, day );
|
||||
else if ( fields.at( attIndex ).type() == QVariant::Time )
|
||||
value = QTime( hour, minute, second );
|
||||
else
|
||||
value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT_X( false, "QgsOgrUtils::getOgrFeatureAttribute", "unsupported field type" );
|
||||
if ( ok )
|
||||
*ok = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = QVariant( QString::null );
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool QgsOgrUtils::readOgrFeatureAttributes(OGRFeatureH ogrFet, const QgsFields& fields, QgsFeature& feature, QTextCodec* encoding )
|
||||
{
|
||||
// read all attributes
|
||||
feature.initAttributes( fields.count() );
|
||||
feature.setFields( fields );
|
||||
|
||||
bool ok = false;
|
||||
for ( int idx = 0; idx < fields.count(); ++idx )
|
||||
{
|
||||
QVariant value = getOgrFeatureAttribute( ogrFet, fields, idx, encoding, &ok );
|
||||
if ( ok )
|
||||
{
|
||||
feature.setAttribute( idx, value );
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsOgrUtils::readOgrFeatureGeometry( OGRFeatureH ogrFet, QgsFeature& feature )
|
||||
{
|
||||
if ( !ogrFet )
|
||||
return false;
|
||||
|
||||
OGRGeometryH geom = OGR_F_GetGeometryRef( ogrFet );
|
||||
if ( !geom )
|
||||
feature.setGeometry( nullptr );
|
||||
else
|
||||
feature.setGeometry( ogrGeometryToQgsGeometry( geom ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QgsGeometry* QgsOgrUtils::ogrGeometryToQgsGeometry( OGRGeometryH geom )
|
||||
{
|
||||
if ( !geom )
|
||||
return nullptr;
|
||||
|
||||
// get the wkb representation
|
||||
int memorySize = OGR_G_WkbSize( geom );
|
||||
unsigned char *wkb = new unsigned char[memorySize];
|
||||
OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
|
||||
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( wkb, memorySize );
|
||||
return g;
|
||||
}
|
108
src/core/qgsogrutils.h
Normal file
108
src/core/qgsogrutils.h
Normal file
@ -0,0 +1,108 @@
|
||||
/***************************************************************************
|
||||
qgsogrutils.h
|
||||
-------------
|
||||
begin : February 2016
|
||||
copyright : (C) 2016 Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSOGRUTILS_H
|
||||
#define QGSOGRUTILS_H
|
||||
|
||||
#include "qgsfeature.h"
|
||||
|
||||
#include <ogr_api.h>
|
||||
#include "cpl_conv.h"
|
||||
#include "cpl_string.h"
|
||||
|
||||
/** \ingroup core
|
||||
* \class QgsOgrUtils
|
||||
* \brief Utilities for working with OGR features and layers
|
||||
*
|
||||
* Contains helper utilities for assisting work with both OGR features and layers.
|
||||
* \note Added in version 2.16
|
||||
* \note not available in Python bindings
|
||||
*/
|
||||
class CORE_EXPORT QgsOgrUtils
|
||||
{
|
||||
public:
|
||||
|
||||
/** Reads an OGR feature and converts it to a QgsFeature.
|
||||
* @param ogrFet OGR feature handle
|
||||
* @param fields fields collection corresponding to feature
|
||||
* @param encoding text encoding
|
||||
* @return valid feature if read was successful
|
||||
*/
|
||||
static QgsFeature readOgrFeature( OGRFeatureH ogrFet, const QgsFields &fields, QTextCodec* encoding );
|
||||
|
||||
/** Reads an OGR feature and returns a corresponding fields collection.
|
||||
* @param ogrFet OGR feature handle
|
||||
* @param encoding text encoding
|
||||
* @returns fields collection if read was successful
|
||||
*/
|
||||
static QgsFields readOgrFields( OGRFeatureH ogrFet, QTextCodec* encoding );
|
||||
|
||||
/** Retrieves an attribute value from an OGR feature.
|
||||
* @param ogrFet OGR feature handle
|
||||
* @param fields fields collection corresponding to feature
|
||||
* @param attIndex index of attribute to retreive
|
||||
* @param encoding text encoding
|
||||
* @param ok optional storage for success of retrieval
|
||||
* @returns attribute converted to a QVariant object
|
||||
* @see readOgrFeatureAttributes()
|
||||
*/
|
||||
static QVariant getOgrFeatureAttribute( OGRFeatureH ogrFet, const QgsFields &fields, int attIndex, QTextCodec* encoding, bool* ok = 0 );
|
||||
|
||||
/** Reads all attributes from an OGR feature into a QgsFeature.
|
||||
* @param ogrFet OGR feature handle
|
||||
* @param fields fields collection corresponding to feature
|
||||
* @param feature QgsFeature to store attributes in
|
||||
* @param encoding text encoding
|
||||
* @returns true if attribute read was successful
|
||||
* @see getOgrFeatureAttribute()
|
||||
*/
|
||||
static bool readOgrFeatureAttributes( OGRFeatureH ogrFet, const QgsFields &fields, QgsFeature& feature, QTextCodec* encoding );
|
||||
|
||||
/** Reads the geometry from an OGR feature into a QgsFeature.
|
||||
* @param ogrFet OGR feature handle
|
||||
* @param feature QgsFeature to store geometry in
|
||||
* @returns true if geometry read was successful
|
||||
* @see readOgrFeatureAttributes()
|
||||
* @see ogrGeometryToQgsGeometry()
|
||||
*/
|
||||
static bool readOgrFeatureGeometry( OGRFeatureH ogrFet, QgsFeature& feature );
|
||||
|
||||
/** Converts an OGR geometry representation to a QgsGeometry object
|
||||
* @param geom OGR geometry handle
|
||||
* @returns new QgsGeometry object, if conversion was successful
|
||||
* @see readOgrFeatureGeometry()
|
||||
*/
|
||||
static QgsGeometry* ogrGeometryToQgsGeometry( OGRGeometryH geom );
|
||||
|
||||
/** Attempts to parse a string representing a collection of features using OGR. For example, this method can be
|
||||
* used to convert a GeoJSON encoded collection to a list of QgsFeatures.
|
||||
* @param string string to parse
|
||||
* @param fields fields collection to use for parsed features (@see stringToFields())
|
||||
* @param encoding text encoding
|
||||
* @returns list of parsed features, or an empty list if no features could be parsed
|
||||
* @see stringToFields()
|
||||
*/
|
||||
static QgsFeatureList stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding );
|
||||
|
||||
/** Attempts to retrieve the fields from a string representing a collection of features using OGR.
|
||||
* @param string string to parse
|
||||
* @param encoding text encoding
|
||||
* @returns retrieved fields collection, or an empty list if no fields could be determined from the string
|
||||
* @see stringToFeatureList()
|
||||
*/
|
||||
static QgsFields stringToFields( const QString& string, QTextCodec* encoding );
|
||||
};
|
||||
|
||||
#endif // QGSOGRUTILS_H
|
@ -95,5 +95,5 @@ QString QgsOgrExpressionCompiler::quotedIdentifier( const QString& identifier )
|
||||
QString QgsOgrExpressionCompiler::quotedValue( const QVariant& value, bool& ok )
|
||||
{
|
||||
ok = true;
|
||||
return QgsOgrUtils::quotedValue( value );
|
||||
return QgsOgrProviderUtils::quotedValue( value );
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "qgsogrgeometrysimplifier.h"
|
||||
#include "qgsogrexpressioncompiler.h"
|
||||
|
||||
#include "qgsogrutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgslogger.h"
|
||||
@ -56,7 +57,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
|
||||
|
||||
if ( !mSource->mSubsetString.isEmpty() )
|
||||
{
|
||||
ogrLayer = QgsOgrUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString );
|
||||
ogrLayer = QgsOgrProviderUtils::setSubsetString( ogrLayer, mConn->ds, mSource->mEncoding, mSource->mSubsetString );
|
||||
mSubsetStringSet = true;
|
||||
}
|
||||
|
||||
@ -69,7 +70,7 @@ QgsOgrFeatureIterator::QgsOgrFeatureIterator( QgsOgrFeatureSource* source, bool
|
||||
// filter if we choose to ignore them (fixes #11223)
|
||||
if (( mSource->mDriverName != "VRT" && mSource->mDriverName != "OGR_VRT" ) || mRequest.filterRect().isNull() )
|
||||
{
|
||||
QgsOgrUtils::setRelevantFields( ogrLayer, mSource->mFields.count(), mFetchGeometry, attrs );
|
||||
QgsOgrProviderUtils::setRelevantFields( ogrLayer, mSource->mFields.count(), mFetchGeometry, attrs );
|
||||
}
|
||||
|
||||
// spatial query to select features
|
||||
@ -265,57 +266,10 @@ bool QgsOgrFeatureIterator::close()
|
||||
|
||||
void QgsOgrFeatureIterator::getFeatureAttribute( OGRFeatureH ogrFet, QgsFeature & f, int attindex )
|
||||
{
|
||||
OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef( ogrFet, attindex );
|
||||
|
||||
if ( ! fldDef )
|
||||
{
|
||||
QgsDebugMsg( "ogrFet->GetFieldDefnRef(attindex) returns NULL" );
|
||||
bool ok = false;
|
||||
QVariant value = QgsOgrUtils::getOgrFeatureAttribute( ogrFet, mSource->mFields, attindex, mSource->mEncoding, &ok );
|
||||
if ( !ok )
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant value;
|
||||
|
||||
if ( OGR_F_IsFieldSet( ogrFet, attindex ) )
|
||||
{
|
||||
switch ( mSource->mFields.at( attindex ).type() )
|
||||
{
|
||||
case QVariant::String:
|
||||
value = QVariant( mSource->mEncoding->toUnicode( OGR_F_GetFieldAsString( ogrFet, attindex ) ) );
|
||||
break;
|
||||
case QVariant::Int:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attindex ) );
|
||||
break;
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 2000000
|
||||
case QVariant::LongLong:
|
||||
value = QVariant( OGR_F_GetFieldAsInteger64( ogrFet, attindex ) );
|
||||
break;
|
||||
#endif
|
||||
case QVariant::Double:
|
||||
value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attindex ) );
|
||||
break;
|
||||
case QVariant::Date:
|
||||
case QVariant::DateTime:
|
||||
case QVariant::Time:
|
||||
{
|
||||
int year, month, day, hour, minute, second, tzf;
|
||||
|
||||
OGR_F_GetFieldAsDateTime( ogrFet, attindex, &year, &month, &day, &hour, &minute, &second, &tzf );
|
||||
if ( mSource->mFields.at( attindex ).type() == QVariant::Date )
|
||||
value = QDate( year, month, day );
|
||||
else if ( mSource->mFields.at( attindex ).type() == QVariant::Time )
|
||||
value = QTime( hour, minute, second );
|
||||
else
|
||||
value = QDateTime( QDate( year, month, day ), QTime( hour, minute, second ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert( 0 && "unsupported field type" );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = QVariant( QString::null );
|
||||
}
|
||||
|
||||
f.setAttribute( attindex, value );
|
||||
}
|
||||
@ -338,22 +292,7 @@ bool QgsOgrFeatureIterator::readFeature( OGRFeatureH fet, QgsFeature& feature )
|
||||
if ( mGeometrySimplifier )
|
||||
mGeometrySimplifier->simplifyGeometry( geom );
|
||||
|
||||
// get the wkb representation
|
||||
int memorySize = OGR_G_WkbSize( geom );
|
||||
unsigned char *wkb = new unsigned char[memorySize];
|
||||
OGR_G_ExportToWkb( geom, ( OGRwkbByteOrder ) QgsApplication::endian(), wkb );
|
||||
|
||||
QgsGeometry* geometry = feature.geometry();
|
||||
if ( !geometry )
|
||||
{
|
||||
QgsGeometry *g = new QgsGeometry();
|
||||
g->fromWkb( wkb, memorySize );
|
||||
feature.setGeometry( g );
|
||||
}
|
||||
else
|
||||
{
|
||||
geometry->fromWkb( wkb, memorySize );
|
||||
}
|
||||
feature.setGeometry( QgsOgrUtils::ogrGeometryToQgsGeometry( geom ) );
|
||||
}
|
||||
else
|
||||
feature.setGeometry( nullptr );
|
||||
|
@ -784,11 +784,11 @@ QString QgsOgrProvider::storageType() const
|
||||
|
||||
void QgsOgrProvider::setRelevantFields( OGRLayerH ogrLayer, bool fetchGeometry, const QgsAttributeList &fetchAttributes )
|
||||
{
|
||||
QgsOgrUtils::setRelevantFields( ogrLayer, mAttributeFields.count(), fetchGeometry, fetchAttributes );
|
||||
QgsOgrProviderUtils::setRelevantFields( ogrLayer, mAttributeFields.count(), fetchGeometry, fetchAttributes );
|
||||
}
|
||||
|
||||
|
||||
void QgsOgrUtils::setRelevantFields( OGRLayerH ogrLayer, int fieldCount, bool fetchGeometry, const QgsAttributeList &fetchAttributes )
|
||||
void QgsOgrProviderUtils::setRelevantFields( OGRLayerH ogrLayer, int fieldCount, bool fetchGeometry, const QgsAttributeList &fetchAttributes )
|
||||
{
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
|
||||
if ( OGR_L_TestCapability( ogrLayer, OLCIgnoreFields ) )
|
||||
@ -2535,7 +2535,7 @@ QVariant QgsOgrProvider::maximumValue( int index )
|
||||
|
||||
QByteArray QgsOgrProvider::quotedIdentifier( QByteArray field ) const
|
||||
{
|
||||
return QgsOgrUtils::quotedIdentifier( field, ogrDriverName );
|
||||
return QgsOgrProviderUtils::quotedIdentifier( field, ogrDriverName );
|
||||
}
|
||||
|
||||
void QgsOgrProvider::forceReload()
|
||||
@ -2543,7 +2543,7 @@ void QgsOgrProvider::forceReload()
|
||||
QgsOgrConnPool::instance()->invalidateConnections( filePath() );
|
||||
}
|
||||
|
||||
QByteArray QgsOgrUtils::quotedIdentifier( QByteArray field, const QString& ogrDriverName )
|
||||
QByteArray QgsOgrProviderUtils::quotedIdentifier( QByteArray field, const QString& ogrDriverName )
|
||||
{
|
||||
if ( ogrDriverName == "MySQL" )
|
||||
{
|
||||
@ -2560,7 +2560,7 @@ QByteArray QgsOgrUtils::quotedIdentifier( QByteArray field, const QString& ogrDr
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsOgrUtils::quotedValue( const QVariant& value )
|
||||
QString QgsOgrProviderUtils::quotedValue( const QVariant& value )
|
||||
{
|
||||
if ( value.isNull() )
|
||||
return "NULL";
|
||||
@ -2698,10 +2698,10 @@ OGRwkbGeometryType QgsOgrProvider::ogrWkbSingleFlatten( OGRwkbGeometryType type
|
||||
|
||||
OGRLayerH QgsOgrProvider::setSubsetString( OGRLayerH layer, OGRDataSourceH ds )
|
||||
{
|
||||
return QgsOgrUtils::setSubsetString( layer, ds, mEncoding, mSubsetString );
|
||||
return QgsOgrProviderUtils::setSubsetString( layer, ds, mEncoding, mSubsetString );
|
||||
}
|
||||
|
||||
OGRLayerH QgsOgrUtils::setSubsetString( OGRLayerH layer, OGRDataSourceH ds, QTextCodec* encoding, const QString& subsetString )
|
||||
OGRLayerH QgsOgrProviderUtils::setSubsetString( OGRLayerH layer, OGRDataSourceH ds, QTextCodec* encoding, const QString& subsetString )
|
||||
{
|
||||
QByteArray layerName = OGR_FD_GetName( OGR_L_GetLayerDefn( layer ) );
|
||||
OGRSFDriverH ogrDriver = OGR_DS_GetDriver( ds );
|
||||
|
@ -359,7 +359,7 @@ class QgsOgrProvider : public QgsVectorDataProvider
|
||||
};
|
||||
|
||||
|
||||
class QgsOgrUtils
|
||||
class QgsOgrProviderUtils
|
||||
{
|
||||
public:
|
||||
static void setRelevantFields( OGRLayerH ogrLayer, int fieldCount, bool fetchGeometry, const QgsAttributeList &fetchAttributes );
|
||||
|
@ -151,6 +151,7 @@ ADD_QGIS_TEST(maptopixeltest testqgsmaptopixel.cpp)
|
||||
ADD_QGIS_TEST(markerlinessymboltest testqgsmarkerlinesymbol.cpp)
|
||||
ADD_QGIS_TEST(networkcontentfetcher testqgsnetworkcontentfetcher.cpp )
|
||||
ADD_QGIS_TEST(ogcutilstest testqgsogcutils.cpp)
|
||||
ADD_QGIS_TEST(ogrutilstest testqgsogrutils.cpp)
|
||||
ADD_QGIS_TEST(painteffectregistrytest testqgspainteffectregistry.cpp)
|
||||
ADD_QGIS_TEST(painteffecttest testqgspainteffect.cpp)
|
||||
ADD_QGIS_TEST(pallabelingtest testqgspallabeling.cpp)
|
||||
|
389
tests/src/core/testqgsogrutils.cpp
Normal file
389
tests/src/core/testqgsogrutils.cpp
Normal file
@ -0,0 +1,389 @@
|
||||
/***************************************************************************
|
||||
testqgsogrutils.cpp
|
||||
-------------------
|
||||
Date : February 2016
|
||||
Copyright : (C) 2016 Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include <QtTest/QtTest>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QSettings>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <ogr_api.h>
|
||||
#include "cpl_conv.h"
|
||||
#include "cpl_string.h"
|
||||
|
||||
#include "qgsgeometry.h"
|
||||
#include "qgsogrutils.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgspointv2.h"
|
||||
|
||||
#if defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1800
|
||||
#define TO8(x) (x).toUtf8().constData()
|
||||
#define TO8F(x) (x).toUtf8().constData()
|
||||
#define FROM8(x) QString::fromUtf8(x)
|
||||
#else
|
||||
#define TO8(x) (x).toLocal8Bit().constData()
|
||||
#define TO8F(x) QFile::encodeName( x ).constData()
|
||||
#define FROM8(x) QString::fromLocal8Bit(x)
|
||||
#endif
|
||||
|
||||
class TestQgsOgrUtils: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();// will be called before the first testfunction is executed.
|
||||
void cleanupTestCase();// will be called after the last testfunction was executed.
|
||||
void init();// will be called before each testfunction is executed.
|
||||
void cleanup();// will be called after every testfunction.
|
||||
void ogrGeometryToQgsGeometry();
|
||||
void readOgrFeatureGeometry();
|
||||
void getOgrFeatureAttribute();
|
||||
void readOgrFeatureAttributes();
|
||||
void readOgrFeature();
|
||||
void readOgrFields();
|
||||
void stringToFeatureList();
|
||||
void stringToFields();
|
||||
|
||||
private:
|
||||
|
||||
QString mTestDataDir;
|
||||
QString mTestFile;
|
||||
};
|
||||
|
||||
void TestQgsOgrUtils::initTestCase()
|
||||
{
|
||||
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
|
||||
mTestDataDir = myDataDir + '/';
|
||||
|
||||
mTestFile = mTestDataDir + "ogr_types.tab";
|
||||
|
||||
QgsApplication::init();
|
||||
QgsApplication::initQgis();
|
||||
QgsApplication::registerOgrDrivers();
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::cleanupTestCase()
|
||||
{
|
||||
QgsApplication::exitQgis();
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::cleanup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::ogrGeometryToQgsGeometry()
|
||||
{
|
||||
// test with null geometry
|
||||
QVERIFY( !QgsOgrUtils::ogrGeometryToQgsGeometry( nullptr ) );
|
||||
|
||||
// get a geometry from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
OGRGeometryH ogrGeom = OGR_F_GetGeometryRef( oFeat );
|
||||
QVERIFY( ogrGeom );
|
||||
|
||||
QScopedPointer< QgsGeometry > geom( QgsOgrUtils::ogrGeometryToQgsGeometry( ogrGeom ) );
|
||||
QVERIFY( geom.data() );
|
||||
QCOMPARE( geom->geometry()->wkbType(), QgsWKBTypes::LineString );
|
||||
QCOMPARE( geom->geometry()->nCoordinates(), 71 );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::readOgrFeatureGeometry()
|
||||
{
|
||||
QgsFeature f;
|
||||
|
||||
// null geometry
|
||||
QgsOgrUtils::readOgrFeatureGeometry( nullptr, f );
|
||||
QVERIFY( !f.constGeometry() );
|
||||
|
||||
//real geometry
|
||||
// get a geometry from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
|
||||
QgsOgrUtils::readOgrFeatureGeometry( oFeat, f );
|
||||
QVERIFY( f.constGeometry() );
|
||||
QCOMPARE( f.constGeometry()->geometry()->wkbType(), QgsWKBTypes::LineString );
|
||||
QCOMPARE( f.constGeometry()->geometry()->nCoordinates(), 71 );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::getOgrFeatureAttribute()
|
||||
{
|
||||
QgsFeature f;
|
||||
QgsFields fields;
|
||||
|
||||
// null feature
|
||||
bool ok = false;
|
||||
QVariant val = QgsOgrUtils::getOgrFeatureAttribute( nullptr, fields, 0, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( !ok );
|
||||
QVERIFY( !val.isValid() );
|
||||
|
||||
//real feature
|
||||
//get a feature from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
|
||||
fields.append( QgsField( "int_field", QVariant::Int ) );
|
||||
fields.append( QgsField( "dbl_field", QVariant::Double ) );
|
||||
fields.append( QgsField( "date_field", QVariant::Date ) );
|
||||
fields.append( QgsField( "time_field", QVariant::Time ) );
|
||||
fields.append( QgsField( "datetime_field", QVariant::DateTime ) );
|
||||
fields.append( QgsField( "string_field", QVariant::String ) );
|
||||
|
||||
// attribute index out of range
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, -1, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( !ok );
|
||||
QVERIFY( !val.isValid() );
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 100, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( !ok );
|
||||
QVERIFY( !val.isValid() );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 0, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( 5 ) );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 1, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( 8.9 ) );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 2, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( QDate( 2005, 01, 05 ) ) );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 3, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( QTime( 8, 11, 01 ) ) );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 4, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( QDateTime( QDate( 2005, 3, 5 ), QTime( 6, 45, 0 ) ) ) );
|
||||
|
||||
val = QgsOgrUtils::getOgrFeatureAttribute( oFeat, fields, 5, QTextCodec::codecForName( "System" ), &ok );
|
||||
QVERIFY( ok );
|
||||
QVERIFY( val.isValid() );
|
||||
QCOMPARE( val, QVariant( "a string" ) );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::readOgrFeatureAttributes()
|
||||
{
|
||||
QgsFeature f;
|
||||
QgsFields fields;
|
||||
|
||||
// null feature
|
||||
QVERIFY( !QgsOgrUtils::readOgrFeatureAttributes( nullptr, fields, f, QTextCodec::codecForName( "System" ) ) );
|
||||
|
||||
//real feature
|
||||
//get a feature from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
|
||||
fields.append( QgsField( "int_field", QVariant::Int ) );
|
||||
fields.append( QgsField( "dbl_field", QVariant::Double ) );
|
||||
fields.append( QgsField( "date_field", QVariant::Date ) );
|
||||
fields.append( QgsField( "time_field", QVariant::Time ) );
|
||||
fields.append( QgsField( "datetime_field", QVariant::DateTime ) );
|
||||
fields.append( QgsField( "string_field", QVariant::String ) );
|
||||
|
||||
QVERIFY( QgsOgrUtils::readOgrFeatureAttributes( oFeat, fields, f, QTextCodec::codecForName( "System" ) ) );
|
||||
QCOMPARE( f.attribute( "int_field" ), QVariant( 5 ) );
|
||||
QCOMPARE( f.attribute( "dbl_field" ), QVariant( 8.9 ) );
|
||||
QCOMPARE( f.attribute( "date_field" ), QVariant( QDate( 2005, 01, 05 ) ) );
|
||||
QCOMPARE( f.attribute( "time_field" ), QVariant( QTime( 8, 11, 01 ) ) );
|
||||
QCOMPARE( f.attribute( "datetime_field" ), QVariant( QDateTime( QDate( 2005, 3, 5 ), QTime( 6, 45, 0 ) ) ) );
|
||||
QCOMPARE( f.attribute( "string_field" ), QVariant( "a string" ) );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::readOgrFeature()
|
||||
{
|
||||
QgsFields fields;
|
||||
|
||||
// null feature
|
||||
QgsFeature f = QgsOgrUtils::readOgrFeature( nullptr, fields, QTextCodec::codecForName( "System" ) );
|
||||
QVERIFY( !f.isValid() );
|
||||
|
||||
//real feature
|
||||
//get a feature from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
|
||||
fields.append( QgsField( "int_field", QVariant::Int ) );
|
||||
fields.append( QgsField( "dbl_field", QVariant::Double ) );
|
||||
fields.append( QgsField( "date_field", QVariant::Date ) );
|
||||
fields.append( QgsField( "time_field", QVariant::Time ) );
|
||||
fields.append( QgsField( "datetime_field", QVariant::DateTime ) );
|
||||
fields.append( QgsField( "string_field", QVariant::String ) );
|
||||
|
||||
f = QgsOgrUtils::readOgrFeature( oFeat, fields, QTextCodec::codecForName( "System" ) );
|
||||
QVERIFY( f.isValid() );
|
||||
QCOMPARE( f.id(), 1LL );
|
||||
QCOMPARE( f.attribute( "int_field" ), QVariant( 5 ) );
|
||||
QCOMPARE( f.attribute( "dbl_field" ), QVariant( 8.9 ) );
|
||||
QCOMPARE( f.attribute( "date_field" ), QVariant( QDate( 2005, 01, 05 ) ) );
|
||||
QCOMPARE( f.attribute( "time_field" ), QVariant( QTime( 8, 11, 01 ) ) );
|
||||
QCOMPARE( f.attribute( "datetime_field" ), QVariant( QDateTime( QDate( 2005, 3, 5 ), QTime( 6, 45, 0 ) ) ) );
|
||||
QCOMPARE( f.attribute( "string_field" ), QVariant( "a string" ) );
|
||||
QVERIFY( f.constGeometry() );
|
||||
QCOMPARE( f.constGeometry()->geometry()->wkbType(), QgsWKBTypes::LineString );
|
||||
QCOMPARE( f.constGeometry()->geometry()->nCoordinates(), 71 );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::readOgrFields()
|
||||
{
|
||||
// null feature
|
||||
QgsFields f = QgsOgrUtils::readOgrFields( nullptr, QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( f.count(), 0 );
|
||||
|
||||
//real feature
|
||||
//get a feature from line file, test
|
||||
OGRDataSourceH hDS = OGROpen( TO8F( mTestFile ), false, nullptr );
|
||||
QVERIFY( hDS );
|
||||
OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 );
|
||||
QVERIFY( ogrLayer );
|
||||
OGRFeatureH oFeat;
|
||||
oFeat = OGR_L_GetNextFeature( ogrLayer );
|
||||
QVERIFY( oFeat );
|
||||
|
||||
f = QgsOgrUtils::readOgrFields( oFeat, QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( f.count(), 6 );
|
||||
QCOMPARE( f.at( 0 ).name(), QString( "int_field" ) );
|
||||
QCOMPARE( f.at( 0 ).type(), QVariant::Int );
|
||||
QCOMPARE( f.at( 1 ).name(), QString( "dbl_field" ) );
|
||||
QCOMPARE( f.at( 1 ).type(), QVariant::Double );
|
||||
QCOMPARE( f.at( 2 ).name(), QString( "date_field" ) );
|
||||
QCOMPARE( f.at( 2 ).type(), QVariant::Date );
|
||||
QCOMPARE( f.at( 3 ).name(), QString( "time_field" ) );
|
||||
QCOMPARE( f.at( 3 ).type(), QVariant::Time );
|
||||
QCOMPARE( f.at( 4 ).name(), QString( "datetime_field" ) );
|
||||
QCOMPARE( f.at( 4 ).type(), QVariant::DateTime );
|
||||
QCOMPARE( f.at( 5 ).name(), QString( "string_field" ) );
|
||||
QCOMPARE( f.at( 5 ).type(), QVariant::String );
|
||||
|
||||
OGR_F_Destroy( oFeat );
|
||||
OGR_DS_Destroy( hDS );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::stringToFeatureList()
|
||||
{
|
||||
QgsFields fields;
|
||||
fields.append( QgsField( "name", QVariant::String ) );
|
||||
|
||||
//empty string
|
||||
QgsFeatureList features = QgsOgrUtils::stringToFeatureList( "", fields, QTextCodec::codecForName( "System" ) );
|
||||
QVERIFY( features.isEmpty() );
|
||||
// bad string
|
||||
features = QgsOgrUtils::stringToFeatureList( "asdasdas", fields, QTextCodec::codecForName( "System" ) );
|
||||
QVERIFY( features.isEmpty() );
|
||||
|
||||
// geojson string with 1 feature
|
||||
features = QgsOgrUtils::stringToFeatureList( "{\n\"type\": \"Feature\",\"geometry\": {\"type\": \"Point\",\"coordinates\": [125, 10]},\"properties\": {\"name\": \"Dinagat Islands\"}}", fields, QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( features.length(), 1 );
|
||||
QVERIFY( features.at( 0 ).constGeometry() && !features.at( 0 ).constGeometry()->isEmpty() );
|
||||
QCOMPARE( features.at( 0 ).constGeometry()->geometry()->wkbType(), QgsWKBTypes::Point );
|
||||
const QgsPointV2* point = dynamic_cast< QgsPointV2* >( features.at( 0 ).constGeometry()->geometry() );
|
||||
QCOMPARE( point->x(), 125.0 );
|
||||
QCOMPARE( point->y(), 10.0 );
|
||||
QCOMPARE( features.at( 0 ).attribute( "name" ).toString(), QString( "Dinagat Islands" ) );
|
||||
|
||||
// geojson string with 2 features
|
||||
features = QgsOgrUtils::stringToFeatureList( "{ \"type\": \"FeatureCollection\",\"features\":[{\n\"type\": \"Feature\",\"geometry\": {\"type\": \"Point\",\"coordinates\": [125, 10]},\"properties\": {\"name\": \"Dinagat Islands\"}},"
|
||||
" {\n\"type\": \"Feature\",\"geometry\": {\"type\": \"Point\",\"coordinates\": [110, 20]},\"properties\": {\"name\": \"Henry Gale Island\"}}]}", fields, QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( features.length(), 2 );
|
||||
QVERIFY( features.at( 0 ).constGeometry() && !features.at( 0 ).constGeometry()->isEmpty() );
|
||||
QCOMPARE( features.at( 0 ).constGeometry()->geometry()->wkbType(), QgsWKBTypes::Point );
|
||||
point = dynamic_cast< QgsPointV2* >( features.at( 0 ).constGeometry()->geometry() );
|
||||
QCOMPARE( point->x(), 125.0 );
|
||||
QCOMPARE( point->y(), 10.0 );
|
||||
QCOMPARE( features.at( 0 ).attribute( "name" ).toString(), QString( "Dinagat Islands" ) );
|
||||
QVERIFY( features.at( 1 ).constGeometry() && !features.at( 1 ).constGeometry()->isEmpty() );
|
||||
QCOMPARE( features.at( 1 ).constGeometry()->geometry()->wkbType(), QgsWKBTypes::Point );
|
||||
point = dynamic_cast< QgsPointV2* >( features.at( 1 ).constGeometry()->geometry() );
|
||||
QCOMPARE( point->x(), 110.0 );
|
||||
QCOMPARE( point->y(), 20.0 );
|
||||
QCOMPARE( features.at( 1 ).attribute( "name" ).toString(), QString( "Henry Gale Island" ) );
|
||||
}
|
||||
|
||||
void TestQgsOgrUtils::stringToFields()
|
||||
{
|
||||
//empty string
|
||||
QgsFields fields = QgsOgrUtils::stringToFields( "", QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( fields.count(), 0 );
|
||||
// bad string
|
||||
fields = QgsOgrUtils::stringToFields( "asdasdas", QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( fields.count(), 0 );
|
||||
|
||||
// geojson string
|
||||
fields = QgsOgrUtils::stringToFields( "{\n\"type\": \"Feature\",\"geometry\": {\"type\": \"Point\",\"coordinates\": [125, 10]},\"properties\": {\"name\": \"Dinagat Islands\",\"height\":5.5}}", QTextCodec::codecForName( "System" ) );
|
||||
QCOMPARE( fields.count(), 2 );
|
||||
QCOMPARE( fields.at( 0 ).name(), QString( "name" ) );
|
||||
QCOMPARE( fields.at( 0 ).type(), QVariant::String );
|
||||
QCOMPARE( fields.at( 1 ).name(), QString( "height" ) );
|
||||
QCOMPARE( fields.at( 1 ).type(), QVariant::Double );
|
||||
}
|
||||
|
||||
|
||||
|
||||
QTEST_MAIN( TestQgsOgrUtils )
|
||||
#include "testqgsogrutils.moc"
|
BIN
tests/testdata/ogr_types.dat
vendored
Normal file
BIN
tests/testdata/ogr_types.dat
vendored
Normal file
Binary file not shown.
BIN
tests/testdata/ogr_types.id
vendored
Normal file
BIN
tests/testdata/ogr_types.id
vendored
Normal file
Binary file not shown.
BIN
tests/testdata/ogr_types.map
vendored
Normal file
BIN
tests/testdata/ogr_types.map
vendored
Normal file
Binary file not shown.
13
tests/testdata/ogr_types.tab
vendored
Normal file
13
tests/testdata/ogr_types.tab
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
!table
|
||||
!version 900
|
||||
!charset Neutral
|
||||
|
||||
Definition Table
|
||||
Type NATIVE Charset "Neutral"
|
||||
Fields 6
|
||||
int_field Integer (10) ;
|
||||
dbl_field Float ;
|
||||
date_field Date ;
|
||||
time_field Time ;
|
||||
datetime_field DateTime ;
|
||||
string_field Char (100) ;
|
Loading…
x
Reference in New Issue
Block a user