ogrpglayer.cpp

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

CPP
1,045
字号
/****************************************************************************** * $Id: ogrpglayer.cpp 11226 2007-04-08 14:54:41Z mloskot $ * * Project:  OpenGIS Simple Features Reference Implementation * Purpose:  Implements OGRPGLayer class  which implements shared handling *           of feature geometry and so forth needed by OGRPGResultLayer and *           OGRPGTableLayer. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2000, Frank Warmerdam * * 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_pg.h"#include "ogrpgutility.h"#include "ogr_p.h"#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrpglayer.cpp 11226 2007-04-08 14:54:41Z mloskot $");#define CURSOR_PAGE     500// These originally are defined in libpq-fs.h.#ifndef INV_WRITE#define INV_WRITE               0x00020000#define INV_READ                0x00040000#endif/* Flags for creating WKB format for PostGIS */#define WKBZOFFSET 0x80000000#define WKBMOFFSET 0x40000000#define WKBSRIDFLAG 0x20000000#define WKBBBOXFLAG 0x10000000/************************************************************************//*                           OGRPGLayer()                               *//************************************************************************/OGRPGLayer::OGRPGLayer(){    poDS = NULL;    bHasWkb = FALSE;    bWkbAsOid = FALSE;    bHasPostGISGeometry = FALSE;    pszGeomColumn = NULL;    pszQueryStatement = NULL;    bHasFid = FALSE;    pszFIDColumn = NULL;    iNextShapeId = 0;    nResultOffset = 0;    poSRS = NULL;    nSRSId = -2; // we haven't even queried the database for it yet.    /* Eventually we may need to make these a unique name */    pszCursorName = "OGRPGLayerReader";    hCursorResult = NULL;    bCursorActive = FALSE;    poFeatureDefn = NULL;}/************************************************************************//*                            ~OGRPGLayer()                             *//************************************************************************/OGRPGLayer::~OGRPGLayer(){    if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )    {        CPLDebug( "PG", "%d features read on layer '%s'.",                  (int) m_nFeaturesRead,                  poFeatureDefn->GetName() );    }    ResetReading();    CPLFree( pszGeomColumn );    CPLFree( pszFIDColumn );    CPLFree( pszQueryStatement );    if( poSRS != NULL )        poSRS->Release();    if( poFeatureDefn )        poFeatureDefn->Release();}/************************************************************************//*                            ResetReading()                            *//************************************************************************/void OGRPGLayer::ResetReading(){    PGconn      *hPGConn = poDS->GetPGConn();    char        szCommand[1024];    iNextShapeId = 0;    if( hCursorResult != NULL )    {        OGRPGClearResult( hCursorResult );        if( bCursorActive )        {            sprintf( szCommand, "CLOSE %s", pszCursorName );            hCursorResult = PQexec(hPGConn, szCommand);            OGRPGClearResult( hCursorResult );        }        poDS->FlushSoftTransaction();        hCursorResult = NULL;    }}/************************************************************************//*                           GetNextFeature()                           *//************************************************************************/OGRFeature *OGRPGLayer::GetNextFeature(){    for( ; TRUE; )    {        OGRFeature      *poFeature;        poFeature = GetNextRawFeature();        if( poFeature == NULL )            return NULL;        if( (m_poFilterGeom == NULL            || bHasPostGISGeometry            || !FilterGeometry( poFeature->GetGeometryRef() ) )            && (m_poAttrQuery == NULL                || m_poAttrQuery->Evaluate( poFeature )) )            return poFeature;        delete poFeature;    }}/************************************************************************//*                          RecordToFeature()                           *//*                                                                      *//*      Convert the indicated record of the current result set into     *//*      a feature.                                                      *//************************************************************************/OGRFeature *OGRPGLayer::RecordToFeature( int iRecord ){/* -------------------------------------------------------------------- *//*      Create a feature from the current result.                       *//* -------------------------------------------------------------------- */    int         iField;    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );    poFeature->SetFID( iNextShapeId );    m_nFeaturesRead++;/* ==================================================================== *//*      Transfer all result fields we can.                              *//* ==================================================================== */    for( iField = 0;         iField < PQnfields(hCursorResult);         iField++ )    {        int     iOGRField;/* -------------------------------------------------------------------- *//*      Handle FID.                                                     *//* -------------------------------------------------------------------- */        if( bHasFid && EQUAL(PQfname(hCursorResult,iField),pszFIDColumn) )            poFeature->SetFID( atoi(PQgetvalue(hCursorResult,iRecord,iField)));/* -------------------------------------------------------------------- *//*      Handle PostGIS geometry                                         *//* -------------------------------------------------------------------- */        if( bHasPostGISGeometry            && (EQUAL(PQfname(hCursorResult,iField),pszGeomColumn)                || EQUAL(PQfname(hCursorResult,iField),"asEWKT")                || EQUAL(PQfname(hCursorResult,iField),"asText") ) )        {            char        *pszWKT;            char        *pszPostSRID;            OGRGeometry *poGeometry = NULL;            pszWKT = PQgetvalue( hCursorResult, iRecord, iField );            pszPostSRID = pszWKT;            // optionally strip off PostGIS SRID identifier.  This            // happens if we got a raw geometry field.            if( EQUALN(pszPostSRID,"SRID=",5) )            {                while( *pszPostSRID != '\0' && *pszPostSRID != ';' )                    pszPostSRID++;                if( *pszPostSRID == ';' )                    pszPostSRID++;            }            if( EQUALN(pszPostSRID,"00",2) || EQUALN(pszPostSRID,"01",2) )            {                poGeometry =                    HEXToGeometry(                        PQgetvalue( hCursorResult, iRecord, iField ) );            }            else                OGRGeometryFactory::createFromWkt( &pszPostSRID, NULL,                                                   &poGeometry );            if( poGeometry != NULL )                poFeature->SetGeometryDirectly( poGeometry );            continue;        }/* -------------------------------------------------------------------- *//*      Handle raw binary geometry ... this hasn't been tested in a     *//*      while.                                                          *//* -------------------------------------------------------------------- */        else if( EQUAL(PQfname(hCursorResult,iField),"WKB_GEOMETRY") )        {            if( bWkbAsOid )            {                poFeature->SetGeometryDirectly(                    OIDToGeometry( (Oid) atoi(                        PQgetvalue( hCursorResult,                                    iRecord, iField ) ) ) );            }            else            {                poFeature->SetGeometryDirectly(                    BYTEAToGeometry(                        PQgetvalue( hCursorResult,                                    iRecord, iField ) ) );            }            continue;        }        /* Handle binary cursor result */        else if ( EQUAL(PQfname(hCursorResult,iField),"AsBinary") )        {            GByte * pabyWkb = (GByte *)PQgetvalue( hCursorResult,                                                   iRecord, iField);            OGRGeometry * poGeom = NULL;            OGRGeometryFactory::createFromWkb(pabyWkb,NULL,&poGeom);            poFeature->SetGeometryDirectly( poGeom );            continue;        }/* -------------------------------------------------------------------- *//*      Transfer regular data fields.                                   *//* -------------------------------------------------------------------- */        iOGRField =            poFeatureDefn->GetFieldIndex(PQfname(hCursorResult,iField));        if( iOGRField < 0 )            continue;        if( PQgetisnull( hCursorResult, iRecord, iField ) )            continue;        OGRFieldType eOGRType =             poFeatureDefn->GetFieldDefn(iOGRField)->GetType();        if( eOGRType == OFTIntegerList)        {            int *panList, nCount, i;#if !defined(PG_PRE74)            if ( PQfformat( hCursorResult, iField ) == 1 ) // Binary data representation            {                char * pData = PQgetvalue( hCursorResult, iRecord, iField );                // goto number of array elements                pData += 3 * sizeof(int);                memcpy( &nCount, pData, sizeof(int) );                CPL_MSBPTR32( &nCount );                panList = (int *) CPLCalloc(sizeof(int),nCount);                // goto first array element                pData += 2 * sizeof(int);                for( i = 0; i < nCount; i++ )                {                    // get element size                    int nSize = *(int *)(pData);                    CPL_MSBPTR32( &nSize );                    CPLAssert( nSize == sizeof(int) );                    pData += sizeof(int);                    memcpy( &panList[i], pData, nSize );                    CPL_MSBPTR32(&panList[i]);                    pData += nSize;                }            }            else#endif /* notdef PG_PRE74 */            {                char **papszTokens;                papszTokens = CSLTokenizeStringComplex(                    PQgetvalue( hCursorResult, iRecord, iField ),                    "{,}", FALSE, FALSE );                nCount = CSLCount(papszTokens);                panList = (int *) CPLCalloc(sizeof(int),nCount);                for( i = 0; i < nCount; i++ )                    panList[i] = atoi(papszTokens[i]);                CSLDestroy( papszTokens );            }            poFeature->SetField( iOGRField, nCount, panList );            CPLFree( panList );        }        else if( eOGRType == OFTRealList )        {

⌨️ 快捷键说明

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