⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qgsogrprovider.cpp

📁 一个非常好的GIS开源新版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************           qgsogrprovider.cpp Data provider for OGR supported formats                    Formerly known as qgsshapefileprovider.cpp  begin                : Oct 29, 2003copyright            : (C) 2003 by Gary E.Shermanemail                : sherman at mrcc.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.                                   * *                                                                         * ***************************************************************************//* $Id: qgsogrprovider.cpp 8355 2008-04-17 02:08:49Z jef $ */#include "qgsogrprovider.h"#include "qgslogger.h"#include <iostream>#include <cassert>#define CPL_SUPRESS_CPLUSPLUS#include <gdal.h>         // to collect version information#include <ogr_api.h>#include <ogr_srs_api.h>#include <cpl_error.h>#include <QtDebug>#include <QFile>#include <QDir>#include <QFileInfo>#include <QMap>#include <QString>//TODO Following ifndef can be removed once WIN32 GEOS support//    is fixed#ifndef NOWIN32GEOSXXX//XXX GEOS support on windows is broken until we can get VC++ to//    tolerate geos.h without throwing a bunch of type errors. It//    appears that the windows version of GEOS may be compiled with //    MINGW rather than VC++.#endif #include "qgsapplication.h"#include "qgsdataprovider.h"#include "qgsfeature.h"#include "qgsfield.h"#include "qgsgeometry.h"#include "qgslogger.h"#include "qgsspatialrefsys.h"static const QString TEXT_PROVIDER_KEY = "ogr";static const QString TEXT_PROVIDER_DESCRIPTION =                QString("OGR data provider")             + " (compiled against GDAL/OGR library version "             + GDAL_RELEASE_NAME             + ", running against GDAL/OGR library version "             + GDALVersionInfo("RELEASE_NAME")             + ")";QgsOgrProvider::QgsOgrProvider(QString const & uri) : QgsVectorDataProvider(uri),   ogrDataSource(0),   extent_(0),   ogrLayer(0),   ogrDriver(0){  OGRRegisterAll();  // set the selection rectangle pointer to 0  mSelectionRectangle = 0;  // make connection to the data source  QgsDebugMsg("Data source uri is " + uri);  // try to open for update, but disable error messages to avoid a  // message if the file is read only, because we cope with that  // ourselves.  CPLPushErrorHandler(CPLQuietErrorHandler);  ogrDataSource = OGROpen(QFile::encodeName(uri).constData(), TRUE, &ogrDriver);  CPLPopErrorHandler();  if(ogrDataSource == NULL)  {    // try to open read-only    ogrDataSource = OGROpen(QFile::encodeName(uri).constData(), FALSE, &ogrDriver);    //TODO Need to set a flag or something to indicate that the layer    //TODO is in read-only mode, otherwise edit ops will fail    //TODO: capabilities() should now reflect this; need to test.  }  if (ogrDataSource != NULL) {    QgsDebugMsg("Data source is valid");    QgsDebugMsg("OGR Driver was " + QString(OGR_Dr_GetName(ogrDriver)));    valid = true;    ogrDriverName = OGR_Dr_GetName(ogrDriver);    ogrLayer = OGR_DS_GetLayer(ogrDataSource,0);    // get the extent_ (envelope) of the layer    QgsDebugMsg("Starting get extent\n");    // TODO: This can be expensive, do we really need it!    extent_ = calloc(sizeof(OGREnvelope),1);    OGR_L_GetExtent(ogrLayer,(OGREnvelope *) extent_, TRUE );    QgsDebugMsg("Finished get extent\n");    // getting the total number of features in the layer    // TODO: This can be expensive, do we really need it!    numberFeatures = OGR_L_GetFeatureCount(ogrLayer, TRUE);    // check the validity of the layer    QgsDebugMsg("checking validity\n");    loadFields();    QgsDebugMsg("Done checking validity\n");  } else {    QgsLogger::critical("Data source is invalid");    const char *er = CPLGetLastErrorMsg();    QgsLogger::critical(er);    valid = false;  }  // create the geos objects  geometryFactory = new GEOS_GEOM::GeometryFactory();  assert(geometryFactory!=0);  mSupportedNativeTypes.insert("Integer");  mSupportedNativeTypes.insert("Real");  mSupportedNativeTypes.insert("String");}QgsOgrProvider::~QgsOgrProvider(){  OGR_DS_Destroy(ogrDataSource);  ogrDataSource = 0;  free(extent_);  extent_ = 0;  delete geometryFactory;  if( mSelectionRectangle )  {    OGR_G_DestroyGeometry( mSelectionRectangle );    mSelectionRectangle = 0;  }}void QgsOgrProvider::setEncoding(const QString& e){  QgsVectorDataProvider::setEncoding(e);  loadFields();}void QgsOgrProvider::loadFields(){  //the attribute fields need to be read again when the encoding changes  mAttributeFields.clear();  OGRFeatureDefnH fdef = OGR_L_GetLayerDefn(ogrLayer);  if(fdef)  {    geomType = OGR_FD_GetGeomType(fdef);    //Some ogr drivers (e.g. GML) are not able to determine the geometry type of a layer like this.    //In such cases, we examine the first feature     if(geomType == wkbUnknown)     {      OGR_L_ResetReading(ogrLayer);      OGRFeatureH firstFeature = OGR_L_GetNextFeature(ogrLayer);      if(firstFeature)      {        OGRGeometryH firstGeometry = OGR_F_GetGeometryRef(firstFeature);        if(firstGeometry)        {          geomType = OGR_G_GetGeometryType(firstGeometry);        }        OGR_F_Destroy( firstFeature );      }      OGR_L_ResetReading(ogrLayer);    }    for(int i=0;i<OGR_FD_GetFieldCount(fdef);++i)    {      OGRFieldDefnH fldDef = OGR_FD_GetFieldDefn(fdef,i);      OGRFieldType ogrType = OGR_Fld_GetType(fldDef);      QVariant::Type varType;      switch (ogrType)      {      case OFTInteger: varType = QVariant::Int; break;      case OFTReal: varType = QVariant::Double; break;        // unsupported in OGR 1.3        //case OFTDateTime: varType = QVariant::DateTime; break;#if GDAL_VERSION_NUM >= 1400      case OFTString: varType = QVariant::String; break;#endif      default: varType = QVariant::String; // other unsupported, leave it as a string      }      mAttributeFields.insert(        i, QgsField(        mEncoding->toUnicode(OGR_Fld_GetNameRef(fldDef)), varType,        mEncoding->toUnicode(OGR_GetFieldTypeName(ogrType)),        OGR_Fld_GetWidth(fldDef),        OGR_Fld_GetPrecision(fldDef) ));    }  }}QString QgsOgrProvider::storageType() const{  // Delegate to the driver loaded in by OGR  return ogrDriverName;}bool QgsOgrProvider::getFeatureAtId(int featureId,                                    QgsFeature& feature,                                    bool fetchGeometry,                                    QgsAttributeList fetchAttributes){  OGRFeatureH fet = OGR_L_GetFeature(ogrLayer,featureId);  if (fet == NULL)    return false;  feature.setFeatureId(OGR_F_GetFID(fet));  /* fetch geometry */  if (fetchGeometry)  {    OGRGeometryH geom = OGR_F_GetGeometryRef(fet);    // get the wkb representation    unsigned char *wkb = new unsigned char[OGR_G_WkbSize(geom)];    OGR_G_ExportToWkb(geom,(OGRwkbByteOrder) QgsApplication::endian(), wkb);    feature.setGeometryAndOwnership(wkb, OGR_G_WkbSize(geom));  }  /* fetch attributes */  for(QgsAttributeList::iterator it = fetchAttributes.begin(); it != fetchAttributes.end(); ++it)  {    getFeatureAttribute(fet,feature,*it);  }  return true;}bool QgsOgrProvider::getNextFeature(QgsFeature& feature){  if (!valid)  {    QgsLogger::warning("Read attempt on an invalid shapefile data source");    return false;  }  OGRFeatureH fet;  QgsRect selectionRect;  while ((fet = OGR_L_GetNextFeature(ogrLayer)) != NULL)  {    // skip features without geometry    if (OGR_F_GetGeometryRef(fet) == NULL && !mFetchFeaturesWithoutGeom)    {      OGR_F_Destroy( fet );      continue;    }    OGRFeatureDefnH featureDefinition = OGR_F_GetDefnRef(fet);    QString featureTypeName = featureDefinition ? QString(OGR_FD_GetName(featureDefinition)) : QString("");    feature.setFeatureId(OGR_F_GetFID(fet));    feature.setTypeName(featureTypeName);    /* fetch geometry */    if (mFetchGeom)    {      OGRGeometryH geom = OGR_F_GetGeometryRef(fet);      // get the wkb representation      unsigned char *wkb = new unsigned char[OGR_G_WkbSize(geom)];      OGR_G_ExportToWkb(geom,(OGRwkbByteOrder) QgsApplication::endian(), wkb);      feature.setGeometryAndOwnership(wkb, OGR_G_WkbSize(geom));      if (mUseIntersect)      {        //precise test for intersection with search rectangle        //first make QgsRect from OGRPolygon        OGREnvelope env;        memset( &env, 0, sizeof(env) );        if(mSelectionRectangle)          OGR_G_GetEnvelope(mSelectionRectangle,&env);        if(env.MinX != 0 || env.MinY != 0 || env.MaxX != 0 || env.MaxY != 0 ) //if envelope is invalid, skip the precise intersection test        {          selectionRect.set(env.MinX, env.MinY, env.MaxX, env.MaxY);          if(!feature.geometry()->intersects(selectionRect))          {            OGR_F_Destroy( fet );            continue;          }        }      }    }    /* fetch attributes */    for(QgsAttributeList::iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it)    {      getFeatureAttribute(fet,feature,*it);    }    /* we have a feature, end this cycle */    break;  } /* while */  if (fet)  {    OGR_F_Destroy( fet );    return true;  }  else  {    QgsDebugMsg("Feature is null");      // probably should reset reading here    OGR_L_ResetReading(ogrLayer);    return false;  }}void QgsOgrProvider::select(QgsAttributeList fetchAttributes, QgsRect rect, bool fetchGeometry, \			    bool useIntersect){  mUseIntersect = useIntersect;  mAttributesToFetch = fetchAttributes;  mFetchGeom = fetchGeometry;  // spatial query to select features  if(rect.isEmpty())  {    OGR_L_SetSpatialFilter(ogrLayer,0);  }  else  {    OGRGeometryH filter = 0;    QString wktExtent = QString("POLYGON ((%1))").arg(rect.asPolygon());    const char *wktText = (const char *)wktExtent;    if(useIntersect)    {      // store the selection rectangle for use in filtering features during      // an identify and display attributes      if( mSelectionRectangle )        OGR_G_DestroyGeometry( mSelectionRectangle );      OGR_G_CreateFromWkt( (char **)&wktText,        NULL, &mSelectionRectangle);    }    wktText = (const char *) wktExtent;    OGR_G_CreateFromWkt( (char **)&wktText, NULL, &filter );    QgsDebugMsg("Setting spatial filter using " + wktExtent);    OGR_L_SetSpatialFilter( ogrLayer, filter );    OGR_G_DestroyGeometry( filter );  }  }unsigned char * QgsOgrProvider::getGeometryPointer(OGRFeatureH fet){  OGRGeometryH geom = OGR_F_GetGeometryRef(fet);  unsigned char *gPtr=0;  if( geom == NULL )    return NULL;  // get the wkb representation  gPtr = new unsigned char[OGR_G_WkbSize(geom)];  OGR_G_ExportToWkb(geom,(OGRwkbByteOrder) QgsApplication::endian(), gPtr);  return gPtr;}QgsRect QgsOgrProvider::extent(){  OGREnvelope *ext = (OGREnvelope *) extent_;  mExtentRect.set(ext->MinX, ext->MinY, ext->MaxX, ext->MaxY);  return mExtentRect;}size_t QgsOgrProvider::layerCount() const{  return OGR_DS_GetLayerCount(ogrDataSource);} // QgsOgrProvider::layerCount()/**  * Return the feature type */QGis::WKBTYPE QgsOgrProvider::geometryType() const{  return (QGis::WKBTYPE) geomType;}/**  * Return the feature type */long QgsOgrProvider::featureCount() const{  return numberFeatures;}/** * Return the number of fields */uint QgsOgrProvider::fieldCount() const{  return mAttributeFields.size();}void QgsOgrProvider::getFeatureAttribute(OGRFeatureH ogrFet, QgsFeature & f, int attindex){  OGRFieldDefnH fldDef = OGR_F_GetFieldDefnRef(ogrFet, attindex);  if ( ! fldDef )  {    QgsDebugMsg("ogrFet->GetFieldDefnRef(attindex) returns NULL");    return;  }  QVariant value;  if( OGR_F_IsFieldSet(ogrFet, attindex) )  {    switch (mAttributeFields[attindex].type())    {    case QVariant::String: value = QVariant( mEncoding->toUnicode( OGR_F_GetFieldAsString(ogrFet,attindex) ) ); break;    case QVariant::Int: value = QVariant( OGR_F_GetFieldAsInteger( ogrFet, attindex ) ); break;    case QVariant::Double: value = QVariant( OGR_F_GetFieldAsDouble( ogrFet, attindex ) ); break;      //case QVariant::DateTime: value = QVariant(QDateTime::fromString(str)); break;    default: assert(NULL && "unsupported field type");    }  }  else  {    value = QVariant( QString::null );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -