📄 ogr_gensql.cpp
字号:
/****************************************************************************** * $Id: ogr_gensql.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRGenSQLResultsLayer. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2002, 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_p.h"#include "ogr_gensql.h"#include "cpl_string.h"CPL_CVSID("$Id: ogr_gensql.cpp 10646 2007-01-18 02:38:10Z warmerdam $");/************************************************************************//* OGRGenSQLResultsLayer() *//************************************************************************/OGRGenSQLResultsLayer::OGRGenSQLResultsLayer( OGRDataSource *poSrcDS, void *pSelectInfo, OGRGeometry *poSpatFilter ){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; this->poSrcDS = poSrcDS; this->pSelectInfo = pSelectInfo; poDefn = NULL; poSummaryFeature = NULL; panFIDIndex = NULL; nIndexSize = 0; nNextIndexFID = 0; nExtraDSCount = 0; papoExtraDS = NULL;/* -------------------------------------------------------------------- *//* Identify all the layers involved in the SELECT. *//* -------------------------------------------------------------------- */ int iTable; papoTableLayers = (OGRLayer **) CPLCalloc( sizeof(OGRLayer *), psSelectInfo->table_count ); for( iTable = 0; iTable < psSelectInfo->table_count; iTable++ ) { swq_table_def *psTableDef = psSelectInfo->table_defs + iTable; OGRDataSource *poTableDS = poSrcDS; if( psTableDef->data_source != NULL ) { OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar(); poTableDS = poReg->OpenShared( psTableDef->data_source, FALSE, NULL ); if( poTableDS == NULL ) { if( strlen(CPLGetLastErrorMsg()) == 0 ) CPLError( CE_Failure, CPLE_AppDefined, "Unable to open secondary datasource\n" "`%s' required by JOIN.", psTableDef->data_source ); return; } papoExtraDS = (OGRDataSource **) CPLRealloc( papoExtraDS, sizeof(void*) * ++nExtraDSCount ); papoExtraDS[nExtraDSCount-1] = poTableDS; } papoTableLayers[iTable] = poTableDS->GetLayerByName( psTableDef->table_name ); CPLAssert( papoTableLayers[iTable] != NULL ); if( papoTableLayers[iTable] == NULL ) return; } poSrcLayer = papoTableLayers[0];/* -------------------------------------------------------------------- *//* Now that we have poSrcLayer, we can install a spatial filter *//* if there is one. *//* -------------------------------------------------------------------- */ if( poSpatFilter != NULL ) SetSpatialFilter( poSpatFilter );/* -------------------------------------------------------------------- *//* Prepare a feature definition based on the query. *//* -------------------------------------------------------------------- */ OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn(); poDefn = new OGRFeatureDefn( psSelectInfo->table_defs[0].table_alias ); poDefn->Reference(); iFIDFieldIndex = poSrcDefn->GetFieldCount(); for( int iField = 0; iField < psSelectInfo->result_columns; iField++ ) { swq_col_def *psColDef = psSelectInfo->column_defs + iField; OGRFieldDefn oFDefn( psColDef->field_name, OFTInteger ); OGRFieldDefn *poSrcFDefn = NULL; OGRFeatureDefn *poLayerDefn = papoTableLayers[psColDef->table_index]->GetLayerDefn(); if( psColDef->field_index > -1 && psColDef->field_index < poLayerDefn->GetFieldCount() ) poSrcFDefn = poLayerDefn->GetFieldDefn(psColDef->field_index); if( psColDef->col_func_name != NULL ) { oFDefn.SetName( CPLSPrintf( "%s_%s",psColDef->col_func_name, psColDef->field_name) ); } if( psColDef->col_func == SWQCF_COUNT ) oFDefn.SetType( OFTInteger ); else if( poSrcFDefn != NULL ) { oFDefn.SetType( poSrcFDefn->GetType() ); oFDefn.SetWidth( poSrcFDefn->GetWidth() ); oFDefn.SetPrecision( poSrcFDefn->GetPrecision() ); } else if ( psColDef->field_index >= iFIDFieldIndex ) { switch ( SpecialFieldTypes[psColDef->field_index-iFIDFieldIndex] ) { case SWQ_INTEGER: oFDefn.SetType( OFTInteger ); break; case SWQ_FLOAT: oFDefn.SetType( OFTReal ); break; default: oFDefn.SetType( OFTString ); break; } } poDefn->AddFieldDefn( &oFDefn ); } poDefn->SetGeomType( poSrcLayer->GetLayerDefn()->GetGeomType() );/* -------------------------------------------------------------------- *//* If an ORDER BY is in effect, apply it now. *//* -------------------------------------------------------------------- */ if( psSelectInfo->order_specs > 0 && psSelectInfo->query_mode == SWQM_RECORDSET ) CreateOrderByIndex(); ResetReading();}/************************************************************************//* ~OGRGenSQLResultsLayer() *//************************************************************************/OGRGenSQLResultsLayer::~OGRGenSQLResultsLayer(){ if( m_nFeaturesRead > 0 && poDefn != NULL ) { CPLDebug( "GenSQL", "%d features read on layer '%s'.", (int) m_nFeaturesRead, poDefn->GetName() ); } ClearFilters();/* -------------------------------------------------------------------- *//* Free various datastructures. *//* -------------------------------------------------------------------- */ CPLFree( papoTableLayers ); papoTableLayers = NULL; if( panFIDIndex != NULL ) CPLFree( panFIDIndex ); if( poSummaryFeature ) delete poSummaryFeature; if( pSelectInfo != NULL ) swq_select_free( (swq_select *) pSelectInfo ); if( poDefn != NULL ) { poDefn->Release(); }/* -------------------------------------------------------------------- *//* Release any additional datasources being used in joins. *//* -------------------------------------------------------------------- */ OGRSFDriverRegistrar *poReg=OGRSFDriverRegistrar::GetRegistrar(); for( int iEDS = 0; iEDS < nExtraDSCount; iEDS++ ) poReg->ReleaseDataSource( papoExtraDS[iEDS] ); CPLFree( papoExtraDS );}/************************************************************************//* ClearFilters() *//* *//* Clear up all filters currently in place on the target layer, *//* and joined layers. We try not to leave them installed *//* except when actively fetching features. *//************************************************************************/void OGRGenSQLResultsLayer::ClearFilters(){/* -------------------------------------------------------------------- *//* Clear any filters installed on the target layer. *//* -------------------------------------------------------------------- */ if( poSrcLayer != NULL ) { poSrcLayer->SetAttributeFilter( "" ); poSrcLayer->SetSpatialFilter( NULL ); }/* -------------------------------------------------------------------- *//* Clear any attribute filter installed on the joined layers. *//* -------------------------------------------------------------------- */ swq_select *psSelectInfo = (swq_select *) pSelectInfo; int iJoin; if( psSelectInfo != NULL ) { for( iJoin = 0; iJoin < psSelectInfo->join_count; iJoin++ ) { swq_join_def *psJoinInfo = psSelectInfo->join_defs + iJoin; OGRLayer *poJoinLayer = papoTableLayers[psJoinInfo->secondary_table]; poJoinLayer->SetAttributeFilter( "" ); } }}/************************************************************************//* ResetReading() *//************************************************************************/void OGRGenSQLResultsLayer::ResetReading() { swq_select *psSelectInfo = (swq_select *) pSelectInfo; if( psSelectInfo->query_mode == SWQM_RECORDSET ) { poSrcLayer->SetAttributeFilter( psSelectInfo->whole_where_clause ); poSrcLayer->SetSpatialFilter( m_poFilterGeom ); poSrcLayer->ResetReading(); } nNextIndexFID = 0;}/************************************************************************//* SetNextByIndex() *//* *//* If we already have an FID list, we can easily resposition *//* ourselves in it. *//************************************************************************/OGRErr OGRGenSQLResultsLayer::SetNextByIndex( long nIndex ){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; if( psSelectInfo->query_mode == SWQM_SUMMARY_RECORD || psSelectInfo->query_mode == SWQM_DISTINCT_LIST || panFIDIndex != NULL ) { nNextIndexFID = nIndex; return OGRERR_NONE; } else { return poSrcLayer->SetNextByIndex( nIndex ); }}/************************************************************************//* GetExtent() *//************************************************************************/OGRErr OGRGenSQLResultsLayer::GetExtent( OGREnvelope *psExtent, int bForce ){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; if( psSelectInfo->query_mode == SWQM_RECORDSET ) return poSrcLayer->GetExtent( psExtent, bForce ); else return OGRERR_FAILURE;}/************************************************************************//* GetSpatialRef() *//************************************************************************/OGRSpatialReference *OGRGenSQLResultsLayer::GetSpatialRef() { swq_select *psSelectInfo = (swq_select *) pSelectInfo; if( psSelectInfo->query_mode != SWQM_RECORDSET ) return NULL; else return poSrcLayer->GetSpatialRef();}/************************************************************************//* GetFeatureCount() *//************************************************************************/int OGRGenSQLResultsLayer::GetFeatureCount( int bForce ){ swq_select *psSelectInfo = (swq_select *) pSelectInfo; if( psSelectInfo->query_mode != SWQM_RECORDSET ) return 1; else if( m_poAttrQuery == NULL ) return poSrcLayer->GetFeatureCount( bForce ); else return OGRLayer::GetFeatureCount( bForce );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -