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 + -
显示快捷键?