static int CountOGRVRTLayers(CPLXMLNode *psTree) { if( psTree->eType != CXT_Element ) return 0; int nCount = 0; if( EQUAL(psTree->pszValue, "OGRVRTLayer") ) nCount ++; CPLXMLNode* psNode; for( psNode=psTree->psChild; psNode != NULL; psNode=psNode->psNext ) { nCount += CountOGRVRTLayers(psNode); } return nCount; }
int OGRVRTDataSource::Initialize( CPLXMLNode *psTree, const char *pszNewName, int bUpdate ) { CPLAssert( nLayers == 0 ); this->psTree = psTree; /* -------------------------------------------------------------------- */ /* Set name, and capture the directory path so we can use it */ /* for relative datasources. */ /* -------------------------------------------------------------------- */ CPLString osVRTDirectory = CPLGetPath( pszNewName ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Look for the OGRVRTDataSource node, it might be after an */ /* <xml> node. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psVRTDSXML = CPLGetXMLNode( psTree, "=OGRVRTDataSource" ); if( psVRTDSXML == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Did not find the <OGRVRTDataSource> node in the root of the document,\n" "this is not really an OGR VRT." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Determine if we must proxy layers. */ /* -------------------------------------------------------------------- */ int nOGRVRTLayerCount = CountOGRVRTLayers(psVRTDSXML); int nMaxSimultaneouslyOpened = atoi(CPLGetConfigOption("OGR_VRT_MAX_OPENED", "100")); if( nMaxSimultaneouslyOpened < 1 ) nMaxSimultaneouslyOpened = 1; if( nOGRVRTLayerCount > nMaxSimultaneouslyOpened ) poLayerPool = new OGRLayerPool(nMaxSimultaneouslyOpened); /* -------------------------------------------------------------------- */ /* Look for layers. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psLTree; for( psLTree=psVRTDSXML->psChild; psLTree != NULL; psLTree=psLTree->psNext ) { if( psLTree->eType != CXT_Element ) continue; /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRLayer *poLayer = InstanciateLayer(psLTree, osVRTDirectory, bUpdate); if( poLayer == NULL ) continue; /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRLayer **) CPLRealloc( papoLayers, sizeof(OGRLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; } return TRUE; }
bool OGRVRTDataSource::Initialize( CPLXMLNode *psTreeIn, const char *pszNewName, int bUpdate ) { CPLAssert(nLayers == 0); AddForbiddenNames(pszNewName); psTree = psTreeIn; // Set name, and capture the directory path so we can use it // for relative datasources. CPLString osVRTDirectory = CPLGetPath(pszNewName); pszName = CPLStrdup(pszNewName); // Look for the OGRVRTDataSource node, it might be after an <xml> node. CPLXMLNode *psVRTDSXML = CPLGetXMLNode(psTree, "=OGRVRTDataSource"); if( psVRTDSXML == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Did not find the <OGRVRTDataSource> node in the root of the " "document, this is not really an OGR VRT."); return false; } // Determine if we must proxy layers. const int nOGRVRTLayerCount = CountOGRVRTLayers(psVRTDSXML); const int nMaxSimultaneouslyOpened = std::max(atoi(CPLGetConfigOption("OGR_VRT_MAX_OPENED", "100")), 1); if( nOGRVRTLayerCount > nMaxSimultaneouslyOpened ) poLayerPool = new OGRLayerPool(nMaxSimultaneouslyOpened); // Apply any dataset level metadata. oMDMD.XMLInit(psVRTDSXML, TRUE); // Look for layers. for( CPLXMLNode *psLTree = psVRTDSXML->psChild; psLTree != nullptr; psLTree = psLTree->psNext ) { if( psLTree->eType != CXT_Element ) continue; // Create the layer object. OGRLayer *poLayer = InstantiateLayer(psLTree, osVRTDirectory, bUpdate); if( poLayer == nullptr ) continue; // Add layer to data source layer list. nLayers++; papoLayers = static_cast<OGRLayer **>( CPLRealloc(papoLayers, sizeof(OGRLayer *) * nLayers)); papoLayers[nLayers - 1] = poLayer; paeLayerType = static_cast<OGRLayerType *>( CPLRealloc(paeLayerType, sizeof(int) * nLayers)); if( poLayerPool != nullptr && EQUAL(psLTree->pszValue, "OGRVRTLayer") ) { paeLayerType[nLayers - 1] = OGR_VRT_PROXIED_LAYER; } else if( EQUAL(psLTree->pszValue, "OGRVRTLayer") ) { paeLayerType[nLayers - 1] = OGR_VRT_LAYER; } else { paeLayerType[nLayers - 1] = OGR_VRT_OTHER_LAYER; } } return true; }