📄 ogrpgtablelayer.cpp
字号:
/****************************************************************************** * $Id: ogrpgtablelayer.cpp,v 1.25 2005/02/22 12:54:05 fwarmerdam Exp $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRPGTableLayer class, access to an existing table. * 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: ogrpgtablelayer.cpp,v $ * Revision 1.25 2005/02/22 12:54:05 fwarmerdam * use OGRLayer base spatial filter support * * Revision 1.24 2005/02/11 22:17:10 fwarmerdam * Applied fix for bug 681. The truncation logic was kicking * inappropriately for integerlist and stringlist values. * * Revision 1.23 2004/11/17 17:49:27 fwarmerdam * implemented SetFeature and DeleteFeature methods * * Revision 1.22 2004/09/16 18:24:47 fwarmerdam * fixed trimming code, just truncate long text * * Revision 1.21 2004/07/10 04:47:40 warmerda * Ensure that setting a NULL (or empty) query reset pszQuery to NULL. * Use soft transactions more carefully. * Ensure that rings are closed on polygons. * * Revision 1.20 2004/07/09 18:36:14 warmerda * Fixed last fix ... put the varchar stuff in side quotes and didn't * address the case with no length set. * * Revision 1.19 2004/07/09 16:34:23 warmerda * Added patch from Markus to trim strings to allowed length. * * Revision 1.18 2004/05/08 02:14:49 warmerda * added GetFeature() on table, generalize FID support a bit * * Revision 1.17 2004/04/30 17:52:42 warmerda * added layer name laundering * * Revision 1.16 2004/04/30 00:47:31 warmerda * launder field name oid to oid_ * * Revision 1.15 2004/03/17 06:53:28 warmerda * Make command string arbitrary length in BuildFullQueryStatement() as * per report from Stephen Frost. * * Revision 1.14 2003/09/11 20:03:36 warmerda * avoid warning * * 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/12/12 14:29:28 warmerda * fixed bug with creating features with no geometry in PostGIS * * Revision 1.9 2002/10/20 03:45:53 warmerda * quote table name in feature insert, and feature count commands * * Revision 1.8 2002/10/09 18:30:10 warmerda * substantial upgrade to type handling, and preservations of width/precision * * Revision 1.7 2002/10/09 14:16:32 warmerda * changed the way that character field widths are extracted from catalog * * Revision 1.6 2002/10/04 14:03:09 warmerda * added column name laundering support * * Revision 1.5 2002/09/19 17:40:42 warmerda * Make initial ResetReading() call to set full query expression in constructor. * * Revision 1.4 2002/05/09 17:21:54 warmerda * Don't add trailing command if no fields to be inserted. * * Revision 1.3 2002/05/09 17:09:08 warmerda * Ensure nSRSId is set before creating any features. * * Revision 1.2 2002/05/09 16:48:08 warmerda * upgrade to quote table and field names * * Revision 1.1 2002/05/09 16:03:46 warmerda * New * */#include "cpl_conv.h"#include "ogr_pg.h"CPL_CVSID("$Id: ogrpgtablelayer.cpp,v 1.25 2005/02/22 12:54:05 fwarmerdam Exp $");#define CURSOR_PAGE 1/************************************************************************//* OGRPGTableLayer() *//************************************************************************/OGRPGTableLayer::OGRPGTableLayer( OGRPGDataSource *poDSIn, const char * pszTableName, int bUpdate, int nSRSIdIn ){ poDS = poDSIn; pszQuery = NULL; pszWHERE = CPLStrdup( "" ); pszQueryStatement = NULL; bUpdateAccess = bUpdate; iNextShapeId = 0; nSRSId = nSRSIdIn; poFeatureDefn = ReadTableDefinition( pszTableName ); ResetReading(); bLaunderColumnNames = TRUE;}/************************************************************************//* ~OGRPGTableLayer() *//************************************************************************/OGRPGTableLayer::~OGRPGTableLayer(){ CPLFree( pszQuery ); CPLFree( pszWHERE );}/************************************************************************//* ReadTableDefinition() *//* *//* Build a schema from the named table. Done by querying the *//* catalog. *//************************************************************************/OGRFeatureDefn *OGRPGTableLayer::ReadTableDefinition( const char * pszTable ){ PGresult *hResult; char szCommand[1024]; PGconn *hPGConn = poDS->GetPGConn(); /* -------------------------------------------------------------------- *//* Fire off commands to get back the schema of the table. *//* -------------------------------------------------------------------- */ poDS->FlushSoftTransaction(); hResult = PQexec(hPGConn, "BEGIN"); if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); sprintf( szCommand, "DECLARE mycursor CURSOR for " "SELECT a.attname, t.typname, a.attlen," " format_type(a.atttypid,a.atttypmod) " "FROM pg_class c, pg_attribute a, pg_type t " "WHERE c.relname = '%s' " "AND a.attnum > 0 AND a.attrelid = c.oid " "AND a.atttypid = t.oid", pszTable ); hResult = PQexec(hPGConn, szCommand ); } if( hResult && PQresultStatus(hResult) == PGRES_COMMAND_OK ) { PQclear( hResult ); hResult = PQexec(hPGConn, "FETCH ALL in mycursor" ); } if( !hResult || PQresultStatus(hResult) != PGRES_TUPLES_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", PQerrorMessage(hPGConn) ); return NULL; }/* -------------------------------------------------------------------- *//* Parse the returned table information. *//* -------------------------------------------------------------------- */ OGRFeatureDefn *poDefn = new OGRFeatureDefn( pszTable ); int iRecord; for( iRecord = 0; iRecord < PQntuples(hResult); iRecord++ ) { const char *pszType, *pszFormatType; OGRFieldDefn oField( PQgetvalue( hResult, iRecord, 0 ), OFTString); pszType = PQgetvalue(hResult, iRecord, 1 ); pszFormatType = PQgetvalue(hResult,iRecord,3); /* TODO: Add detection of other primary key to use as FID */ if( EQUAL(oField.GetNameRef(),"ogc_fid") ) { bHasFid = TRUE; pszFIDColumn = CPLStrdup(oField.GetNameRef()); continue; } else if( EQUAL(pszType,"geometry") ) { bHasPostGISGeometry = TRUE; pszGeomColumn = CPLStrdup( oField.GetNameRef()); continue; } else if( EQUAL(oField.GetNameRef(),"WKB_GEOMETRY") ) { bHasWkb = TRUE; if( EQUAL(pszType,"OID") ) bWkbAsOid = TRUE; continue; } if( EQUAL(pszType,"varchar") || EQUAL(pszType,"text") ) { oField.SetType( OFTString ); } else if( EQUAL(pszType,"bpchar") ) { int nWidth; nWidth = atoi(PQgetvalue(hResult,iRecord,2)); if( nWidth == -1 ) { if( EQUALN(pszFormatType,"character(",10) ) nWidth = atoi(pszFormatType+10); else nWidth = 0; } oField.SetType( OFTString ); oField.SetWidth( nWidth ); } else if( EQUAL(pszType,"numeric") ) { const char *pszFormatName = PQgetvalue(hResult,iRecord,3); const char *pszPrecision = strstr(pszFormatName,","); int nWidth, nPrecision = 0; nWidth = atoi(pszFormatName + 8); if( pszPrecision != NULL ) nPrecision = atoi(pszPrecision+1); if( nPrecision == 0 ) oField.SetType( OFTInteger ); else oField.SetType( OFTReal ); oField.SetWidth( nWidth ); oField.SetPrecision( nPrecision ); } else if( EQUAL(pszFormatType,"integer[]") ) { oField.SetType( OFTIntegerList ); } else if( EQUAL(pszFormatType,"float[]") ) { oField.SetType( OFTRealList ); } else if( EQUAL(pszType,"int2") ) { oField.SetType( OFTInteger ); oField.SetWidth( 5 ); } else if( EQUALN(pszType,"int",3) ) { oField.SetType( OFTInteger ); } else if( EQUALN(pszType,"float",5) || EQUALN(pszType,"double",6) ) { oField.SetType( OFTReal ); } else if( EQUAL(pszType, "date") ) { oField.SetType( OFTString ); oField.SetWidth( 10 ); } else if( EQUAL(pszType, "time") ) { oField.SetType( OFTString ); oField.SetWidth( 8 ); } poDefn->AddFieldDefn( &oField ); } PQclear( hResult ); hResult = PQexec(hPGConn, "CLOSE mycursor"); PQclear( hResult ); hResult = PQexec(hPGConn, "COMMIT"); PQclear( hResult ); return poDefn;}/************************************************************************//* SetSpatialFilter() *//************************************************************************/void OGRPGTableLayer::SetSpatialFilter( OGRGeometry * poGeomIn ){ if( !InstallFilter( poGeomIn ) ) return; BuildWhere(); ResetReading();}/************************************************************************//* BuildWhere() *//* *//* Build the WHERE statement appropriate to the current set of *//* criteria (spatial and attribute queries). *//************************************************************************/void OGRPGTableLayer::BuildWhere(){ char szWHERE[4096]; CPLFree( pszWHERE ); pszWHERE = NULL; szWHERE[0] = '\0'; if( m_poFilterGeom != NULL && bHasPostGISGeometry ) { OGREnvelope sEnvelope; m_poFilterGeom->getEnvelope( &sEnvelope ); sprintf( szWHERE, "WHERE %s && GeometryFromText('BOX3D(%.12f %.12f, %.12f %.12f)'::box3d,%d) ", pszGeomColumn, sEnvelope.MinX, sEnvelope.MinY, sEnvelope.MaxX, sEnvelope.MaxY, nSRSId ); } if( pszQuery != NULL ) { if( strlen(szWHERE) == 0 ) sprintf( szWHERE, "WHERE %s ", pszQuery ); else sprintf( szWHERE+strlen(szWHERE), "AND %s ", pszQuery ); } pszWHERE = CPLStrdup(szWHERE);}/************************************************************************//* BuildFullQueryStatement() *//************************************************************************/void OGRPGTableLayer::BuildFullQueryStatement(){ if( pszQueryStatement != NULL ) { CPLFree( pszQueryStatement ); pszQueryStatement = NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -