?? ogrfeaturequery.cpp
字號:
/******************************************************************************
* $Id: ogrfeaturequery.cpp 11207 2007-04-04 17:02:36Z warmerdam $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Implementation of simple SQL WHERE style attributes queries
* for OGRFeatures.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 2001, Frank Warmerdam <warmerdam@pobox.com>
*
* 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 <assert.h>
#include "ogr_feature.h"
#include "ogr_p.h"
#include "ogr_attrind.h"
CPL_CVSID("$Id: ogrfeaturequery.cpp 11207 2007-04-04 17:02:36Z warmerdam $");
/************************************************************************/
/* Support for special attributes (feature query and selection) */
/************************************************************************/
char* SpecialFieldNames[SPECIAL_FIELD_COUNT]
= {"FID", "OGR_GEOMETRY", "OGR_STYLE", "OGR_GEOM_WKT"};
swq_field_type SpecialFieldTypes[SPECIAL_FIELD_COUNT]
= {SWQ_INTEGER, SWQ_STRING, SWQ_STRING, SWQ_STRING};
/************************************************************************/
/* OGRFeatureQuery() */
/************************************************************************/
OGRFeatureQuery::OGRFeatureQuery()
{
poTargetDefn = NULL;
pSWQExpr = NULL;
}
/************************************************************************/
/* ~OGRFeatureQuery() */
/************************************************************************/
OGRFeatureQuery::~OGRFeatureQuery()
{
if( pSWQExpr != NULL )
swq_expr_free( (swq_expr *) pSWQExpr );
}
/************************************************************************/
/* Parse */
/************************************************************************/
OGRErr OGRFeatureQuery::Compile( OGRFeatureDefn *poDefn,
const char * pszExpression )
{
/* -------------------------------------------------------------------- */
/* Clear any existing expression. */
/* -------------------------------------------------------------------- */
if( pSWQExpr != NULL )
swq_expr_free( (swq_expr *) pSWQExpr );
/* -------------------------------------------------------------------- */
/* Build list of fields. */
/* -------------------------------------------------------------------- */
char **papszFieldNames;
swq_field_type *paeFieldTypes;
int iField;
int nFieldCount = poDefn->GetFieldCount() + SPECIAL_FIELD_COUNT;
papszFieldNames = (char **)
CPLMalloc(sizeof(char *) * nFieldCount );
paeFieldTypes = (swq_field_type *)
CPLMalloc(sizeof(swq_field_type) * nFieldCount );
for( iField = 0; iField < poDefn->GetFieldCount(); iField++ )
{
OGRFieldDefn *poField = poDefn->GetFieldDefn( iField );
papszFieldNames[iField] = (char *) poField->GetNameRef();
switch( poField->GetType() )
{
case OFTInteger:
paeFieldTypes[iField] = SWQ_INTEGER;
break;
case OFTReal:
paeFieldTypes[iField] = SWQ_FLOAT;
break;
case OFTString:
paeFieldTypes[iField] = SWQ_STRING;
break;
default:
paeFieldTypes[iField] = SWQ_OTHER;
break;
}
}
iField = 0;
while (iField < SPECIAL_FIELD_COUNT)
{
papszFieldNames[poDefn->GetFieldCount() + iField] = SpecialFieldNames[iField];
paeFieldTypes[poDefn->GetFieldCount() + iField] = SpecialFieldTypes[iField];
++iField;
}
/* -------------------------------------------------------------------- */
/* Try to parse. */
/* -------------------------------------------------------------------- */
const char *pszError;
OGRErr eErr = OGRERR_NONE;
poTargetDefn = poDefn;
pszError = swq_expr_compile( pszExpression, nFieldCount,
papszFieldNames, paeFieldTypes,
(swq_expr **) &pSWQExpr );
if( pszError != NULL )
{
CPLError( CE_Failure, CPLE_AppDefined,
"%s", pszError );
eErr = OGRERR_CORRUPT_DATA;
pSWQExpr = NULL;
}
CPLFree( papszFieldNames );
CPLFree( paeFieldTypes );
return eErr;
}
/************************************************************************/
/* OGRFeatureQueryEvaluator() */
/************************************************************************/
static int OGRFeatureQueryEvaluator( swq_field_op *op, OGRFeature *poFeature )
{
OGRField sField;
OGRField *psField;
int iSpecialField = op->field_index - poFeature->GetDefnRef()->GetFieldCount();
if( iSpecialField >= 0 )
{
if ( iSpecialField < SPECIAL_FIELD_COUNT )
{
switch ( SpecialFieldTypes[iSpecialField] )
{
case SWQ_INTEGER:
sField.Integer = poFeature->GetFieldAsInteger(op->field_index);
break;
case SWQ_STRING:
sField.String = (char*)
poFeature->GetFieldAsString( op->field_index );
break;
}
}
else
{
CPLDebug( "OGRFeatureQuery", "Illegal special field index.");
return FALSE;
}
psField = &sField;
}
else
psField = poFeature->GetRawFieldRef( op->field_index );
switch( op->field_type )
{
case SWQ_INTEGER:
switch( op->operation )
{
case SWQ_EQ:
return psField->Integer == op->int_value;
case SWQ_NE:
return psField->Integer != op->int_value;
case SWQ_LT:
return psField->Integer < op->int_value;
case SWQ_GT:
return psField->Integer > op->int_value;
case SWQ_LE:
return psField->Integer <= op->int_value;
case SWQ_GE:
return psField->Integer >= op->int_value;
case SWQ_ISNULL:
return !poFeature->IsFieldSet( op->field_index );
case SWQ_IN:
{
const char *pszSrc;
pszSrc = op->string_value;
while( *pszSrc != '\0' )
{
if( atoi(pszSrc) == psField->Integer )
return TRUE;
pszSrc += strlen(pszSrc) + 1;
}
return FALSE;
}
default:
CPLDebug( "OGRFeatureQuery",
"Illegal operation (%d) on integer field.",
op->operation );
return FALSE;
}
case SWQ_FLOAT:
switch( op->operation )
{
case SWQ_EQ:
return psField->Real == op->float_value;
case SWQ_NE:
return psField->Real != op->float_value;
case SWQ_LT:
return psField->Real < op->float_value;
case SWQ_GT:
return psField->Real > op->float_value;
case SWQ_LE:
return psField->Real <= op->float_value;
case SWQ_GE:
return psField->Real >= op->float_value;
case SWQ_ISNULL:
return !poFeature->IsFieldSet( op->field_index );
case SWQ_IN:
{
const char *pszSrc;
pszSrc = op->string_value;
while( *pszSrc != '\0' )
{
if( atof(pszSrc) == psField->Real )
return TRUE;
pszSrc += strlen(pszSrc) + 1;
}
return FALSE;
}
default:
CPLDebug( "OGRFeatureQuery",
"Illegal operation (%d) on float field.",
op->operation );
return FALSE;
}
case SWQ_STRING:
switch( op->operation )
{
case SWQ_EQ:
if (psField->Set.nMarker1 == OGRUnsetMarker
&& psField->Set.nMarker2 == OGRUnsetMarker )
{
return (op->string_value[0] == '\0');
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -