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

📄 ogrpgtablelayer.cpp

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        // Grow the command buffer?        if( strlen(pszStrValue) + strlen(pszCommand+nOffset) + nOffset             > nCommandBufSize-50 )        {            nCommandBufSize = strlen(pszCommand) + strlen(pszStrValue) + 10000;            pszCommand = (char *) CPLRealloc(pszCommand, nCommandBufSize );        }        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger                 && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal )        {            int         iChar;            /* We need to quote and escape string fields. */            strcat( pszCommand+nOffset, "'" );            nOffset += strlen(pszCommand+nOffset);                        for( iChar = 0; pszStrValue[iChar] != '\0'; iChar++ )            {                if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTIntegerList                    && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTRealList                    && poFeatureDefn->GetFieldDefn(i)->GetWidth() > 0                     && iChar == poFeatureDefn->GetFieldDefn(i)->GetWidth() )                {                    CPLDebug( "PG",                               "Truncated %s field value, it was too long.",                              poFeatureDefn->GetFieldDefn(i)->GetNameRef() );                    break;                }                if( pszStrValue[iChar] == '\\'                     || pszStrValue[iChar] == '\'' )                {                    pszCommand[nOffset++] = '\\';                    pszCommand[nOffset++] = pszStrValue[iChar];                }                else                    pszCommand[nOffset++] = pszStrValue[iChar];            }            pszCommand[nOffset] = '\0';            strcat( pszCommand+nOffset, "'" );        }        else        {            strcat( pszCommand+nOffset, pszStrValue );        }        if( pszNeedToFree )            CPLFree( pszNeedToFree );    }    strcat( pszCommand+nOffset, ")" );/* -------------------------------------------------------------------- *//*      Execute the insert.                                             *//* -------------------------------------------------------------------- */    hResult = PQexec(hPGConn, pszCommand);    if( PQresultStatus(hResult) != PGRES_COMMAND_OK )    {        CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand );        CPLFree( pszCommand );        CPLError( CE_Failure, CPLE_AppDefined,                   "INSERT command for new feature failed.\n%s",                   PQerrorMessage(hPGConn) );        PQclear( hResult );                poDS->SoftRollback();        return OGRERR_FAILURE;    }    CPLFree( pszCommand );#ifdef notdef    /* Should we use this oid to get back the FID and assign back to the       feature?  I think we are supposed to. */    Oid nNewOID = PQoidValue( hResult );    printf( "nNewOID = %d\n", (int) nNewOID );#endif    PQclear( hResult );    return poDS->SoftCommit();}/************************************************************************//*                           TestCapability()                           *//************************************************************************/int OGRPGTableLayer::TestCapability( const char * pszCap ){    if( EQUAL(pszCap,OLCSequentialWrite)              || EQUAL(pszCap,OLCRandomWrite) )        return bUpdateAccess;    else if( EQUAL(pszCap,OLCCreateField) )        return bUpdateAccess;    else if( EQUAL(pszCap,OLCRandomRead) )        return bHasFid;    else         return OGRPGLayer::TestCapability( pszCap );}/************************************************************************//*                            CreateField()                             *//************************************************************************/OGRErr OGRPGTableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK ){    PGconn              *hPGConn = poDS->GetPGConn();    PGresult            *hResult;    char                szCommand[1024];    char                szFieldType[256];    OGRFieldDefn        oField( poFieldIn );/* -------------------------------------------------------------------- *//*      Do we want to "launder" the column names into Postgres          *//*      friendly format?                                                *//* -------------------------------------------------------------------- */    if( bLaunderColumnNames )    {        char    *pszSafeName = poDS->LaunderName( oField.GetNameRef() );        oField.SetName( pszSafeName );        CPLFree( pszSafeName );        if( EQUAL(oField.GetNameRef(),"oid") )        {            CPLError( CE_Warning, CPLE_AppDefined,                       "Renaming field 'oid' to 'oid_' to avoid conflict with internal oid field." );            oField.SetName( "oid_" );        }    }    /* -------------------------------------------------------------------- *//*      Work out the PostgreSQL type.                                   *//* -------------------------------------------------------------------- */    if( oField.GetType() == OFTInteger )    {        if( oField.GetWidth() > 0 && bPreservePrecision )            sprintf( szFieldType, "NUMERIC(%d,0)", oField.GetWidth() );        else            strcpy( szFieldType, "INTEGER" );    }    else if( oField.GetType() == OFTReal )    {        if( oField.GetWidth() > 0 && oField.GetPrecision() > 0             && bPreservePrecision )            sprintf( szFieldType, "NUMERIC(%d,%d)",                      oField.GetWidth(), oField.GetPrecision() );        else            strcpy( szFieldType, "FLOAT8" );    }    else if( oField.GetType() == OFTString )    {        if( oField.GetWidth() == 0 || !bPreservePrecision )            strcpy( szFieldType, "VARCHAR" );        else            sprintf( szFieldType, "CHAR(%d)", oField.GetWidth() );    }    else if( oField.GetType() == OFTIntegerList )    {        strcpy( szFieldType, "INTEGER[]" );    }    else if( oField.GetType() == OFTRealList )    {        strcpy( szFieldType, "FLOAT8[]" );    }    else if( bApproxOK )    {        CPLError( CE_Warning, CPLE_NotSupported,                  "Can't create field %s with type %s on PostgreSQL layers.  Creating as VARCHAR.",                  oField.GetNameRef(),                  OGRFieldDefn::GetFieldTypeName(oField.GetType()) );        strcpy( szFieldType, "VARCHAR" );    }    else    {        CPLError( CE_Failure, CPLE_NotSupported,                  "Can't create field %s with type %s on PostgreSQL layers.",                  oField.GetNameRef(),                  OGRFieldDefn::GetFieldTypeName(oField.GetType()) );        return OGRERR_FAILURE;    }/* -------------------------------------------------------------------- *//*      Create the new field.                                           *//* -------------------------------------------------------------------- */    poDS->FlushSoftTransaction();    hResult = PQexec(hPGConn, "BEGIN");    PQclear( hResult );    sprintf( szCommand, "ALTER TABLE \"%s\" ADD COLUMN \"%s\" %s",              poFeatureDefn->GetName(), oField.GetNameRef(), szFieldType );    hResult = PQexec(hPGConn, szCommand);    if( PQresultStatus(hResult) != PGRES_COMMAND_OK )    {        CPLError( CE_Failure, CPLE_AppDefined,                   "%s\n%s", szCommand, PQerrorMessage(hPGConn) );        PQclear( hResult );        hResult = PQexec( hPGConn, "ROLLBACK" );        PQclear( hResult );        return OGRERR_FAILURE;    }    PQclear( hResult );    hResult = PQexec(hPGConn, "COMMIT");    PQclear( hResult );    poFeatureDefn->AddFieldDefn( &oField );    return OGRERR_NONE;}/************************************************************************//*                             GetFeature()                             *//************************************************************************/OGRFeature *OGRPGTableLayer::GetFeature( long nFeatureId ){    if( pszFIDColumn == NULL )        return OGRLayer::GetFeature( nFeatureId );/* -------------------------------------------------------------------- *//*      Discard any existing resultset.                                 *//* -------------------------------------------------------------------- */    ResetReading();/* -------------------------------------------------------------------- *//*      Issue query for a single record.                                *//* -------------------------------------------------------------------- */    OGRFeature  *poFeature = NULL;    PGresult    *hResult;    PGconn      *hPGConn = poDS->GetPGConn();    char        *pszFieldList = BuildFields();    char        *pszCommand = (char *) CPLMalloc(strlen(pszFieldList)+2000);    poDS->FlushSoftTransaction();    poDS->SoftStartTransaction();    sprintf( pszCommand,              "DECLARE getfeaturecursor CURSOR for "             "SELECT %s FROM \"%s\" WHERE %s = %ld",              pszFieldList, poFeatureDefn->GetName(), pszFIDColumn,              nFeatureId );    CPLFree( pszFieldList );    hResult = PQexec(hPGConn, pszCommand );    CPLFree( pszCommand );    if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK )    {        PQclear( hResult );        hResult = PQexec(hPGConn, "FETCH ALL in getfeaturecursor" );        if( hResult && PQresultStatus(hResult) == PGRES_TUPLES_OK )        {            hCursorResult = hResult;            poFeature = RecordToFeature( 0 );            hCursorResult = NULL;        }    }/* -------------------------------------------------------------------- *//*      Cleanup                                                         *//* -------------------------------------------------------------------- */    PQclear( hResult );    hResult = PQexec(hPGConn, "CLOSE getfeaturecursor");    PQclear( hResult );    poDS->FlushSoftTransaction();    return poFeature;}/************************************************************************//*                          GetFeatureCount()                           *//*                                                                      *//*      If a spatial filter is in effect, we turn control over to       *//*      the generic counter.  Otherwise we return the total count.      *//*      Eventually we should consider implementing a more efficient     *//*      way of counting features matching a spatial query.              *//************************************************************************/int OGRPGTableLayer::GetFeatureCount( int bForce ){/* -------------------------------------------------------------------- *//*      Use a more brute force mechanism if we have a spatial query     *//*      in play.                                                        *//* -------------------------------------------------------------------- */    if( m_poFilterGeom != NULL && !bHasPostGISGeometry )        return OGRPGLayer::GetFeatureCount( bForce );/* -------------------------------------------------------------------- *//*      In theory it might be wise to cache this result, but it         *//*      won't be trivial to work out the lifetime of the value.         *//*      After all someone else could be adding records from another     *//*      application when working against a database.                    *//* -------------------------------------------------------------------- */    PGconn              *hPGConn = poDS->GetPGConn();    PGresult            *hResult;    char                szCommand[4096];    int                 nCount = 0;    poDS->FlushSoftTransaction();    hResult = PQexec(hPGConn, "BEGIN");    PQclear( hResult );    sprintf( szCommand,              "DECLARE countCursor CURSOR for "             "SELECT count(*) FROM \"%s\" "             "%s",             poFeatureDefn->GetName(), pszWHERE );    CPLDebug( "OGR_PG", "PQexec(%s)\n",               szCommand );    hResult = PQexec(hPGConn, szCommand);    PQclear( hResult );    hResult = PQexec(hPGConn, "FETCH ALL in countCursor");    if( hResult != NULL && PQresultStatus(hResult) == PGRES_TUPLES_OK )        nCount = atoi(PQgetvalue(hResult,0,0));    else        CPLDebug( "OGR_PG", "%s; failed.", szCommand );    PQclear( hResult );    hResult = PQexec(hPGConn, "CLOSE countCursor");    PQclear( hResult );    hResult = PQexec(hPGConn, "COMMIT");    PQclear( hResult );        return nCount;}/************************************************************************//*                           GetSpatialRef()                            *//*                                                                      *//*      We override this to try and fetch the table SRID from the       *//*      geometry_columns table if the srsid is -2 (meaning we           *//*      haven't yet even looked for it).                                *//************************************************************************/OGRSpatialReference *OGRPGTableLayer::GetSpatialRef(){    if( nSRSId == -2 )    {        PGconn          *hPGConn = poDS->GetPGConn();        PGresult        *hResult;        char            szCommand[1024];        nSRSId = -1;        poDS->SoftStartTransaction();        sprintf( szCommand,                  "SELECT srid FROM geometry_columns "                 "WHERE f_table_name = '%s'",                 poFeatureDefn->GetName() );        hResult = PQexec(hPGConn, szCommand );        if( hResult             && PQresultStatus(hResult) == PGRES_TUPLES_OK             && PQntuples(hResult) == 1 )        {            nSRSId = atoi(PQgetvalue(hResult,0,0));        }        PQclear( hResult );        poDS->SoftCommit();    }    return OGRPGLayer::GetSpatialRef();}

⌨️ 快捷键说明

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