?? ogrvrtlayer.cpp
字號:
/****************************************************************************** * $Id: ogrvrtlayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project: OpenGIS Simple Features Reference Implementation * Purpose: Implements OGRVRTLayer class. * Author: Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2003, 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 "cpl_conv.h"#include "ogr_vrt.h"#include "cpl_string.h"#include <string>CPL_CVSID("$Id: ogrvrtlayer.cpp 10646 2007-01-18 02:38:10Z warmerdam $");typedef struct { OGRwkbGeometryType eType; const char *pszName;} OGRGeomTypeName;static OGRGeomTypeName asGeomTypeNames[] = { /* 25D versions are implicit */ { wkbUnknown, "wkbUnknown" }, { wkbPoint, "wkbPoint" }, { wkbLineString, "wkbLineString" }, { wkbPolygon, "wkbPolygon" }, { wkbMultiPoint, "wkbMultiPoint" }, { wkbMultiLineString, "wkbLineString" }, { wkbMultiPolygon, "wkbPolygon" }, { wkbGeometryCollection, "wkbGeometryCollection" }, { wkbNone, "wkbNone" }, { wkbLinearRing, "wkbLinearRing" }, { wkbNone, NULL }};/************************************************************************//* OGRVRTLayer() *//************************************************************************/OGRVRTLayer::OGRVRTLayer(){ poFeatureDefn = NULL; poSrcLayer = NULL; poSRS = NULL; bUseSpatialSubquery = FALSE; iFIDField = -1; eGeometryType = VGS_Direct; iGeomField = iGeomXField = iGeomYField = iGeomZField = -1; pszAttrFilter = NULL; panSrcField = NULL; pabDirectCopy = NULL; bNeedReset = TRUE; bSrcLayerFromSQL = FALSE; bSrcClip = FALSE; poSrcRegion = NULL;}/************************************************************************//* ~OGRVRTLayer() *//************************************************************************/OGRVRTLayer::~OGRVRTLayer(){ if( m_nFeaturesRead > 0 && poFeatureDefn != NULL ) { CPLDebug( "VRT", "%d features read on layer '%s'.", (int) m_nFeaturesRead, poFeatureDefn->GetName() ); } if( poSRS != NULL ) poSRS->Release(); if( poSrcDS != NULL ) { if( bSrcLayerFromSQL && poSrcLayer ) poSrcDS->ReleaseResultSet( poSrcLayer ); OGRSFDriverRegistrar::GetRegistrar()->ReleaseDataSource( poSrcDS ); } if( poFeatureDefn ) poFeatureDefn->Release(); CPLFree( panSrcField ); CPLFree( pabDirectCopy ); CPLFree( pszAttrFilter ); if( poSrcRegion != NULL ) delete poSrcRegion;}/************************************************************************//* Initialize() *//************************************************************************/int OGRVRTLayer::Initialize( CPLXMLNode *psLTree, const char *pszVRTDirectory ){ if( !EQUAL(psLTree->pszValue,"OGRVRTLayer") ) return FALSE;/* -------------------------------------------------------------------- *//* Get layer name. *//* -------------------------------------------------------------------- */ const char *pszLayerName = CPLGetXMLValue( psLTree, "name", NULL ); if( pszLayerName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing name attribute on OGRVRTLayer" ); return FALSE; } poFeatureDefn = new OGRFeatureDefn( pszLayerName ); poFeatureDefn->Reference();/* -------------------------------------------------------------------- *//* Figure out the data source name. It may be treated relative *//* to vrt filename, but normally it is used directly. *//* -------------------------------------------------------------------- */ OGRSFDriverRegistrar *poReg = OGRSFDriverRegistrar::GetRegistrar(); char *pszSrcDSName = (char *) CPLGetXMLValue(psLTree,"SrcDataSource",NULL); if( pszSrcDSName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing SrcDataSource for layer %s.", pszLayerName ); return FALSE; } if( atoi(CPLGetXMLValue( psLTree, "SrcDataSource.relativetoVRT", "0")) ) { pszSrcDSName = CPLStrdup( CPLProjectRelativeFilename( pszVRTDirectory, pszSrcDSName ) ); } else { pszSrcDSName = CPLStrdup(pszSrcDSName); }/* -------------------------------------------------------------------- *//* Try to access the datasource. *//* -------------------------------------------------------------------- */ CPLErrorReset(); poSrcDS = poReg->OpenShared( pszSrcDSName, FALSE, NULL ); if( poSrcDS == NULL ) { if( strlen(CPLGetLastErrorMsg()) == 0 ) CPLError( CE_Failure, CPLE_AppDefined, "Failed to open datasource `%s'.", pszSrcDSName ); CPLFree( pszSrcDSName ); return FALSE; }/* -------------------------------------------------------------------- *//* Is this layer derived from an SQL query result? *//* -------------------------------------------------------------------- */ const char *pszSQL = CPLGetXMLValue( psLTree, "SrcSQL", NULL ); if( pszSQL != NULL ) { poSrcLayer = poSrcDS->ExecuteSQL( pszSQL, NULL, NULL ); if( poSrcLayer == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "SQL statement failed, or returned no layer result:\n%s", pszSQL ); return FALSE; } bSrcLayerFromSQL = TRUE; }/* -------------------------------------------------------------------- *//* Fetch the layer if it is a regular layer. *//* -------------------------------------------------------------------- */ if( poSrcLayer == NULL ) { const char *pszSrcLayerName = CPLGetXMLValue( psLTree, "SrcLayer", pszLayerName ); poSrcLayer = poSrcDS->GetLayerByName( pszSrcLayerName ); if( poSrcLayer == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find layer '%s' on datasource '%s'.", pszSrcLayerName, pszSrcDSName ); CPLFree( pszSrcDSName ); return FALSE; } } CPLFree( pszSrcDSName );/* -------------------------------------------------------------------- *//* Do we have a fixed geometry type? If so use it, otherwise *//* derive from the source layer. *//* -------------------------------------------------------------------- */ const char *pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL ); if( pszGType != NULL ) { int iType; for( iType = 0; asGeomTypeNames[iType].pszName != NULL; iType++ ) { if( EQUALN(pszGType, asGeomTypeNames[iType].pszName, strlen(asGeomTypeNames[iType].pszName)) ) { poFeatureDefn->SetGeomType( asGeomTypeNames[iType].eType ); if( strstr(pszGType,"25D") != NULL ) poFeatureDefn->SetGeomType( (OGRwkbGeometryType) (poFeatureDefn->GetGeomType() | wkb25DBit) ); break; } } if( asGeomTypeNames[iType].pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GeometryType %s not recognised.", pszGType ); return FALSE; } } else { poFeatureDefn->SetGeomType(poSrcLayer->GetLayerDefn()->GetGeomType()); } /* -------------------------------------------------------------------- *//* For now we copy the schema directly from the source layer. *//* -------------------------------------------------------------------- */ int iField; OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn(); panSrcField = (int *) CPLMalloc(sizeof(int) * poSrcDefn->GetFieldCount()); pabDirectCopy = (int *) CPLMalloc(sizeof(int)*poSrcDefn->GetFieldCount()); for( iField = 0; iField < poSrcDefn->GetFieldCount(); iField++ ) { poFeatureDefn->AddFieldDefn( poSrcDefn->GetFieldDefn( iField ) ); panSrcField[iField] = iField; pabDirectCopy[iField] = TRUE; } /* -------------------------------------------------------------------- *//* Apply a spatial reference system if provided, otherwise copy *//* from source. *//* -------------------------------------------------------------------- */ const char *pszLayerSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL ); if( pszLayerSRS != NULL ) { if( EQUAL(pszLayerSRS,"NULL") ) poSRS = NULL; else { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to import LayerSRS `%s'.", pszLayerSRS ); return FALSE; } poSRS = oSRS.Clone(); } } else { if( poSrcLayer->GetSpatialRef() != NULL ) poSRS = poSrcLayer->GetSpatialRef()->Clone(); else poSRS = NULL; }/* -------------------------------------------------------------------- *//* Handle GeometryField. *//* -------------------------------------------------------------------- */ const char *pszEncoding; pszEncoding = CPLGetXMLValue( psLTree,"GeometryField.encoding", "direct"); if( EQUAL(pszEncoding,"Direct") ) eGeometryType = VGS_Direct; else if( EQUAL(pszEncoding,"None") ) eGeometryType = VGS_None; else if( EQUAL(pszEncoding,"WKT") ) eGeometryType = VGS_WKT; else if( EQUAL(pszEncoding,"WKB") ) eGeometryType = VGS_WKB; else if( EQUAL(pszEncoding,"Shape") ) eGeometryType = VGS_Shape; else if( EQUAL(pszEncoding,"PointFromColumns") ) { eGeometryType = VGS_PointFromColumns; bUseSpatialSubquery = CSLTestBoolean( CPLGetXMLValue(psLTree, "GeometryField.useSpatialSubquery", "TRUE")); iGeomXField = poSrcLayer->GetLayerDefn()->GetFieldIndex( CPLGetXMLValue( psLTree, "GeometryField.x", "missing" ) ); iGeomYField = poSrcLayer->GetLayerDefn()->GetFieldIndex( CPLGetXMLValue( psLTree, "GeometryField.y", "missing" ) ); iGeomZField = poSrcLayer->GetLayerDefn()->GetFieldIndex( CPLGetXMLValue( psLTree, "GeometryField.z", "missing" ) ); if( iGeomXField == -1 || iGeomYField == -1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify source X or Y field for PointFromColumns encoding." ); return FALSE; } } else { CPLError( CE_Failure, CPLE_AppDefined, "encoding=\"%s\" not recognised.", pszEncoding ); return FALSE; } if( eGeometryType == VGS_WKT || eGeometryType == VGS_WKB || eGeometryType == VGS_Shape ) { const char *pszFieldName = CPLGetXMLValue( psLTree, "GeometryField.field", "missing" ); iGeomField = poSrcLayer->GetLayerDefn()->GetFieldIndex(pszFieldName); if( iGeomField == -1 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to identify source field '%s' for geometry.", pszFieldName ); return FALSE; } } /* -------------------------------------------------------------------- *//* Figure out what should be used as an FID. */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -