OGRSpatialReference *OGRShapeLayer::GetSpatialRef() { if (bSRSSet) return poSRS; bSRSSet = TRUE; /* -------------------------------------------------------------------- */ /* Is there an associated .prj file we can read? */ /* -------------------------------------------------------------------- */ const char *pszPrjFile = CPLResetExtension( pszFullName, "prj" ); char **papszLines; char* apszOptions[] = { (char*)"EMIT_ERROR_IF_CANNOT_OPEN_FILE=FALSE", NULL }; papszLines = CSLLoad2( pszPrjFile, -1, -1, apszOptions ); if (papszLines == NULL) { pszPrjFile = CPLResetExtension( pszFullName, "PRJ" ); papszLines = CSLLoad2( pszPrjFile, -1, -1, apszOptions ); } if( papszLines != NULL ) { poSRS = new OGRSpatialReference(); if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE ) { delete poSRS; poSRS = NULL; } CSLDestroy( papszLines ); } return poSRS; }
int OGRIdrisiLayer::Detect_AVL_ADC(const char* pszFilename) { // -------------------------------------------------------------------- // Look for .adc file // -------------------------------------------------------------------- const char* pszADCFilename = CPLResetExtension(pszFilename, "adc"); VSILFILE* fpADC = VSIFOpenL(pszADCFilename, "rb"); if (fpADC == NULL) { pszADCFilename = CPLResetExtension(pszFilename, "ADC"); fpADC = VSIFOpenL(pszADCFilename, "rb"); } char** papszADC = NULL; if (fpADC != NULL) { VSIFCloseL(fpADC); fpADC = NULL; CPLPushErrorHandler(CPLQuietErrorHandler); papszADC = CSLLoad2(pszADCFilename, 1024, 256, NULL); CPLPopErrorHandler(); CPLErrorReset(); } if (papszADC == NULL) return FALSE; CSLSetNameValueSeparator( papszADC, ":" ); const char *pszVersion = CSLFetchNameValue( papszADC, "file format " ); if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Values A.1" ) ) { CSLDestroy( papszADC ); return FALSE; } const char *pszFileType = CSLFetchNameValue( papszADC, "file type " ); if( pszFileType == NULL || !EQUAL( pszFileType, "ascii" ) ) { CPLDebug("IDRISI", ".adc file found, but file type != ascii"); CSLDestroy( papszADC ); return FALSE; } const char* pszRecords = CSLFetchNameValue( papszADC, "records " ); if( pszRecords == NULL || atoi(pszRecords) != (int)nTotalFeatures ) { CPLDebug("IDRISI", ".adc file found, but 'records' not found or not " "consistent with feature number declared in .vdc"); CSLDestroy( papszADC ); return FALSE; } const char* pszFields = CSLFetchNameValue( papszADC, "fields " ); if( pszFields == NULL || atoi(pszFields) <= 1 ) { CPLDebug("IDRISI", ".adc file found, but 'fields' not found or invalid"); CSLDestroy( papszADC ); return FALSE; } // -------------------------------------------------------------------- // Look for .avl file // -------------------------------------------------------------------- const char* pszAVLFilename = CPLResetExtension(pszFilename, "avl"); fpAVL = VSIFOpenL(pszAVLFilename, "rb"); if (fpAVL == NULL) { pszAVLFilename = CPLResetExtension(pszFilename, "AVL"); fpAVL = VSIFOpenL(pszAVLFilename, "rb"); } if (fpAVL == NULL) { CSLDestroy( papszADC ); return FALSE; } // -------------------------------------------------------------------- // Build layer definition // -------------------------------------------------------------------- int iCurField; char szKey[32]; iCurField = 0; sprintf(szKey, "field %d ", iCurField); char** papszIter = papszADC; const char* pszLine; int bFieldFound = FALSE; CPLString osFieldName; while((pszLine = *papszIter) != NULL) { //CPLDebug("IDRISI", "%s", pszLine); if (strncmp(pszLine, szKey, strlen(szKey)) == 0) { const char* pszColon = strchr(pszLine, ':'); if (pszColon) { osFieldName = pszColon + 1; bFieldFound = TRUE; } } else if (bFieldFound && strncmp(pszLine, "data type :", strlen("data type :")) == 0) { const char* pszFieldType = pszLine + strlen("data type :"); OGRFieldDefn oFieldDefn(osFieldName.c_str(), EQUAL(pszFieldType, "integer") ? OFTInteger : EQUAL(pszFieldType, "real") ? OFTReal : OFTString); if( iCurField == 0 && oFieldDefn.GetType() != OFTInteger ) { CSLDestroy( papszADC ); return FALSE; } if( iCurField != 0 ) poFeatureDefn->AddFieldDefn( &oFieldDefn ); iCurField ++; sprintf(szKey, "field %d ", iCurField); } papszIter++; } CSLDestroy(papszADC); return TRUE; }
int OGRIdrisiDataSource::Open( const char * pszFilename ) { pszName = CPLStrdup( pszFilename ); VSILFILE* fpVCT = VSIFOpenL(pszFilename, "rb"); if (fpVCT == NULL) return FALSE; char* pszWTKString = NULL; // -------------------------------------------------------------------- // Look for .vdc file // -------------------------------------------------------------------- const char* pszVDCFilename = CPLResetExtension(pszFilename, "vdc"); VSILFILE* fpVDC = VSIFOpenL(pszVDCFilename, "rb"); if (fpVDC == NULL) { pszVDCFilename = CPLResetExtension(pszFilename, "VDC"); fpVDC = VSIFOpenL(pszVDCFilename, "rb"); } char** papszVDC = NULL; if (fpVDC != NULL) { VSIFCloseL(fpVDC); fpVDC = NULL; CPLPushErrorHandler(CPLQuietErrorHandler); papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, NULL); CPLPopErrorHandler(); CPLErrorReset(); } OGRwkbGeometryType eType = wkbUnknown; if (papszVDC != NULL) { CSLSetNameValueSeparator( papszVDC, ":" ); const char *pszVersion = CSLFetchNameValue( papszVDC, "file format " ); if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Vector A.1" ) ) { CSLDestroy( papszVDC ); VSIFCloseL(fpVCT); return FALSE; } const char *pszRefSystem = CSLFetchNameValue( papszVDC, "ref. system " ); const char *pszRefUnits = CSLFetchNameValue( papszVDC, "ref. units " ); if (pszRefSystem != NULL && pszRefUnits != NULL) IdrisiGeoReference2Wkt( pszFilename, pszRefSystem, pszRefUnits, &pszWTKString); } GByte chType; if (VSIFReadL(&chType, 1, 1, fpVCT) != 1) { VSIFCloseL(fpVCT); CSLDestroy( papszVDC ); return FALSE; } if (chType == 1) eType = wkbPoint; else if (chType == 2) eType = wkbLineString; else if (chType == 3) eType = wkbPolygon; else { CPLError( CE_Failure, CPLE_AppDefined, "Unsupport geometry type : %d", static_cast<int>(chType) ); VSIFCloseL(fpVCT); CSLDestroy( papszVDC ); return FALSE; } const char *pszMinX = CSLFetchNameValue( papszVDC, "min. X " ); const char *pszMaxX = CSLFetchNameValue( papszVDC, "max. X " ); const char *pszMinY = CSLFetchNameValue( papszVDC, "min. Y " ); const char *pszMaxY = CSLFetchNameValue( papszVDC, "max. Y " ); OGRIdrisiLayer* poLayer = new OGRIdrisiLayer(pszFilename, CPLGetBasename(pszFilename), fpVCT, eType, pszWTKString); papoLayers = static_cast<OGRLayer**>( CPLMalloc(sizeof(OGRLayer*)) ); papoLayers[nLayers ++] = poLayer; if( pszMinX != NULL && pszMaxX != NULL && pszMinY != NULL && pszMaxY != NULL) { poLayer->SetExtent( CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX), CPLAtof(pszMaxY) ); } CPLFree(pszWTKString); CSLDestroy( papszVDC ); return TRUE; }
GDALDataset *OZIDataset::Open( GDALOpenInfo * poOpenInfo ) { if (!Identify(poOpenInfo)) return NULL; GByte abyHeader[14]; CPLString osImgFilename = poOpenInfo->pszFilename; int bIsMap = FALSE; if (EQUALN((const char*)poOpenInfo->pabyHeader, "OziExplorer Map Data File Version ", 34) ) { char** papszLines = CSLLoad2( poOpenInfo->pszFilename, 1000, 200, NULL ); if ( !papszLines || CSLCount(papszLines) < 5) { CSLDestroy(papszLines); return FALSE; } bIsMap = TRUE; osImgFilename = papszLines[2]; VSIStatBufL sStat; if (VSIStatL(osImgFilename, &sStat) != 0) { if (CPLIsFilenameRelative(osImgFilename)) { CPLString osPath = CPLGetPath(poOpenInfo->pszFilename); osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL); } else { CPLString osPath = CPLGetPath(poOpenInfo->pszFilename); osImgFilename = CPLGetFilename(osImgFilename); osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL); } } CSLDestroy(papszLines); GDALOpenInfo oOpenInfo(osImgFilename, GA_ReadOnly); if (!Identify(&oOpenInfo)) return NULL; memcpy(abyHeader, oOpenInfo.pabyHeader, 14); } else memcpy(abyHeader, poOpenInfo->pabyHeader, 14); int bOzi3 = (abyHeader[0] == 0x80 && abyHeader[1] == 0x77); VSILFILE* fp = VSIFOpenL(osImgFilename.c_str(), "rb"); if (fp == NULL) return NULL; OZIDataset* poDS = new OZIDataset(); poDS->fp = fp; if (bIsMap) { poDS->bReadMapFileSuccess = GDALLoadOziMapFile( poOpenInfo->pszFilename, poDS->adfGeoTransform, &poDS->pszWKT, &poDS->nGCPCount, &poDS->pasGCPs ); } GByte nRandomNumber = 0; GByte nKeyInit = 0; if (bOzi3) { VSIFSeekL(fp, 14, SEEK_SET); VSIFReadL(&nRandomNumber, 1, 1, fp); //printf("nRandomNumber = %d\n", nRandomNumber); if (nRandomNumber < 0x94) { delete poDS; return NULL; } VSIFSeekL(fp, 0x93, SEEK_CUR); VSIFReadL(&nKeyInit, 1, 1, fp); VSIFSeekL(fp, 0, SEEK_SET); VSIFReadL(abyHeader, 1, 14, fp); OZIDecrypt(abyHeader, 14, nKeyInit); if (!(abyHeader[6] == 0x40 && abyHeader[7] == 0x00 && abyHeader[8] == 0x01 && abyHeader[9] == 0x00 && abyHeader[10] == 0x36 && abyHeader[11] == 0x04 && abyHeader[12] == 0x00 && abyHeader[13] == 0x00)) { delete poDS; return NULL; } VSIFSeekL(fp, 14 + 1 + nRandomNumber, SEEK_SET); int nMagic = ReadInt(fp, bOzi3, nKeyInit); CPLDebug("OZI", "OZI version code : 0x%08X", nMagic); poDS->bOzi3 = bOzi3; } else { VSIFSeekL(fp, 14, SEEK_SET); } GByte abyHeader2[40], abyHeader2_Backup[40]; VSIFReadL(abyHeader2, 40, 1, fp); memcpy(abyHeader2_Backup, abyHeader2, 40); /* There's apparently a relationship between the nMagic number */ /* and the nKeyInit, but I'm too lazy to add switch/cases that might */ /* be not exhaustive, so let's try the 'brute force' attack !!! */ /* It is much so funny to be able to run one in a few microseconds :-) */ for(nKeyInit = 0; nKeyInit < 256; nKeyInit ++) { GByte* pabyHeader2 = abyHeader2; if (bOzi3) OZIDecrypt(abyHeader2, 40, nKeyInit); int nHeaderSize = ReadInt(&pabyHeader2); /* should be 40 */ poDS->nRasterXSize = ReadInt(&pabyHeader2); poDS->nRasterYSize = ReadInt(&pabyHeader2); int nDepth = ReadShort(&pabyHeader2); /* should be 1 */ int nBPP = ReadShort(&pabyHeader2); /* should be 8 */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* pixel number (height * width) : unused */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* ?? 0x100 */ ReadInt(&pabyHeader2); /* ?? 0x100 */ if (nHeaderSize != 40 || nDepth != 1 || nBPP != 8) { if (bOzi3) { if (nKeyInit != 255) { memcpy(abyHeader2, abyHeader2_Backup,40); continue; } else { CPLDebug("OZI", "Cannot decypher 2nd header. Sorry..."); delete poDS; return NULL; } } else { CPLDebug("OZI", "nHeaderSize = %d, nDepth = %d, nBPP = %d", nHeaderSize, nDepth, nBPP); delete poDS; return NULL; } } else break; } poDS->nKeyInit = nKeyInit; int nSeparator = ReadInt(fp); if (!bOzi3 && nSeparator != 0x77777777) { CPLDebug("OZI", "didn't get end of header2 marker"); delete poDS; return NULL; } poDS->nZoomLevelCount = ReadShort(fp); //CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount); if (poDS->nZoomLevelCount < 0 || poDS->nZoomLevelCount >= 256) { CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount); delete poDS; return NULL; } /* Skip array of zoom level percentage. We don't need it for GDAL */ VSIFSeekL(fp, sizeof(float) * poDS->nZoomLevelCount, SEEK_CUR); nSeparator = ReadInt(fp); if (!bOzi3 && nSeparator != 0x77777777) { /* Some files have 8 extra bytes before the marker. I'm not sure */ /* what they are used for. So just skeep them and hope that */ /* we'll find the marker */ nSeparator = ReadInt(fp); nSeparator = ReadInt(fp); if (nSeparator != 0x77777777) { CPLDebug("OZI", "didn't get end of zoom levels marker"); delete poDS; return NULL; } } VSIFSeekL(fp, 0, SEEK_END); vsi_l_offset nFileSize = VSIFTellL(fp); poDS->nFileSize = nFileSize; VSIFSeekL(fp, nFileSize - 4, SEEK_SET); int nZoomLevelTableOffset = ReadInt(fp, bOzi3, nKeyInit); if (nZoomLevelTableOffset < 0 || (vsi_l_offset)nZoomLevelTableOffset >= nFileSize) { CPLDebug("OZI", "nZoomLevelTableOffset = %d", nZoomLevelTableOffset); delete poDS; return NULL; } VSIFSeekL(fp, nZoomLevelTableOffset, SEEK_SET); poDS->panZoomLevelOffsets = (int*)CPLMalloc(sizeof(int) * poDS->nZoomLevelCount); int i; for(i=0;i<poDS->nZoomLevelCount;i++) { poDS->panZoomLevelOffsets[i] = ReadInt(fp, bOzi3, nKeyInit); if (poDS->panZoomLevelOffsets[i] < 0 || (vsi_l_offset)poDS->panZoomLevelOffsets[i] >= nFileSize) { CPLDebug("OZI", "panZoomLevelOffsets[%d] = %d", i, poDS->panZoomLevelOffsets[i]); delete poDS; return NULL; } } poDS->papoBands = (OZIRasterBand**)CPLCalloc(sizeof(OZIRasterBand*), poDS->nZoomLevelCount); for(i=0;i<poDS->nZoomLevelCount;i++) { VSIFSeekL(fp, poDS->panZoomLevelOffsets[i], SEEK_SET); int nW = ReadInt(fp, bOzi3, nKeyInit); int nH = ReadInt(fp, bOzi3, nKeyInit); short nTileX = ReadShort(fp, bOzi3, nKeyInit); short nTileY = ReadShort(fp, bOzi3, nKeyInit); if (i == 0 && (nW != poDS->nRasterXSize || nH != poDS->nRasterYSize)) { CPLDebug("OZI", "zoom[%d] inconsistant dimensions for zoom level 0 : nW=%d, nH=%d, nTileX=%d, nTileY=%d, nRasterXSize=%d, nRasterYSize=%d", i, nW, nH, nTileX, nTileY, poDS->nRasterXSize, poDS->nRasterYSize); delete poDS; return NULL; } /* Note (#3895): some files such as world.ozf2 provided with OziExplorer */ /* expose nTileY=33, but have nH=2048, so only require 32 tiles in vertical dimension. */ /* So there's apparently one extra and useless tile that will be ignored */ /* without causing apparent issues */ /* Some other files have more tile in horizontal direction than needed, so let's */ /* accept that. But in that case we really need to keep the nTileX value for IReadBlock() */ /* to work properly */ if ((nW + 63) / 64 > nTileX || (nH + 63) / 64 > nTileY) { CPLDebug("OZI", "zoom[%d] unexpected number of tiles : nW=%d, nH=%d, nTileX=%d, nTileY=%d", i, nW, nH, nTileX, nTileY); delete poDS; return NULL; } GDALColorTable* poColorTable = new GDALColorTable(); GByte abyColorTable[256*4]; VSIFReadL(abyColorTable, 1, 1024, fp); if (bOzi3) OZIDecrypt(abyColorTable, 1024, nKeyInit); int j; for(j=0;j<256;j++) { GDALColorEntry sEntry; sEntry.c1 = abyColorTable[4*j + 2]; sEntry.c2 = abyColorTable[4*j + 1]; sEntry.c3 = abyColorTable[4*j + 0]; sEntry.c4 = 255; poColorTable->SetColorEntry(j, &sEntry); } poDS->papoBands[i] = new OZIRasterBand(poDS, i, nW, nH, nTileX, poColorTable); if (i > 0) { GByte* pabyTranslationTable = poDS->papoBands[i]->GetIndexColorTranslationTo(poDS->papoBands[0], NULL, NULL); delete poDS->papoBands[i]->poColorTable; poDS->papoBands[i]->poColorTable = poDS->papoBands[0]->poColorTable->Clone(); poDS->papoBands[i]->pabyTranslationTable = pabyTranslationTable; } } poDS->SetBand(1, poDS->papoBands[0]); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
char **CPL_STDCALL GDALLoadRPCFile( const char *pszFilename, char **papszSiblingFiles ) { /* -------------------------------------------------------------------- */ /* Try to identify the RPC file in upper or lower case. */ /* -------------------------------------------------------------------- */ CPLString osTarget; /* Is this already a _RPC.TXT file ? */ if (strlen(pszFilename) > 8 && EQUAL(pszFilename + strlen(pszFilename) - 8, "_RPC.TXT")) osTarget = pszFilename; else { CPLString osSrcPath = pszFilename; CPLString soPt("."); size_t found = osSrcPath.rfind(soPt); if (found == CPLString::npos) return NULL; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt"); CPLString osTarget = osSrcPath; if( papszSiblingFiles == NULL ) { VSIStatBufL sStatBuf; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { return NULL; } } } } else { int iSibling = CSLFindString( papszSiblingFiles, CPLGetFilename(osTarget) ); if( iSibling < 0 ) return NULL; osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling])); osTarget += papszSiblingFiles[iSibling]; } } /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ char **papszLines = CSLLoad2( osTarget, 100, 100, NULL ); if(!papszLines) return NULL; char **papszMD = NULL; /* From LINE_OFF to HEIGHT_SCALE */ for(size_t i = 0; i < 19; i += 2 ) { const char *pszRPBVal = CSLFetchNameValue(papszLines, apszRPBMap[i] ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), apszRPBMap[i]); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], pszRPBVal ); } } /* For LINE_NUM_COEFF, LINE_DEN_COEFF, SAMP_NUM_COEFF, SAMP_DEN_COEFF */ /* parameters that have 20 values each */ for(size_t i = 20; apszRPBMap[i] != NULL; i += 2 ) { CPLString soVal; for(int j = 1; j <= 20; j++) { CPLString soRPBMapItem; soRPBMapItem.Printf("%s_%d", apszRPBMap[i], j); const char *pszRPBVal = CSLFetchNameValue(papszLines, soRPBMapItem.c_str() ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), soRPBMapItem.c_str() ); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { soVal += pszRPBVal; soVal += " "; } } papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], soVal.c_str() ); } CSLDestroy( papszLines ); return papszMD; }