ogrocitablelayer.cpp

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

CPP
1,710
字号
/****************************************************************************** * $Id: ogrocitablelayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project:  Oracle Spatial Driver * Purpose:  Implementation of the OGROCITableLayer class.  This class provides *           layer semantics on a table, but utilizing alot of machinery from *           the OGROCILayer base class. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com> * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************/#include "ogr_oci.h"#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrocitablelayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $");static int nDiscarded = 0;static int nHits = 0;#define HSI_UNKNOWN  -2/************************************************************************//*                          OGROCITableLayer()                          *//************************************************************************/OGROCITableLayer::OGROCITableLayer( OGROCIDataSource *poDSIn,                                     const char * pszTableName,                                    int nSRIDIn, int bUpdate, int bNewLayerIn ){    poDS = poDSIn;    pszQuery = NULL;    pszWHERE = CPLStrdup( "" );    pszQueryStatement = NULL;        bUpdateAccess = bUpdate;    bNewLayer = bNewLayerIn;    iNextShapeId = 0;    iNextFIDToWrite = 1;    bValidTable = FALSE;    if( bNewLayerIn )        bHaveSpatialIndex = FALSE;    else        bHaveSpatialIndex = HSI_UNKNOWN;    poFeatureDefn = ReadTableDefinition( pszTableName );    nSRID = nSRIDIn;    if( nSRID == -1 )        nSRID = LookupTableSRID();            poSRS = poDSIn->FetchSRS( nSRID );    if( poSRS != NULL )        poSRS->Reference();    hOrdVARRAY = NULL;    hElemInfoVARRAY = NULL;    poBoundStatement = NULL;    nWriteCacheMax = 0;    nWriteCacheUsed = 0;    pasWriteGeoms = NULL;    papsWriteGeomMap = NULL;    pasWriteGeomInd = NULL;    papsWriteGeomIndMap = NULL;    papWriteFields = NULL;    papaeWriteFieldInd = NULL;    panWriteFIDs = NULL;    ResetReading();}/************************************************************************//*                         ~OGROCITableLayer()                          *//************************************************************************/OGROCITableLayer::~OGROCITableLayer(){    int   i;    if( bNewLayer )        FinalizeNewLayer();    CPLFree( panWriteFIDs );    if( papWriteFields != NULL )    {        for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )        {            CPLFree( papWriteFields[i] );            CPLFree( papaeWriteFieldInd[i] );        }    }    CPLFree( papWriteFields );    CPLFree( papaeWriteFieldInd );    if( poBoundStatement != NULL )        delete poBoundStatement;    CPLFree( pasWriteGeomInd );    CPLFree( papsWriteGeomIndMap );        CPLFree( papsWriteGeomMap );    CPLFree( pasWriteGeoms );    CPLFree( pszQuery );    CPLFree( pszWHERE );    if( poSRS != NULL && poSRS->Dereference() == 0 )        delete poSRS;}/************************************************************************//*                        ReadTableDefinition()                         *//*                                                                      *//*      Build a schema from the named table.  Done by querying the      *//*      catalog.                                                        *//************************************************************************/OGRFeatureDefn *OGROCITableLayer::ReadTableDefinition( const char * pszTable ){    OGROCISession      *poSession = poDS->GetSession();    sword               nStatus;    OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable );    poDefn->Reference();/* -------------------------------------------------------------------- *//*      Do a DescribeAll on the table.                                  *//* -------------------------------------------------------------------- */    OCIParam *hAttrParam = NULL;    OCIParam *hAttrList = NULL;    nStatus =         OCIDescribeAny( poSession->hSvcCtx, poSession->hError,                         (dvoid *) pszTable, strlen(pszTable), OCI_OTYPE_NAME,                         OCI_DEFAULT, OCI_PTYPE_TABLE, poSession->hDescribe );    if( poSession->Failed( nStatus, "OCIDescribeAny" ) )    {        CPLErrorReset();        nStatus =            OCIDescribeAny(poSession->hSvcCtx, poSession->hError,                           (dvoid *)pszTable, strlen(pszTable), OCI_OTYPE_NAME,                           OCI_DEFAULT, OCI_PTYPE_VIEW, poSession->hDescribe );        if( poSession->Failed( nStatus, "OCIDescribeAny" ) )            return poDefn;    }        if( poSession->Failed(         OCIAttrGet( poSession->hDescribe, OCI_HTYPE_DESCRIBE,                     &hAttrParam, 0, OCI_ATTR_PARAM, poSession->hError ),        "OCIAttrGet(ATTR_PARAM)") )        return poDefn;    if( poSession->Failed(         OCIAttrGet( hAttrParam, OCI_DTYPE_PARAM, &hAttrList, 0,                     OCI_ATTR_LIST_COLUMNS, poSession->hError ),        "OCIAttrGet(ATTR_LIST_COLUMNS)" ) )        return poDefn;/* -------------------------------------------------------------------- *//*      What is the name of the column to use as FID?  This defaults    *//*      to OGR_FID but we allow it to be overridden by a config         *//*      variable.  Ideally we would identify a column that is a         *//*      primary key and use that, but I'm not yet sure how to           *//*      accomplish that.                                                *//* -------------------------------------------------------------------- */    const char *pszExpectedFIDName =         CPLGetConfigOption( "OCI_FID", "OGR_FID" );/* -------------------------------------------------------------------- *//*      Parse the returned table information.                           *//* -------------------------------------------------------------------- */    for( int iRawFld = 0; TRUE; iRawFld++ )    {        OGRFieldDefn    oField( "", OFTString);        OCIParam     *hParmDesc;        ub2          nOCIType;        ub4          nOCILen;        sword        nStatus;        nStatus = OCIParamGet( hAttrList, OCI_DTYPE_PARAM,                               poSession->hError, (dvoid**)&hParmDesc,                                (ub4) iRawFld+1 );        if( nStatus != OCI_SUCCESS )            break;        if( poSession->GetParmInfo( hParmDesc, &oField, &nOCIType, &nOCILen )            != CE_None )            return poDefn;        if( oField.GetType() == OFTBinary )        {            if( nOCIType == 108 && pszGeomName == NULL )            {                CPLFree( pszGeomName );                pszGeomName = CPLStrdup( oField.GetNameRef() );                iGeomColumn = iRawFld;            }            continue;                           }        if( EQUAL(oField.GetNameRef(),pszExpectedFIDName)             && oField.GetType() == OFTInteger )        {            pszFIDName = CPLStrdup(oField.GetNameRef());            continue;        }        poDefn->AddFieldDefn( &oField );    }    bValidTable = TRUE;    return poDefn;}/************************************************************************//*                          SetSpatialFilter()                          *//************************************************************************/void OGROCITableLayer::SetSpatialFilter( OGRGeometry * poGeomIn ){    if( !InstallFilter( poGeomIn ) )        return;    BuildWhere();    ResetReading();}/************************************************************************//*                        TestForSpatialIndex()                         *//************************************************************************/void OGROCITableLayer::TestForSpatialIndex( const char *pszSpatWHERE ){    OGROCIStringBuf oTestCmd;    OGROCIStatement oTestStatement( poDS->GetSession() );            oTestCmd.Append( "SELECT COUNT(*) FROM " );    oTestCmd.Append( poFeatureDefn->GetName() );    oTestCmd.Append( pszSpatWHERE );    if( oTestStatement.Execute( oTestCmd.GetString() ) != CE_None )        bHaveSpatialIndex = FALSE;    else        bHaveSpatialIndex = TRUE;}/************************************************************************//*                             BuildWhere()                             *//*                                                                      *//*      Build the WHERE statement appropriate to the current set of     *//*      criteria (spatial and attribute queries).                       *//************************************************************************/void OGROCITableLayer::BuildWhere(){    OGROCIStringBuf oWHERE;    CPLFree( pszWHERE );    pszWHERE = NULL;    if( m_poFilterGeom != NULL && bHaveSpatialIndex )    {        OGREnvelope  sEnvelope;        m_poFilterGeom->getEnvelope( &sEnvelope );        oWHERE.Append( " WHERE sdo_filter(" );        oWHERE.Append( pszGeomName );        oWHERE.Append( ", MDSYS.SDO_GEOMETRY(2003," );        if( nSRID == -1 )            oWHERE.Append( "NULL" );        else            oWHERE.Appendf( 15, "%d", nSRID );        oWHERE.Append( ",NULL," );        oWHERE.Append( "MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1)," );        oWHERE.Append( "MDSYS.SDO_ORDINATE_ARRAY(" );        oWHERE.Appendf( 600,                "%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g,%.16g",                        sEnvelope.MinX, sEnvelope.MinY,                        sEnvelope.MaxX, sEnvelope.MinY,                        sEnvelope.MaxX, sEnvelope.MaxY,                        sEnvelope.MinX, sEnvelope.MaxY,                        sEnvelope.MinX, sEnvelope.MinY);        oWHERE.Append( ")), 'querytype=window') = 'TRUE' " );    }    if( bHaveSpatialIndex == HSI_UNKNOWN )    {        TestForSpatialIndex( oWHERE.GetString() );        if( !bHaveSpatialIndex )            oWHERE.Clear();    }    if( pszQuery != NULL )    {        if( oWHERE.GetLast() == '\0' )            oWHERE.Append( "WHERE " );        else            oWHERE.Append( "AND " );        oWHERE.Append( pszQuery );    }    pszWHERE = oWHERE.StealString();}

⌨️ 快捷键说明

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