📄 ogrpglayer.cpp
字号:
/****************************************************************************** * $Id: ogrpglayer.cpp,v 1.17 2005/02/22 12:54:05 fwarmerdam Exp $ * * 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. ****************************************************************************** * * $Log: ogrpglayer.cpp,v $ * Revision 1.17 2005/02/22 12:54:05 fwarmerdam * use OGRLayer base spatial filter support * * Revision 1.16 2005/02/02 20:54:27 fwarmerdam * track m_nFeaturesRead * * Revision 1.15 2004/07/10 04:46:24 warmerda * initialize nResultOffset, use soft transactions * * Revision 1.14 2004/05/08 02:14:49 warmerda * added GetFeature() on table, generalize FID support a bit * * Revision 1.13 2003/05/21 03:59:42 warmerda * expand tabs * * Revision 1.12 2003/02/01 07:55:48 warmerda * avoid dependence on libpq-fs.h * * Revision 1.11 2003/01/08 22:07:14 warmerda * Added support for integer and real list field types * * Revision 1.10 2002/05/09 16:03:19 warmerda * major upgrade to support SRS better and add ExecuteSQL * * Revision 1.9 2001/11/15 21:19:47 warmerda * added soft transaction semantics, handle null fields properly * * Revision 1.8 2001/11/15 16:10:12 warmerda * fixed some escaping issues with string field values * * Revision 1.7 2001/09/28 04:03:52 warmerda * partially upraded to PostGIS 0.6 * * Revision 1.6 2001/07/18 04:55:16 warmerda * added CPL_CSVID * * Revision 1.5 2001/06/26 20:59:13 warmerda * implement efficient spatial and attribute query support * * Revision 1.4 2001/06/19 22:29:12 warmerda * upgraded to include PostGIS support * * Revision 1.3 2001/06/19 15:50:23 warmerda * added feature attribute query support * * Revision 1.2 2000/11/23 06:03:35 warmerda * added Oid support * * Revision 1.1 2000/10/17 17:46:51 warmerda * New * */#include "cpl_conv.h"#include "ogr_pg.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrpglayer.cpp,v 1.17 2005/02/22 12:54:05 fwarmerdam Exp $");#define CURSOR_PAGE 1// These originally are defined in libpq-fs.h.#ifndef INV_WRITE#define INV_WRITE 0x00020000#define INV_READ 0x00040000#endif/************************************************************************//* 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->Dereference(); if( poFeatureDefn ) delete poFeatureDefn;}/************************************************************************//* ResetReading() *//************************************************************************/void OGRPGLayer::ResetReading(){ PGconn *hPGConn = poDS->GetPGConn(); char szCommand[1024]; iNextShapeId = 0; if( hCursorResult != NULL ) { PQclear( hCursorResult ); if( bCursorActive ) { sprintf( szCommand, "CLOSE %s", pszCursorName ); hCursorResult = PQexec(hPGConn, szCommand); PQclear( 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),"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++; } 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; }/* -------------------------------------------------------------------- *//* Transfer regular data fields. *//* -------------------------------------------------------------------- */ iOGRField = poFeatureDefn->GetFieldIndex(PQfname(hCursorResult,iField)); if( iOGRField < 0 ) continue; if( PQgetisnull( hCursorResult, iRecord, iField ) ) continue; if( poFeatureDefn->GetFieldDefn(iOGRField)->GetType() == OFTIntegerList) { char **papszTokens; int *panList, nCount, i; 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]); poFeature->SetField( iOGRField, nCount, panList ); CPLFree( panList ); CSLDestroy( papszTokens ); } else if( poFeatureDefn->GetFieldDefn(iOGRField)->GetType() == OFTRealList) { char **papszTokens; int nCount, i; double *padfList; papszTokens = CSLTokenizeStringComplex( PQgetvalue( hCursorResult, iRecord, iField ), "{,}", FALSE, FALSE ); nCount = CSLCount(papszTokens); padfList = (double *) CPLCalloc(sizeof(double),nCount); for( i = 0; i < nCount; i++ ) padfList[i] = atof(papszTokens[i]); poFeature->SetField( iOGRField, nCount, padfList );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -