bool FGdbDataSource::OpenFGDBTables(const std::wstring &type, const std::vector<std::wstring> &layers) { fgdbError hr; for ( unsigned int i = 0; i < layers.size(); i++ ) { Table* pTable = new Table; //CPLDebug("FGDB", "Opening %s", WStringToString(layers[i]).c_str()); if (FAILED(hr = m_pGeodatabase->OpenTable(layers[i], *pTable))) { delete pTable; GDBErr(hr, "Error opening " + WStringToString(layers[i]), CE_Warning, ". Skipping it. " "Might be due to unsupported spatial reference system. Using OpenFileGDB driver should solve it"); continue; } FGdbLayer* pLayer = new FGdbLayer(); if (!pLayer->Initialize(this, pTable, layers[i], type)) { delete pLayer; return GDBErr(hr, "Error initializing OGRLayer for " + WStringToString(layers[i])); } m_layers.push_back(pLayer); } return true; }
bool FGdbDataSource::OpenFGDBTables(const std::wstring &type, const std::vector<std::wstring> &layers) { fgdbError hr; for ( unsigned int i = 0; i < layers.size(); i++ ) { Table* pTable = new Table; //CPLDebug("FGDB", "Opening %s", WStringToString(layers[i]).c_str()); if (FAILED(hr = m_pGeodatabase->OpenTable(layers[i], *pTable))) { delete pTable; GDBDebug(hr, "Error opening " + WStringToString(layers[i]) + ". Skipping it"); continue; } FGdbLayer* pLayer = new FGdbLayer; if (!pLayer->Initialize(this, pTable, layers[i], type)) { delete pLayer; return GDBErr(hr, "Error initializing OGRLayer for " + WStringToString(layers[i])); } m_layers.push_back(pLayer); } return true; }
OGRLayer * FGdbDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { FGdbLayer* pLayer = new FGdbLayer; if (!pLayer->Create(this, pszLayerName, poSRS, eType, papszOptions)) { delete pLayer; return NULL; } m_layers.push_back(pLayer); return pLayer; }
bool FGdbDataSource::OpenFGDBTables(const std::wstring &type, const std::vector<std::wstring> &layers) { fgdbError hr; for ( unsigned int i = 0; i < layers.size(); i++ ) { Table* pTable = new Table; //CPLDebug("FGDB", "Opening %s", WStringToString(layers[i]).c_str()); if (FAILED(hr = m_pGeodatabase->OpenTable(layers[i], *pTable))) { delete pTable; std::wstring fgdb_error_desc_w; fgdbError er; er = FileGDBAPI::ErrorInfo::GetErrorDescription(hr, fgdb_error_desc_w); const char* pszLikelyReason = "Might be due to unsupported spatial reference system. Using OpenFileGDB driver or FileGDB SDK >= 1.4 should solve it"; if ( er == S_OK ) { std::string fgdb_error_desc = WStringToString(fgdb_error_desc_w); if( fgdb_error_desc == "FileGDB compression is not installed." ) { pszLikelyReason = "Using FileGDB SDK 1.4 or later should solve this issue."; } } GDBErr(hr, "Error opening " + WStringToString(layers[i]), CE_Warning, (". Skipping it. " + CPLString(pszLikelyReason)).c_str()); continue; } FGdbLayer* pLayer = new FGdbLayer(); if (!pLayer->Initialize(this, pTable, layers[i], type)) { delete pLayer; return GDBErr(hr, "Error initializing OGRLayer for " + WStringToString(layers[i])); } m_layers.push_back(pLayer); } return true; }
OGRErr FGdbDataSource::DeleteLayer( int iLayer ) { if( !m_bUpdate ) return OGRERR_FAILURE; if( iLayer < 0 || iLayer >= static_cast<int>(m_layers.size()) ) return OGRERR_FAILURE; FGdbLayer* poBaseLayer = m_layers[iLayer]; // Fetch FGDBAPI Table before deleting OGR layer object //Table* pTable = poBaseLayer->GetTable(); std::string name = poBaseLayer->GetLayerDefn()->GetName(); std::wstring strPath = poBaseLayer->GetTablePath(); std::wstring strType = poBaseLayer->GetType(); // delete OGR layer delete m_layers[iLayer]; //pTable = NULL; // OGR Layer had ownership of FGDB Table m_layers.erase(m_layers.begin() + iLayer); long hr; if (FAILED(hr = m_pGeodatabase->Delete(strPath, strType))) { CPLError( CE_Warning, CPLE_AppDefined, "%s was not deleted however it has been closed", name.c_str()); GDBErr(hr, "Failed deleting dataset"); return OGRERR_FAILURE; } return OGRERR_NONE; }
OGRLayer * FGdbDataSource::ExecuteSQL( const char *pszSQLCommand, OGRGeometry *poSpatialFilter, const char *pszDialect ) { size_t count = m_layers.size(); for(size_t i = 0; i < count; ++i ) { m_layers[i]->EndBulkLoad(); } /* -------------------------------------------------------------------- */ /* Use generic implementation for recognized dialects */ /* -------------------------------------------------------------------- */ if( IsGenericSQLDialect(pszDialect) ) return OGRDataSource::ExecuteSQL( pszSQLCommand, poSpatialFilter, pszDialect ); /* -------------------------------------------------------------------- */ /* Special case GetLayerDefinition */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerDefinition ", strlen("GetLayerDefinition "))) { FGdbLayer* poLayer = (FGdbLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerDefinition ")); if (poLayer) { char* pszVal = NULL; poLayer->GetLayerXML(&pszVal); OGRLayer* poRet = new OGRFGdbSingleFeatureLayer( "LayerDefinition", pszVal ); CPLFree(pszVal); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLayerMetadata */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerMetadata ", strlen("GetLayerMetadata "))) { FGdbLayer* poLayer = (FGdbLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerMetadata ")); if (poLayer) { char* pszVal = NULL; poLayer->GetLayerMetadataXML(&pszVal); OGRLayer* poRet = new OGRFGdbSingleFeatureLayer( "LayerMetadata", pszVal ); CPLFree(pszVal); return poRet; } else return NULL; } /* TODO: remove that workaround when the SDK has finally a decent */ /* SQL support ! */ if( EQUALN(pszSQLCommand, "SELECT ", 7) && pszDialect == NULL ) { CPLDebug("FGDB", "Support for SELECT is known to be partially " "non-compliant with FileGDB SDK API v1.2.\n" "So for now, we use default OGR SQL engine. " "Explicitly specify -dialect FileGDB\n" "to use the SQL engine from the FileGDB SDK API"); return OGRDataSource::ExecuteSQL( pszSQLCommand, poSpatialFilter, pszDialect ); } /* -------------------------------------------------------------------- */ /* Run the SQL */ /* -------------------------------------------------------------------- */ EnumRows* pEnumRows = new EnumRows; long hr; try { hr = m_pGeodatabase->ExecuteSQL( StringToWString(pszSQLCommand), true, *pEnumRows); } catch(...) { CPLError(CE_Failure, CPLE_AppDefined, "Exception occured at executing '%s'. Application may become unstable", pszSQLCommand); delete pEnumRows; return NULL; } if (FAILED(hr)) { GDBErr(hr, CPLSPrintf("Failed at executing '%s'", pszSQLCommand)); delete pEnumRows; return NULL; } if( EQUALN(pszSQLCommand, "SELECT ", 7) ) { return new FGdbResultLayer(this, pszSQLCommand, pEnumRows); } else { delete pEnumRows; return NULL; } }
// Flattens out hierarchichal GDB structure bool FGdbDataSource::LoadLayersOld(const std::vector<wstring> & datasetTypes, const wstring & parent) { long hr = S_OK; // I didn't find an API to give me the type of the dataset based on name - I am *not* // parsing XML for something like this - in the meantime I can use this hack to see // if the dataset had any children whatsoever - if so, then I won't attempt to open it // otherwise, do attempt to do that bool childrenFound = false; bool errorsEncountered = false; for (size_t dsTypeIndex = 0; dsTypeIndex < datasetTypes.size(); dsTypeIndex++) { std::vector<wstring> childDatasets; m_pGeodatabase->GetChildDatasets( parent, datasetTypes[dsTypeIndex], childDatasets); if (childDatasets.size() > 0) { //it is a container of other datasets for (size_t childDatasetIndex = 0; childDatasetIndex < childDatasets.size(); childDatasetIndex++) { childrenFound = true; // do something with it // For now, we just ignore dataset containers and only open the children //std::wcout << datasetTypes[dsTypeIndex] << L" " << childDatasets[childDatasetIndex] << std::endl; if (!LoadLayersOld(datasetTypes, childDatasets[childDatasetIndex])) errorsEncountered = true; } } } //it is a full fledged dataset itself without children - open it (except the root) if ((!childrenFound) && parent != L"\\") { //wcout << "Opening " << parent << "..."; Table* pTable = new Table; if (FAILED(hr = m_pGeodatabase->OpenTable(parent,*pTable))) { delete pTable; return GDBErr(hr, "Error opening " + WStringToString(parent)); } FGdbLayer* pLayer = new FGdbLayer; //pLayer has ownership of the table pointer as soon Initialize is called if (!pLayer->Initialize(this, pTable, parent)) { delete pLayer; return GDBErr(hr, "Error initializing OGRLayer for " + WStringToString(parent)); } m_layers.push_back(pLayer); } return !errorsEncountered; }
OGRLayer * FGdbDataSource::ExecuteSQL( const char *pszSQLCommand, OGRGeometry *poSpatialFilter, const char *pszDialect ) { if ( pszDialect != NULL && EQUAL(pszDialect, "OGRSQL") ) return OGRDataSource::ExecuteSQL( pszSQLCommand, poSpatialFilter, pszDialect ); /* -------------------------------------------------------------------- */ /* Special case GetLayerDefinition */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerDefinition ", strlen("GetLayerDefinition "))) { FGdbLayer* poLayer = (FGdbLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerDefinition ")); if (poLayer) { char* pszVal = NULL; poLayer->GetLayerXML(&pszVal); OGRLayer* poRet = new OGRFGdbSingleFeatureLayer( "LayerDefinition", pszVal ); CPLFree(pszVal); return poRet; } else return NULL; } /* -------------------------------------------------------------------- */ /* Special case GetLayerMetadata */ /* -------------------------------------------------------------------- */ if (EQUALN(pszSQLCommand, "GetLayerMetadata ", strlen("GetLayerMetadata "))) { FGdbLayer* poLayer = (FGdbLayer*) GetLayerByName(pszSQLCommand + strlen("GetLayerMetadata ")); if (poLayer) { char* pszVal = NULL; poLayer->GetLayerMetadataXML(&pszVal); OGRLayer* poRet = new OGRFGdbSingleFeatureLayer( "LayerMetadata", pszVal ); CPLFree(pszVal); return poRet; } else return NULL; } /* TODO: remove that workaround when the SDK has finally a decent */ /* SQL support ! */ if( EQUALN(pszSQLCommand, "SELECT ", 7) && pszDialect == NULL ) { CPLDebug("FGDB", "Support for SELECT is known to be partially " "non-compliant with FileGDB SDK API v1.2.\n" "So for now, we use default OGR SQL engine. " "Explicitely specify -dialect FileGDB\n" "to use the SQL engine from the FileGDB SDK API"); return OGRDataSource::ExecuteSQL( pszSQLCommand, poSpatialFilter, pszDialect ); } /* -------------------------------------------------------------------- */ /* Run the SQL */ /* -------------------------------------------------------------------- */ EnumRows* pEnumRows = new EnumRows; long hr; if (FAILED(hr = m_pGeodatabase->ExecuteSQL( StringToWString(pszSQLCommand), true, *pEnumRows))) { GDBErr(hr, CPLSPrintf("Failed at executing '%s'", pszSQLCommand)); delete pEnumRows; return NULL; } if( EQUALN(pszSQLCommand, "SELECT ", 7) ) { return new FGdbResultLayer(this, pszSQLCommand, pEnumRows); } else { delete pEnumRows; return NULL; } }