EVOLUTION-MANAGER
Edit File: ogrwalktablelayer.cpp
/****************************************************************************** * $Id: ogrwalktablelayer.cpp * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRWalkTableLayer class, access to an existing table. * Author: Xian Chen, chenxian at walkinfo.com.cn * ****************************************************************************** * Copyright (c) 2013, ZJU Walkinfo Technology Corp., Ltd. * * 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 "ogrwalk.h" #include "cpl_conv.h" /************************************************************************/ /* OGRWalkTableLayer() */ /************************************************************************/ OGRWalkTableLayer::OGRWalkTableLayer( OGRWalkDataSource *poDSIn ) { poDS = poDSIn; pszQuery = NULL; iNextShapeId = 0; poFeatureDefn = NULL; memset( &sExtent, 0, sizeof(sExtent) ); } /************************************************************************/ /* ~OGRWalkTableLayer() */ /************************************************************************/ OGRWalkTableLayer::~OGRWalkTableLayer() { CPLFree( pszQuery ); ClearStatement(); } /************************************************************************/ /* Initialize() */ /************************************************************************/ CPLErr OGRWalkTableLayer::Initialize( const char *pszLayerName, const char *pszGeomCol, double minE, double maxE, double minN, double maxN, const char *pszMemo) { CPLODBCSession *poSession = poDS->GetSession(); CPLFree( pszFIDColumn ); pszFIDColumn = NULL; sExtent.MinX = minE; sExtent.MaxX = maxE; sExtent.MinY = minN; sExtent.MaxY = maxN; /* -------------------------------------------------------------------- */ /* Look up the Spatial Reference */ /* -------------------------------------------------------------------- */ LookupSpatialRef( pszMemo ); /* -------------------------------------------------------------------- */ /* Generate the Feature Tablename from the Layer Name */ /* which is in the form <layername>Features */ /* -------------------------------------------------------------------- */ char* pszFeatureTableName = (char *) CPLMalloc(strlen(pszLayerName)+10); sprintf(pszFeatureTableName, "%sFeatures", pszLayerName); /* -------------------------------------------------------------------- */ /* Do we have a simple primary key? */ /* -------------------------------------------------------------------- */ CPLODBCStatement oGetKey( poSession ); if( oGetKey.GetPrimaryKeys( pszFeatureTableName, NULL, NULL ) && oGetKey.Fetch() ) { pszFIDColumn = CPLStrdup(oGetKey.GetColData( 3 )); if( oGetKey.Fetch() ) // more than one field in key! { CPLFree( pszFIDColumn ); pszFIDColumn = NULL; CPLDebug( "Walk", "Table %s has multiple primary key fields, " "ignoring them all.", pszFeatureTableName ); } } /* -------------------------------------------------------------------- */ /* Have we been provided a geometry column? */ /* -------------------------------------------------------------------- */ CPLFree( pszGeomColumn ); if( pszGeomCol == NULL ) pszGeomColumn = NULL; else pszGeomColumn = CPLStrdup( pszGeomCol ); /* -------------------------------------------------------------------- */ /* Get the column definitions for this table. */ /* -------------------------------------------------------------------- */ CPLODBCStatement oGetCol( poSession ); CPLErr eErr; if( !oGetCol.GetColumns( pszFeatureTableName, NULL, NULL ) ) { CPLFree( pszFeatureTableName ); return CE_Failure; } eErr = BuildFeatureDefn( pszLayerName, &oGetCol ); if( eErr != CE_None ) { CPLFree( pszFeatureTableName ); return eErr; } if( poFeatureDefn->GetFieldCount() == 0 ) { CPLError( CE_Warning, CPLE_AppDefined, "No column definitions found for table '%s', layer not usable.", pszLayerName ); CPLFree( pszFeatureTableName ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* If we got a geometry column, does it exist? Is it binary? */ /* -------------------------------------------------------------------- */ if( pszGeomColumn != NULL ) { int iColumn = oGetCol.GetColId( pszGeomColumn ); if( iColumn < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Column %s requested for geometry, but it does not exist.", pszGeomColumn ); CPLFree( pszGeomColumn ); pszGeomColumn = NULL; } else { if( CPLODBCStatement::GetTypeMapping( oGetCol.GetColType( iColumn )) == SQL_C_BINARY ) bGeomColumnWKB = TRUE; } } CPLFree( pszFeatureTableName ); return CE_None; } /************************************************************************/ /* ClearStatement() */ /************************************************************************/ void OGRWalkTableLayer::ClearStatement() { if( poStmt != NULL ) { delete poStmt; poStmt = NULL; } } /************************************************************************/ /* GetStatement() */ /************************************************************************/ CPLODBCStatement *OGRWalkTableLayer::GetStatement() { if( poStmt == NULL ) ResetStatement(); return poStmt; } /************************************************************************/ /* ResetStatement() */ /************************************************************************/ OGRErr OGRWalkTableLayer::ResetStatement() { ClearStatement(); iNextShapeId = 0; poStmt = new CPLODBCStatement( poDS->GetSession() ); poStmt->Append( "SELECT * FROM " ); poStmt->Append( poFeatureDefn->GetName() ); poStmt->Append( "Features" ); /* Append attribute query if we have it */ if( (pszQuery != NULL) && strcmp(pszQuery, "") ) poStmt->Appendf( " WHERE %s", pszQuery ); CPLDebug( "Walk", "ExecuteSQL(%s)", poStmt->GetCommand() ); if( poStmt->ExecuteSQL() ) return OGRERR_NONE; else { delete poStmt; poStmt = NULL; return OGRERR_FAILURE; } } /************************************************************************/ /* ResetReading() */ /************************************************************************/ void OGRWalkTableLayer::ResetReading() { ClearStatement(); OGRWalkLayer::ResetReading(); } /************************************************************************/ /* GetFeature() */ /************************************************************************/ OGRFeature *OGRWalkTableLayer::GetFeature( long nFeatureId ) { if( pszFIDColumn == NULL ) return OGRWalkLayer::GetFeature( nFeatureId ); ClearStatement(); iNextShapeId = nFeatureId; poStmt = new CPLODBCStatement( poDS->GetSession() ); poStmt->Append( "SELECT * FROM " ); poStmt->Append( poFeatureDefn->GetName() ); poStmt->Append( "Features" ); poStmt->Appendf( " WHERE %s = %ld", pszFIDColumn, nFeatureId ); if( !poStmt->ExecuteSQL() ) { delete poStmt; poStmt = NULL; return NULL; } return GetNextRawFeature(); } /************************************************************************/ /* SetAttributeFilter() */ /************************************************************************/ OGRErr OGRWalkTableLayer::SetAttributeFilter( const char *pszQuery ) { CPLFree(m_pszAttrQueryString); m_pszAttrQueryString = (pszQuery) ? CPLStrdup(pszQuery) : NULL; if( (pszQuery == NULL && this->pszQuery == NULL) || (pszQuery != NULL && this->pszQuery != NULL && EQUAL(pszQuery,this->pszQuery)) ) return OGRERR_NONE; CPLFree( this->pszQuery ); this->pszQuery = (pszQuery != NULL ) ? CPLStrdup( pszQuery ) : NULL; ClearStatement(); return OGRERR_NONE; } /************************************************************************/ /* TestCapability() */ /************************************************************************/ int OGRWalkTableLayer::TestCapability( const char * pszCap ) { if( EQUAL(pszCap,OLCRandomRead) ) return TRUE; else return OGRWalkLayer::TestCapability( pszCap ); } /************************************************************************/ /* GetFeatureCount() */ /* */ /* If a spatial filter is in effect, we turn control over to */ /* the generic counter. Otherwise we return the total count. */ /* Eventually we should consider implementing a more efficient */ /* way of counting features matching a spatial query. */ /************************************************************************/ int OGRWalkTableLayer::GetFeatureCount( int bForce ) { if( m_poFilterGeom != NULL ) return OGRWalkLayer::GetFeatureCount( bForce ); CPLODBCStatement oStmt( poDS->GetSession() ); oStmt.Append( "SELECT COUNT(*) FROM " ); oStmt.Append( poFeatureDefn->GetName() ); oStmt.Append( "Features" ); if( (pszQuery != NULL) && strcmp(pszQuery, "") ) oStmt.Appendf( " WHERE %s", pszQuery ); if( !oStmt.ExecuteSQL() || !oStmt.Fetch() ) { CPLError( CE_Failure, CPLE_AppDefined, "GetFeatureCount() failed on query %s.\n%s", oStmt.GetCommand(), poDS->GetSession()->GetLastError() ); return OGRWalkLayer::GetFeatureCount(bForce); } return atoi(oStmt.GetColData(0)); } /************************************************************************/ /* GetExtent() */ /************************************************************************/ OGRErr OGRWalkTableLayer::GetExtent( OGREnvelope *psExtent, CPL_UNUSED int bForce ) { *psExtent = sExtent; return OGRERR_NONE; }