int OGRNASDataSource::Open( const char * pszNewName ) { poReader = CreateNASReader(); if( poReader == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be NAS but the NAS reader cannot\n" "be instantiated, likely because Xerces support was not\n" "configured in.", pszNewName ); return FALSE; } poReader->SetSourceFile( pszNewName ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Can we find a NAS Feature Schema (.gfs) for the input file? */ /* -------------------------------------------------------------------- */ bool bHaveSchema = false; const char *pszGFSFilename = CPLResetExtension( pszNewName, "gfs" ); VSIStatBuf sGFSStatBuf; if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 ) { VSIStatBuf sNASStatBuf; if( CPLStat( pszNewName, &sNASStatBuf ) == 0 && sNASStatBuf.st_mtime > sGFSStatBuf.st_mtime ) { CPLDebug( "NAS", "Found %s but ignoring because it appears\n" "be older than the associated NAS file.", pszGFSFilename ); } else { bHaveSchema = poReader->LoadClasses( pszGFSFilename ); } } /* -------------------------------------------------------------------- */ /* Force a first pass to establish the schema. Eventually we */ /* will have mechanisms for remembering the schema and related */ /* information. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); if( !bHaveSchema && !poReader->PrescanForSchema( TRUE ) && CPLGetLastErrorType() == CE_Failure ) { // Assume an error has been reported. return FALSE; } /* -------------------------------------------------------------------- */ /* Save the schema file if possible. Do not make a fuss if we */ /* cannot. It could be read-only directory or something. */ /* -------------------------------------------------------------------- */ if( !bHaveSchema && poReader->GetClassCount() > 0 ) { FILE *fp = NULL; pszGFSFilename = CPLResetExtension( pszNewName, "gfs" ); if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0 && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL ) { VSIFClose( fp ); poReader->SaveClasses( pszGFSFilename ); } else { CPLDebug( "NAS", "Not saving %s files already exists or can't be created.", pszGFSFilename ); } } /* -------------------------------------------------------------------- */ /* Translate the NASFeatureClasses into layers. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRLayer **) CPLCalloc( sizeof(OGRNASLayer *), poReader->GetClassCount()+1 ); nLayers = 0; while( nLayers < poReader->GetClassCount() ) { papoLayers[nLayers] = TranslateNASSchema(poReader->GetClass(nLayers)); nLayers++; } poRelationLayer = new OGRNASRelationLayer( this ); // keep delete the last layer if( nLayers>0 && EQUAL( papoLayers[nLayers-1]->GetName(), "Delete" ) ) { papoLayers[nLayers] = papoLayers[nLayers-1]; papoLayers[nLayers-1] = poRelationLayer; } else { papoLayers[nLayers] = poRelationLayer; } nLayers++; return TRUE; }
int OGRNASDataSource::Open( const char * pszNewName, int bTestOpen ) { FILE *fp; char szHeader[8192]; /* -------------------------------------------------------------------- */ /* Open the source file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpen( pszNewName, "r" ); if( fp == NULL ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open NAS file `%s'.", pszNewName ); return FALSE; } /* -------------------------------------------------------------------- */ /* If we aren't sure it is NAS, load a header chunk and check */ /* for signs it is NAS */ /* -------------------------------------------------------------------- */ if( bTestOpen ) { size_t nRead = VSIFRead( szHeader, 1, sizeof(szHeader), fp ); if (nRead <= 0) { VSIFClose( fp ); return FALSE; } szHeader[MIN(nRead, sizeof(szHeader))-1] = '\0'; /* -------------------------------------------------------------------- */ /* Check for a UTF-8 BOM and skip if found */ /* */ /* TODO: BOM is variable-lenght parameter and depends on encoding. */ /* Add BOM detection for other encodings. */ /* -------------------------------------------------------------------- */ // Used to skip to actual beginning of XML data char* szPtr = szHeader; if( ( (unsigned char)szHeader[0] == 0xEF ) && ( (unsigned char)szHeader[1] == 0xBB ) && ( (unsigned char)szHeader[2] == 0xBF) ) { szPtr += 3; } /* -------------------------------------------------------------------- */ /* Here, we expect the opening chevrons of NAS tree root element */ /* -------------------------------------------------------------------- */ if( szPtr[0] != '<' || strstr(szPtr,"opengis.net/gml") == NULL || strstr(szPtr,"NAS-Operationen.xsd") == NULL ) { VSIFClose( fp ); return FALSE; } } /* -------------------------------------------------------------------- */ /* We assume now that it is NAS. Close and instantiate a */ /* NASReader on it. */ /* -------------------------------------------------------------------- */ VSIFClose( fp ); poReader = CreateNASReader(); if( poReader == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be NAS but the NAS reader can't\n" "be instantiated, likely because Xerces support wasn't\n" "configured in.", pszNewName ); return FALSE; } poReader->SetSourceFile( pszNewName ); pszName = CPLStrdup( pszNewName ); /* -------------------------------------------------------------------- */ /* Can we find a NAS Feature Schema (.gfs) for the input file? */ /* -------------------------------------------------------------------- */ const char *pszGFSFilename; VSIStatBuf sGFSStatBuf, sNASStatBuf; int bHaveSchema = FALSE; pszGFSFilename = CPLResetExtension( pszNewName, "gfs" ); if( CPLStat( pszGFSFilename, &sGFSStatBuf ) == 0 ) { CPLStat( pszNewName, &sNASStatBuf ); if( sNASStatBuf.st_mtime > sGFSStatBuf.st_mtime ) { CPLDebug( "NAS", "Found %s but ignoring because it appears\n" "be older than the associated NAS file.", pszGFSFilename ); } else { bHaveSchema = poReader->LoadClasses( pszGFSFilename ); } } /* -------------------------------------------------------------------- */ /* Force a first pass to establish the schema. Eventually we */ /* will have mechanisms for remembering the schema and related */ /* information. */ /* -------------------------------------------------------------------- */ if( !bHaveSchema && !poReader->PrescanForSchema( TRUE ) ) { // we assume an errors have been reported. return FALSE; } /* -------------------------------------------------------------------- */ /* Save the schema file if possible. Don't make a fuss if we */ /* can't ... could be read-only directory or something. */ /* -------------------------------------------------------------------- */ if( !bHaveSchema ) { FILE *fp = NULL; pszGFSFilename = CPLResetExtension( pszNewName, "gfs" ); if( CPLStat( pszGFSFilename, &sGFSStatBuf ) != 0 && (fp = VSIFOpen( pszGFSFilename, "wt" )) != NULL ) { VSIFClose( fp ); poReader->SaveClasses( pszGFSFilename ); } else { CPLDebug("NAS", "Not saving %s files already exists or can't be created.", pszGFSFilename ); } } /* -------------------------------------------------------------------- */ /* Translate the NASFeatureClasses into layers. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRLayer **) CPLCalloc( sizeof(OGRNASLayer *), poReader->GetClassCount()+1 ); nLayers = 0; while( nLayers < poReader->GetClassCount() ) { papoLayers[nLayers] = TranslateNASSchema(poReader->GetClass(nLayers)); nLayers++; } poRelationLayer = new OGRNASRelationLayer( this ); papoLayers[nLayers++] = poRelationLayer; return TRUE; }