ogrpgtablelayer.cpp

来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 1,798 行 · 第 1/4 页

CPP
1,798
字号
                if( j != 0 )                    strcat( pszNeedToFree+nOff, "," );                nOff += strlen(pszNeedToFree+nOff);                sprintf( pszNeedToFree+nOff, "%d", panItems[j] );            }            strcat( pszNeedToFree+nOff, "}" );            pszStrValue = pszNeedToFree;        }        // We need special formatting for real list values.        if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTRealList )        {            int nCount, nOff = 0, j;            const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount);            pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10);            strcpy( pszNeedToFree, "{" );            for( j = 0; j < nCount; j++ )            {                if( j != 0 )                    strcat( pszNeedToFree+nOff, "," );                nOff += strlen(pszNeedToFree+nOff);                sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] );            }            strcat( pszNeedToFree+nOff, "}" );            pszStrValue = pszNeedToFree;        }        // Check if date is NULL: 0000-00-00        if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTDate )        {            if( EQUALN( pszStrValue, "0000", 4 ) )            {                pszStrValue = "NULL";                bIsDateNull = TRUE;            }        }        if( poFeatureDefn->GetFieldDefn(i)->GetType() != OFTInteger            && poFeatureDefn->GetFieldDefn(i)->GetType() != OFTReal            && !bIsDateNull )        {            int         iChar;            /* We need to quote and escape string fields. */            osCommand += "'";            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] == '\'' )                {                    osCommand += '\\';                    osCommand += pszStrValue[iChar];                }                else                {                    osCommand += pszStrValue[iChar];                }            }            osCommand += "'";        }        else        {            osCommand += pszStrValue;        }        if( pszNeedToFree )            CPLFree( pszNeedToFree );    }    osCommand += ")";/* -------------------------------------------------------------------- *//*      Execute the insert.                                             *//* -------------------------------------------------------------------- */    hResult = PQexec(hPGConn, osCommand);    if( PQresultStatus(hResult) != PGRES_COMMAND_OK )    {        CPLDebug( "OGR_PG", "PQexec(%s)\n", osCommand.c_str() );        CPLError( CE_Failure, CPLE_AppDefined,                  "INSERT command for new feature failed.\n%s\nCommand: %s",                  PQerrorMessage(hPGConn), osCommand.c_str() );        OGRPGClearResult( hResult );        poDS->SoftRollback();        return OGRERR_FAILURE;    }#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    OGRPGClearResult( hResult );    return poDS->SoftCommit();}/************************************************************************//*                        CreateFeatureViaCopy()                        *//************************************************************************/OGRErr OGRPGTableLayer::CreateFeatureViaCopy( OGRFeature *poFeature ){    int nCommandBufSize = 4000;    /* First process geometry */    OGRGeometry *poGeometry = (OGRGeometry *) poFeature->GetGeometryRef();        char *pszGeom = NULL;    if ( NULL != poGeometry )    {        poGeometry->closeRings();        poGeometry->setCoordinateDimension( nCoordDimension );        pszGeom = GeometryToHex( poGeometry, nSRSId );        nCommandBufSize = nCommandBufSize + strlen(pszGeom);    }    char *pszCommand = (char *) CPLMalloc(nCommandBufSize);    if ( poGeometry )    {        sprintf( pszCommand, "%s", pszGeom);        CPLFree( pszGeom );    }    else    {        sprintf( pszCommand, "\\N");    }    strcat( pszCommand, "\t" );    /* Next process the field id column */    if( bHasFid && poFeatureDefn->GetFieldIndex( pszFIDColumn ) != -1 )    {        /* Set the FID */        if( poFeature->GetFID() != OGRNullFID )        {            sprintf( pszCommand + strlen(pszCommand), "%ld ", poFeature->GetFID());        }        else	    {	        strcat( pszCommand, "\\N" );        }        strcat( pszCommand, "\t" );    }    /* Now process the remaining fields */    int nOffset = strlen(pszCommand);    int nFieldCount = poFeatureDefn->GetFieldCount();    for( int i = 0; i < nFieldCount;  i++ )    {        const char *pszStrValue = poFeature->GetFieldAsString(i);        char *pszNeedToFree = NULL;        if( !poFeature->IsFieldSet( i ) )        {            strcat( pszCommand, "\\N" );            if( i < nFieldCount - 1 )                strcat( pszCommand, "\t" );            continue;        }        // We need special formatting for integer list values.        if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTIntegerList )        {            int nCount, nOff = 0, j;            const int *panItems = poFeature->GetFieldAsIntegerList(i,&nCount);            pszNeedToFree = (char *) CPLMalloc(nCount * 13 + 10);            strcpy( pszNeedToFree, "{" );            for( j = 0; j < nCount; j++ )            {                if( j != 0 )                    strcat( pszNeedToFree+nOff, "," );                nOff += strlen(pszNeedToFree+nOff);                sprintf( pszNeedToFree+nOff, "%d", panItems[j] );            }            strcat( pszNeedToFree+nOff, "}" );            pszStrValue = pszNeedToFree;        }        // We need special formatting for real list values.        if( poFeatureDefn->GetFieldDefn(i)->GetType() == OFTRealList )        {            int nCount, nOff = 0, j;            const double *padfItems =poFeature->GetFieldAsDoubleList(i,&nCount);            pszNeedToFree = (char *) CPLMalloc(nCount * 40 + 10);            strcpy( pszNeedToFree, "{" );            for( j = 0; j < nCount; j++ )            {                if( j != 0 )                    strcat( pszNeedToFree+nOff, "," );                nOff += strlen(pszNeedToFree+nOff);                sprintf( pszNeedToFree+nOff, "%.16g", padfItems[j] );            }            strcat( pszNeedToFree+nOff, "}" );            pszStrValue = pszNeedToFree;        }        // Grow the command buffer?        if( (int) (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;            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;                }                /* Escape embedded \, \t, \n, \r since they will cause COPY                   to misinterpret a line of text and thus abort */                if( pszStrValue[iChar] == '\\' ||                     pszStrValue[iChar] == '\t' ||                     pszStrValue[iChar] == '\r' ||                     pszStrValue[iChar] == '\n'   )                {                    pszCommand[nOffset++] = '\\';                }                pszCommand[nOffset++] = pszStrValue[iChar];            }            pszCommand[nOffset] = '\0';//            strcat( pszCommand+nOffset, "'" );        }        else        {            strcat( pszCommand+nOffset, pszStrValue );        }        if( pszNeedToFree )            CPLFree( pszNeedToFree );        if( i < nFieldCount - 1 )            strcat( pszCommand, "\t" );    }    /* Add end of line marker */    strcat( pszCommand, "\n" );    /* ------------------------------------------------------------ */    /*      Execute the copy.                                       */    /* ------------------------------------------------------------ */    PGconn *hPGConn = poDS->GetPGConn();    OGRErr result = OGRERR_NONE;    /* This is for postgresql  7.4 and higher */#if !defined(PG_PRE74)    int copyResult = PQputCopyData(hPGConn, pszCommand, strlen(pszCommand));    switch (copyResult)    {    case 0:        CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand );        CPLError( CE_Failure, CPLE_AppDefined, "Writing COPY data blocked.");        result = OGRERR_FAILURE;        break;    case -1:        CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand );        CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) );        result = OGRERR_FAILURE;        break;    }#else /* else defined(PG_PRE74) */    int copyResult = PQputline(hPGConn, pszCommand);    if (copyResult == EOF)    {      CPLDebug( "OGR_PG", "PQexec(%s)\n", pszCommand );      CPLError( CE_Failure, CPLE_AppDefined, "Writing COPY data blocked.");      result = OGRERR_FAILURE;    }  #endif /* end of defined(PG_PRE74) */    /* Free the buffer we allocated before returning */    CPLFree( pszCommand );    return result;}/************************************************************************//*                           TestCapability()                           *//************************************************************************/int OGRPGTableLayer::TestCapability( const char * pszCap ){    if ( bUpdateAccess )    {        if( EQUAL(pszCap,OLCSequentialWrite) || EQUAL(pszCap,OLCCreateField) )            return TRUE;        else if( EQUAL(pszCap,OLCRandomRead) || EQUAL(pszCap,OLCRandomWrite) )            return bHasFid;    }    return OGRPGLayer::TestCapability( pszCap );}/************************************************************************//*                            CreateField()                             *//************************************************************************/OGRErr OGRPGTableLayer::CreateField( OGRFieldDefn *poFieldIn, int bApproxOK ){    PGconn              *hPGConn = poDS->GetPGConn();    PGresult            *hResult = NULL;    CPLString           osCommand;    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( oField.GetType() == OFTDate )    {        strcpy( szFieldType, "date" );    }    else if( oField.GetType() == OFTTime )    {        strcpy( szFieldType, "time" );    }    else if( oField.GetType() == OFTDateTime )    {        strcpy( szFieldType, "timestamp with time zone" );    }    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();

⌨️ 快捷键说明

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