260 changes: 2 additions & 258 deletions src/providers/ogr/qgsogrprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,6 @@ static const QString TEXT_PROVIDER_DESCRIPTION =
+ GDALVersionInfo( "RELEASE_NAME" )
+ ")";

#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 QgsCPLErrorHandler
{
Expand Down Expand Up @@ -470,7 +461,7 @@ void QgsOgrProvider::setEncoding( const QString& e )
}

// This is reused by dataItem
int getOgrGeomType( OGRLayerH ogrLayer )
int QgsOgrProvider::getOgrGeomType( OGRLayerH ogrLayer )
{
OGRFeatureDefnH fdef = OGR_L_GetLayerDefn( ogrLayer );
int geomType = wkbUnknown;
Expand Down Expand Up @@ -2262,254 +2253,7 @@ void QgsOgrProvider::recalculateFeatureCount()
}
}

QGISEXTERN int dataCapabilities()
{
return QgsDataProvider::File | QgsDataProvider::Dir;
}

QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem* parent,
QString name, QString path, QString uri, LayerType layerType )
: QgsLayerItem( parent, name, path, uri, layerType, "ogr" )
{
mToolTip = uri;
mPopulated = true; // children are not expected
}

QgsOgrLayerItem::~QgsOgrLayerItem()
{
}

QgsLayerItem::Capability QgsOgrLayerItem::capabilities()
{
QgsDebugMsg( "mPath = " + mPath );
OGRRegisterAll();
OGRSFDriverH hDriver;
OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), true, &hDriver );

if ( !hDataSource )
return NoCapabilities;

QString driverName = OGR_Dr_GetName( hDriver );
OGR_DS_Destroy( hDataSource );

if ( driverName == "ESRI Shapefile" )
return SetCrs;

return NoCapabilities;
}

bool QgsOgrLayerItem::setCrs( QgsCoordinateReferenceSystem crs )
{
QgsDebugMsg( "mPath = " + mPath );
OGRRegisterAll();
OGRSFDriverH hDriver;
OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), true, &hDriver );

if ( !hDataSource )
return false;

QString driverName = OGR_Dr_GetName( hDriver );
OGR_DS_Destroy( hDataSource );

// we are able to assign CRS only to shapefiles :-(
if ( driverName == "ESRI Shapefile" )
{
QString layerName = mPath.left( mPath.indexOf( ".shp", Qt::CaseInsensitive ) );
QString wkt = crs.toWkt();

// save ordinary .prj file
OGRSpatialReferenceH hSRS = OSRNewSpatialReference( wkt.toLocal8Bit().data() );
OSRMorphToESRI( hSRS ); // this is the important stuff for shapefile .prj
char* pszOutWkt = NULL;
OSRExportToWkt( hSRS, &pszOutWkt );
QFile prjFile( layerName + ".prj" );
if ( prjFile.open( QIODevice::WriteOnly ) )
{
QTextStream prjStream( &prjFile );
prjStream << pszOutWkt << endl;
prjFile.close();
}
else
{
QgsDebugMsg( "Couldn't open file " + layerName + ".prj" );
return false;
}
OSRDestroySpatialReference( hSRS );
CPLFree( pszOutWkt );

// save qgis-specific .qpj file (maybe because of better wkt compatibility?)
QFile qpjFile( layerName + ".qpj" );
if ( qpjFile.open( QIODevice::WriteOnly ) )
{
QTextStream qpjStream( &qpjFile );
qpjStream << wkt.toLocal8Bit().data() << endl;
qpjFile.close();
}
else
{
QgsDebugMsg( "Couldn't open file " + layerName + ".qpj" );
return false;
}

return true;
}

// It it is impossible to assign a crs to an existing layer
// No OGR_L_SetSpatialRef : http://trac.osgeo.org/gdal/ticket/4032
return false;
}


static QgsOgrLayerItem* dataItemForLayer( QgsDataItem* parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )
{
OGRLayerH hLayer = OGR_DS_GetLayer( hDataSource, layerId );
OGRFeatureDefnH hDef = OGR_L_GetLayerDefn( hLayer );

QgsLayerItem::LayerType layerType = QgsLayerItem::Vector;
int ogrType = getOgrGeomType( hLayer );
switch ( ogrType )
{
case wkbUnknown:
case wkbGeometryCollection:
break;
case wkbNone:
layerType = QgsLayerItem::TableLayer;
break;
case wkbPoint:
case wkbMultiPoint:
case wkbPoint25D:
case wkbMultiPoint25D:
layerType = QgsLayerItem::Point;
break;
case wkbLineString:
case wkbMultiLineString:
case wkbLineString25D:
case wkbMultiLineString25D:
layerType = QgsLayerItem::Line;
break;
case wkbPolygon:
case wkbMultiPolygon:
case wkbPolygon25D:
case wkbMultiPolygon25D:
layerType = QgsLayerItem::Polygon;
break;
default:
break;
}

QgsDebugMsg( QString( "ogrType = %1 layertype = %2" ).arg( ogrType ).arg( layerType ) );

QString layerUri = path;

if ( name.isEmpty() )
{
// we are in a collection
name = FROM8( OGR_FD_GetName( hDef ) );
QgsDebugMsg( "OGR layer name : " + name );

layerUri += "|layerid=" + QString::number( layerId );

path += "/" + name;
}

QgsDebugMsg( "OGR layer uri : " + layerUri );

return new QgsOgrLayerItem( parentItem, name, path, layerUri, layerType );
}

QGISEXTERN QgsDataItem * dataItem( QString thePath, QgsDataItem* parentItem )
{
if ( thePath.isEmpty() )
return 0;

QFileInfo info( thePath );
if ( !info.isFile() )
return 0;

// We have to filter by extensions, otherwise e.g. all Shapefile files are displayed
// because OGR drive can open also .dbf, .shx.
QStringList myExtensions = fileExtensions();
if ( myExtensions.indexOf( info.suffix().toLower() ) < 0 )
{
bool matches = false;
foreach( QString wildcard, wildcards() )
{
QRegExp rx( wildcard, Qt::CaseInsensitive, QRegExp::Wildcard );
if ( rx.exactMatch( info.fileName() ) )
{
matches = true;
break;
}
}
if ( !matches )
return 0;
}

// .dbf should probably appear if .shp is not present
if ( info.suffix().toLower() == "dbf" )
{
QString pathShp = thePath.left( thePath.count() - 4 ) + ".shp";
if ( QFileInfo( pathShp ).exists() )
return 0;
}

OGRRegisterAll();
OGRSFDriverH hDriver;
OGRDataSourceH hDataSource = OGROpen( TO8F( thePath ), false, &hDriver );

if ( !hDataSource )
return 0;

QString driverName = OGR_Dr_GetName( hDriver );
QgsDebugMsg( "OGR Driver : " + driverName );

int numLayers = OGR_DS_GetLayerCount( hDataSource );

QgsDataItem* item = 0;

if ( numLayers == 1 )
{
QString name = info.completeBaseName();
item = dataItemForLayer( parentItem, name, thePath, hDataSource, 0 );
}
else if ( numLayers > 1 )
{
item = new QgsOgrDataCollectionItem( parentItem, info.fileName(), thePath );
}

OGR_DS_Destroy( hDataSource );
return item;
}

QgsOgrDataCollectionItem::QgsOgrDataCollectionItem( QgsDataItem* parent, QString name, QString path )
: QgsDataCollectionItem( parent, name, path )
{
}

QgsOgrDataCollectionItem::~QgsOgrDataCollectionItem()
{
}

QVector<QgsDataItem*> QgsOgrDataCollectionItem::createChildren()
{
QVector<QgsDataItem*> children;

OGRSFDriverH hDriver;
OGRDataSourceH hDataSource = OGROpen( TO8F( mPath ), false, &hDriver );
if ( !hDataSource )
return children;
int numLayers = OGR_DS_GetLayerCount( hDataSource );

for ( int i = 0; i < numLayers; i++ )
{
QgsOgrLayerItem* item = dataItemForLayer( this, QString(), mPath, hDataSource, i );
children.append( item );
}

OGR_DS_Destroy( hDataSource );

return children;
}
// ---------------------------------------------------------------------------

QGISEXTERN QgsVectorLayerImport::ImportError createEmptyLayer(
const QString& uri,
Expand Down
35 changes: 13 additions & 22 deletions src/providers/ogr/qgsogrprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ email : sherman at mrcc.com
* *
***************************************************************************/

#include "qgsdataitem.h"
#include "qgsrectangle.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorfilewriter.h"
Expand All @@ -26,6 +25,16 @@ class QgsVectorLayerImport;

#include <ogr_api.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 QgsOgrProvider
\brief Data provider for ESRI shapefiles
Expand Down Expand Up @@ -255,6 +264,9 @@ class QgsOgrProvider : public QgsVectorDataProvider
@note: added in version 1.4*/
virtual bool doesStrictFeatureTypeCheck() const { return false;}

/** return OGR geometry type */
static int getOgrGeomType( OGRLayerH ogrLayer );

protected:
/** loads fields from input file to member attributeFields */
void loadFields();
Expand Down Expand Up @@ -323,24 +335,3 @@ class QgsOgrProvider : public QgsVectorDataProvider
/**Calls OGR_L_SyncToDisk and recreates the spatial index if present*/
bool syncToDisc();
};

class QgsOgrLayerItem : public QgsLayerItem
{
Q_OBJECT
public:
QgsOgrLayerItem( QgsDataItem* parent, QString name, QString path, QString uri, LayerType layerType );
~QgsOgrLayerItem();

bool setCrs( QgsCoordinateReferenceSystem crs );
Capability capabilities();
};

class QgsOgrDataCollectionItem : public QgsDataCollectionItem
{
Q_OBJECT
public:
QgsOgrDataCollectionItem( QgsDataItem* parent, QString name, QString path );
~QgsOgrDataCollectionItem();

QVector<QgsDataItem*> createChildren();
};