OGRSQLiteSelectLayer::OGRSQLiteSelectLayer( OGRSQLiteDataSource *poDSIn, CPLString osSQLIn, sqlite3_stmt *hStmtIn, int bUseStatementForGetNextFeature, int bEmptyLayer, int bAllowMultipleGeomFieldsIn ) { poBehaviour = new OGRSQLiteSelectLayerCommonBehaviour(poDSIn, this, osSQLIn, bEmptyLayer); poDS = poDSIn; this->bAllowMultipleGeomFields = bAllowMultipleGeomFieldsIn; std::set<CPLString> aosEmpty; BuildFeatureDefn( "SELECT", hStmtIn, aosEmpty, aosEmpty ); SetDescription( "SELECT" ); if( bUseStatementForGetNextFeature ) { hStmt = hStmtIn; bDoStep = FALSE; // Try to extract SRS from first geometry for( int iField = 0; !bEmptyLayer && iField < poFeatureDefn->GetGeomFieldCount(); iField ++) { OGRSQLiteGeomFieldDefn* poGeomFieldDefn = poFeatureDefn->myGetGeomFieldDefn(iField); if( wkbFlatten(poGeomFieldDefn->GetType()) != wkbUnknown ) continue; int nBytes; if( sqlite3_column_type( hStmt, poGeomFieldDefn->iCol ) == SQLITE_BLOB && (nBytes = sqlite3_column_bytes( hStmt, poGeomFieldDefn->iCol )) > 39 ) { const GByte* pabyBlob = (const GByte*)sqlite3_column_blob( hStmt, poGeomFieldDefn->iCol ); int eByteOrder = pabyBlob[1]; if( pabyBlob[0] == 0x00 && (eByteOrder == wkbNDR || eByteOrder == wkbXDR) && pabyBlob[38] == 0x7C ) { int nSRSId; memcpy(&nSRSId, pabyBlob + 2, 4); #ifdef CPL_LSB if( eByteOrder != wkbNDR) CPL_SWAP32PTR(&nSRSId); #else if( eByteOrder == wkbNDR) CPL_SWAP32PTR(&nSRSId); #endif CPLPushErrorHandler(CPLQuietErrorHandler); OGRSpatialReference* poSRS = poDS->FetchSRS( nSRSId ); CPLPopErrorHandler(); if( poSRS != NULL ) { poGeomFieldDefn->nSRSId = nSRSId; poGeomFieldDefn->SetSpatialRef(poSRS); } else CPLErrorReset(); } #ifdef SQLITE_HAS_COLUMN_METADATA else if( iField == 0 ) { const char* pszTableName = sqlite3_column_table_name( hStmt, poGeomFieldDefn->iCol ); if( pszTableName != NULL ) { OGRSQLiteLayer* poLayer = (OGRSQLiteLayer*) poDS->GetLayerByName(pszTableName); if( poLayer != NULL && poLayer->GetLayerDefn()->GetGeomFieldCount() > 0) { OGRSQLiteGeomFieldDefn* poSrcGFldDefn = poLayer->myGetLayerDefn()->myGetGeomFieldDefn(0); poGeomFieldDefn->nSRSId = poSrcGFldDefn->nSRSId; poGeomFieldDefn->SetSpatialRef(poSrcGFldDefn->GetSpatialRef()); } } } #endif } } } else sqlite3_finalize( hStmtIn ); }
CPLErr OGRSQLiteViewLayer::EstablishFeatureDefn() { int rc; sqlite3 *hDB = poDS->GetDB(); sqlite3_stmt *hColStmt = NULL; const char *pszSQL; OGRSQLiteLayer* poUnderlyingLayer = GetUnderlyingLayer(); if (poUnderlyingLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find underlying layer %s for view %s", osUnderlyingTableName.c_str(), pszViewName); return CE_Failure; } if ( !poUnderlyingLayer->IsTableLayer() ) { CPLError(CE_Failure, CPLE_AppDefined, "Underlying layer %s for view %s is not a regular table", osUnderlyingTableName.c_str(), pszViewName); return CE_Failure; } int nUnderlyingLayerGeomFieldIndex = poUnderlyingLayer->GetLayerDefn()->GetGeomFieldIndex(osUnderlyingGeometryColumn); if ( nUnderlyingLayerGeomFieldIndex < 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "Underlying layer %s for view %s has not expected geometry column name %s", osUnderlyingTableName.c_str(), pszViewName, osUnderlyingGeometryColumn.c_str()); return CE_Failure; } this->bHasSpatialIndex = poUnderlyingLayer->HasSpatialIndex(nUnderlyingLayerGeomFieldIndex); /* -------------------------------------------------------------------- */ /* Get the column definitions for this table. */ /* -------------------------------------------------------------------- */ hColStmt = NULL; pszSQL = CPLSPrintf( "SELECT \"%s\", * FROM '%s' LIMIT 1", OGRSQLiteEscapeName(pszFIDColumn).c_str(), pszEscapedTableName ); rc = sqlite3_prepare( hDB, pszSQL, strlen(pszSQL), &hColStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to query table %s for column definitions : %s.", pszViewName, sqlite3_errmsg(hDB) ); return CE_Failure; } rc = sqlite3_step( hColStmt ); if ( rc != SQLITE_DONE && rc != SQLITE_ROW ) { CPLError( CE_Failure, CPLE_AppDefined, "In Initialize(): sqlite3_step(%s):\n %s", pszSQL, sqlite3_errmsg(hDB) ); sqlite3_finalize( hColStmt ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Collect the rest of the fields. */ /* -------------------------------------------------------------------- */ std::set<CPLString> aosGeomCols; std::set<CPLString> aosIgnoredCols; aosGeomCols.insert(osGeomColumn); BuildFeatureDefn( pszViewName, hColStmt, aosGeomCols, aosIgnoredCols ); sqlite3_finalize( hColStmt ); /* -------------------------------------------------------------------- */ /* Set the properties of the geometry column. */ /* -------------------------------------------------------------------- */ if( poFeatureDefn->GetGeomFieldCount() != 0 ) { OGRSQLiteGeomFieldDefn* poSrcGeomFieldDefn = poUnderlyingLayer->myGetLayerDefn()->myGetGeomFieldDefn(nUnderlyingLayerGeomFieldIndex); OGRSQLiteGeomFieldDefn* poGeomFieldDefn = poFeatureDefn->myGetGeomFieldDefn(0); poGeomFieldDefn->SetType(poSrcGeomFieldDefn->GetType()); poGeomFieldDefn->SetSpatialRef(poSrcGeomFieldDefn->GetSpatialRef()); poGeomFieldDefn->nSRSId = poSrcGeomFieldDefn->nSRSId; if( eGeomFormat != OSGF_None ) poGeomFieldDefn->eGeomFormat = eGeomFormat; } return CE_None; }