OGRErr OGRGeoconceptDriver::DeleteDataSource( const char *pszDataSource ) { int iExt; VSIStatBuf sStatBuf; static const char *apszExtensions[] = { "gxt", "txt", "gct", "gcm", "gcr", NULL }; if( VSIStat( pszDataSource, &sStatBuf ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "%s does not appear to be a file or directory.", pszDataSource ); return OGRERR_FAILURE; } if( VSI_ISREG(sStatBuf.st_mode) && ( EQUAL(CPLGetExtension(pszDataSource),"gxt") || EQUAL(CPLGetExtension(pszDataSource),"txt") ) ) { for( iExt=0; apszExtensions[iExt] != NULL; iExt++ ) { const char *pszFile = CPLResetExtension(pszDataSource, apszExtensions[iExt] ); if( VSIStat( pszFile, &sStatBuf ) == 0 ) VSIUnlink( pszFile ); } } else if( VSI_ISDIR(sStatBuf.st_mode) ) { char **papszDirEntries = CPLReadDir( pszDataSource ); int iFile; for( iFile = 0; papszDirEntries != NULL && papszDirEntries[iFile] != NULL; iFile++ ) { if( CSLFindString( (char **) apszExtensions, CPLGetExtension(papszDirEntries[iFile])) != -1) { VSIUnlink( CPLFormFilename( pszDataSource, papszDirEntries[iFile], NULL ) ); } } CSLDestroy( papszDirEntries ); VSIRmdir( pszDataSource ); } return OGRERR_NONE; }
OGRErr OGRMILayerAttrIndex::Initialize( const char *pszIndexPathIn, OGRLayer *poLayerIn ) { if( poLayerIn == poLayer ) return OGRERR_NONE; /* -------------------------------------------------------------------- */ /* Capture input information and form static pathnames. */ /* -------------------------------------------------------------------- */ poLayer = poLayerIn; pszIndexPath = CPLStrdup( pszIndexPathIn ); pszMetadataFilename = CPLStrdup( CPLResetExtension( pszIndexPathIn, "idm" ) ); pszMIINDFilename = CPLStrdup(CPLResetExtension( pszIndexPathIn, "ind" )); /* -------------------------------------------------------------------- */ /* If a metadata file already exists, load it. */ /* -------------------------------------------------------------------- */ OGRErr eErr; VSIStatBuf sStat; if( VSIStat( pszMetadataFilename, &sStat ) == 0 ) { eErr = LoadConfigFromXML(); if( eErr != OGRERR_NONE ) return eErr; } return OGRERR_NONE; }
OGRDataSource *OGRMDBDriver::Open( const char * pszFilename, int bUpdate ) { OGRMDBDataSource *poDS; if( EQUALN(pszFilename, "PGEO:", strlen("PGEO:")) ) return NULL; if( EQUALN(pszFilename, "GEOMEDIA:", strlen("GEOMEDIA:")) ) return NULL; if( EQUALN(pszFilename, "WALK:", strlen("WALK:")) ) return NULL; if( !EQUAL(CPLGetExtension(pszFilename),"mdb") ) return NULL; VSIStatBuf sStat; if (VSIStat(pszFilename, &sStat) != 0) return NULL; // Open data source poDS = new OGRMDBDataSource(); if( !poDS->Open( pszFilename, bUpdate, TRUE ) ) { delete poDS; return NULL; } else return poDS; }
/********************************************************************** * TABAdjustFilenameExtension() * * Because Unix filenames are case sensitive and MapInfo datasets often have * mixed cases filenames, we use this function to find the right filename * to use ot open a specific file. * * This function works directly on the source string, so the filename it * contains at the end of the call is the one that should be used. * * Returns TRUE if one of the extensions worked, and FALSE otherwise. * If none of the extensions worked then the original extension will NOT be * restored. **********************************************************************/ GBool TABAdjustFilenameExtension(char *pszFname) { VSIStatBuf sStatBuf; int i; /*----------------------------------------------------------------- * First try using filename as provided *----------------------------------------------------------------*/ if (VSIStat(pszFname, &sStatBuf) == 0) { return TRUE; } /*----------------------------------------------------------------- * Try using uppercase extension (we assume that fname contains a '.') *----------------------------------------------------------------*/ for(i = strlen(pszFname)-1; i >= 0 && pszFname[i] != '.'; i--) { pszFname[i] = toupper(pszFname[i]); } if (VSIStat(pszFname, &sStatBuf) == 0) { return TRUE; } /*----------------------------------------------------------------- * Try using lowercase extension *----------------------------------------------------------------*/ for(i = strlen(pszFname)-1; i >= 0 && pszFname[i] != '.'; i--) { pszFname[i] = tolower(pszFname[i]); } if (VSIStat(pszFname, &sStatBuf) == 0) { return TRUE; } /*----------------------------------------------------------------- * None of the extensions worked! * Try adjusting cases in the whole path and filename *----------------------------------------------------------------*/ return TABAdjustCaseSensitiveFilename(pszFname); }
/********************************************************************** * DumpMapFileBlocks() * * Read and dump a .MAP file... simply dump all blocks sequentially. **********************************************************************/ static int DumpMapFileBlocks(const char *pszFname) { FILE *fp; TABRawBinBlock *poBlock; int nOffset = 0; VSIStatBuf sStatBuf; /*--------------------------------------------------------------------- * Try to open source file * Note: we use stat() to fetch the file size. *--------------------------------------------------------------------*/ if ( VSIStat(pszFname, &sStatBuf) == -1 ) { printf("stat() failed for %s\n", pszFname); return -1; } fp = fopen(pszFname, "rb"); if (fp == NULL) { printf("Failed to open %s\n", pszFname); return -1; } /*--------------------------------------------------------------------- * Read/Dump blocks until EOF is reached *--------------------------------------------------------------------*/ while (nOffset < sStatBuf.st_size ) { poBlock = TABCreateMAPBlockFromFile(fp, nOffset, 512); if (poBlock) { poBlock->Dump(); printf("\n"); delete poBlock; } else { // An error happened (could be EOF)... abort now. break; } nOffset += 512; } /*--------------------------------------------------------------------- * Cleanup and exit. *--------------------------------------------------------------------*/ fclose(fp); return 0; }
bool OGRGeomediaDriver::LibraryExists(const char* pszLibPath) { CPLAssert( 0 != pszLibPath ); VSIStatBuf stb = { 0 } ; if ( 0 == VSIStat( pszLibPath, &stb ) ) { if (VSI_ISREG( stb.st_mode ) || VSI_ISLNK(stb.st_mode)) { return true; } } return false; }
bool OGRODBCMDBDriver::LibraryExists(const char* pszLibPath) { CPLAssert( nullptr != pszLibPath ); VSIStatBuf stb; if ( 0 == VSIStat( pszLibPath, &stb ) ) { if (VSI_ISREG( stb.st_mode ) || VSI_ISLNK(stb.st_mode)) { return true; } } return false; }
OGRDataSource *OGRCSVDriver::CreateDataSource( const char * pszName, char ** /* papszOptions */ ) { /* -------------------------------------------------------------------- */ /* First, ensure there isn't any such file yet. */ /* -------------------------------------------------------------------- */ VSIStatBuf sStatBuf; if( VSIStat( pszName, &sStatBuf ) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "It seems a file system object called '%s' already exists.", pszName ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a directory. */ /* -------------------------------------------------------------------- */ if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to create directory %s:\n%s", pszName, VSIStrerror( errno ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Force it to open as a datasource. */ /* -------------------------------------------------------------------- */ OGRCSVDataSource *poDS = new OGRCSVDataSource(); if( !poDS->Open( pszName, TRUE, TRUE ) ) { delete poDS; return NULL; } return poDS; }
const char *CPLDefaultFindFile( const char *pszClass, const char *pszBasename ) { int i, nLocations = CSLCount( papszFinderLocations ); (void) pszClass; for( i = nLocations-1; i >= 0; i-- ) { const char *pszResult; VSIStatBuf sStat; pszResult = CPLFormFilename( papszFinderLocations[i], pszBasename, NULL ); if( VSIStat( pszResult, &sStat ) == 0 ) return pszResult; } return NULL; }
/********************************************************************** * AVCE00WriteOpen() * * Open (create) an Arc/Info coverage, ready to be receive a stream * of ASCII E00 lines and convert that to the binary coverage format. * * For now, writing to or overwriting existing coverages is not supported * (and may quite well never be!)... you can only create new coverages. * * Important Note: The E00 source lines are assumed to be valid... the * library performs no validation on the consistency of what it is * given as input (i.e. topology, polygons consistency, etc.). * So the coverage that will be created will be only as good as the * E00 input that is used to generate it. * * pszCoverPath MUST be the name of the coverage directory, including * the path to it. * (contrary to AVCE00ReadOpen(), you cannot pass the name of one of * the files in the coverage directory). * The name of the coverage MUST be included in pszCoverPath... this * means that passing "." is invalid. * * nPrecision should always be AVC_DEFAULT_PREC to automagically detect the * source coverage's precision and use that same precision * for the new coverage. * * This parameter has been included to allow adding the * possibility to eventually create coverages with a precision * different from the source E00. * Given the way the lib is built, it could be possible to * also pass AVC_SINGLE_PREC or AVC_DOUBLE_PREC to explicitly * request the creation of a coverage with that precision, * but the library does not (not yet!) properly convert the * TABLE attributes' precision, and the resulting coverage may * be invalid in some cases. * This improvement is on the ToDo list! * * Returns a new AVCE00WritePtr handle or NULL if the coverage could * not be created or if a coverage with that name already exists. * * The handle will eventually have to be released with AVCE00ReadClose(). **********************************************************************/ AVCE00WritePtr AVCE00WriteOpen(const char *pszCoverPath, int nPrecision) { AVCE00WritePtr psInfo; int i, nLen; VSIStatBuf sStatBuf; CPLErrorReset(); /*----------------------------------------------------------------- * Create pszCoverPath directory. * This should fail if the directory already exists. *----------------------------------------------------------------*/ if (pszCoverPath == NULL || strlen(pszCoverPath) == 0 || #ifdef WIN32 mkdir(pszCoverPath) != 0 #else mkdir (pszCoverPath, 0777) != 0 #endif ) { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create coverage directory: %s.", pszCoverPath?pszCoverPath:"(NULL)"); return NULL; } /*----------------------------------------------------------------- * Alloc the AVCE00WritePtr handle *----------------------------------------------------------------*/ psInfo = (AVCE00WritePtr)CPLCalloc(1, sizeof(struct AVCE00WriteInfo_t)); /*----------------------------------------------------------------- * Requested precision for the new coverage... for now only * AVC_DEFAULT_PREC is supported. When the first section is * read, then this section's precision will be used for the whole * coverage. (This is done inside AVCE00WriteNextLine()) *----------------------------------------------------------------*/ if (nPrecision == AVC_DEFAULT_PREC) psInfo->nPrecision = nPrecision; else { CPLError(CE_Failure, CPLE_IllegalArg, "Coverages can only be created using AVC_DEFAULT_PREC. " "Please see the documentation for AVCE00WriteOpen()."); CPLFree(psInfo); return NULL; } /*----------------------------------------------------------------- * Make sure coverage directory name is terminated with a '/' (or '\\') *----------------------------------------------------------------*/ nLen = strlen(pszCoverPath); if (pszCoverPath[nLen-1] == '/' || pszCoverPath[nLen-1] == '\\') psInfo->pszCoverPath = CPLStrdup(pszCoverPath); else { #ifdef WIN32 psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s\\",pszCoverPath)); #else psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s/",pszCoverPath)); #endif } /*----------------------------------------------------------------- * Extract the coverage name from the coverage path. Note that * for this the coverage path must be in the form: * "dir1/dir2/dir3/covername/" ... if it is not the case, then * we would have to use getcwd() to find the current directory name... * but for now we'll just produce an error if this happens. *----------------------------------------------------------------*/ nLen = 0; for( i = strlen(psInfo->pszCoverPath)-1; i > 0 && psInfo->pszCoverPath[i-1] != '/' && psInfo->pszCoverPath[i-1] != '\\'&& psInfo->pszCoverPath[i-1] != ':'; i-- ) { nLen++; } if (nLen > 0) { psInfo->pszCoverName = CPLStrdup(psInfo->pszCoverPath+i); psInfo->pszCoverName[nLen] = '\0'; } else { CPLError(CE_Failure, CPLE_OpenFailed, "Invalid coverage path (%s): " "coverage name must be included in path.", pszCoverPath); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo); return NULL; } if (strlen(psInfo->pszCoverName) > 13 || !_IsStringAlnum(psInfo->pszCoverName) ) { CPLError(CE_Failure, CPLE_OpenFailed, "Invalid coverage name (%s): " "coverage name must be 13 chars or less and contain only " "alphanumerical characters or '_'.", psInfo->pszCoverName); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo->pszCoverName); CPLFree(psInfo); return NULL; } /*----------------------------------------------------------------- * Lazy way to build the INFO path: simply add "../info/"... * this could probably be improved! *----------------------------------------------------------------*/ psInfo->pszInfoPath = (char*)CPLMalloc((strlen(psInfo->pszCoverPath)+9)* sizeof(char)); #ifdef WIN32 # define AVC_INFOPATH "..\\info\\" #else # define AVC_INFOPATH "../info/" #endif sprintf(psInfo->pszInfoPath, "%s%s", psInfo->pszCoverPath, AVC_INFOPATH); /*----------------------------------------------------------------- * Check if the info directory exists and contains the "arc.dir" * if the info dir does not exist, then make sure we can create * the arc.dir file (i.e. try to create an empty one) * * Note: On Windows, this VSIStat() call seems to sometimes fail even * when the directory exists (buffering issue?), and the * following if() block is sometimes executed even if it * should not, but this should not cause problems since the * arc.dir is opened with "a+b" access. *----------------------------------------------------------------*/ if ( VSIStat(psInfo->pszInfoPath, &sStatBuf) == -1) { FILE *fp; char *pszArcDir; #ifdef WIN32 mkdir(psInfo->pszInfoPath); #else mkdir (psInfo->pszInfoPath, 0777); #endif pszArcDir = CPLStrdup(CPLSPrintf("%s%s", psInfo->pszInfoPath, "arc.dir")); fp = VSIFOpen(pszArcDir, "a+b"); CPLFree(pszArcDir); if (fp) { VSIFClose(fp); } else { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create (or write to) 'info' directory %s", psInfo->pszInfoPath); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo->pszInfoPath); CPLFree(psInfo); return NULL; } } /*----------------------------------------------------------------- * Init the E00 parser. *----------------------------------------------------------------*/ psInfo->hParseInfo = AVCE00ParseInfoAlloc(); psInfo->eCurFileType = AVCFileUnknown; /*----------------------------------------------------------------- * If an error happened during the open call, cleanup and return NULL. *----------------------------------------------------------------*/ if (CPLGetLastErrorNo() != 0) { AVCE00WriteClose(psInfo); psInfo = NULL; } return psInfo; }
int OGRTABDataSource::Open( const char * pszName, int bTestOpen ) { VSIStatBuf stat; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); /* -------------------------------------------------------------------- */ /* Is this a file or directory? */ /* -------------------------------------------------------------------- */ if( VSIStat( pszName, &stat ) != 0 || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) ) { if( !bTestOpen ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s is not a file or directory.\n" "Unable to open as a Mapinfo dataset.\n", pszName ); } return FALSE; } /* -------------------------------------------------------------------- */ /* If it is a file, try to open as a Mapinfo file. */ /* -------------------------------------------------------------------- */ if( VSI_ISREG(stat.st_mode) ) { IMapInfoFile *poFile; poFile = IMapInfoFile::SmartOpen( pszName, bTestOpen ); if( poFile == NULL ) return FALSE; m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); } /* -------------------------------------------------------------------- */ /* Otherwise, we need to scan the whole directory for files */ /* ending in .tab or .mif. */ /* -------------------------------------------------------------------- */ else { char **papszFileList = CPLReadDir( pszName ); m_pszDirectory = CPLStrdup( pszName ); for( int iFile = 0; papszFileList != NULL && papszFileList[iFile] != NULL; iFile++ ) { IMapInfoFile *poFile; const char *pszExtension = CPLGetExtension(papszFileList[iFile]); char *pszSubFilename; if( !EQUAL(pszExtension,"tab") && !EQUAL(pszExtension,"mif") ) continue; pszSubFilename = CPLStrdup( CPLFormFilename( m_pszDirectory, papszFileList[iFile], NULL )); poFile = IMapInfoFile::SmartOpen( pszSubFilename, bTestOpen ); CPLFree( pszSubFilename ); if( poFile == NULL ) { CSLDestroy( papszFileList ); return FALSE; } m_nLayerCount++; m_papoLayers = (IMapInfoFile **) CPLRealloc(m_papoLayers,sizeof(void*)*m_nLayerCount); m_papoLayers[m_nLayerCount-1] = poFile; } CSLDestroy( papszFileList ); if( m_nLayerCount == 0 ) { if( !bTestOpen ) CPLError( CE_Failure, CPLE_OpenFailed, "No mapinfo files found in directory %s.\n", m_pszDirectory ); return FALSE; } } return TRUE; }
int OGRTABDataSource::Create( const char * pszName, char **papszOptions ) { VSIStatBuf sStat; const char *pszOpt; CPLAssert( m_pszName == NULL ); m_pszName = CPLStrdup( pszName ); m_papszOptions = CSLDuplicate( papszOptions ); if( (pszOpt=CSLFetchNameValue(papszOptions,"FORMAT")) != NULL && EQUAL(pszOpt, "MIF") ) m_bCreateMIF = TRUE; else if( EQUAL(CPLGetExtension(pszName),"mif") || EQUAL(CPLGetExtension(pszName),"mid") ) m_bCreateMIF = TRUE; if( (pszOpt=CSLFetchNameValue(papszOptions,"SPATIAL_INDEX_MODE")) != NULL && EQUAL(pszOpt, "QUICK") ) m_bQuickSpatialIndexMode = TRUE; /* -------------------------------------------------------------------- */ /* Create a new empty directory. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetExtension(pszName)) == 0 ) { if( VSIStat( pszName, &sStat ) == 0 ) { if( !VSI_ISDIR(sStat.st_mode) ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create dataset named %s,\n" "but that is an existing file.\n", pszName ); return FALSE; } } else { if( VSIMkdir( pszName, 0755 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to create directory %s.\n", pszName ); return FALSE; } } m_pszDirectory = CPLStrdup(pszName); } /* -------------------------------------------------------------------- */ /* Create a new single file. */ /* -------------------------------------------------------------------- */ else { IMapInfoFile *poFile; if( m_bCreateMIF ) poFile = new MIFFile; else poFile = new TABFile; if( poFile->Open( pszName, "wb", FALSE ) != 0 ) { delete poFile; return FALSE; } m_nLayerCount = 1; m_papoLayers = (IMapInfoFile **) CPLMalloc(sizeof(void*)); m_papoLayers[0] = poFile; m_pszDirectory = CPLStrdup( CPLGetPath(pszName) ); m_bSingleFile = TRUE; } return TRUE; }
int OGRSOSIDataSource::Open( const char *pszFilename, int bUpdate ) { papoBuiltGeometries = NULL; poFileadm = NULL; poBaseadm = NULL; char *pszPos; if ( bUpdate ) { CPLError( CE_Failure, CPLE_OpenFailed, "Update access not supported by the SOSI driver." ); return FALSE; } /* Check that the file exists otherwise HO_TestSOSI() emits an error */ VSIStatBuf sStat; if( VSIStat(pszFilename, &sStat) != 0 ) return FALSE; pszName = CPLStrdup( pszFilename ); /* We ignore any layer parameters for now. */ pszPos = strchr(pszName, ','); if (pszPos != NULL) { pszPos[0] = '\0'; } /* Confirm that we are dealing with a SOSI file. Used also by data * format auto-detection in some ogr utilities. */ UT_INT64 nEnd = 0; int bIsSosi = HO_TestSOSI ( pszName, &nEnd ); if ( bIsSosi == UT_FALSE ) { return FALSE; /* No error message: This is used by file format auto-detection */ } short nStatus = 0, nDetStatus = 0; /* immediate status, detailed status */ /* open index base and sosi file */ poBaseadm = LC_OpenBase(LC_BASE); nStatus = LC_OpenSos(pszName, LC_BASE_FRAMGR, LC_GML_IDX, LC_INGEN_STATUS, &poFileadm, &nDetStatus); if ( nStatus == UT_FALSE ) { char *pszErrorMessage; LC_StrError(nDetStatus, &pszErrorMessage); CPLError( CE_Failure, CPLE_OpenFailed, "File %s could not be opened by SOSI Driver: %s", pszName, pszErrorMessage ); return FALSE; } /* --------------------------------------------------------------------* * Prefetch all the information needed to determine layers * * and prebuild LineString features for later assembly. * * --------------------------------------------------------------------*/ /* allocate room for one pointer per feature */ nNumFeatures = static_cast<unsigned int>(poFileadm->lAntGr); void* mem = VSI_MALLOC2_VERBOSE(nNumFeatures, sizeof(void*)); if (mem == NULL) { return FALSE; } else { papoBuiltGeometries = (OGRGeometry**)mem; } for (unsigned int i=0; i<nNumFeatures; i++) papoBuiltGeometries[i] = NULL; /* Various iterators and return values used to iterate through SOSI features */ short nName, nNumLines; long nNumCoo; unsigned short nInfo; LC_SNR_ADM oSnradm; LC_BGR oNextSerial; LC_BGR *poNextSerial; poNextSerial =&oNextSerial; bool bPointLayer = FALSE; /* Initialize four layers for the different geometry types */ bool bCurveLayer = FALSE; bool bPolyLayer = FALSE; bool bTextLayer = FALSE; poPolyHeaders = new S2I(); poPointHeaders = new S2I(); poCurveHeaders = new S2I(); poTextHeaders = new S2I(); LC_SBSn(&oSnradm, poFileadm, 0, nNumFeatures); /* Set FYBA search limits */ LC_InitNextBgr(poNextSerial); /* Prebuilding simple features and extracting layer information. */ while (LC_NextBgr(poNextSerial,LC_FRAMGR)) { /* Fetch next group information */ nName = LC_RxGr(poNextSerial, LES_OPTIMALT, &nNumLines, &nNumCoo, &nInfo); S2S oHeaders; S2S::iterator iHeaders; int iH; /* Extract all strings from group header. */ for (short i=1; i<=nNumLines; i++) { char *pszLine = LC_GetGi(i); /* Get one header line */ if ((pszLine[0] == ':')||(pszLine[0] == '(')) continue; /* If we have a continued REF line, skip it. */ if (pszLine[0] == '!') continue; /* If we have a comment line, skip it. */ char *pszUTFLine = CPLRecode(pszLine, pszEncoding, CPL_ENC_UTF8); /* switch to UTF encoding here, if it is known. */ char *pszUTFLineIter = pszUTFLine; while (pszUTFLineIter[0] == '.') pszUTFLineIter++; /* Skipping the dots at the beginning of a SOSI line */ char *pszPos2 = strstr(pszUTFLineIter, " "); /* Split header and value */ if (pszPos2 != NULL) { CPLString osKey = CPLString(std::string(pszUTFLineIter,pszPos2)); /* FIXME: clean instantiation of CPLString? */ CPLString osValue = CPLString(pszPos2+1); oHeaders[osKey]=osValue; /* Add to header map */ switch (nName) { /* Add to header list for the corresponding layer, if it is not */ case L_FLATE: { /* in there already */ if (poPolyHeaders->find(osKey) == poPolyHeaders->end()) { iH = static_cast<int>(poPolyHeaders->size()); (*poPolyHeaders)[osKey] = iH; } break; } case L_KURVE: case L_LINJE: case L_BUEP: { /* FIXME: maybe not use the same headers for both */ if (poCurveHeaders->find(osKey) == poCurveHeaders->end()) { iH = static_cast<int>(poCurveHeaders->size()); (*poCurveHeaders)[osKey] = iH; } break; } case L_PUNKT: case L_SYMBOL: { if (poPointHeaders->find(osKey) == poPointHeaders->end()) { iH = static_cast<int>(poPointHeaders->size()); (*poPointHeaders)[osKey] = iH; } break; } case L_TEKST: { if (poTextHeaders->find(osKey) == poTextHeaders->end()) { iH = static_cast<int>(poTextHeaders->size()); (*poTextHeaders)[osKey] = iH; } break; } } } CPLFree(pszUTFLine); } /* Feature-specific tasks */ switch (nName) { case L_PUNKT: { /* Pre-build a point feature. Activate point layer. */ bPointLayer = TRUE; buildOGRPoint(oNextSerial.lNr); break; } case L_FLATE: { /* Activate polygon layer. */ bPolyLayer = TRUE; /* cannot build geometries that reference others yet */ break; } case L_KURVE: case L_LINJE: { /* Pre-build a line feature. Activate line/curve layer. */ bCurveLayer = TRUE; buildOGRLineString(static_cast<int>(nNumCoo), oNextSerial.lNr); break; } case L_BUEP: { /* Pre-build a line feature as interpolation from an arc. Activate line/curve layer. */ bCurveLayer = TRUE; buildOGRLineStringFromArc(oNextSerial.lNr); break; } case L_TEKST: { /* Pre-build a text line contour feature. Activate text layer. */ /* Todo: observe only points 2ff if more than one point is given for follow mode */ bTextLayer = TRUE; buildOGRMultiPoint(static_cast<int>(nNumCoo), oNextSerial.lNr); break; } case L_HODE: { /* Get SRS from SOSI header. */ unsigned short nMask = LC_TR_ALLT; LC_TRANSPAR oTrans; if (LC_GetTransEx(&nMask,&oTrans) == UT_FALSE) { CPLError( CE_Failure, CPLE_OpenFailed, "TRANSPAR section not found - No reference system information available."); return FALSE; } poSRS = new OGRSpatialReference(); /* Get coordinate system from SOSI header. */ int nEPSG = sosi2epsg(oTrans.sKoordsys); if (poSRS->importFromEPSG(nEPSG) != OGRERR_NONE) { CPLError( CE_Failure, CPLE_OpenFailed, "OGR could not load coordinate system definition EPSG:%i.", nEPSG); return FALSE; } /* Get character encoding from SOSI header. */ iHeaders = oHeaders.find("TEGNSETT"); if (iHeaders != oHeaders.end()) { CPLString osLine = iHeaders->second; if (osLine.compare("ISO8859-1")==0) { pszEncoding = CPL_ENC_ISO8859_1; } else if (osLine.compare("ISO8859-10")==0) { pszEncoding = CPL_ENC_ISO8859_10; } else if (osLine.compare("UTF-8")==0) { pszEncoding = CPL_ENC_UTF8; } } break; } default: { break; } } } /* -------------------------------------------------------------------- * * Create a corresponding layers. One per geometry type * * -------------------------------------------------------------------- */ int l_nLayers = 0; if (bPolyLayer) l_nLayers++; if (bCurveLayer) l_nLayers++; if (bPointLayer) l_nLayers++; if (bTextLayer) l_nLayers++; this->nLayers = l_nLayers; /* allocate some memory for up to three layers */ papoLayers = (OGRSOSILayer **) VSI_MALLOC2_VERBOSE(sizeof(void*), l_nLayers); if( papoLayers == NULL ) { this->nLayers = 0; return FALSE; } /* Define each layer, using a proper feature definition, geometry type, * and adding every SOSI header encountered in the file as field. */ S2I::iterator i; if (bPolyLayer) { S2I * poHeadersNew = new S2I(); OGRFeatureDefn *poFeatureDefn = defineLayer("polygons", wkbPolygon, poPolyHeaders, &poHeadersNew); delete poPolyHeaders; poPolyHeaders = poHeadersNew; poFeatureDefn->Reference(); papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPolyHeaders ); } else { delete poPolyHeaders; poPolyHeaders = NULL; } if (bCurveLayer) { S2I * poHeadersNew = new S2I(); OGRFeatureDefn *poFeatureDefn = defineLayer("lines", wkbLineString, poCurveHeaders, &poHeadersNew); delete poCurveHeaders; poCurveHeaders = poHeadersNew; poFeatureDefn->Reference(); papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poCurveHeaders ); } else { delete poCurveHeaders; poCurveHeaders = NULL; } if (bPointLayer) { S2I * poHeadersNew = new S2I(); OGRFeatureDefn *poFeatureDefn = defineLayer("points", wkbPoint, poPointHeaders, &poHeadersNew); delete poPointHeaders; poPointHeaders = poHeadersNew; poFeatureDefn->Reference(); papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poPointHeaders ); } else { delete poPointHeaders; poPointHeaders = NULL; } if (bTextLayer) { S2I * poHeadersNew = new S2I(); OGRFeatureDefn *poFeatureDefn = defineLayer("text", wkbMultiPoint, poTextHeaders, &poHeadersNew); delete poTextHeaders; poTextHeaders = poHeadersNew; poFeatureDefn->Reference(); papoLayers[--l_nLayers] = new OGRSOSILayer( this, poFeatureDefn, poFileadm, poTextHeaders ); } else { delete poTextHeaders; poTextHeaders = NULL; } return TRUE; }
int main(int argc, char *argv[]) { const char *index_filename = NULL; const char *tile_index = "location"; int i_arg, ti_field; OGRDataSourceH hTileIndexDS; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFDefn; int write_absolute_path = FALSE; char* current_path = NULL; int i; int nExistingFiles; int skip_different_projection = FALSE; char** existingFilesTab = NULL; int alreadyExistingProjectionRefValid = FALSE; char* alreadyExistingProjectionRef = NULL; char* index_filename_mod; int bExists; VSIStatBuf sStatBuf; const char *pszTargetSRS = ""; int bSetTargetSRS = FALSE; OGRSpatialReferenceH hTargetSRS = NULL; /* Check that we are running against at least GDAL 1.4 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Get commandline arguments other than the GDAL raster filenames. */ /* -------------------------------------------------------------------- */ for( i_arg = 1; i_arg < argc; i_arg++ ) { if( EQUAL(argv[i_arg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( strcmp(argv[i_arg],"-tileindex") == 0 ) { tile_index = argv[++i_arg]; } else if( strcmp(argv[i_arg],"-t_srs") == 0 ) { pszTargetSRS = argv[++i_arg]; bSetTargetSRS = TRUE; } else if ( strcmp(argv[i_arg],"-write_absolute_path") == 0 ) { write_absolute_path = TRUE; } else if ( strcmp(argv[i_arg],"-skip_different_projection") == 0 ) { skip_different_projection = TRUE; } else if( argv[i_arg][0] == '-' ) Usage(); else if( index_filename == NULL ) { index_filename = argv[i_arg]; i_arg++; break; } } if( index_filename == NULL || i_arg == argc ) Usage(); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ if( bSetTargetSRS ) { if ( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target shapefile and DBF file. */ /* -------------------------------------------------------------------- */ index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); if (!bExists) { CPLFree(index_filename_mod); index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); } CPLFree(index_filename_mod); if (bExists) { hTileIndexDS = OGROpen( index_filename, TRUE, NULL ); if (hTileIndexDS != NULL) { hLayer = OGR_DS_GetLayer(hTileIndexDS, 0); } } else { OGRSFDriverH hDriver; const char* pszDriverName = "ESRI Shapefile"; printf( "Creating new index file...\n" ); hDriver = OGRGetDriverByName( pszDriverName ); if( hDriver == NULL ) { printf( "%s driver not available.\n", pszDriverName ); exit( 1 ); } hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL ); if (hTileIndexDS) { char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ OGRSpatialReferenceH hSpatialRef = NULL; if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if (hDS) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != NULL && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } } hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL ); CPLFree(pszLayerName); if (hSpatialRef) OSRRelease(hSpatialRef); if (hLayer) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); OGR_Fld_SetWidth( hFieldDefn, 255); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == NULL || hLayer == NULL ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } hFDefn = OGR_L_GetLayerDefn(hLayer); for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field ); if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 ) break; } if( ti_field == OGR_FD_GetFieldCount(hFDefn) ) { fprintf( stderr, "Unable to find field `%s' in DBF file `%s'.\n", tile_index, index_filename ); exit(2); } /* Load in memory existing file names in SHP */ nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE); if (nExistingFiles) { OGRFeatureH hFeature; existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*)); for(i=0;i<nExistingFiles;i++) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if (i == 0) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if (hDS) { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ for( ; i_arg < argc; i_arg++ ) { GDALDatasetH hDS; double adfGeoTransform[6]; double adfX[5], adfY[5]; int nXSize, nYSize; char* fileNameToWrite; const char* projectionRef; VSIStatBuf sStatBuf; int k; OGRFeatureH hFeature; OGRGeometryH hPoly, hRing; /* Make sure it is a file before building absolute path name */ if (write_absolute_path && CPLIsFilenameRelative( argv[i_arg] ) && VSIStat( argv[i_arg], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[i_arg])); } else { fileNameToWrite = CPLStrdup(argv[i_arg]); } /* Checks that file is not already in tileindex */ for(i=0;i<nExistingFiles;i++) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } hDS = GDALOpen( argv[i_arg], GA_ReadOnly ); if( hDS == NULL ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[i_arg] ); CPLFree(fileNameToWrite); continue; } GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && ABS(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[i_arg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } projectionRef = GDALGetProjectionRef(hDS); /* if not set target srs, test that the current file uses same projection as others */ if( !bSetTargetSRS ) { if (alreadyExistingProjectionRefValid) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf(stderr, "Warning : %s is not using the same projection system as " "other files in the tileindex.\n" "This may cause problems when using it in MapServer for example.\n" "Use -t_srs option to set target projection system (not supported by MapServer).\n" "%s\n", argv[i_arg], (skip_different_projection) ? "Skipping this file." : ""); if (skip_different_projection) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; /* if set target srs, do the forward transformation of all points */ if( bSetTargetSRS ) { OGRSpatialReferenceH hSourceSRS = NULL; OGRCoordinateTransformationH hCT = NULL; hSourceSRS = OSRNewSpatialReference( projectionRef ); if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == NULL || !OCTTransform( hCT, 5, adfX, adfY, NULL ) ) { fprintf( stderr, "Warning : unable to transform points from source SRS `%s' to target SRS `%s'\n" "for file `%s' - file skipped\n", projectionRef, pszTargetSRS, fileNameToWrite ); if ( hCT ) OCTDestroyCoordinateTransformation( hCT ); if ( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); continue; } if ( hCT ) OCTDestroyCoordinateTransformation( hCT ); } if ( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); } hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); hPoly = OGR_G_CreateGeometry(wkbPolygon); hRing = OGR_G_CreateGeometry(wkbLinearRing); for(k=0;k<5;k++) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } CPLFree(current_path); if (nExistingFiles) { for(i=0;i<nExistingFiles;i++) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); OGR_DS_Destroy( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }
int main( int argc, char ** argv ) { EarlySetConfigOptions(argc, argv); /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); for( int i = 0; argv != NULL && argv[i] != NULL; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[i],"--help") ) { Usage(NULL); } } GDALBuildVRTOptionsForBinary* psOptionsForBinary = GDALBuildVRTOptionsForBinaryNew(); /* coverity[tainted_data] */ GDALBuildVRTOptions *psOptions = GDALBuildVRTOptionsNew(argv + 1, psOptionsForBinary); CSLDestroy( argv ); if( psOptions == NULL ) { Usage(NULL); } if( psOptionsForBinary->pszDstFilename == NULL ) { Usage("No target filename specified."); } if( !(psOptionsForBinary->bQuiet) ) { GDALBuildVRTOptionsSetProgress(psOptions, GDALTermProgress, NULL); } /* Avoid overwriting a non VRT dataset if the user did not put the */ /* filenames in the right order */ VSIStatBuf sBuf; if (!psOptionsForBinary->bOverwrite) { int bExists = (VSIStat(psOptionsForBinary->pszDstFilename, &sBuf) == 0); if (bExists) { GDALDriverH hDriver = GDALIdentifyDriver( psOptionsForBinary->pszDstFilename, NULL ); if (hDriver && !(EQUAL(GDALGetDriverShortName(hDriver), "VRT") || (EQUAL(GDALGetDriverShortName(hDriver), "API_PROXY") && EQUAL(CPLGetExtension(psOptionsForBinary->pszDstFilename), "VRT"))) ) { fprintf(stderr, "'%s' is an existing GDAL dataset managed by %s driver.\n" "There is an high chance you did not put filenames in the right order.\n" "If you want to overwrite %s, add -overwrite option to the command line.\n\n", psOptionsForBinary->pszDstFilename, GDALGetDriverShortName(hDriver), psOptionsForBinary->pszDstFilename); Usage(); } } } int bUsageError = FALSE; GDALDatasetH hOutDS = GDALBuildVRT(psOptionsForBinary->pszDstFilename, psOptionsForBinary->nSrcFiles, NULL, (const char* const*)psOptionsForBinary->papszSrcFiles, psOptions, &bUsageError); if( bUsageError ) Usage(); int nRetCode = (hOutDS) ? 0 : 1; GDALBuildVRTOptionsFree(psOptions); GDALBuildVRTOptionsForBinaryFree(psOptionsForBinary); CPLErrorReset(); // The flush to disk is only done at that stage, so check if any error has // happened GDALClose( hOutDS ); if( CPLGetLastErrorType() != CE_None ) nRetCode = 1; GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); OGRCleanupAll(); return nRetCode; }
/********************************************************************** * TABAdjustCaseSensitiveFilename() * * Scan a filename and its path, adjust uppercase/lowercases if * necessary. * * Returns TRUE if file found, or FALSE if it could not be located with * a case-insensitive search. * * This function works on the original buffer and returns a reference to it. * It does nothing on Windows systems where filenames are not case sensitive. **********************************************************************/ GBool TABAdjustCaseSensitiveFilename(char *pszFname) { #ifdef _WIN32 /*----------------------------------------------------------------- * Nothing to do on Windows *----------------------------------------------------------------*/ return TRUE; #else /*----------------------------------------------------------------- * Unix case. *----------------------------------------------------------------*/ VSIStatBuf sStatBuf; char *pszTmpPath = NULL; int nTotalLen, iTmpPtr; GBool bValidPath; /*----------------------------------------------------------------- * First check if the filename is OK as is. *----------------------------------------------------------------*/ if (VSIStat(pszFname, &sStatBuf) == 0) { return TRUE; } /*----------------------------------------------------------------- * OK, file either does not exist or has the wrong cases... we'll * go backwards until we find a portion of the path that is valid. *----------------------------------------------------------------*/ pszTmpPath = CPLStrdup(pszFname); nTotalLen = strlen(pszTmpPath); iTmpPtr = nTotalLen; bValidPath = FALSE; while(iTmpPtr > 0 && !bValidPath) { /*------------------------------------------------------------- * Move back to the previous '/' separator *------------------------------------------------------------*/ pszTmpPath[--iTmpPtr] = '\0'; while( iTmpPtr > 0 && pszTmpPath[iTmpPtr-1] != '/' ) { pszTmpPath[--iTmpPtr] = '\0'; } if (iTmpPtr > 0 && VSIStat(pszTmpPath, &sStatBuf) == 0) bValidPath = TRUE; } CPLAssert(iTmpPtr >= 0); /*----------------------------------------------------------------- * Assume that CWD is valid... so an empty path is a valid path *----------------------------------------------------------------*/ if (iTmpPtr == 0) bValidPath = TRUE; /*----------------------------------------------------------------- * OK, now that we have a valid base, reconstruct the whole path * by scanning all the sub-directories. * If we get to a point where a path component does not exist then * we simply return the rest of the path as is. *----------------------------------------------------------------*/ while(bValidPath && (int)strlen(pszTmpPath) < nTotalLen) { char **papszDir=NULL; int iEntry, iLastPartStart; iLastPartStart = iTmpPtr; papszDir = CPLReadDir(pszTmpPath); /*------------------------------------------------------------- * Add one component to the current path *------------------------------------------------------------*/ pszTmpPath[iTmpPtr] = pszFname[iTmpPtr]; iTmpPtr++; for( ; pszFname[iTmpPtr] != '\0' && pszFname[iTmpPtr]!='/'; iTmpPtr++) { pszTmpPath[iTmpPtr] = pszFname[iTmpPtr]; } while(iLastPartStart < iTmpPtr && pszTmpPath[iLastPartStart] == '/') iLastPartStart++; /*------------------------------------------------------------- * And do a case insensitive search in the current dir... *------------------------------------------------------------*/ for(iEntry=0; papszDir && papszDir[iEntry]; iEntry++) { if (EQUAL(pszTmpPath+iLastPartStart, papszDir[iEntry])) { /* Fount it! */ strcpy(pszTmpPath+iLastPartStart, papszDir[iEntry]); break; } } if (iTmpPtr > 0 && VSIStat(pszTmpPath, &sStatBuf) != 0) bValidPath = FALSE; CSLDestroy(papszDir); } /*----------------------------------------------------------------- * We reached the last valid path component... just copy the rest * of the path as is. *----------------------------------------------------------------*/ if (iTmpPtr < nTotalLen-1) { strncpy(pszTmpPath+iTmpPtr, pszFname+iTmpPtr, nTotalLen-iTmpPtr); } /*----------------------------------------------------------------- * Update the source buffer and return. *----------------------------------------------------------------*/ strcpy(pszFname, pszTmpPath); CPLFree(pszTmpPath); return bValidPath; #endif }
CPLErr GTIFFBuildOverviews( const char * pszFilename, int nBands, GDALRasterBand **papoBandList, int nOverviews, int * panOverviewList, const char * pszResampling, GDALProgressFunc pfnProgress, void * pProgressData ) { TIFF *hOTIFF; int nBitsPerPixel=0, nCompression=COMPRESSION_NONE, nPhotometric=0; int nSampleFormat=0, nPlanarConfig, iOverview, iBand; int nXSize=0, nYSize=0; if( nBands == 0 || nOverviews == 0 ) return CE_None; GTiffOneTimeInit(); /* -------------------------------------------------------------------- */ /* Verify that the list of bands is suitable for emitting in */ /* TIFF file. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < nBands; iBand++ ) { int nBandBits, nBandFormat; GDALRasterBand *hBand = papoBandList[iBand]; switch( hBand->GetRasterDataType() ) { case GDT_Byte: nBandBits = 8; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_UInt16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int16: nBandBits = 16; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_UInt32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_UINT; break; case GDT_Int32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_INT; break; case GDT_Float32: nBandBits = 32; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_Float64: nBandBits = 64; nBandFormat = SAMPLEFORMAT_IEEEFP; break; case GDT_CInt16: nBandBits = 32; nBandFormat = SAMPLEFORMAT_COMPLEXINT; break; case GDT_CFloat32: nBandBits = 64; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; case GDT_CFloat64: nBandBits = 128; nBandFormat = SAMPLEFORMAT_COMPLEXIEEEFP; break; default: CPLAssert( FALSE ); return CE_Failure; } if( iBand == 0 ) { nBitsPerPixel = nBandBits; nSampleFormat = nBandFormat; nXSize = hBand->GetXSize(); nYSize = hBand->GetYSize(); } else if( nBitsPerPixel != nBandBits || nSampleFormat != nBandFormat ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support a mixture of band" " data types." ); return CE_Failure; } else if( hBand->GetColorTable() != NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of multiple colormapped bands." ); return CE_Failure; } else if( hBand->GetXSize() != nXSize || hBand->GetYSize() != nYSize ) { CPLError( CE_Failure, CPLE_NotSupported, "GTIFFBuildOverviews() doesn't support building" " overviews of different sized bands." ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Use specified compression method. */ /* -------------------------------------------------------------------- */ const char *pszCompress = CPLGetConfigOption( "COMPRESS_OVERVIEW", NULL ); if( pszCompress != NULL && pszCompress[0] != '\0' ) { if( EQUAL( pszCompress, "JPEG" ) ) nCompression = COMPRESSION_JPEG; else if( EQUAL( pszCompress, "LZW" ) ) nCompression = COMPRESSION_LZW; else if( EQUAL( pszCompress, "PACKBITS" )) nCompression = COMPRESSION_PACKBITS; else if( EQUAL( pszCompress, "DEFLATE" ) || EQUAL( pszCompress, "ZIP" )) nCompression = COMPRESSION_ADOBE_DEFLATE; else CPLError( CE_Warning, CPLE_IllegalArg, "COMPRESS_OVERVIEW=%s value not recognised, ignoring.", pszCompress ); } /* -------------------------------------------------------------------- */ /* Figure out the planar configuration to use. */ /* -------------------------------------------------------------------- */ if( nBands == 1 ) nPlanarConfig = PLANARCONFIG_CONTIG; else nPlanarConfig = PLANARCONFIG_SEPARATE; const char* pszInterleave = CPLGetConfigOption( "INTERLEAVE_OVERVIEW", NULL ); if (pszInterleave != NULL && pszInterleave[0] != '\0') { if( EQUAL( pszInterleave, "PIXEL" ) ) nPlanarConfig = PLANARCONFIG_CONTIG; else if( EQUAL( pszInterleave, "BAND" ) ) nPlanarConfig = PLANARCONFIG_SEPARATE; else { CPLError( CE_Failure, CPLE_AppDefined, "INTERLEAVE_OVERVIEW=%s unsupported, value must be PIXEL or BAND. ignoring", pszInterleave ); } } /* -------------------------------------------------------------------- */ /* Figure out the photometric interpretation to use. */ /* -------------------------------------------------------------------- */ if( nBands == 3 ) nPhotometric = PHOTOMETRIC_RGB; else if( papoBandList[0]->GetColorTable() != NULL && !EQUALN(pszResampling,"AVERAGE_BIT2",12) ) { nPhotometric = PHOTOMETRIC_PALETTE; /* should set the colormap up at this point too! */ } else nPhotometric = PHOTOMETRIC_MINISBLACK; const char* pszPhotometric = CPLGetConfigOption( "PHOTOMETRIC_OVERVIEW", NULL ); if (pszPhotometric != NULL && pszPhotometric[0] != '\0') { if( EQUAL( pszPhotometric, "MINISBLACK" ) ) nPhotometric = PHOTOMETRIC_MINISBLACK; else if( EQUAL( pszPhotometric, "MINISWHITE" ) ) nPhotometric = PHOTOMETRIC_MINISWHITE; else if( EQUAL( pszPhotometric, "RGB" )) { nPhotometric = PHOTOMETRIC_RGB; } else if( EQUAL( pszPhotometric, "CMYK" )) { nPhotometric = PHOTOMETRIC_SEPARATED; } else if( EQUAL( pszPhotometric, "YCBCR" )) { nPhotometric = PHOTOMETRIC_YCBCR; } else if( EQUAL( pszPhotometric, "CIELAB" )) { nPhotometric = PHOTOMETRIC_CIELAB; } else if( EQUAL( pszPhotometric, "ICCLAB" )) { nPhotometric = PHOTOMETRIC_ICCLAB; } else if( EQUAL( pszPhotometric, "ITULAB" )) { nPhotometric = PHOTOMETRIC_ITULAB; } else { CPLError( CE_Warning, CPLE_IllegalArg, "PHOTOMETRIC_OVERVIEW=%s value not recognised, ignoring.\n", pszPhotometric ); } } /* -------------------------------------------------------------------- */ /* Create the file, if it does not already exist. */ /* -------------------------------------------------------------------- */ VSIStatBuf sStatBuf; if( VSIStat( pszFilename, &sStatBuf ) != 0 ) { hOTIFF = XTIFFOpen( pszFilename, "w+" ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in XTIFFOpen().\n", pszFilename ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Otherwise just open it for update access. */ /* -------------------------------------------------------------------- */ else { hOTIFF = XTIFFOpen( pszFilename, "r+" ); if( hOTIFF == NULL ) { if( CPLGetLastErrorNo() == 0 ) CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create new tiff file `%s'\n" "failed in XTIFFOpen().\n", pszFilename ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Do we have a palette? If so, create a TIFF compatible version. */ /* -------------------------------------------------------------------- */ unsigned short *panRed=NULL, *panGreen=NULL, *panBlue=NULL; if( nPhotometric == PHOTOMETRIC_PALETTE ) { GDALColorTable *poCT = papoBandList[0]->GetColorTable(); int nColorCount; if( nBitsPerPixel <= 8 ) nColorCount = 256; else nColorCount = 65536; panRed = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panGreen = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); panBlue = (unsigned short *) CPLCalloc(nColorCount,sizeof(unsigned short)); for( int iColor = 0; iColor < nColorCount; iColor++ ) { GDALColorEntry sRGB; if( poCT->GetColorEntryAsRGB( iColor, &sRGB ) ) { panRed[iColor] = (unsigned short) (257 * sRGB.c1); panGreen[iColor] = (unsigned short) (257 * sRGB.c2); panBlue[iColor] = (unsigned short) (257 * sRGB.c3); } } } /* -------------------------------------------------------------------- */ /* Do we need some metadata for the overviews? */ /* -------------------------------------------------------------------- */ CPLString osMetadata; GDALDataset *poBaseDS = papoBandList[0]->GetDataset(); GTIFFBuildOverviewMetadata( pszResampling, poBaseDS, osMetadata ); /* -------------------------------------------------------------------- */ /* Loop, creating overviews. */ /* -------------------------------------------------------------------- */ for( iOverview = 0; iOverview < nOverviews; iOverview++ ) { int nOXSize, nOYSize; uint32 nDirOffset; nOXSize = (nXSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nOYSize = (nYSize + panOverviewList[iOverview] - 1) / panOverviewList[iOverview]; nDirOffset = GTIFFWriteDirectory(hOTIFF, FILETYPE_REDUCEDIMAGE, nOXSize, nOYSize, nBitsPerPixel, nPlanarConfig, nBands, 128, 128, TRUE, nCompression, nPhotometric, nSampleFormat, panRed, panGreen, panBlue, 0, NULL, /* FIXME ? how can we fetch extrasamples from here */ osMetadata ); } if (panRed) { CPLFree(panRed); CPLFree(panGreen); CPLFree(panBlue); panRed = panGreen = panBlue = NULL; } XTIFFClose( hOTIFF ); /* -------------------------------------------------------------------- */ /* Open the overview dataset so that we can get at the overview */ /* bands. */ /* -------------------------------------------------------------------- */ GDALDataset *hODS; hODS = (GDALDataset *) GDALOpen( pszFilename, GA_Update ); if( hODS == NULL ) return CE_Failure; /* -------------------------------------------------------------------- */ /* Loop writing overview data. */ /* -------------------------------------------------------------------- */ if (nCompression != COMPRESSION_NONE && nPlanarConfig == PLANARCONFIG_CONTIG && GDALDataTypeIsComplex(papoBandList[0]->GetRasterDataType()) == FALSE && papoBandList[0]->GetColorTable() == NULL && (EQUALN(pszResampling, "NEAR", 4) || EQUAL(pszResampling, "AVERAGE") || EQUAL(pszResampling, "GAUSS"))) { /* In the case of pixel interleaved compressed overviews, we want to generate */ /* the overviews for all the bands block by block, and not band after band, */ /* in order to write the block once and not loose space in the TIFF file */ GDALRasterBand ***papapoOverviewBands; papapoOverviewBands = (GDALRasterBand ***) CPLCalloc(sizeof(void*),nBands); for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBand *hDstBand = hODS->GetRasterBand( iBand+1 ); papapoOverviewBands[iBand] = (GDALRasterBand **) CPLCalloc(sizeof(void*),nOverviews); papapoOverviewBands[iBand][0] = hDstBand; for( int i = 0; i < nOverviews-1; i++ ) { papapoOverviewBands[iBand][i+1] = hDstBand->GetOverview(i); } } GDALRegenerateOverviewsMultiBand(nBands, papoBandList, nOverviews, papapoOverviewBands, pszResampling, pfnProgress, pProgressData ); for( iBand = 0; iBand < nBands; iBand++ ) { CPLFree(papapoOverviewBands[iBand]); } CPLFree(papapoOverviewBands); } else { GDALRasterBand **papoOverviews; papoOverviews = (GDALRasterBand **) CPLCalloc(sizeof(void*),128); for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBand *hSrcBand = papoBandList[iBand]; GDALRasterBand *hDstBand; int nDstOverviews; CPLErr eErr; hDstBand = hODS->GetRasterBand( iBand+1 ); papoOverviews[0] = hDstBand; nDstOverviews = hDstBand->GetOverviewCount() + 1; CPLAssert( nDstOverviews < 128 ); nDstOverviews = MIN(128,nDstOverviews); for( int i = 0; i < nDstOverviews-1; i++ ) { papoOverviews[i+1] = hDstBand->GetOverview(i); } void *pScaledProgressData; pScaledProgressData = GDALCreateScaledProgress( iBand / (double) nBands, (iBand+1) / (double) nBands, pfnProgress, pProgressData ); eErr = GDALRegenerateOverviews( (GDALRasterBandH) hSrcBand, nDstOverviews, (GDALRasterBandH *) papoOverviews, pszResampling, GDALScaledProgress, pScaledProgressData); GDALDestroyScaledProgress( pScaledProgressData ); if( eErr != CE_None ) { delete hODS; return eErr; } } CPLFree( papoOverviews ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ hODS->FlushCache(); delete hODS; pfnProgress( 1.0, NULL, pProgressData ); return CE_None; }
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, int bUpdateIn) { int bExplicitFeatures = FALSE; int bWaypoints = TRUE, bTracks = TRUE, bRoutes = TRUE; if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GPSBabel driver does not support opening a file in update mode"); return FALSE; } if (!EQUALN(pszDatasourceName, "GPSBABEL:", 9)) { VSILFILE* fp = VSIFOpenL(pszDatasourceName, "rb"); if (fp == NULL) return FALSE; char szHeader[1024 + 1]; memset(szHeader, 0, 1024+1); VSIFReadL(szHeader, 1, 1024, fp); if (memcmp(szHeader, "MsRcd", 5) == 0) pszGPSBabelDriverName = CPLStrdup("mapsource"); else if (memcmp(szHeader, "MsRcf", 5) == 0) pszGPSBabelDriverName = CPLStrdup("gdb"); else if (strstr(szHeader, "<osm") != NULL) pszGPSBabelDriverName = CPLStrdup("osm"); else if (strstr(szHeader, "$GPGSA") != NULL || strstr(szHeader, "$GPGGA") != NULL) pszGPSBabelDriverName = CPLStrdup("nmea"); else if (EQUALN(szHeader, "OziExplorer",11)) pszGPSBabelDriverName = CPLStrdup("ozi"); else if (strstr(szHeader, "Grid") && strstr(szHeader, "Datum") && strstr(szHeader, "Header")) pszGPSBabelDriverName = CPLStrdup("garmin_txt"); else if (szHeader[0] == 13 && szHeader[10] == 'M' && szHeader[11] == 'S' && (szHeader[12] >= '0' && szHeader[12] <= '9') && (szHeader[13] >= '0' && szHeader[13] <= '9') && szHeader[12] * 10 + szHeader[13] >= 30 && (szHeader[14] == 1 || szHeader[14] == 2) && szHeader[15] == 0 && szHeader[16] == 0 && szHeader[17] == 0) pszGPSBabelDriverName = CPLStrdup("mapsend"); else if (strstr(szHeader, "$PMGNWPL") != NULL || strstr(szHeader, "$PMGNRTE") != NULL) pszGPSBabelDriverName = CPLStrdup("magellan"); VSIFCloseL(fp); if (pszGPSBabelDriverName == NULL) { return FALSE; } pszFilename = CPLStrdup(pszDatasourceName); } pszName = CPLStrdup( pszDatasourceName ); if (pszGPSBabelDriverName == NULL) { const char* pszSep = strchr(pszDatasourceName + 9, ':'); if (pszSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name:file_name"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9); *(strchr(pszGPSBabelDriverName, ':')) = '\0'; /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; /* Parse optionnal features= option */ if (EQUALN(pszSep+1, "features=", 9)) { const char* pszNextSep = strchr(pszSep+1, ':'); if (pszNextSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name[,options]*:[features=waypoints,tracks,routes:]file_name"); return FALSE; } char* pszFeatures = CPLStrdup(pszSep+1+9); *strchr(pszFeatures, ':') = 0; char** papszTokens = CSLTokenizeString(pszFeatures); char** papszIter = papszTokens; int bErr = FALSE; bExplicitFeatures = TRUE; bWaypoints = bTracks = bRoutes = FALSE; while(papszIter && *papszIter) { if (EQUAL(*papszIter, "waypoints")) bWaypoints = TRUE; else if (EQUAL(*papszIter, "tracks")) bTracks = TRUE; else if (EQUAL(*papszIter, "routes")) bRoutes = TRUE; else { CPLError(CE_Failure, CPLE_AppDefined, "Wrong value for 'features' options"); bErr = TRUE; } papszIter ++; } CSLDestroy(papszTokens); CPLFree(pszFeatures); if (bErr) return FALSE; pszSep = pszNextSep; } pszFilename = CPLStrdup(pszSep+1); } const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL); if (pszOptionUseTempFile && CSLTestBoolean(pszOptionUseTempFile)) osTmpFileName = CPLGenerateTempFilename(NULL); else osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this); int bRet = FALSE; if (IsSpecialFile(pszFilename)) { /* Special file : don't try to open it */ char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } else { VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s", pszFilename); return FALSE; } char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, "-"); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); CPLPushErrorHandler(CPLQuietErrorHandler); bRet = (CPLSpawn(argv, fp, tmpfp, TRUE) == 0); CPLPopErrorHandler(); CSLDestroy(argv); argv = NULL; CPLErr nLastErrorType = CPLGetLastErrorType(); int nLastErrorNo = CPLGetLastErrorNo(); CPLString osLastErrorMsg = CPLGetLastErrorMsg(); VSIFCloseL(tmpfp); tmpfp = NULL; VSIFCloseL(fp); fp = NULL; if (!bRet) { if (strstr(osLastErrorMsg.c_str(), "This format cannot be used in piped commands") == NULL) { CPLError(nLastErrorType, nLastErrorNo, "%s", osLastErrorMsg.c_str()); } else { VSIStatBuf sStatBuf; if (VSIStat(pszFilename, &sStatBuf) != 0) { CPLError(CE_Failure, CPLE_NotSupported, "Driver %s only supports real (non virtual) files", pszGPSBabelDriverName); return FALSE; } /* Try without piping in */ argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } } } if (bRet) { poGPXDS = OGRSFDriverRegistrar::Open(osTmpFileName.c_str()); if (poGPXDS) { OGRLayer* poLayer; if (bWaypoints) { poLayer = poGPXDS->GetLayerByName("waypoints"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bRoutes) { poLayer = poGPXDS->GetLayerByName("routes"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("route_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bTracks) { poLayer = poGPXDS->GetLayerByName("tracks"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("track_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } } } return nLayers > 0; }
OGRDataSource *OGRGeoconceptDriver::CreateDataSource( const char* pszName, char** papszOptions ) { VSIStatBuf stat; int bSingleNewFile = FALSE; if( pszName==NULL || strlen(pszName)==0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid datasource name (null or empty)"); return NULL; } /* -------------------------------------------------------------------- */ /* Is the target a valid existing directory? */ /* -------------------------------------------------------------------- */ if( CPLStat( pszName, &stat ) == 0 ) { if( !VSI_ISDIR(stat.st_mode) ) { CPLError( CE_Failure, CPLE_AppDefined, "%s is not a valid existing directory.", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Does it end with the extension .gxt indicating the user likely */ /* wants to create a single file set? */ /* -------------------------------------------------------------------- */ else if( EQUAL(CPLGetExtension(pszName),"gxt") || EQUAL(CPLGetExtension(pszName),"txt") ) { bSingleNewFile = TRUE; } /* -------------------------------------------------------------------- */ /* Otherwise try to create a new directory. */ /* -------------------------------------------------------------------- */ else { VSIStatBuf sStat; if( VSIStat( pszName, &sStat ) == 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create datasource named %s, " "but that is an existing directory.", pszName ); return NULL; } } /* -------------------------------------------------------------------- */ /* Return a new OGRDataSource() */ /* -------------------------------------------------------------------- */ OGRGeoconceptDataSource *poDS = NULL; poDS = new OGRGeoconceptDataSource(); if( !poDS->Create( pszName, papszOptions ) ) { delete poDS; return NULL; } return poDS; }
/********************************************************************** * AVCE00DeleteCoverage() * * Delete a coverage directory, its contents, and the associated info * tables. * * Note: * When deleting tables, only the ../info/arc????.nit and arc????.dat * need to be deleted; the arc.dir does not need to be updated. This * is exactly what Arc/Info's KILL command does. * * Returns 0 on success or -1 on error. **********************************************************************/ int AVCE00DeleteCoverage(const char *pszCoverToDelete) { int i, j, nStatus = 0; char *pszInfoPath, *pszCoverPath, *pszCoverName; const char *pszFname; char **papszTables=NULL, **papszFiles=NULL; AVCE00ReadPtr psInfo; VSIStatBuf sStatBuf; CPLErrorReset(); /*----------------------------------------------------------------- * Since we don't want to duplicate all the logic to figure coverage * and info dir name, etc... we'll simply open the coverage and * grab the info we need from the coverage handle. * By the same way, this will verify that the coverage exists and is * valid. *----------------------------------------------------------------*/ psInfo = AVCE00ReadOpen(pszCoverToDelete); if (psInfo == NULL) { CPLError(CE_Failure, CPLE_FileIO, "Cannot delete coverage %s: it does not appear to be valid\n", pszCoverToDelete); return -1; } pszCoverPath = CPLStrdup(psInfo->pszCoverPath); pszInfoPath = CPLStrdup(psInfo->pszInfoPath); pszCoverName = CPLStrdup(psInfo->pszCoverName); AVCE00ReadClose(psInfo); /*----------------------------------------------------------------- * Delete files in cover directory. *----------------------------------------------------------------*/ papszFiles = CPLReadDir(pszCoverPath); for(i=0; nStatus==0 && papszFiles && papszFiles[i]; i++) { if (!EQUAL(".", papszFiles[i]) && !EQUAL("..", papszFiles[i])) { pszFname = CPLSPrintf("%s%s", pszCoverPath, papszFiles[i]); if (unlink(pszFname) != 0) { CPLError(CE_Failure, CPLE_FileIO, "Failed deleting %s%s: %s", pszCoverPath, papszFiles[i], strerror); nStatus = -1; break; } } } CSLDestroy(papszFiles); papszFiles = NULL; /*----------------------------------------------------------------- * Get the list of info files (ARC????) to delete and delete them *----------------------------------------------------------------*/ if (nStatus == 0) { papszTables = AVCBinReadListTables(pszInfoPath, pszCoverName, &papszFiles); for(i=0; nStatus==0 && papszFiles && papszFiles[i]; i++) { /* Convert table filename to lowercases */ for(j=0; papszFiles[i] && papszFiles[i][j]!='\0'; j++) papszFiles[i][j] = tolower(papszFiles[i][j]); /* Delete the .DAT file */ pszFname = CPLSPrintf("%s%s.dat", pszInfoPath, papszFiles[i]); if ( VSIStat(pszFname, &sStatBuf) != -1 && unlink(pszFname) != 0) { CPLError(CE_Failure, CPLE_FileIO, "Failed deleting %s%s: %s", pszInfoPath, papszFiles[i], strerror); nStatus = -1; break; } /* Delete the .DAT file */ pszFname = CPLSPrintf("%s%s.nit", pszInfoPath, papszFiles[i]); if ( VSIStat(pszFname, &sStatBuf) != -1 && unlink(pszFname) != 0) { CPLError(CE_Failure, CPLE_FileIO, "Failed deleting %s%s: %s", pszInfoPath, papszFiles[i], strerror); nStatus = -1; break; } } CSLDestroy(papszTables); CSLDestroy(papszFiles); } /*----------------------------------------------------------------- * Delete the coverage directory itself *----------------------------------------------------------------*/ if (rmdir(pszCoverPath) != 0) { CPLError(CE_Failure, CPLE_FileIO, "Failed deleting directory %s: %s", pszCoverPath, strerror); nStatus = -1; } CPLFree(pszCoverPath); CPLFree(pszInfoPath); CPLFree(pszCoverName); return nStatus; }
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, const char* pszGPSBabelDriverNameIn, char** papszOpenOptionsIn ) { if (!STARTS_WITH_CI(pszDatasourceName, "GPSBABEL:")) { CPLAssert(pszGPSBabelDriverNameIn); pszGPSBabelDriverName = CPLStrdup(pszGPSBabelDriverNameIn); pszFilename = CPLStrdup(pszDatasourceName); } else { if( CSLFetchNameValue(papszOpenOptionsIn, "FILENAME") ) pszFilename = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "FILENAME")); if( CSLFetchNameValue(papszOpenOptionsIn, "GPSBABEL_DRIVER") ) { if( pszFilename == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Missing FILENAME"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(CSLFetchNameValue(papszOpenOptionsIn, "DRIVER")); /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; } } pszName = CPLStrdup( pszDatasourceName ); bool bExplicitFeatures = false; bool bWaypoints = true; bool bTracks = true; bool bRoutes = true; if (pszGPSBabelDriverName == NULL) { const char* pszSep = strchr(pszDatasourceName + 9, ':'); if (pszSep == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name:file_name"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9); *(strchr(pszGPSBabelDriverName, ':')) = '\0'; /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; /* Parse optional features= option */ if (STARTS_WITH_CI(pszSep+1, "features=")) { const char* pszNextSep = strchr(pszSep+1, ':'); if (pszNextSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected " "GPSBabel:driver_name[,options]*:[" "features=waypoints,tracks,routes:]file_name"); return FALSE; } char* pszFeatures = CPLStrdup(pszSep+1+9); *strchr(pszFeatures, ':') = 0; char** papszTokens = CSLTokenizeString(pszFeatures); char** papszIter = papszTokens; bool bErr = false; bExplicitFeatures = true; bWaypoints = false; bTracks = false; bRoutes = false; while(papszIter && *papszIter) { if (EQUAL(*papszIter, "waypoints")) bWaypoints = true; else if (EQUAL(*papszIter, "tracks")) bTracks = true; else if (EQUAL(*papszIter, "routes")) bRoutes = true; else { CPLError( CE_Failure, CPLE_AppDefined, "Wrong value for 'features' options"); bErr = true; } papszIter++; } CSLDestroy(papszTokens); CPLFree(pszFeatures); if (bErr) return FALSE; pszSep = pszNextSep; } if( pszFilename == NULL ) pszFilename = CPLStrdup(pszSep+1); } const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL); if (pszOptionUseTempFile && CPLTestBool(pszOptionUseTempFile)) osTmpFileName = CPLGenerateTempFilename(NULL); else osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this); bool bRet = false; if (IsSpecialFile(pszFilename)) { /* Special file : don't try to open it */ char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } else { VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s", pszFilename); return FALSE; } char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, "-"); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); CPLPushErrorHandler(CPLQuietErrorHandler); bRet = (CPLSpawn(argv, fp, tmpfp, TRUE) == 0); CPLPopErrorHandler(); CSLDestroy(argv); argv = NULL; CPLErr nLastErrorType = CPLGetLastErrorType(); CPLErrorNum nLastErrorNo = CPLGetLastErrorNo(); CPLString osLastErrorMsg = CPLGetLastErrorMsg(); VSIFCloseL(tmpfp); tmpfp = NULL; VSIFCloseL(fp); fp = NULL; if (!bRet) { if ( strstr(osLastErrorMsg.c_str(), "This format cannot be used in piped commands") == NULL) { CPLError( nLastErrorType, nLastErrorNo, "%s", osLastErrorMsg.c_str()); } else { VSIStatBuf sStatBuf; if (VSIStat(pszFilename, &sStatBuf) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Driver %s only supports real (non virtual) " "files", pszGPSBabelDriverName ); return FALSE; } /* Try without piping in */ argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } } } if (bRet) { poGPXDS = static_cast<GDALDataset *>( GDALOpenEx( osTmpFileName.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL ) ); if (poGPXDS) { if (bWaypoints) { OGRLayer* poLayer = poGPXDS->GetLayerByName("waypoints"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bRoutes) { OGRLayer* poLayer = poGPXDS->GetLayerByName("routes"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("route_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bTracks) { OGRLayer* poLayer = poGPXDS->GetLayerByName("tracks"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("track_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } } } return nLayers > 0; }
bool OGRGeomediaDriver::FindDriverLib() { // Default name and path of driver library const char* aszDefaultLibName[] = { "libmdbodbc.so", "libmdbodbc.so.0" /* for Ubuntu 8.04 support */ }; const int nLibNames = sizeof(aszDefaultLibName) / sizeof(aszDefaultLibName[0]); const char* libPath[] = { "/usr/lib", "/usr/local/lib" }; const int nLibPaths = sizeof(libPath) / sizeof(libPath[0]); CPLString strLibPath(""); const char* pszDrvCfg = CPLGetConfigOption("MDBDRIVER_PATH", NULL); if ( NULL != pszDrvCfg ) { // Directory or file path strLibPath = pszDrvCfg; VSIStatBuf sStatBuf = { 0 }; if ( VSIStat( pszDrvCfg, &sStatBuf ) == 0 && VSI_ISDIR( sStatBuf.st_mode ) ) { // Find default library in custom directory const char* pszDriverFile = CPLFormFilename( pszDrvCfg, aszDefaultLibName[0], NULL ); CPLAssert( 0 != pszDriverFile ); strLibPath = pszDriverFile; } if ( LibraryExists( strLibPath.c_str() ) ) { // Save custom driver path osDriverFile = strLibPath; return true; } } // Try to find library in default path for ( int i = 0; i < nLibPaths; i++ ) { for ( int j = 0; j < nLibNames; j++ ) { const char* pszDriverFile = CPLFormFilename( libPath[i], aszDefaultLibName[j], NULL ); CPLAssert( 0 != pszDriverFile ); if ( LibraryExists( pszDriverFile ) ) { // Save default driver path osDriverFile = pszDriverFile; return true; } } } CPLError(CE_Failure, CPLE_AppDefined, "Geomedia: MDB Tools driver not found!\n"); // Driver not found! return false; }
OGRLayer * OGRCSVDataSource::CreateLayer( const char *pszLayerName, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { /* -------------------------------------------------------------------- */ /* Verify we are in update mode. */ /* -------------------------------------------------------------------- */ if (!bUpdate) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Data source %s opened read-only.\n" "New layer %s cannot be created.\n", pszName, pszLayerName ); return NULL; } /* -------------------------------------------------------------------- */ /* Verify that the datasource is a directory. */ /* -------------------------------------------------------------------- */ VSIStatBuf sStatBuf; if( VSIStat( pszName, &sStatBuf ) != 0 || !VSI_ISDIR( sStatBuf.st_mode ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create csv layer (file) against a non-directory datasource." ); return NULL; } /* -------------------------------------------------------------------- */ /* What filename would we use? */ /* -------------------------------------------------------------------- */ const char *pszFilename; pszFilename = CPLFormFilename( pszName, pszLayerName, "csv" ); /* -------------------------------------------------------------------- */ /* does this file already exist? */ /* -------------------------------------------------------------------- */ if( VSIStat( pszName, &sStatBuf ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create layer %s, but file %s already exists.", pszLayerName, pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the empty file. */ /* -------------------------------------------------------------------- */ FILE *fp; fp = VSIFOpen( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create %s:\n%s", pszFilename, VSIStrerror( errno ) ); return NULL; } const char *pszDelimiter = CSLFetchNameValue( papszOptions, "SEPARATOR"); char chDelimiter = ','; if (pszDelimiter != NULL) { if (EQUAL(pszDelimiter, "COMMA")) chDelimiter = ','; else if (EQUAL(pszDelimiter, "SEMICOLON")) chDelimiter = ';'; else if (EQUAL(pszDelimiter, "TAB")) chDelimiter = '\t'; else { CPLError( CE_Warning, CPLE_AppDefined, "SEPARATOR=%s not understood, use one of COMMA, SEMICOLON or TAB.", pszDelimiter ); } } /* -------------------------------------------------------------------- */ /* Create a layer. */ /* -------------------------------------------------------------------- */ nLayers++; papoLayers = (OGRCSVLayer **) CPLRealloc(papoLayers, sizeof(void*) * nLayers); papoLayers[nLayers-1] = new OGRCSVLayer( pszLayerName, fp, pszFilename, TRUE, TRUE, chDelimiter ); /* -------------------------------------------------------------------- */ /* Was a partiuclar CRLF order requested? */ /* -------------------------------------------------------------------- */ const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); int bUseCRLF; if( pszCRLFFormat == NULL ) { #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } else if( EQUAL(pszCRLFFormat,"CRLF") ) bUseCRLF = TRUE; else if( EQUAL(pszCRLFFormat,"LF") ) bUseCRLF = FALSE; else { CPLError( CE_Warning, CPLE_AppDefined, "LINEFORMAT=%s not understood, use one of CRLF or LF.", pszCRLFFormat ); #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } papoLayers[nLayers-1]->SetCRLF( bUseCRLF ); /* -------------------------------------------------------------------- */ /* Should we write the geometry ? */ /* -------------------------------------------------------------------- */ const char *pszGeometry = CSLFetchNameValue( papszOptions, "GEOMETRY"); if (pszGeometry != NULL) { if (EQUAL(pszGeometry, "AS_WKT")) { papoLayers[nLayers-1]->SetWriteGeometry(OGR_CSV_GEOM_AS_WKT); } else if (EQUAL(pszGeometry, "AS_XYZ") || EQUAL(pszGeometry, "AS_XY") || EQUAL(pszGeometry, "AS_YX")) { if (eGType == wkbUnknown || wkbFlatten(eGType) == wkbPoint) { papoLayers[nLayers-1]->SetWriteGeometry(EQUAL(pszGeometry, "AS_XYZ") ? OGR_CSV_GEOM_AS_XYZ : EQUAL(pszGeometry, "AS_XY") ? OGR_CSV_GEOM_AS_XY : OGR_CSV_GEOM_AS_YX); } else { CPLError( CE_Warning, CPLE_AppDefined, "Geometry type %s is not compatible with GEOMETRY=AS_XYZ.", OGRGeometryTypeToName(eGType) ); } } else { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported value %s for creation option GEOMETRY", pszGeometry ); } } /* -------------------------------------------------------------------- */ /* Should we create a CSVT file ? */ /* -------------------------------------------------------------------- */ const char *pszCreateCSVT = CSLFetchNameValue( papszOptions, "CREATE_CSVT"); if (pszCreateCSVT) papoLayers[nLayers-1]->SetCreateCSVT(CSLTestBoolean(pszCreateCSVT)); return papoLayers[nLayers-1]; }
int main( int nArgc, char ** papszArgv ) { int nFirstSourceDataset = -1, bLayersWildcarded = TRUE, iArg; const char *pszFormat = "ESRI Shapefile"; const char *pszTileIndexField = "LOCATION"; const char *pszOutputName = NULL; int write_absolute_path = FALSE; int skip_different_projection = FALSE; char* current_path = NULL; int accept_different_schemas = FALSE; int bFirstWarningForNonMatchingAttributes = TRUE; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(papszArgv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register format(s). */ /* -------------------------------------------------------------------- */ OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Processing command line arguments. */ /* -------------------------------------------------------------------- */ for( iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", papszArgv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(papszArgv[iArg],"-f") && iArg < nArgc-1 ) { pszFormat = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-write_absolute_path")) { write_absolute_path = TRUE; } else if( EQUAL(papszArgv[iArg],"-skip_different_projection")) { skip_different_projection = TRUE; } else if( EQUAL(papszArgv[iArg],"-accept_different_schemas")) { accept_different_schemas = TRUE; } else if( EQUAL(papszArgv[iArg],"-tileindex") && iArg < nArgc-1 ) { pszTileIndexField = papszArgv[++iArg]; } else if( EQUAL(papszArgv[iArg],"-lnum") || EQUAL(papszArgv[iArg],"-lname") ) { iArg++; bLayersWildcarded = FALSE; } else if( papszArgv[iArg][0] == '-' ) Usage(); else if( pszOutputName == NULL ) pszOutputName = papszArgv[iArg]; else if( nFirstSourceDataset == -1 ) nFirstSourceDataset = iArg; } if( pszOutputName == NULL || nFirstSourceDataset == -1 ) Usage(); /* -------------------------------------------------------------------- */ /* Try to open as an existing dataset for update access. */ /* -------------------------------------------------------------------- */ OGRDataSource *poDstDS; OGRLayer *poDstLayer = NULL; poDstDS = OGRSFDriverRegistrar::Open( pszOutputName, TRUE ); /* -------------------------------------------------------------------- */ /* If that failed, find the driver so we can create the tile index.*/ /* -------------------------------------------------------------------- */ if( poDstDS == NULL ) { OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar(); OGRSFDriver *poDriver = NULL; int iDriver; for( iDriver = 0; iDriver < poR->GetDriverCount() && poDriver == NULL; iDriver++ ) { if( EQUAL(poR->GetDriver(iDriver)->GetName(),pszFormat) ) { poDriver = poR->GetDriver(iDriver); } } if( poDriver == NULL ) { fprintf( stderr, "Unable to find driver `%s'.\n", pszFormat ); fprintf( stderr, "The following drivers are available:\n" ); for( iDriver = 0; iDriver < poR->GetDriverCount(); iDriver++ ) { fprintf( stderr, " -> `%s'\n", poR->GetDriver(iDriver)->GetName() ); } exit( 1 ); } if( !poDriver->TestCapability( ODrCCreateDataSource ) ) { fprintf( stderr, "%s driver does not support data source creation.\n", pszFormat ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Now create it. */ /* -------------------------------------------------------------------- */ poDstDS = poDriver->CreateDataSource( pszOutputName, NULL ); if( poDstDS == NULL ) { fprintf( stderr, "%s driver failed to create %s\n", pszFormat, pszOutputName ); exit( 1 ); } if( poDstDS->GetLayerCount() == 0 ) { OGRFieldDefn oLocation( pszTileIndexField, OFTString ); oLocation.SetWidth( 200 ); if( nFirstSourceDataset < nArgc && papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; } OGRSpatialReference* poSrcSpatialRef = NULL; /* Fetches the SRS of the first layer and use it when creating the tileindex layer */ if (nFirstSourceDataset < nArgc) { OGRDataSource* poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if (poDS) { int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; if ( poLayer->GetSpatialRef() ) poSrcSpatialRef = poLayer->GetSpatialRef()->Clone(); break; } } OGRDataSource::DestroyDataSource( poDS ); } poDstLayer = poDstDS->CreateLayer( "tileindex", poSrcSpatialRef ); poDstLayer->CreateField( &oLocation, OFTString ); OGRSpatialReference::DestroySpatialReference( poSrcSpatialRef ); } } /* -------------------------------------------------------------------- */ /* Identify target layer and field. */ /* -------------------------------------------------------------------- */ int iTileIndexField; poDstLayer = poDstDS->GetLayer(0); if( poDstLayer == NULL ) { fprintf( stderr, "Can't find any layer in output tileindex!\n" ); exit( 1 ); } iTileIndexField = poDstLayer->GetLayerDefn()->GetFieldIndex( pszTileIndexField ); if( iTileIndexField == -1 ) { fprintf( stderr, "Can't find %s field in tile index dataset.\n", pszTileIndexField ); exit( 1 ); } OGRFeatureDefn* poFeatureDefn = NULL; /* Load in memory existing file names in SHP */ int nExistingLayers = 0; char** existingLayersTab = NULL; OGRSpatialReference* alreadyExistingSpatialRef = NULL; int alreadyExistingSpatialRefValid = FALSE; nExistingLayers = poDstLayer->GetFeatureCount(); if (nExistingLayers) { int i; existingLayersTab = (char**)CPLMalloc(nExistingLayers * sizeof(char*)); for(i=0;i<nExistingLayers;i++) { OGRFeature* feature = poDstLayer->GetNextFeature(); existingLayersTab[i] = CPLStrdup(feature->GetFieldAsString( iTileIndexField)); if (i == 0) { OGRDataSource *poDS; char* filename = CPLStrdup(existingLayersTab[i]); int j; for(j=strlen(filename)-1;j>=0;j--) { if (filename[j] == ',') break; } if (j >= 0) { int iLayer = atoi(filename + j + 1); filename[j] = 0; poDS = OGRSFDriverRegistrar::Open(filename, FALSE ); if (poDS) { OGRLayer *poLayer = poDS->GetLayer(iLayer); if (poLayer) { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (poLayer->GetSpatialRef()) ? poLayer->GetSpatialRef()->Clone() : NULL; if (poFeatureDefn == NULL) poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } OGRDataSource::DestroyDataSource( poDS ); } } } } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* ==================================================================== */ /* Process each input datasource in turn. */ /* ==================================================================== */ for(; nFirstSourceDataset < nArgc; nFirstSourceDataset++ ) { int i; OGRDataSource *poDS; if( papszArgv[nFirstSourceDataset][0] == '-' ) { nFirstSourceDataset++; continue; } char* fileNameToWrite; VSIStatBuf sStatBuf; if (write_absolute_path && CPLIsFilenameRelative( papszArgv[nFirstSourceDataset] ) && VSIStat( papszArgv[nFirstSourceDataset], &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path,papszArgv[nFirstSourceDataset])); } else { fileNameToWrite = CPLStrdup(papszArgv[nFirstSourceDataset]); } poDS = OGRSFDriverRegistrar::Open( papszArgv[nFirstSourceDataset], FALSE ); if( poDS == NULL ) { fprintf( stderr, "Failed to open dataset %s, skipping.\n", papszArgv[nFirstSourceDataset] ); CPLFree(fileNameToWrite); continue; } /* -------------------------------------------------------------------- */ /* Check all layers, and see if they match requests. */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < poDS->GetLayerCount(); iLayer++ ) { int bRequested = bLayersWildcarded; OGRLayer *poLayer = poDS->GetLayer(iLayer); for( iArg = 1; iArg < nArgc && !bRequested; iArg++ ) { if( EQUAL(papszArgv[iArg],"-lnum") && atoi(papszArgv[iArg+1]) == iLayer ) bRequested = TRUE; else if( EQUAL(papszArgv[iArg],"-lname") && EQUAL(papszArgv[iArg+1], poLayer->GetLayerDefn()->GetName()) ) bRequested = TRUE; } if( !bRequested ) continue; /* Checks that the layer is not already in tileindex */ for(i=0;i<nExistingLayers;i++) { char szLocation[5000]; sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); if (EQUAL(szLocation, existingLayersTab[i])) { fprintf(stderr, "Layer %d of %s is already in tileindex. Skipping it.\n", iLayer, papszArgv[nFirstSourceDataset]); break; } } if (i != nExistingLayers) { continue; } OGRSpatialReference* spatialRef = poLayer->GetSpatialRef(); if (alreadyExistingSpatialRefValid) { if ((spatialRef != NULL && alreadyExistingSpatialRef != NULL && spatialRef->IsSame(alreadyExistingSpatialRef) == FALSE) || ((spatialRef != NULL) != (alreadyExistingSpatialRef != NULL))) { fprintf(stderr, "Warning : layer %d of %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", iLayer, papszArgv[nFirstSourceDataset], (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { continue; } } } else { alreadyExistingSpatialRefValid = TRUE; alreadyExistingSpatialRef = (spatialRef) ? spatialRef->Clone() : NULL; } /* -------------------------------------------------------------------- */ /* Check if all layers in dataset have the same attributes schema. */ /* -------------------------------------------------------------------- */ if( poFeatureDefn == NULL ) { poFeatureDefn = poLayer->GetLayerDefn()->Clone(); } else if ( !accept_different_schemas ) { OGRFeatureDefn* poFeatureDefnCur = poLayer->GetLayerDefn(); assert(NULL != poFeatureDefnCur); int fieldCount = poFeatureDefnCur->GetFieldCount(); if( fieldCount != poFeatureDefn->GetFieldCount()) { fprintf( stderr, "Number of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } continue; } int bSkip = FALSE; for( int fn = 0; fn < poFeatureDefnCur->GetFieldCount(); fn++ ) { OGRFieldDefn* poField = poFeatureDefn->GetFieldDefn(fn); OGRFieldDefn* poFieldCur = poFeatureDefnCur->GetFieldDefn(fn); /* XXX - Should those pointers be checked against NULL? */ assert(NULL != poField); assert(NULL != poFieldCur); if( poField->GetType() != poFieldCur->GetType() || poField->GetWidth() != poFieldCur->GetWidth() || poField->GetPrecision() != poFieldCur->GetPrecision() || !EQUAL( poField->GetNameRef(), poFieldCur->GetNameRef() ) ) { fprintf( stderr, "Schema of attributes of layer %s of %s does not match ... skipping it.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset]); if (bFirstWarningForNonMatchingAttributes) { fprintf( stderr, "Note : you can override this behaviour with -accept_different_schemas option\n" "but this may result in a tileindex incompatible with MapServer\n"); bFirstWarningForNonMatchingAttributes = FALSE; } bSkip = TRUE; break; } } if (bSkip) continue; } /* -------------------------------------------------------------------- */ /* Get layer extents, and create a corresponding polygon */ /* geometry. */ /* -------------------------------------------------------------------- */ OGREnvelope sExtents; OGRPolygon oRegion; OGRLinearRing oRing; if( poLayer->GetExtent( &sExtents, TRUE ) != OGRERR_NONE ) { fprintf( stderr, "GetExtent() failed on layer %s of %s, skipping.\n", poLayer->GetLayerDefn()->GetName(), papszArgv[nFirstSourceDataset] ); continue; } oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MaxY ); oRing.addPoint( sExtents.MaxX, sExtents.MinY ); oRing.addPoint( sExtents.MinX, sExtents.MinY ); oRegion.addRing( &oRing ); /* -------------------------------------------------------------------- */ /* Add layer to tileindex. */ /* -------------------------------------------------------------------- */ char szLocation[5000]; OGRFeature oTileFeat( poDstLayer->GetLayerDefn() ); sprintf( szLocation, "%s,%d", fileNameToWrite, iLayer ); oTileFeat.SetGeometry( &oRegion ); oTileFeat.SetField( iTileIndexField, szLocation ); if( poDstLayer->CreateFeature( &oTileFeat ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature on tile index ... terminating." ); OGRDataSource::DestroyDataSource( poDstDS ); exit( 1 ); } } /* -------------------------------------------------------------------- */ /* Cleanup this data source. */ /* -------------------------------------------------------------------- */ CPLFree(fileNameToWrite); OGRDataSource::DestroyDataSource( poDS ); } /* -------------------------------------------------------------------- */ /* Close tile index and clear buffers. */ /* -------------------------------------------------------------------- */ OGRDataSource::DestroyDataSource( poDstDS ); OGRFeatureDefn::DestroyFeatureDefn( poFeatureDefn ); if (alreadyExistingSpatialRef != NULL) OGRSpatialReference::DestroySpatialReference( alreadyExistingSpatialRef ); CPLFree(current_path); if (nExistingLayers) { int i; for(i=0;i<nExistingLayers;i++) { CPLFree(existingLayersTab[i]); } CPLFree(existingLayersTab); } return 0; }
/********************************************************************** * TABIDFile::Open() * * Open a .ID file, and initialize the structures to be ready to read * objects from it. * * If the filename that is passed in contains a .MAP extension then * the extension will be changed to .ID before trying to open the file. * * Returns 0 on success, -1 on error. **********************************************************************/ int TABIDFile::Open(const char *pszFname, const char *pszAccess) { int nLen; if (m_fp) { CPLError(CE_Failure, CPLE_FileIO, "Open() failed: object already contains an open file"); return -1; } /*----------------------------------------------------------------- * Validate access mode and make sure we use binary access. *----------------------------------------------------------------*/ if (EQUALN(pszAccess, "r", 1)) { m_eAccessMode = TABRead; pszAccess = "rb"; } else if (EQUALN(pszAccess, "w", 1)) { m_eAccessMode = TABWrite; pszAccess = "wb"; } else { CPLError(CE_Failure, CPLE_FileIO, "Open() failed: access mode \"%s\" not supported", pszAccess); return -1; } /*----------------------------------------------------------------- * Change .MAP extension to .ID if necessary *----------------------------------------------------------------*/ m_pszFname = CPLStrdup(pszFname); nLen = strlen(m_pszFname); if (nLen > 4 && strcmp(m_pszFname+nLen-4, ".MAP")==0) strcpy(m_pszFname+nLen-4, ".ID"); else if (nLen > 4 && strcmp(m_pszFname+nLen-4, ".map")==0) strcpy(m_pszFname+nLen-4, ".id"); /*----------------------------------------------------------------- * Change .MAP extension to .ID if necessary *----------------------------------------------------------------*/ #ifndef _WIN32 TABAdjustFilenameExtension(m_pszFname); #endif /*----------------------------------------------------------------- * Open file *----------------------------------------------------------------*/ m_fp = VSIFOpen(m_pszFname, pszAccess); if (m_fp == NULL) { CPLError(CE_Failure, CPLE_FileIO, "Open() failed for %s", m_pszFname); CPLFree(m_pszFname); m_pszFname = NULL; return -1; } if (m_eAccessMode == TABRead) { /*------------------------------------------------------------- * READ access: * Establish the number of object IDs from the size of the file *------------------------------------------------------------*/ VSIStatBuf sStatBuf; if ( VSIStat(m_pszFname, &sStatBuf) == -1 ) { CPLError(CE_Failure, CPLE_FileIO, "stat() failed for %s\n", m_pszFname); Close(); return -1; } m_nMaxId = sStatBuf.st_size/4; m_nBlockSize = MIN(1024, m_nMaxId*4); /*------------------------------------------------------------- * Read the first block from the file *------------------------------------------------------------*/ m_poIDBlock = new TABRawBinBlock(m_eAccessMode, FALSE); if (m_nMaxId == 0) { // .ID file size = 0 ... just allocate a blank block but // it won't get really used anyways. m_nBlockSize = 512; m_poIDBlock->InitNewBlock(m_fp, m_nBlockSize, 0); } else if (m_poIDBlock->ReadFromFile(m_fp, 0, m_nBlockSize) != 0) { // CPLError() has already been called. Close(); return -1; } } else { /*------------------------------------------------------------- * WRITE access: * Get ready to write to the file *------------------------------------------------------------*/ m_poIDBlock = new TABRawBinBlock(m_eAccessMode, FALSE); m_nMaxId = 0; m_nBlockSize = 1024; m_poIDBlock->InitNewBlock(m_fp, m_nBlockSize, 0); } return 0; }
MAIN_START(argc, argv) { // Check that we are running against at least GDAL 1.4. // Note to developers: if we use newer API, please change the requirement. if( atoi(GDALVersionInfo("VERSION_NUM")) < 1400 ) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Get commandline arguments other than the GDAL raster filenames. */ /* -------------------------------------------------------------------- */ const char* pszIndexLayerName = nullptr; const char *index_filename = nullptr; const char *tile_index = "location"; const char* pszDriverName = nullptr; size_t nMaxFieldSize = 254; bool write_absolute_path = false; char* current_path = nullptr; bool skip_different_projection = false; const char *pszTargetSRS = ""; bool bSetTargetSRS = false; const char* pszSrcSRSName = nullptr; int i_SrcSRSName = -1; bool bSrcSRSFormatSpecified = false; SrcSRSFormat eSrcSRSFormat = FORMAT_AUTO; int iArg = 1; // Used after for. for( ; iArg < argc; iArg++ ) { if( EQUAL(argv[iArg], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against " "GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); CSLDestroy( argv ); return 0; } else if( EQUAL(argv[iArg],"--help") ) Usage(nullptr); else if( (strcmp(argv[iArg],"-f") == 0 || strcmp(argv[iArg],"-of") == 0) ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszDriverName = argv[++iArg]; } else if( strcmp(argv[iArg],"-lyr_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszIndexLayerName = argv[++iArg]; } else if( strcmp(argv[iArg],"-tileindex") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); tile_index = argv[++iArg]; } else if( strcmp(argv[iArg],"-t_srs") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszTargetSRS = argv[++iArg]; bSetTargetSRS = true; } else if ( strcmp(argv[iArg],"-write_absolute_path") == 0 ) { write_absolute_path = true; } else if ( strcmp(argv[iArg],"-skip_different_projection") == 0 ) { skip_different_projection = true; } else if( strcmp(argv[iArg], "-src_srs_name") == 0 ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszSrcSRSName = argv[++iArg]; } else if( strcmp(argv[iArg], "-src_srs_format") == 0 ) { const char* pszFormat; bSrcSRSFormatSpecified = true; CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++iArg]; if( EQUAL(pszFormat, "AUTO") ) eSrcSRSFormat = FORMAT_AUTO; else if( EQUAL(pszFormat, "WKT") ) eSrcSRSFormat = FORMAT_WKT; else if( EQUAL(pszFormat, "EPSG") ) eSrcSRSFormat = FORMAT_EPSG; else if( EQUAL(pszFormat, "PROJ") ) eSrcSRSFormat = FORMAT_PROJ; } else if( argv[iArg][0] == '-' ) Usage(CPLSPrintf("Unknown option name '%s'", argv[iArg])); else if( index_filename == nullptr ) { index_filename = argv[iArg]; iArg++; break; } } if( index_filename == nullptr ) Usage("No index filename specified."); if( iArg == argc ) Usage("No file to index specified."); if( bSrcSRSFormatSpecified && pszSrcSRSName == nullptr ) Usage("-src_srs_name must be specified when -src_srs_format is " "specified."); /* -------------------------------------------------------------------- */ /* Create and validate target SRS if given. */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hTargetSRS = nullptr; if( bSetTargetSRS ) { if( skip_different_projection ) { fprintf( stderr, "Warning : -skip_different_projection does not apply " "when -t_srs is requested.\n" ); } hTargetSRS = OSRNewSpatialReference(""); OSRSetAxisMappingStrategy(hTargetSRS, OAMS_TRADITIONAL_GIS_ORDER); // coverity[tainted_data] if( OSRSetFromUserInput( hTargetSRS, pszTargetSRS ) != CE_None ) { OSRDestroySpatialReference( hTargetSRS ); fprintf( stderr, "Invalid target SRS `%s'.\n", pszTargetSRS ); exit(1); } } /* -------------------------------------------------------------------- */ /* Open or create the target datasource */ /* -------------------------------------------------------------------- */ GDALDatasetH hTileIndexDS = GDALOpenEx( index_filename, GDAL_OF_VECTOR | GDAL_OF_UPDATE, nullptr, nullptr, nullptr ); OGRLayerH hLayer = nullptr; CPLString osFormat; if( hTileIndexDS != nullptr ) { GDALDriverH hDriver = GDALGetDatasetDriver(hTileIndexDS); if( hDriver ) osFormat = GDALGetDriverShortName(hDriver); if( GDALDatasetGetLayerCount(hTileIndexDS) == 1 ) { hLayer = GDALDatasetGetLayer(hTileIndexDS, 0); } else { if( pszIndexLayerName == nullptr ) { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } CPLPushErrorHandler(CPLQuietErrorHandler); hLayer = GDALDatasetGetLayerByName(hTileIndexDS, pszIndexLayerName); CPLPopErrorHandler(); } } else { printf( "Creating new index file...\n" ); if( pszDriverName == nullptr ) { std::vector<CPLString> aoDrivers = GetOutputDriversFor(index_filename, GDAL_OF_VECTOR); if( aoDrivers.empty() ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot guess driver for %s", index_filename); exit( 10 ); } else { if( aoDrivers.size() > 1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Several drivers matching %s extension. Using %s", CPLGetExtension(index_filename), aoDrivers[0].c_str() ); } osFormat = aoDrivers[0]; } } else { osFormat = pszDriverName; } if( !EQUAL(osFormat, "ESRI Shapefile") ) nMaxFieldSize = 0; GDALDriverH hDriver = GDALGetDriverByName( osFormat.c_str() ); if( hDriver == nullptr ) { printf( "%s driver not available.\n", osFormat.c_str() ); exit( 1 ); } hTileIndexDS = GDALCreate( hDriver, index_filename, 0, 0, 0, GDT_Unknown, nullptr ); } if( hTileIndexDS != nullptr && hLayer == nullptr ) { OGRSpatialReferenceH hSpatialRef = nullptr; char* pszLayerName = nullptr; if( pszIndexLayerName == nullptr ) { VSIStatBuf sStat; if( EQUAL(osFormat, "ESRI Shapefile") || VSIStat(index_filename, &sStat) == 0 ) { pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); } else { printf( "-lyr_name must be specified.\n" ); exit( 1 ); } } else { pszLayerName = CPLStrdup(pszIndexLayerName); } /* get spatial reference for output file from target SRS (if set) */ /* or from first input file */ if( bSetTargetSRS ) { hSpatialRef = OSRClone( hTargetSRS ); } else { GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS ) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != nullptr && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); OSRSetAxisMappingStrategy(hSpatialRef, OAMS_TRADITIONAL_GIS_ORDER); } GDALClose(hDS); } } hLayer = GDALDatasetCreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, nullptr ); CPLFree(pszLayerName); if( hSpatialRef ) OSRRelease(hSpatialRef); if( hLayer ) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth( hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); if( pszSrcSRSName != nullptr ) { hFieldDefn = OGR_Fld_Create( pszSrcSRSName, OFTString ); if( nMaxFieldSize ) OGR_Fld_SetWidth(hFieldDefn, static_cast<int>(nMaxFieldSize)); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == nullptr || hLayer == nullptr ) { fprintf( stderr, "Unable to open/create shapefile `%s'.\n", index_filename ); exit(2); } OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hLayer); const int ti_field = OGR_FD_GetFieldIndex( hFDefn, tile_index ); if( ti_field < 0 ) { fprintf( stderr, "Unable to find field `%s' in file `%s'.\n", tile_index, index_filename ); exit(2); } if( pszSrcSRSName != nullptr ) i_SrcSRSName = OGR_FD_GetFieldIndex( hFDefn, pszSrcSRSName ); // Load in memory existing file names in SHP. int nExistingFiles = static_cast<int>(OGR_L_GetFeatureCount(hLayer, FALSE)); if( nExistingFiles < 0) nExistingFiles = 0; char** existingFilesTab = nullptr; bool alreadyExistingProjectionRefValid = false; char* alreadyExistingProjectionRef = nullptr; if( nExistingFiles > 0 ) { OGRFeatureH hFeature = nullptr; existingFilesTab = static_cast<char **>( CPLMalloc(nExistingFiles * sizeof(char*))); for( int i = 0; i < nExistingFiles; i++ ) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if( i == 0 ) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if( hDS ) { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if( write_absolute_path ) { current_path = CPLGetCurrentDir(); if (current_path == nullptr) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n" ); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ for( ; iArg < argc; iArg++ ) { char *fileNameToWrite = nullptr; VSIStatBuf sStatBuf; // Make sure it is a file before building absolute path name. if( write_absolute_path && CPLIsFilenameRelative( argv[iArg] ) && VSIStat( argv[iArg], &sStatBuf ) == 0 ) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv[iArg])); } else { fileNameToWrite = CPLStrdup(argv[iArg]); } // Checks that file is not already in tileindex. { int i = 0; // Used after for. for( ; i < nExistingFiles; i++ ) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } } GDALDatasetH hDS = GDALOpen( argv[iArg], GA_ReadOnly ); if( hDS == nullptr ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv[iArg] ); CPLFree(fileNameToWrite); continue; } double adfGeoTransform[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && std::abs(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv[iArg] ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } const char *projectionRef = GDALGetProjectionRef(hDS); // If not set target srs, test that the current file uses same // projection as others. if( !bSetTargetSRS ) { if( alreadyExistingProjectionRefValid ) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf( stderr, "Warning : %s is not using the same projection system " "as other files in the tileindex.\n" "This may cause problems when using it in MapServer " "for example.\n" "Use -t_srs option to set target projection system " "(not supported by MapServer).\n" "%s\n", argv[iArg], skip_different_projection ? "Skipping this file." : ""); if( skip_different_projection ) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = true; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } } const int nXSize = GDALGetRasterXSize( hDS ); const int nYSize = GDALGetRasterYSize( hDS ); double adfX[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; double adfY[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 }; adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; OGRSpatialReferenceH hSourceSRS = nullptr; if( (bSetTargetSRS || i_SrcSRSName >= 0) && projectionRef != nullptr && projectionRef[0] != '\0' ) { hSourceSRS = OSRNewSpatialReference( projectionRef ); OSRSetAxisMappingStrategy(hSourceSRS, OAMS_TRADITIONAL_GIS_ORDER); } // If set target srs, do the forward transformation of all points. if( bSetTargetSRS && projectionRef != nullptr && projectionRef[0] != '\0' ) { OGRCoordinateTransformationH hCT = nullptr; if( hSourceSRS && !OSRIsSame( hSourceSRS, hTargetSRS ) ) { hCT = OCTNewCoordinateTransformation( hSourceSRS, hTargetSRS ); if( hCT == nullptr || !OCTTransform( hCT, 5, adfX, adfY, nullptr ) ) { fprintf( stderr, "Warning : unable to transform points from source " "SRS `%s' to target SRS `%s'\n" "for file `%s' - file skipped\n", projectionRef, pszTargetSRS, fileNameToWrite ); if( hCT ) OCTDestroyCoordinateTransformation( hCT ); if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); continue; } if( hCT ) OCTDestroyCoordinateTransformation( hCT ); } } OGRFeatureH hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); if( i_SrcSRSName >= 0 && hSourceSRS != nullptr ) { const char* pszAuthorityCode = OSRGetAuthorityCode(hSourceSRS, nullptr); const char* pszAuthorityName = OSRGetAuthorityName(hSourceSRS, nullptr); if( eSrcSRSFormat == FORMAT_AUTO ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } else if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString(hFeature, i_SrcSRSName, projectionRef); } else { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } else { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } } } else if( eSrcSRSFormat == FORMAT_WKT ) { if( nMaxFieldSize == 0 || strlen(projectionRef) <= nMaxFieldSize ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, projectionRef ); } else { fprintf(stderr, "Cannot write WKT for file %s as it is too long!\n", fileNameToWrite); } } else if( eSrcSRSFormat == FORMAT_PROJ ) { char* pszProj4 = nullptr; if( OSRExportToProj4(hSourceSRS, &pszProj4) == OGRERR_NONE ) { OGR_F_SetFieldString( hFeature, i_SrcSRSName, pszProj4 ); CPLFree(pszProj4); } } else if( eSrcSRSFormat == FORMAT_EPSG ) { if( pszAuthorityName != nullptr && pszAuthorityCode != nullptr ) OGR_F_SetFieldString( hFeature, i_SrcSRSName, CPLSPrintf("%s:%s", pszAuthorityName, pszAuthorityCode) ); } } if( hSourceSRS ) OSRDestroySpatialReference( hSourceSRS ); OGRGeometryH hPoly = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hRing = OGR_G_CreateGeometry(wkbLinearRing); for( int k = 0; k < 5; k++ ) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { printf( "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } CPLFree(current_path); if (nExistingFiles) { for( int i = 0; i < nExistingFiles; i++ ) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); if ( hTargetSRS ) OSRDestroySpatialReference( hTargetSRS ); GDALClose( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); CSLDestroy(argv); exit( 0 ); }
int VSIStatL( const char * pszFilename, VSIStatBufL *psStatBuf ) { return( VSIStat( pszFilename, (VSIStatBuf *) psStatBuf ) ); }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
int tindex(maps*& conf, maps*& inputs,maps*& outputs) { char *index_filename = NULL; const char *tile_index = "location"; int i_arg, ti_field; OGRDataSourceH hTileIndexDS; OGRLayerH hLayer = NULL; OGRFeatureDefnH hFDefn; int write_absolute_path = FALSE; char* current_path = NULL; int i; int nExistingFiles; int skip_different_projection = FALSE; char** existingFilesTab = NULL; int alreadyExistingProjectionRefValid = FALSE; char* alreadyExistingProjectionRef = NULL; char* index_filename_mod; int bExists; VSIStatBuf sStatBuf; /* Check that we are running against at least GDAL 1.4 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { char tmp[1024]; sprintf(tmp, "At least, GDAL >= 1.4.0 is required for this version of" "tindex, which was compiled against GDAL %s\n", GDAL_RELEASE_NAME); return SERVICE_FAILED; } GDALAllRegister(); OGRRegisterAll(); /* -------------------------------------------------------------------- */ /* Get the directory name to search for raster file to index. */ /* -------------------------------------------------------------------- */ char *tmpDataDir; char *pszDataDir; map* tmpMap=getMapFromMaps(conf,"main","isTrial"); map* tmpMap1=getMapFromMaps(conf,"main","dataPath"); map* tmpInputMap=getMapFromMaps(inputs,"dir","value"); if(tmpMap!=NULL && strcasecmp(tmpMap->value,"true")==0){ pszDataDir=(char*) malloc((strlen(tmpInputMap->value)+strlen(tmpMap1->value)+5+1)*sizeof(char)); sprintf(pszDataDir,"%s/ftp/%s",tmpMap1->value,tmpInputMap->value); }else{ pszDataDir=(char*) malloc(((strlen(tmpInputMap->value)+1)*sizeof(char))); sprintf(pszDataDir,"%s",tmpInputMap->value); } tmpMap=getMapFromMaps(inputs,"iname","value"); tmpMap1=getMapFromMaps(inputs,"idir","value"); map* tmpMap2=getMapFromMaps(conf,"main","dataPath"); if(tmpMap!=NULL && tmpMap1!=NULL && tmpMap2!=NULL){ index_filename = (char*) malloc((strlen(tmpMap->value)+strlen(tmpMap1->value)+strlen(tmpMap2->value)+12)*sizeof(char)); sprintf(index_filename,"%s/dirs/%s/%s.shp",tmpMap2->value,tmpMap1->value,tmpMap->value); } fprintf(stderr,"Filename %s\n",index_filename); /* -------------------------------------------------------------------- */ /* Open or create the target shapefile and DBF file. */ /* -------------------------------------------------------------------- */ index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "shp")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); if (!bExists) { CPLFree(index_filename_mod); index_filename_mod = CPLStrdup(CPLResetExtension(index_filename, "SHP")); bExists = (VSIStat(index_filename_mod, &sStatBuf) == 0); } CPLFree(index_filename_mod); if (bExists) { hTileIndexDS = OGROpen( index_filename, TRUE, NULL ); if (hTileIndexDS != NULL) { hLayer = OGR_DS_GetLayer(hTileIndexDS, 0); } } else { OGRSFDriverH hDriver; const char* pszDriverName = "ESRI Shapefile"; fprintf( stderr,"Creating new index file...\n" ); hDriver = OGRGetDriverByName( pszDriverName ); if( hDriver == NULL ) { char msg[1024]; sprintf( msg, "%s driver not available.", pszDriverName ); setMapInMaps(conf,"lenv","message",msg); return SERVICE_FAILED; } hTileIndexDS = OGR_Dr_CreateDataSource( hDriver, index_filename, NULL ); if (hTileIndexDS) { char* pszLayerName = CPLStrdup(CPLGetBasename(index_filename)); OGRSpatialReferenceH hSpatialRef = NULL; GDALDatasetH hDS = GDALOpen( index_filename, GA_ReadOnly ); if (hDS) { const char* pszWKT = GDALGetProjectionRef(hDS); if (pszWKT != NULL && pszWKT[0] != '\0') { hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } DIR *dirp = opendir(pszDataDir); if(dirp==NULL){ char tmp1[1024]; sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir); setMapInMaps(conf,"lenv","message",tmp1); return SERVICE_FAILED; } char *res=NULL; struct dirent *dp; tmpMap=getMapFromMaps(inputs,"ext","value"); char *ext; if(tmpMap!=NULL) ext=tmpMap->value; while ((dp = readdir(dirp)) != NULL){ if(strncmp(dp->d_name,".",1)!=0&&strncmp(dp->d_name,"..",2)!=0){ char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char)); sprintf(argv,"%s/%s",pszDataDir,dp->d_name); GDALDatasetH hDS0 = GDALOpen( argv, GA_ReadOnly ); if (hDS0) { const char* pszWKT = GDALGetProjectionRef(hDS0); fprintf(stderr,"SRS %s \n",pszWKT); if (pszWKT != NULL && pszWKT[0] != '\0') { if (hSpatialRef) OSRRelease(hSpatialRef); hSpatialRef = OSRNewSpatialReference(pszWKT); } GDALClose(hDS); } break; } } closedir(dirp); hLayer = OGR_DS_CreateLayer( hTileIndexDS, pszLayerName, hSpatialRef, wkbPolygon, NULL ); CPLFree(pszLayerName); if (hSpatialRef) OSRRelease(hSpatialRef); if (hLayer) { OGRFieldDefnH hFieldDefn = OGR_Fld_Create( tile_index, OFTString ); OGR_Fld_SetWidth( hFieldDefn, 255); OGR_L_CreateField( hLayer, hFieldDefn, TRUE ); OGR_Fld_Destroy(hFieldDefn); } } } if( hTileIndexDS == NULL || hLayer == NULL ) { char msg[1024]; sprintf( msg, "Unable to open/create shapefile `%s'.", index_filename ); setMapInMaps(conf,"lenv","message",msg); } hFDefn = OGR_L_GetLayerDefn(hLayer); for( ti_field = 0; ti_field < OGR_FD_GetFieldCount(hFDefn); ti_field++ ) { OGRFieldDefnH hFieldDefn = OGR_FD_GetFieldDefn( hFDefn, ti_field ); if( strcmp(OGR_Fld_GetNameRef(hFieldDefn), tile_index) == 0 ) break; } if( ti_field == OGR_FD_GetFieldCount(hFDefn) ) { char msg[1024]; sprintf( msg, "Unable to find field `%s' in DBF file `%s'.\n", tile_index, index_filename ); setMapInMaps(conf,"lenv","message",msg); return SERVICE_FAILED; } /* Load in memory existing file names in SHP */ nExistingFiles = OGR_L_GetFeatureCount(hLayer, FALSE); if (nExistingFiles) { OGRFeatureH hFeature; existingFilesTab = (char**)CPLMalloc(nExistingFiles * sizeof(char*)); for(i=0;i<nExistingFiles;i++) { hFeature = OGR_L_GetNextFeature(hLayer); existingFilesTab[i] = CPLStrdup(OGR_F_GetFieldAsString( hFeature, ti_field )); if (i == 0) { GDALDatasetH hDS = GDALOpen(existingFilesTab[i], GA_ReadOnly ); if (hDS) { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(GDALGetProjectionRef(hDS)); GDALClose(hDS); } } OGR_F_Destroy( hFeature ); } } if (write_absolute_path) { current_path = CPLGetCurrentDir(); if (current_path == NULL) { fprintf( stderr, "This system does not support the CPLGetCurrentDir call. " "The option -write_absolute_path will have no effect\n"); write_absolute_path = FALSE; } } /* -------------------------------------------------------------------- */ /* loop over GDAL files, processing. */ /* -------------------------------------------------------------------- */ DIR *dirp = opendir(pszDataDir); if(dirp==NULL){ char tmp1[1024]; sprintf(tmp1,_ss("The specified path %s doesn't exist."),pszDataDir); setMapInMaps(conf,"lenv","message",tmp1); return SERVICE_FAILED; } char *res=NULL; struct dirent *dp; tmpMap=getMapFromMaps(inputs,"ext","value"); char *ext; if(tmpMap!=NULL) ext=tmpMap->value; while ((dp = readdir(dirp)) != NULL){ if(strlen(dp->d_name)>2 && strstr(dp->d_name,".")!=0 && strstr(dp->d_name,ext)>0){ char* argv=(char*) malloc((strlen(dp->d_name)+strlen(pszDataDir)+2)*sizeof(char)); sprintf(argv,"%s/%s",pszDataDir,dp->d_name); GDALDatasetH hDS; double adfGeoTransform[6]; double adfX[5], adfY[5]; int nXSize, nYSize; char* fileNameToWrite; const char* projectionRef; VSIStatBuf sStatBuf; int k; OGRFeatureH hFeature; OGRGeometryH hPoly, hRing; /* Make sure it is a file before building absolute path name */ if (write_absolute_path && CPLIsFilenameRelative( argv ) && VSIStat( argv, &sStatBuf ) == 0) { fileNameToWrite = CPLStrdup(CPLProjectRelativeFilename(current_path, argv)); } else { fileNameToWrite = CPLStrdup(argv); } /* Checks that file is not already in tileindex */ for(i=0;i<nExistingFiles;i++) { if (EQUAL(fileNameToWrite, existingFilesTab[i])) { fprintf(stderr, "File %s is already in tileindex. Skipping it.\n", fileNameToWrite); break; } } if (i != nExistingFiles) { CPLFree(fileNameToWrite); continue; } hDS = GDALOpen( argv, GA_ReadOnly ); if( hDS == NULL ) { fprintf( stderr, "Unable to open %s, skipping.\n", argv ); CPLFree(fileNameToWrite); continue; } GDALGetGeoTransform( hDS, adfGeoTransform ); if( adfGeoTransform[0] == 0.0 && adfGeoTransform[1] == 1.0 && adfGeoTransform[3] == 0.0 && ABS(adfGeoTransform[5]) == 1.0 ) { fprintf( stderr, "It appears no georeferencing is available for\n" "`%s', skipping.\n", argv ); GDALClose( hDS ); CPLFree(fileNameToWrite); continue; } projectionRef = GDALGetProjectionRef(hDS); if (alreadyExistingProjectionRefValid) { int projectionRefNotNull, alreadyExistingProjectionRefNotNull; projectionRefNotNull = projectionRef && projectionRef[0]; alreadyExistingProjectionRefNotNull = alreadyExistingProjectionRef && alreadyExistingProjectionRef[0]; if ((projectionRefNotNull && alreadyExistingProjectionRefNotNull && EQUAL(projectionRef, alreadyExistingProjectionRef) == 0) || (projectionRefNotNull != alreadyExistingProjectionRefNotNull)) { fprintf(stderr, "Warning : %s is not using the same projection system as " "other files in the tileindex. This may cause problems when " "using it in MapServer for example.%s\n", argv, (skip_different_projection) ? " Skipping it" : ""); if (skip_different_projection) { CPLFree(fileNameToWrite); GDALClose( hDS ); continue; } } } else { alreadyExistingProjectionRefValid = TRUE; alreadyExistingProjectionRef = CPLStrdup(projectionRef); } nXSize = GDALGetRasterXSize( hDS ); nYSize = GDALGetRasterYSize( hDS ); adfX[0] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[0] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[1] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[1] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + 0 * adfGeoTransform[5]; adfX[2] = adfGeoTransform[0] + nXSize * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[2] = adfGeoTransform[3] + nXSize * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[3] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + nYSize * adfGeoTransform[2]; adfY[3] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + nYSize * adfGeoTransform[5]; adfX[4] = adfGeoTransform[0] + 0 * adfGeoTransform[1] + 0 * adfGeoTransform[2]; adfY[4] = adfGeoTransform[3] + 0 * adfGeoTransform[4] + 0 * adfGeoTransform[5]; hFeature = OGR_F_Create( OGR_L_GetLayerDefn( hLayer ) ); OGR_F_SetFieldString( hFeature, ti_field, fileNameToWrite ); hPoly = OGR_G_CreateGeometry(wkbPolygon); hRing = OGR_G_CreateGeometry(wkbLinearRing); for(k=0;k<5;k++) OGR_G_SetPoint_2D(hRing, k, adfX[k], adfY[k]); OGR_G_AddGeometryDirectly( hPoly, hRing ); OGR_F_SetGeometryDirectly( hFeature, hPoly ); if( OGR_L_CreateFeature( hLayer, hFeature ) != OGRERR_NONE ) { fprintf( stderr, "Failed to create feature in shapefile.\n" ); break; } OGR_F_Destroy( hFeature ); CPLFree(fileNameToWrite); GDALClose( hDS ); } } CPLFree(current_path); if (nExistingFiles) { for(i=0;i<nExistingFiles;i++) { CPLFree(existingFilesTab[i]); } CPLFree(existingFilesTab); } CPLFree(alreadyExistingProjectionRef); OGR_DS_Destroy( hTileIndexDS ); GDALDestroyDriverManager(); OGRCleanupAll(); setMapInMaps(outputs,"Result","value","Tile index successfully created."); //CSLDestroy(argv); return SERVICE_SUCCEEDED; }