void BSBDataset::ScanForGCPsBSB() { /* -------------------------------------------------------------------- */ /* Collect standalone GCPs. They look like: */ /* */ /* REF/1,115,2727,32.346666666667,-60.881666666667 */ /* REF/n,pixel,line,lat,long */ /* -------------------------------------------------------------------- */ int fileGCPCount=0; int i; // Count the GCPs (reference points) in psInfo->papszHeader for( i = 0; psInfo->papszHeader[i] != NULL; i++ ) if( EQUALN(psInfo->papszHeader[i],"REF/",4) ) fileGCPCount++; // Memory has not been allocated to fileGCPCount yet pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),fileGCPCount+1); for( i = 0; psInfo->papszHeader[i] != NULL; i++ ) { char **papszTokens; char szName[50]; if( !EQUALN(psInfo->papszHeader[i],"REF/",4) ) continue; papszTokens = CSLTokenizeStringComplex( psInfo->papszHeader[i]+4, ",", FALSE, FALSE ); if( CSLCount(papszTokens) > 4 ) { GDALInitGCPs( 1, pasGCPList + nGCPCount ); pasGCPList[nGCPCount].dfGCPX = atof(papszTokens[4]); pasGCPList[nGCPCount].dfGCPY = atof(papszTokens[3]); pasGCPList[nGCPCount].dfGCPPixel = atof(papszTokens[1]); pasGCPList[nGCPCount].dfGCPLine = atof(papszTokens[2]); CPLFree( pasGCPList[nGCPCount].pszId ); if( CSLCount(papszTokens) > 5 ) { pasGCPList[nGCPCount].pszId = CPLStrdup(papszTokens[5]); } else { sprintf( szName, "GCP_%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szName ); } nGCPCount++; } CSLDestroy( papszTokens ); } }
void BSBDataset::ScanForGCPsNos( const char *pszFilename ) { char **Tokens; const char *geofile; const char *extension; int fileGCPCount=0; extension = CPLGetExtension(pszFilename); // pseudointelligently try and guess whether we want a .geo or a .GEO if (extension[1] == 'O') { geofile = CPLResetExtension( pszFilename, "GEO"); } else { geofile = CPLResetExtension( pszFilename, "geo"); } FILE *gfp = VSIFOpen( geofile, "r" ); // Text files if( gfp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Couldn't find a matching .GEO file: %s", geofile ); return; } char *thisLine = (char *) CPLMalloc( 80 ); // FIXME // Count the GCPs (reference points) and seek the file pointer 'gfp' to the starting point while (fgets(thisLine, 80, gfp)) { if( EQUALN(thisLine, "Point", 5) ) fileGCPCount++; } VSIRewind( gfp ); // Memory has not been allocated to fileGCPCount yet pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),fileGCPCount+1); while (fgets(thisLine, 80, gfp)) { if( EQUALN(thisLine, "Point", 5) ) { // got a point line, turn it into a gcp Tokens = CSLTokenizeStringComplex(thisLine, "= ", FALSE, FALSE); if (CSLCount(Tokens) >= 5) { GDALInitGCPs( 1, pasGCPList + nGCPCount ); pasGCPList[nGCPCount].dfGCPX = atof(Tokens[1]); pasGCPList[nGCPCount].dfGCPY = atof(Tokens[2]); pasGCPList[nGCPCount].dfGCPPixel = atof(Tokens[4]); pasGCPList[nGCPCount].dfGCPLine = atof(Tokens[3]); CPLFree( pasGCPList[nGCPCount].pszId ); char szName[50]; sprintf( szName, "GCP_%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szName ); nGCPCount++; } CSLDestroy(Tokens); } } CPLFree(thisLine); VSIFClose(gfp); }
void *GDALDeserializeGCPTransformer( CPLXMLNode *psTree ) { GDAL_GCP *pasGCPList = 0; int nGCPCount = 0; void *pResult; int nReqOrder; int bReversed; int bRefine; int nMinimumGcps; double dfTolerance; /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { int nGCPMax = 0; CPLXMLNode *psXMLGCP; // Count GCPs. for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ nReqOrder = atoi(CPLGetXMLValue(psTree,"Order","3")); bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); bRefine = atoi(CPLGetXMLValue(psTree,"Refine","0")); nMinimumGcps = atoi(CPLGetXMLValue(psTree,"MinimumGcps","6")); dfTolerance = atof(CPLGetXMLValue(psTree,"Tolerance","1.0")); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ if(bRefine) { pResult = GDALCreateGCPRefineTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed, dfTolerance, nMinimumGcps ); } else { pResult = GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, bReversed ); } /* -------------------------------------------------------------------- */ /* Cleanup GCP copy. */ /* -------------------------------------------------------------------- */ GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); return pResult; }
CPLErr GDALPamDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath ) { /* -------------------------------------------------------------------- */ /* Check for an SRS node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "SRS", "")) > 0 ) { OGRSpatialReference oSRS; CPLFree( psPam->pszProjection ); psPam->pszProjection = NULL; if( oSRS.SetFromUserInput( CPLGetXMLValue(psTree, "SRS", "") ) == OGRERR_NONE ) oSRS.exportToWkt( &(psPam->pszProjection) ); } /* -------------------------------------------------------------------- */ /* Check for a GeoTransform node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "GeoTransform", "")) > 0 ) { const char *pszGT = CPLGetXMLValue(psTree, "GeoTransform", ""); char **papszTokens; papszTokens = CSLTokenizeStringComplex( pszGT, ",", FALSE, FALSE ); if( CSLCount(papszTokens) != 6 ) { CPLError( CE_Warning, CPLE_AppDefined, "GeoTransform node does not have expected six values."); } else { for( int iTA = 0; iTA < 6; iTA++ ) psPam->adfGeoTransform[iTA] = atof(papszTokens[iTA]); psPam->bHaveGeoTransform = TRUE; } CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { CPLXMLNode *psXMLGCP; OGRSpatialReference oSRS; const char *pszRawProj = CPLGetXMLValue(psGCPList, "Projection", ""); CPLFree( psPam->pszGCPProjection ); if( strlen(pszRawProj) > 0 && oSRS.SetFromUserInput( pszRawProj ) == OGRERR_NONE ) oSRS.exportToWkt( &(psPam->pszGCPProjection) ); else psPam->pszGCPProjection = CPLStrdup(""); // Count GCPs. int nGCPMax = 0; for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; psPam->pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = psPam->pasGCPList + psPam->nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); psPam->nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Process bands. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psBandTree; for( psBandTree = psTree->psChild; psBandTree != NULL; psBandTree = psBandTree->psNext ) { if( psBandTree->eType != CXT_Element || !EQUAL(psBandTree->pszValue,"PAMRasterBand") ) continue; int nBand = atoi(CPLGetXMLValue( psBandTree, "band", "0")); if( nBand < 1 || nBand > GetRasterCount() ) continue; GDALPamRasterBand *poBand = (GDALPamRasterBand *) GetRasterBand(nBand); if( poBand == NULL || !(poBand->GetMOFlags() & GMO_PAM_CLASS) ) continue; poBand->XMLInit( psBandTree, pszVRTPath ); } /* -------------------------------------------------------------------- */ /* Clear dirty flag. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; return CE_None; }
void EnvisatDataset::ScanForGCPs_ASAR() { int nDatasetIndex, nNumDSR, nDSRSize, iRecord; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "GEOLOCATION GRID ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 || nDSRSize != 521 ) return; /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte abyRecord[521]; int nRange=0, nSample, iGCP, nRangeOffset=0; GUInt32 unValue; nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),(nNumDSR+1) * 11); for( iRecord = 0; iRecord < nNumDSR; iRecord++ ) { if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, iRecord, abyRecord ) != SUCCESS ) continue; memcpy( &unValue, abyRecord + 13, 4 ); nRange = CPL_MSBWORD32( unValue ) + nRangeOffset; if((iRecord>1) && (int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) > nRange)) { int delta = (int) (pasGCPList[nGCPCount-1].dfGCPLine - pasGCPList[nGCPCount-12].dfGCPLine); nRange = int(pasGCPList[nGCPCount-1].dfGCPLine+0.5) + delta; nRangeOffset = nRange-1; } for( iGCP = 0; iGCP < 11; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, abyRecord + 25 + iGCP*4, 4 ); nSample = CPL_MSBWORD32(unValue); memcpy( &unValue, abyRecord + 25 + 176 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, abyRecord + 25 + 132 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5; pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5; nGCPCount++; } } /* -------------------------------------------------------------------- */ /* We also collect the bottom GCPs from the last granule. */ /* -------------------------------------------------------------------- */ memcpy( &unValue, abyRecord + 17, 4 ); nRange = nRange + CPL_MSBWORD32( unValue ) - 1; for( iGCP = 0; iGCP < 11; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, abyRecord + 279 + iGCP*4, 4 ); nSample = CPL_MSBWORD32(unValue); memcpy( &unValue, abyRecord + 279 + 176 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, abyRecord + 279 + 132 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = nRange - 0.5; pasGCPList[nGCPCount].dfGCPPixel = nSample - 0.5; nGCPCount++; } }
void PAuxDataset::ScanForGCPs() { static const int MAX_GCP = 256; nGCPCount = 0; pasGCPList = reinterpret_cast<GDAL_GCP *>( CPLCalloc( sizeof(GDAL_GCP), MAX_GCP ) ); /* -------------------------------------------------------------------- */ /* Get the GCP coordinate system. */ /* -------------------------------------------------------------------- */ const char *pszMapUnits = CSLFetchNameValue( papszAuxLines, "GCP_1_MapUnits" ); const char *pszProjParms = CSLFetchNameValue( papszAuxLines, "GCP_1_ProjParms" ); if( pszMapUnits != NULL ) pszGCPProjection = PCI2WKT( pszMapUnits, pszProjParms ); /* -------------------------------------------------------------------- */ /* Collect standalone GCPs. They look like: */ /* */ /* GCP_1_n = row, col, x, y [,z [,"id"[, "desc"]]] */ /* -------------------------------------------------------------------- */ for( int i = 0; nGCPCount < MAX_GCP; i++ ) { char szName[50]; snprintf( szName, sizeof(szName), "GCP_1_%d", i+1 ); if( CSLFetchNameValue( papszAuxLines, szName ) == NULL ) break; char **papszTokens = CSLTokenizeStringComplex( CSLFetchNameValue( papszAuxLines, szName ), " ", TRUE, FALSE ); if( CSLCount(papszTokens) >= 4 ) { GDALInitGCPs( 1, pasGCPList + nGCPCount ); pasGCPList[nGCPCount].dfGCPX = CPLAtof(papszTokens[2]); pasGCPList[nGCPCount].dfGCPY = CPLAtof(papszTokens[3]); pasGCPList[nGCPCount].dfGCPPixel = CPLAtof(papszTokens[0]); pasGCPList[nGCPCount].dfGCPLine = CPLAtof(papszTokens[1]); if( CSLCount(papszTokens) > 4 ) pasGCPList[nGCPCount].dfGCPZ = CPLAtof(papszTokens[4]); CPLFree( pasGCPList[nGCPCount].pszId ); if( CSLCount(papszTokens) > 5 ) { pasGCPList[nGCPCount].pszId = CPLStrdup(papszTokens[5]); } else { snprintf( szName, sizeof(szName), "GCP_%d", i+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szName ); } if( CSLCount(papszTokens) > 6 ) { CPLFree( pasGCPList[nGCPCount].pszInfo ); pasGCPList[nGCPCount].pszInfo = CPLStrdup(papszTokens[6]); } nGCPCount++; } CSLDestroy(papszTokens); } }
GDAL_GCP * PrepareGCP(const CPLString& sFileName, OGRPoint *pt1, OGRPoint *pt2, OGRPoint *pt3, OGRPoint *pt4, OGRPoint *ptCenter, const OGRSpatialReference &oDstOGRSpatialReference, const int nRasterSizeX, const int nRasterSizeY, int &nGCPCount, OGREnvelope &DstEnv) { // to meters double dfFocusM = dfFocus / 100; double dfFilmHalfHeightM = dfFilmHeight / 200; double dfRatio = dfFilmHalfHeightM / dfFocusM; //create center point and line of scene OGRPoint ptShortSideBeg = GetCenterOfLine(pt1, pt4); OGRPoint ptShortSideEnd = GetCenterOfLine(pt2, pt3); OGRLineString lnTmp; lnTmp.addPoint(&ptShortSideBeg); lnTmp.addPoint(&ptShortSideEnd); lnTmp.Value(lnTmp.Project(pt1), &ptShortSideBeg); lnTmp.Value(lnTmp.Project(pt2), &ptShortSideEnd); double dfDist1 = pt1->Distance(pt2); double dfDist2 = pt2->Distance(pt3); double dfDist3 = pt3->Distance(pt4); double dfDist4 = pt4->Distance(pt1); double dfHalfWidth = (dfDist2 + dfDist4) / 4; double dfHalfHeight = (dfDist1 + dfDist3) / 4; double dfAltitudeAtSide = (dfHalfWidth * dfFocusM) / dfFilmHalfHeightM; double dfAltitudeAtSceneCenter = sqrt( dfAltitudeAtSide * dfAltitudeAtSide - dfHalfHeight * dfHalfHeight); double dfAltitude = dfAltitudeAtSceneCenter * cos(dfMountAngleRad); // 145 - 220 km double dfDistCenter = dfAltitudeAtSceneCenter * sin(dfMountAngleRad); OGRLineString lnCenterLeft; lnCenterLeft.addPoint(&ptShortSideBeg); lnCenterLeft.addPoint(ptCenter); OGRPoint ptSatCenter = GetTangetPoint(lnCenterLeft, dfDistCenter); std::vector<OGRPoint> aPt1, aPt2; int nTotalGCPCount = ((SEGMENT_STEPS + 1) * 2); GDAL_GCP *paGSPs = (GDAL_GCP *) CPLMalloc (nTotalGCPCount * sizeof(GDAL_GCP)); GDALInitGCPs(nTotalGCPCount, paGSPs); double dfImageStepLen = double(nRasterSizeX) / SEGMENT_STEPS; double dfImageCenterX = 0; OGRLineString lnCenter; lnCenter.addPoint(&ptShortSideBeg); lnCenter.addPoint(ptCenter); lnCenter.addPoint(&ptShortSideEnd); double dfCenterLineLen = lnCenter.get_Length(); double dfStepLen = dfCenterLineLen / SEGMENT_STEPS; double dfCenterLineHalfLen = dfCenterLineLen / 2; for(double i = 0; i <= dfCenterLineLen; i += dfStepLen) { OGRPoint ptTmp; lnCenter.Value(i, &ptTmp); double dfDist = fabs(dfCenterLineHalfLen - i); double dfWidthTmp = GetWidthForHeight(dfAltitudeAtSceneCenter, dfDist, dfRatio); OGRLineString lnTmpLine; lnTmpLine.addPoint(ptCenter); lnTmpLine.addPoint(&ptTmp); int direction = 1; if(dfCenterLineHalfLen < i) direction = -1; OGRPoint ptUp = GetTangetPoint(lnTmpLine, dfWidthTmp * direction); OGRPoint ptDown = GetTangetPoint(lnTmpLine, -dfWidthTmp * direction); //OGRPoint ptUp = GetValue(dfWidthTmp, lnTmpLine); //OGRPoint ptDown = GetValue(-dfWidthTmp, lnTmpLine); aPt1.push_back(ptUp); aPt2.push_back(ptDown); paGSPs[nGCPCount].dfGCPLine = 0; paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX; paGSPs[nGCPCount].dfGCPX = ptDown.getX(); paGSPs[nGCPCount].dfGCPY = ptDown.getY(); paGSPs[nGCPCount].dfGCPZ = dfMeanHeight; paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount)); nGCPCount++; paGSPs[nGCPCount].dfGCPLine = nRasterSizeY; paGSPs[nGCPCount].dfGCPPixel = dfImageCenterX; paGSPs[nGCPCount].dfGCPX = ptUp.getX(); paGSPs[nGCPCount].dfGCPY = ptUp.getY(); paGSPs[nGCPCount].dfGCPZ = dfMeanHeight; paGSPs[nGCPCount].pszId = CPLStrdup(CPLSPrintf("pt%d", nGCPCount)); nGCPCount++; dfImageCenterX += dfImageStepLen; } // add points to polygon OGRLinearRing Ring; for(int i = 0; i < aPt1.size(); ++i) Ring.addPoint(aPt1[i].getX(), aPt1[i].getY()); for(int i = aPt2.size() - 1; i >= 0; --i) Ring.addPoint(aPt2[i].getX(), aPt2[i].getY()); Ring.closeRings(); OGRPolygon Rgn; Rgn.addRingDirectly((OGRCurve*)Ring.clone()); Rgn.assignSpatialReference(oDstOGRSpatialReference.Clone()); Rgn.flattenTo2D(); Rgn.getEnvelope(&DstEnv); SaveGeometry(CPLResetExtension(sFileName, "shp"), Rgn, oDstOGRSpatialReference); return paGSPs; }
int main( int argc, char ** argv ) { const char *pszSrcFilename = NULL; const char *pszDstFilename = NULL; int nOrder = 0; void *hTransformArg; GDALTransformerFunc pfnTransformer = NULL; int nGCPCount = 0; GDAL_GCP *pasGCPs = NULL; int bInverse = FALSE; char **papszTO = NULL; /* Check that we are running against at least GDAL 1.5 */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; for( i = 1; i < argc; 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")); return 0; } else if( EQUAL(argv[i],"-t_srs") && i < argc-1 ) { char *pszSRS = SanitizeSRS(argv[++i]); papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSRS ); CPLFree( pszSRS ); } else if( EQUAL(argv[i],"-s_srs") && i < argc-1 ) { char *pszSRS = SanitizeSRS(argv[++i]); papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSRS ); CPLFree( pszSRS ); } else if( EQUAL(argv[i],"-order") && i < argc-1 ) { nOrder = atoi(argv[++i]); papszTO = CSLSetNameValue( papszTO, "MAX_GCP_ORDER", argv[i] ); } else if( EQUAL(argv[i],"-tps") ) { papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" ); nOrder = -1; } else if( EQUAL(argv[i],"-rpc") ) { papszTO = CSLSetNameValue( papszTO, "METHOD", "RPC" ); } else if( EQUAL(argv[i],"-geoloc") ) { papszTO = CSLSetNameValue( papszTO, "METHOD", "GEOLOC_ARRAY" ); } else if( EQUAL(argv[i],"-i") ) { bInverse = TRUE; } else if( EQUAL(argv[i],"-to") && i < argc-1 ) { papszTO = CSLAddString( papszTO, argv[++i] ); } else if( EQUAL(argv[i],"-gcp") && i < argc - 4 ) { char* endptr = NULL; /* -gcp pixel line easting northing [elev] */ nGCPCount++; pasGCPs = (GDAL_GCP *) CPLRealloc( pasGCPs, sizeof(GDAL_GCP) * nGCPCount ); GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 ); pasGCPs[nGCPCount-1].dfGCPPixel = atof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPLine = atof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPX = atof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPY = atof(argv[++i]); if( argv[i+1] != NULL && (CPLStrtod(argv[i+1], &endptr) != 0.0 || argv[i+1][0] == '0') ) { /* Check that last argument is really a number and not a filename */ /* looking like a number (see ticket #863) */ if (endptr && *endptr == 0) pasGCPs[nGCPCount-1].dfGCPZ = atof(argv[++i]); } /* should set id and info? */ } else if( argv[i][0] == '-' ) Usage(); else if( pszSrcFilename == NULL ) pszSrcFilename = argv[i]; else if( pszDstFilename == NULL ) pszDstFilename = argv[i]; else Usage(); } /* -------------------------------------------------------------------- */ /* Open src and destination file, if appropriate. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = NULL, hDstDS = NULL; if( pszSrcFilename != NULL ) { hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly ); if( hSrcDS == NULL ) exit( 1 ); } if( pszDstFilename != NULL ) { hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly ); if( hDstDS == NULL ) exit( 1 ); } if( hSrcDS != NULL && nGCPCount > 0 ) { fprintf( stderr, "Commandline GCPs and input file specified, specify one or the other.\n" ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create a transformation object from the source to */ /* destination coordinate system. */ /* -------------------------------------------------------------------- */ if( nGCPCount != 0 && nOrder == -1 ) { pfnTransformer = GDALTPSTransform; hTransformArg = GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE ); } else if( nGCPCount != 0 ) { pfnTransformer = GDALGCPTransform; hTransformArg = GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE ); } else { pfnTransformer = GDALGenImgProjTransform; hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO ); } CSLDestroy( papszTO ); if( hTransformArg == NULL ) { exit( 1 ); } /* -------------------------------------------------------------------- */ /* Read points from stdin, transform and write to stdout. */ /* -------------------------------------------------------------------- */ while( !feof(stdin) ) { char szLine[1024]; if( fgets( szLine, sizeof(szLine)-1, stdin ) == NULL ) break; char **papszTokens = CSLTokenizeString(szLine); double dfX, dfY, dfZ = 0.0; int bSuccess = TRUE; if( CSLCount(papszTokens) < 2 ) { CSLDestroy(papszTokens); continue; } dfX = atof(papszTokens[0]); dfY = atof(papszTokens[1]); if( CSLCount(papszTokens) >= 3 ) dfZ = atof(papszTokens[2]); if( pfnTransformer( hTransformArg, bInverse, 1, &dfX, &dfY, &dfZ, &bSuccess ) && bSuccess ) { printf( "%.15g %.15g %.15g\n", dfX, dfY, dfZ ); } else { printf( "transformation failed.\n" ); } CSLDestroy(papszTokens); } if( nGCPCount != 0 && nOrder == -1 ) { GDALDestroyTPSTransformer(hTransformArg); } else if( nGCPCount != 0 ) { GDALDestroyGCPTransformer(hTransformArg); } else { GDALDestroyGenImgProjTransformer(hTransformArg); } if (nGCPCount) { GDALDeinitGCPs( nGCPCount, pasGCPs ); CPLFree( pasGCPs ); } if (hSrcDS) GDALClose(hSrcDS); if (hDstDS) GDALClose(hDstDS); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CSLDestroy( argv ); return 0; }
CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(EQUALN(osMissionLevel,"RAW",3)) productType = PROD_CSK_L0; if(EQUALN(osMissionLevel,"SSC",3)) productType = PROD_CSK_L1A; if(EQUALN(osMissionLevel,"DGM",3)) productType = PROD_CSK_L1B; if(EQUALN(osMissionLevel,"GEC",3)) productType = PROD_CSK_L1C; if(EQUALN(osMissionLevel,"GTC",3)) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { #define NBGCPLAT 100 #define NBGCPLON 30 hid_t LatitudeDatasetID = -1; hid_t LongitudeDatasetID = -1; hid_t LatitudeDataspaceID; hid_t LongitudeDataspaceID; float* Latitude; float* Longitude; int i,j; int nDeltaLat; int nDeltaLon; nDeltaLat = nRasterYSize / NBGCPLAT; nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { return CE_None; } /* -------------------------------------------------------------------- */ /* The Lattitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { Latitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); Longitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon; pasGCPList = ( GDAL_GCP * ) CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat; int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon; for( j = 0; j < nYLimit; j+=nDeltaLat ) { for( i = 0; i < nXLimit; i+=nDeltaLon ) { int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0; pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP]; pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }
/** * Retrieves and stores the GCPs from a COSMO-SKYMED dataset * It only retrieves the GCPs for L0, L1A and L1B products * for L1C and L1D products, geotransform is provided. * The GCPs provided will be the Image's corners. * @param iProductType type of CSK product @see HDF5CSKProductEnum */ void HDF5ImageDataset::CaptureCSKGCPs(int iProductType) { //Only retrieve GCPs for L0,L1A and L1B products if(iProductType == PROD_CSK_L0||iProductType == PROD_CSK_L1A|| iProductType == PROD_CSK_L1B) { int i; double *pdCornerCoordinates; nGCPCount=4; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),4); CPLString osCornerName[4]; double pdCornerPixel[4]; double pdCornerLine[4]; const char *pszSubdatasetName = GetSubdatasetName(); //Load the subdataset name first for(i=0;i <4;i++) osCornerName[i] = pszSubdatasetName; //Load the attribute name, and raster coordinates for //all the corners osCornerName[0] += "/Top Left Geodetic Coordinates"; pdCornerPixel[0] = 0; pdCornerLine[0] = 0; osCornerName[1] += "/Top Right Geodetic Coordinates"; pdCornerPixel[1] = GetRasterXSize(); pdCornerLine[1] = 0; osCornerName[2] += "/Bottom Left Geodetic Coordinates"; pdCornerPixel[2] = 0; pdCornerLine[2] = GetRasterYSize(); osCornerName[3] += "/Bottom Right Geodetic Coordinates"; pdCornerPixel[3] = GetRasterXSize(); pdCornerLine[3] = GetRasterYSize(); //For all the image's corners for(i=0;i<4;i++) { GDALInitGCPs( 1, pasGCPList + i ); CPLFree( pasGCPList[i].pszId ); pasGCPList[i].pszId = NULL; //Retrieve the attributes if(HDF5ReadDoubleAttr(osCornerName[i].c_str(), &pdCornerCoordinates) == CE_Failure) { CPLError( CE_Failure, CPLE_OpenFailed, "Error retrieving CSK GCPs\n" ); // Free on failure, e.g. in case of QLK subdataset. for( int i = 0; i < 4; i++ ) { if( pasGCPList[i].pszId ) CPLFree( pasGCPList[i].pszId ); if( pasGCPList[i].pszInfo ) CPLFree( pasGCPList[i].pszInfo ); } CPLFree( pasGCPList ); pasGCPList = NULL; nGCPCount = 0; break; } //Fill the GCPs name pasGCPList[i].pszId = CPLStrdup( osCornerName[i].c_str() ); //Fill the coordinates pasGCPList[i].dfGCPX = pdCornerCoordinates[1]; pasGCPList[i].dfGCPY = pdCornerCoordinates[0]; pasGCPList[i].dfGCPZ = pdCornerCoordinates[2]; pasGCPList[i].dfGCPPixel = pdCornerPixel[i]; pasGCPList[i].dfGCPLine = pdCornerLine[i]; //Free the returned coordinates CPLFree(pdCornerCoordinates); } } }
void *GDALDeserializeTPSTransformer( CPLXMLNode *psTree ) { GDAL_GCP *pasGCPList = 0; int nGCPCount = 0; void *pResult; int bReversed; /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { int nGCPMax = 0; CPLXMLNode *psXMLGCP; // Count GCPs. for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Get other flags. */ /* -------------------------------------------------------------------- */ bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0")); /* -------------------------------------------------------------------- */ /* Generate transformation. */ /* -------------------------------------------------------------------- */ pResult = GDALCreateTPSTransformer( nGCPCount, pasGCPList, bReversed ); /* -------------------------------------------------------------------- */ /* Cleanup GCP copy. */ /* -------------------------------------------------------------------- */ GDALDeinitGCPs( nGCPCount, pasGCPList ); CPLFree( pasGCPList ); return pResult; }
static int ProxyMain(int argc, char **argv) { GDALDatasetH hDataset, hOutDS; int i; int nRasterXSize, nRasterYSize; const char *pszSource = NULL, *pszDest = NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; int *panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */ int nBandCount = 0, bDefBands = TRUE; double adfGeoTransform[6]; GDALDataType eOutputType = GDT_Unknown; int nOXSize = 0, nOYSize = 0; char *pszOXSize = NULL, *pszOYSize = NULL; char **papszCreateOptions = NULL; int anSrcWin[4], bStrict = FALSE; const char *pszProjection; int bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale = FALSE; double dfScaleSrcMin = 0.0, dfScaleSrcMax = 255.0; double dfScaleDstMin = 0.0, dfScaleDstMax = 255.0; double dfULX, dfULY, dfLRX, dfLRY; char **papszMetadataOptions = NULL; char *pszOutputSRS = NULL; int bQuiet = FALSE, bGotBounds = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int nGCPCount = 0; GDAL_GCP *pasGCPs = NULL; int iSrcFileArg = -1, iDstFileArg = -1; int bCopySubDatasets = FALSE; double adfULLR[4] = { 0, 0, 0, 0 }; int bSetNoData = FALSE; int bUnsetNoData = FALSE; double dfNoDataReal = 0.0; int nRGBExpand = 0; int bParsedMaskArgument = FALSE; int eMaskMode = MASK_AUTO; int nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */ int bStats = FALSE, bApproxStats = FALSE; anSrcWin[0] = 0; anSrcWin[1] = 0; anSrcWin[2] = 0; anSrcWin[3] = 0; dfULX = dfULY = dfLRX = dfLRY = 0.0; /* Check strict compilation and runtime library version as we use C++ API */ if (!GDAL_CHECK_VERSION(argv[0])) exit(1); /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for (i = 1; i < argc; i++) { if (EQUAL(argv[i], "--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP")) { CPLSetConfigOption(argv[i + 1], argv[i + 2]); i += 2; } } /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor(argc, &argv, 0); if (argc < 1) exit(-argc); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for (i = 1; i < argc; 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")); return 0; } else if (EQUAL(argv[i], "-of") && i < argc - 1) pszFormat = argv[++i]; else if (EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet")) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if (EQUAL(argv[i], "-ot") && i < argc - 1) { int iType; for (iType = 1; iType < GDT_TypeCount; iType++) { if (GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i + 1])) { eOutputType = (GDALDataType) iType; } } if (eOutputType == GDT_Unknown) { printf("Unknown output pixel type: %s\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-b") && i < argc - 1) { const char *pszBand = argv[i + 1]; int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; /* If we use tha source mask band as a regular band */ /* don't create a target mask band by default */ if (!bParsedMaskArgument) eMaskMode = MASK_DISABLED; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; nBandCount++; panBandList = (int*) CPLRealloc(panBandList, sizeof(int) * nBandCount); panBandList[nBandCount - 1] = nBand; if (bMask) panBandList[nBandCount - 1] *= -1; if (panBandList[nBandCount - 1] != nBandCount) bDefBands = FALSE; } else if (EQUAL(argv[i], "-mask") && i < argc - 1) { bParsedMaskArgument = TRUE; const char *pszBand = argv[i + 1]; if (EQUAL(pszBand, "none")) { eMaskMode = MASK_DISABLED; } else if (EQUAL(pszBand, "auto")) { eMaskMode = MASK_AUTO; } else { int bMask = FALSE; if (EQUAL(pszBand, "mask")) pszBand = "mask,1"; if (EQUALN(pszBand, "mask,", 5)) { bMask = TRUE; pszBand += 5; } int nBand = atoi(pszBand); if (nBand < 1) { printf("Unrecognizable band number (%s).\n", argv[i + 1]); Usage(); GDALDestroyDriverManager(); exit(2); } eMaskMode = MASK_USER; nMaskBand = nBand; if (bMask) nMaskBand *= -1; } i++; } else if (EQUAL(argv[i], "-not_strict")) bStrict = FALSE; else if (EQUAL(argv[i], "-strict")) bStrict = TRUE; else if (EQUAL(argv[i], "-sds")) bCopySubDatasets = TRUE; else if (EQUAL(argv[i], "-gcp") && i < argc - 4) { char *endptr = NULL; /* -gcp pixel line easting northing [elev] */ nGCPCount++; pasGCPs = (GDAL_GCP*) CPLRealloc(pasGCPs, sizeof(GDAL_GCP) * nGCPCount); GDALInitGCPs(1, pasGCPs + nGCPCount - 1); pasGCPs[nGCPCount - 1].dfGCPPixel = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPLine = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPX = CPLAtofM(argv[++i]); pasGCPs[nGCPCount - 1].dfGCPY = CPLAtofM(argv[++i]); if (argv[i + 1] != NULL && (CPLStrtod(argv[i + 1], &endptr) != 0.0 || argv[i + 1][0] == '0')) { /* Check that last argument is really a number and not a filename */ /* looking like a number (see ticket #863) */ if (endptr && *endptr == 0) pasGCPs[nGCPCount - 1].dfGCPZ = CPLAtofM(argv[++i]); } /* should set id and info? */ } else if (EQUAL(argv[i], "-a_nodata") && i < argc - 1) { if (EQUAL(argv[i + 1], "none")) { bUnsetNoData = TRUE; } else { bSetNoData = TRUE; dfNoDataReal = CPLAtofM(argv[i + 1]); } i += 1; } else if (EQUAL(argv[i], "-a_ullr") && i < argc - 4) { adfULLR[0] = CPLAtofM(argv[i + 1]); adfULLR[1] = CPLAtofM(argv[i + 2]); adfULLR[2] = CPLAtofM(argv[i + 3]); adfULLR[3] = CPLAtofM(argv[i + 4]); bGotBounds = TRUE; i += 4; } else if (EQUAL(argv[i], "-co") && i < argc - 1) { papszCreateOptions = CSLAddString(papszCreateOptions, argv[++i]); } else if (EQUAL(argv[i], "-scale")) { bScale = TRUE; if (i < argc - 2 && ArgIsNumeric(argv[i + 1])) { bHaveScaleSrc = TRUE; dfScaleSrcMin = CPLAtofM(argv[i + 1]); dfScaleSrcMax = CPLAtofM(argv[i + 2]); i += 2; } if (i < argc - 2 && bHaveScaleSrc && ArgIsNumeric(argv[i + 1])) { dfScaleDstMin = CPLAtofM(argv[i + 1]); dfScaleDstMax = CPLAtofM(argv[i + 2]); i += 2; } else { dfScaleDstMin = 0.0; dfScaleDstMax = 255.999; } } else if (EQUAL(argv[i], "-unscale")) { bUnscale = TRUE; } else if (EQUAL(argv[i], "-mo") && i < argc - 1) { papszMetadataOptions = CSLAddString(papszMetadataOptions, argv[++i]); } else if (EQUAL(argv[i], "-outsize") && i < argc - 2) { pszOXSize = argv[++i]; pszOYSize = argv[++i]; } else if (EQUAL(argv[i], "-srcwin") && i < argc - 4) { anSrcWin[0] = atoi(argv[++i]); anSrcWin[1] = atoi(argv[++i]); anSrcWin[2] = atoi(argv[++i]); anSrcWin[3] = atoi(argv[++i]); } else if (EQUAL(argv[i], "-projwin") && i < argc - 4) { dfULX = CPLAtofM(argv[++i]); dfULY = CPLAtofM(argv[++i]); dfLRX = CPLAtofM(argv[++i]); dfLRY = CPLAtofM(argv[++i]); } else if (EQUAL(argv[i], "-a_srs") && i < argc - 1) { OGRSpatialReference oOutputSRS; if (oOutputSRS.SetFromUserInput(argv[i + 1]) != OGRERR_NONE) { fprintf(stderr, "Failed to process SRS definition: %s\n", argv[i + 1]); GDALDestroyDriverManager(); exit(1); } oOutputSRS.exportToWkt(&pszOutputSRS); i++; } else if (EQUAL(argv[i], "-expand") && i < argc - 1) { if (EQUAL(argv[i + 1], "gray")) nRGBExpand = 1; else if (EQUAL(argv[i + 1], "rgb")) nRGBExpand = 3; else if (EQUAL(argv[i + 1], "rgba")) nRGBExpand = 4; else { printf("Value %s unsupported. Only gray, rgb or rgba are supported.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } i++; } else if (EQUAL(argv[i], "-stats")) { bStats = TRUE; bApproxStats = FALSE; } else if (EQUAL(argv[i], "-approx_stats")) { bStats = TRUE; bApproxStats = TRUE; } else if (argv[i][0] == '-') { printf("Option %s incomplete, or not recognised.\n\n", argv[i]); Usage(); GDALDestroyDriverManager(); exit(2); } else if (pszSource == NULL) { iSrcFileArg = i; pszSource = argv[i]; } else if (pszDest == NULL) { pszDest = argv[i]; iDstFileArg = i; } else { printf("Too many command options.\n\n"); Usage(); GDALDestroyDriverManager(); exit(2); } } if (pszDest == NULL) { Usage(); GDALDestroyDriverManager(); exit(10); } if (strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit(1); } if (strcmp(pszDest, "/vsistdout/") == 0) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hDataset = GDALOpenShared(pszSource, GA_ReadOnly); if (hDataset == NULL) { fprintf(stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg()); GDALDestroyDriverManager(); exit(1); } /* -------------------------------------------------------------------- */ /* Handle subdatasets. */ /* -------------------------------------------------------------------- */ if (!bCopySubDatasets && CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && GDALGetRasterCount(hDataset) == 0) { fprintf(stderr, "Input file contains subdatasets. Please, select one of them for reading.\n"); GDALClose(hDataset); GDALDestroyDriverManager(); exit(1); } if (CSLCount(GDALGetMetadata(hDataset, "SUBDATASETS")) > 0 && bCopySubDatasets) { char **papszSubdatasets = GDALGetMetadata(hDataset, "SUBDATASETS"); char *pszSubDest = (char*) CPLMalloc(strlen(pszDest) + 32); int i; int bOldSubCall = bSubCall; char **papszDupArgv = CSLDuplicate(argv); int nRet = 0; CPLFree(papszDupArgv[iDstFileArg]); papszDupArgv[iDstFileArg] = pszSubDest; bSubCall = TRUE; for (i = 0; papszSubdatasets[i] != NULL; i += 2) { CPLFree(papszDupArgv[iSrcFileArg]); papszDupArgv[iSrcFileArg] = CPLStrdup(strstr(papszSubdatasets[i], "=") + 1); sprintf(pszSubDest, "%s%d", pszDest, i / 2 + 1); nRet = ProxyMain(argc, papszDupArgv); if (nRet != 0) break; } CSLDestroy(papszDupArgv); bSubCall = bOldSubCall; CSLDestroy(argv); GDALClose(hDataset); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } return nRet; } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ nRasterXSize = GDALGetRasterXSize(hDataset); nRasterYSize = GDALGetRasterYSize(hDataset); if (!bQuiet) printf("Input file size is %d, %d\n", nRasterXSize, nRasterYSize); if (anSrcWin[2] == 0 && anSrcWin[3] == 0) { anSrcWin[2] = nRasterXSize; anSrcWin[3] = nRasterYSize; } /* -------------------------------------------------------------------- */ /* Build band list to translate */ /* -------------------------------------------------------------------- */ if (nBandCount == 0) { nBandCount = GDALGetRasterCount(hDataset); if (nBandCount == 0) { fprintf(stderr, "Input file has no bands, and so cannot be translated.\n"); GDALDestroyDriverManager(); exit(1); } panBandList = (int*) CPLMalloc(sizeof(int) * nBandCount); for (i = 0; i < nBandCount; i++) panBandList[i] = i + 1; } else { for (i = 0; i < nBandCount; i++) { if (ABS(panBandList[i]) > GDALGetRasterCount(hDataset)) { fprintf(stderr, "Band %d requested, but only bands 1 to %d available.\n", ABS(panBandList[i]), GDALGetRasterCount(hDataset)); GDALDestroyDriverManager(); exit(2); } } if (nBandCount != GDALGetRasterCount(hDataset)) bDefBands = FALSE; } /* -------------------------------------------------------------------- */ /* Compute the source window from the projected source window */ /* if the projected coordinates were provided. Note that the */ /* projected coordinates are in ulx, uly, lrx, lry format, */ /* while the anSrcWin is xoff, yoff, xsize, ysize with the */ /* xoff,yoff being the ulx, uly in pixel/line. */ /* -------------------------------------------------------------------- */ if (dfULX != 0.0 || dfULY != 0.0 || dfLRX != 0.0 || dfLRY != 0.0) { double adfGeoTransform[6]; GDALGetGeoTransform(hDataset, adfGeoTransform); if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { fprintf(stderr, "The -projwin option was used, but the geotransform is\n" "rotated. This configuration is not supported.\n"); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); exit(1); } anSrcWin[0] = (int) ((dfULX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001); anSrcWin[1] = (int) ((dfULY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001); anSrcWin[2] = (int) ((dfLRX - dfULX) / adfGeoTransform[1] + 0.5); anSrcWin[3] = (int) ((dfLRY - dfULY) / adfGeoTransform[5] + 0.5); if (!bQuiet) fprintf(stdout, "Computed -srcwin %d %d %d %d from projected window.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3]); if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "Computed -srcwin falls outside raster size of %dx%d.\n", GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } } /* -------------------------------------------------------------------- */ /* Verify source window. */ /* -------------------------------------------------------------------- */ if (anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[2] <= 0 || anSrcWin[3] <= 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hDataset) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hDataset)) { fprintf(stderr, "-srcwin %d %d %d %d falls outside raster size of %dx%d\n" "or is otherwise illegal.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], GDALGetRasterXSize(hDataset), GDALGetRasterYSize(hDataset)); exit(1); } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName(pszFormat); if (hDriver == NULL) { int iDr; printf("Output driver `%s' not recognised.\n", pszFormat); printf("The following format drivers are configured and support output:\n"); for (iDr = 0; iDr < GDALGetDriverCount(); iDr++) { GDALDriverH hDriver = GDALGetDriver(iDr); if (GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATE, NULL) != NULL || GDALGetMetadataItem(hDriver, GDAL_DCAP_CREATECOPY, NULL) != NULL) { printf(" %s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } } printf("\n"); Usage(); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* -------------------------------------------------------------------- */ /* The short form is to CreateCopy(). We use this if the input */ /* matches the whole dataset. Eventually we should rewrite */ /* this entire program to use virtual datasets to construct a */ /* virtual input source to copy from. */ /* -------------------------------------------------------------------- */ int bSpatialArrangementPreserved = ( anSrcWin[0] == 0 && anSrcWin[1] == 0 && anSrcWin[2] == GDALGetRasterXSize(hDataset) && anSrcWin[3] == GDALGetRasterYSize(hDataset) && pszOXSize == NULL && pszOYSize == NULL); if (eOutputType == GDT_Unknown && !bScale && !bUnscale && CSLCount(papszMetadataOptions) == 0 && bDefBands && eMaskMode == MASK_AUTO && bSpatialArrangementPreserved && nGCPCount == 0 && !bGotBounds && pszOutputSRS == NULL && !bSetNoData && !bUnsetNoData && nRGBExpand == 0 && !bStats) { hOutDS = GDALCreateCopy(hDriver, pszDest, hDataset, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) GDALClose(hOutDS); GDALClose(hDataset); CPLFree(panBandList); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; } /* -------------------------------------------------------------------- */ /* Establish some parameters. */ /* -------------------------------------------------------------------- */ if (pszOXSize == NULL) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = (int) ((pszOXSize[strlen(pszOXSize) - 1] == '%' ? CPLAtofM(pszOXSize) / 100 * anSrcWin[2] : atoi(pszOXSize))); nOYSize = (int) ((pszOYSize[strlen(pszOYSize) - 1] == '%' ? CPLAtofM(pszOYSize) / 100 * anSrcWin[3] : atoi(pszOYSize))); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = (VRTDataset*) VRTCreate(nOXSize, nOYSize); if (nGCPCount == 0) { if (pszOutputSRS != NULL) { poVDS->SetProjection(pszOutputSRS); } else { pszProjection = GDALGetProjectionRef(hDataset); if (pszProjection != NULL && strlen(pszProjection) > 0) poVDS->SetProjection(pszProjection); } } if (bGotBounds) { adfGeoTransform[0] = adfULLR[0]; adfGeoTransform[1] = (adfULLR[2] - adfULLR[0]) / nOXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = adfULLR[1]; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (adfULLR[3] - adfULLR[1]) / nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } else if (GDALGetGeoTransform(hDataset, adfGeoTransform) == CE_None && nGCPCount == 0) { adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2]; adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5]; adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize; adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize; poVDS->SetGeoTransform(adfGeoTransform); } if (nGCPCount != 0) { const char *pszGCPProjection = pszOutputSRS; if (pszGCPProjection == NULL) pszGCPProjection = GDALGetGCPProjection(hDataset); if (pszGCPProjection == NULL) pszGCPProjection = ""; poVDS->SetGCPs(nGCPCount, pasGCPs, pszGCPProjection); GDALDeinitGCPs(nGCPCount, pasGCPs); CPLFree(pasGCPs); } else if (GDALGetGCPCount(hDataset) > 0) { GDAL_GCP *pasGCPs; int nGCPs = GDALGetGCPCount(hDataset); pasGCPs = GDALDuplicateGCPs(nGCPs, GDALGetGCPs(hDataset)); for (i = 0; i < nGCPs; i++) { pasGCPs[i].dfGCPPixel -= anSrcWin[0]; pasGCPs[i].dfGCPLine -= anSrcWin[1]; pasGCPs[i].dfGCPPixel *= (nOXSize / (double) anSrcWin[2]); pasGCPs[i].dfGCPLine *= (nOYSize / (double) anSrcWin[3]); } poVDS->SetGCPs(nGCPs, pasGCPs, GDALGetGCPProjection(hDataset)); GDALDeinitGCPs(nGCPs, pasGCPs); CPLFree(pasGCPs); } /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ poVDS->SetMetadata(((GDALDataset*)hDataset)->GetMetadata()); AttachMetadata((GDALDatasetH) poVDS, papszMetadataOptions); const char *pszInterleave = GDALGetMetadataItem(hDataset, "INTERLEAVE", "IMAGE_STRUCTURE"); if (pszInterleave) poVDS->SetMetadataItem("INTERLEAVE", pszInterleave, "IMAGE_STRUCTURE"); /* -------------------------------------------------------------------- */ /* Transfer metadata that remains valid if the spatial */ /* arrangement of the data is unaltered. */ /* -------------------------------------------------------------------- */ if (bSpatialArrangementPreserved) { char **papszMD; papszMD = ((GDALDataset*)hDataset)->GetMetadata("RPC"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "RPC"); papszMD = ((GDALDataset*)hDataset)->GetMetadata("GEOLOCATION"); if (papszMD != NULL) poVDS->SetMetadata(papszMD, "GEOLOCATION"); } int nSrcBandCount = nBandCount; if (nRGBExpand != 0) { GDALRasterBand *poSrcBand; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(panBandList[0])); if (panBandList[0] < 0) poSrcBand = poSrcBand->GetMaskBand(); GDALColorTable *poColorTable = poSrcBand->GetColorTable(); if (poColorTable == NULL) { fprintf(stderr, "Error : band %d has no color table\n", ABS(panBandList[0])); GDALClose(hDataset); CPLFree(panBandList); GDALDestroyDriverManager(); CSLDestroy(argv); CSLDestroy(papszCreateOptions); exit(1); } /* Check that the color table only contains gray levels */ /* when using -expand gray */ if (nRGBExpand == 1) { int nColorCount = poColorTable->GetColorEntryCount(); int nColor; for (nColor = 0; nColor < nColorCount; nColor++) { const GDALColorEntry *poEntry = poColorTable->GetColorEntry(nColor); if (poEntry->c1 != poEntry->c2 || poEntry->c1 != poEntry->c2) { fprintf(stderr, "Warning : color table contains non gray levels colors\n"); break; } } } if (nBandCount == 1) nBandCount = nRGBExpand; else if (nBandCount == 2 && (nRGBExpand == 3 || nRGBExpand == 4)) nBandCount = nRGBExpand; else { fprintf(stderr, "Error : invalid use of -expand option.\n"); exit(1); } } int bFilterOutStatsMetadata = (bScale || bUnscale || !bSpatialArrangementPreserved || nRGBExpand != 0); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ for (i = 0; i < nBandCount; i++) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; int nComponent = 0; int nSrcBand; if (nRGBExpand != 0) { if (nSrcBandCount == 2 && nRGBExpand == 4 && i == 3) nSrcBand = panBandList[1]; else { nSrcBand = panBandList[0]; nComponent = i + 1; } } else nSrcBand = panBandList[i]; poSrcBand = ((GDALDataset*) hDataset)->GetRasterBand(ABS(nSrcBand)); /* -------------------------------------------------------------------- */ /* Select output data type to match source. */ /* -------------------------------------------------------------------- */ if (eOutputType == GDT_Unknown) eBandType = poSrcBand->GetRasterDataType(); else eBandType = eOutputType; /* -------------------------------------------------------------------- */ /* Create this band. */ /* -------------------------------------------------------------------- */ poVDS->AddBand(eBandType, NULL); poVRTBand = (VRTSourcedRasterBand*) poVDS->GetRasterBand(i + 1); if (nSrcBand < 0) { poVRTBand->AddMaskBandSource(poSrcBand); continue; } /* -------------------------------------------------------------------- */ /* Do we need to collect scaling information? */ /* -------------------------------------------------------------------- */ double dfScale = 1.0, dfOffset = 0.0; if (bScale && !bHaveScaleSrc) { double adfCMinMax[2]; GDALComputeRasterMinMax(poSrcBand, TRUE, adfCMinMax); dfScaleSrcMin = adfCMinMax[0]; dfScaleSrcMax = adfCMinMax[1]; } if (bScale) { if (dfScaleSrcMax == dfScaleSrcMin) dfScaleSrcMax += 0.1; if (dfScaleDstMax == dfScaleDstMin) dfScaleDstMax += 0.1; dfScale = (dfScaleDstMax - dfScaleDstMin) / (dfScaleSrcMax - dfScaleSrcMin); dfOffset = -1 * dfScaleSrcMin * dfScale + dfScaleDstMin; } if (bUnscale) { dfScale = poSrcBand->GetScale(); dfOffset = poSrcBand->GetOffset(); } /* -------------------------------------------------------------------- */ /* Create a simple or complex data source depending on the */ /* translation type required. */ /* -------------------------------------------------------------------- */ if (bUnscale || bScale || (nRGBExpand != 0 && i < nRGBExpand)) { poVRTBand->AddComplexSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, dfOffset, dfScale, VRT_NODATA_UNSET, nComponent); } else poVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); /* -------------------------------------------------------------------- */ /* In case of color table translate, we only set the color */ /* interpretation other info copied by CopyBandInfo are */ /* not relevant in RGB expansion. */ /* -------------------------------------------------------------------- */ if (nRGBExpand == 1) { poVRTBand->SetColorInterpretation(GCI_GrayIndex); } else if (nRGBExpand != 0 && i < nRGBExpand) { poVRTBand->SetColorInterpretation((GDALColorInterp) (GCI_RedBand + i)); } /* -------------------------------------------------------------------- */ /* copy over some other information of interest. */ /* -------------------------------------------------------------------- */ else { CopyBandInfo(poSrcBand, poVRTBand, !bStats && !bFilterOutStatsMetadata, !bUnscale, !bSetNoData && !bUnsetNoData); } /* -------------------------------------------------------------------- */ /* Set a forcable nodata value? */ /* -------------------------------------------------------------------- */ if (bSetNoData) { double dfVal = dfNoDataReal; int bClamped = FALSE, bRounded = FALSE; #define CLAMP(val, type, minval, maxval) \ do { if (val < minval) { bClamped = TRUE; val = minval; \ } \ else if (val > maxval) { bClamped = TRUE; val = maxval; } \ else if (val != (type)val) { bRounded = TRUE; val = (type)(val + 0.5); } \ } \ while (0) switch (eBandType) { case GDT_Byte: CLAMP(dfVal, GByte, 0.0, 255.0); break; case GDT_Int16: CLAMP(dfVal, GInt16, -32768.0, 32767.0); break; case GDT_UInt16: CLAMP(dfVal, GUInt16, 0.0, 65535.0); break; case GDT_Int32: CLAMP(dfVal, GInt32, -2147483648.0, 2147483647.0); break; case GDT_UInt32: CLAMP(dfVal, GUInt32, 0.0, 4294967295.0); break; default: break; } if (bClamped) { printf("for band %d, nodata value has been clamped " "to %.0f, the original value being out of range.\n", i + 1, dfVal); } else if (bRounded) { printf("for band %d, nodata value has been rounded " "to %.0f, %s being an integer datatype.\n", i + 1, dfVal, GDALGetDataTypeName(eBandType)); } poVRTBand->SetNoDataValue(dfVal); } if (eMaskMode == MASK_AUTO && (GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) & GMF_PER_DATASET) == 0 && (poSrcBand->GetMaskFlags() & (GMF_ALL_VALID | GMF_NODATA)) == 0) { if (poVRTBand->CreateMaskBand(poSrcBand->GetMaskFlags()) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*)poVRTBand->GetMaskBand(); hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } } if (eMaskMode == MASK_USER) { GDALRasterBand *poSrcBand = (GDALRasterBand*)GDALGetRasterBand(hDataset, ABS(nMaskBand)); if (poSrcBand && poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); if (nMaskBand > 0) hMaskVRTBand->AddSimpleSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); else hMaskVRTBand->AddMaskBandSource(poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } else if (eMaskMode == MASK_AUTO && nSrcBandCount > 0 && GDALGetMaskFlags(GDALGetRasterBand(hDataset, 1)) == GMF_PER_DATASET) { if (poVDS->CreateMaskBand(GMF_PER_DATASET) == CE_None) { VRTSourcedRasterBand *hMaskVRTBand = (VRTSourcedRasterBand*) GDALGetMaskBand(GDALGetRasterBand((GDALDatasetH)poVDS, 1)); hMaskVRTBand->AddMaskBandSource((GDALRasterBand*)GDALGetRasterBand(hDataset, 1), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize); } } /* -------------------------------------------------------------------- */ /* Compute stats if required. */ /* -------------------------------------------------------------------- */ if (bStats) { for (i = 0; i < poVDS->GetRasterCount(); i++) { double dfMin, dfMax, dfMean, dfStdDev; poVDS->GetRasterBand(i + 1)->ComputeStatistics(bApproxStats, &dfMin, &dfMax, &dfMean, &dfStdDev, GDALDummyProgress, NULL); } } /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ hOutDS = GDALCreateCopy(hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL); if (hOutDS != NULL) { int bHasGotErr = FALSE; CPLErrorReset(); GDALFlushCache(hOutDS); if (CPLGetLastErrorType() != CE_None) bHasGotErr = TRUE; GDALClose(hOutDS); if (bHasGotErr) hOutDS = NULL; } GDALClose((GDALDatasetH) poVDS); GDALClose(hDataset); CPLFree(panBandList); CPLFree(pszOutputSRS); if (!bSubCall) { GDALDumpOpenDatasets(stderr); GDALDestroyDriverManager(); } CSLDestroy(argv); CSLDestroy(papszCreateOptions); return hOutDS == NULL; }
CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(STARTS_WITH_CI(osMissionLevel, "RAW")) productType = PROD_CSK_L0; if(STARTS_WITH_CI(osMissionLevel, "SSC")) productType = PROD_CSK_L1A; if(STARTS_WITH_CI(osMissionLevel, "DGM")) productType = PROD_CSK_L1B; if(STARTS_WITH_CI(osMissionLevel, "GEC")) productType = PROD_CSK_L1C; if(STARTS_WITH_CI(osMissionLevel, "GTC")) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { static const int NBGCPLAT = 100; static const int NBGCPLON = 30; const int nDeltaLat = nRasterYSize / NBGCPLAT; const int nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { if( GetMetadataItem("where_projdef") != NULL ) return CreateODIMH5Projection(); return CE_None; } /* -------------------------------------------------------------------- */ /* The Latitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ const hid_t LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); const hid_t LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); // LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { float * const Latitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); float * const Longitude = static_cast<float *>( CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = (nRasterYSize/nDeltaLat) * (nRasterXSize/nDeltaLon); pasGCPList = static_cast<GDAL_GCP *>( CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; const int nYLimit = (static_cast<int>(nRasterYSize)/nDeltaLat) * nDeltaLat; const int nXLimit = (static_cast<int>(nRasterXSize)/nDeltaLon) * nDeltaLon; // The original code in https://trac.osgeo.org/gdal/changeset/8066 // always add +180 to the longitudes, but without justification // I suspect this might be due to handling products crossing the // antimeridian. Trying to do it just when needed through a heuristics. bool bHasLonNearMinus180 = false; bool bHasLonNearPlus180 = false; bool bHasLonNearZero = false; for( int j = 0; j < nYLimit; j+=nDeltaLat ) { for( int i = 0; i < nXLimit; i+=nDeltaLon ) { const int iGCP = j * nRasterXSize + i; if( Longitude[iGCP] > 170 && Longitude[iGCP] <= 180 ) bHasLonNearPlus180 = true; if( Longitude[iGCP] < -170 && Longitude[iGCP] >= -180 ) bHasLonNearMinus180 = true; if( fabs(Longitude[iGCP]) < 90 ) bHasLonNearZero = true; } } const char* pszShiftGCP = CPLGetConfigOption("HDF5_SHIFT_GCPX_BY_180", NULL); const bool bAdd180 = (bHasLonNearPlus180 && bHasLonNearMinus180 && !bHasLonNearZero && pszShiftGCP == NULL) || (pszShiftGCP != NULL && CPLTestBool(pszShiftGCP)); for( int j = 0; j < nYLimit; j+=nDeltaLat ) { for( int i = 0; i < nXLimit; i+=nDeltaLon ) { const int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = static_cast<double>(Longitude[iGCP]); if( bAdd180 ) pasGCPList[k].dfGCPX += 180.0; pasGCPList[k].dfGCPY = static_cast<double>(Latitude[iGCP]); pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }
/* Matlab Gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { char *pszSRS_WKT = NULL; GDALDatasetH hSrcDS, hDstDS; GDALDriverH hDriver; GDALRasterBandH hBand; OGRSpatialReference oSrcSRS, oDstSRS; GDALResampleAlg interpMethod = GRA_NearestNeighbour; GDALTransformerFunc pfnTransformer = NULL; CPLErr eErr; GDAL_GCP *pasGCPs = NULL; void *hTransformArg; static int runed_once = FALSE; /* It will be set to true if reaches end of main */ int nx, ny, i, j, m, n, c = 0, n_pts, n_fields; char *pszSrcSRS = NULL, *pszSrcWKT = NULL; char *pszDstSRS = NULL, *pszDstWKT = NULL; double *in_data, *ptr_d, *x, *y, *z; mxArray *mx_ptr; int nGCPCount = 0, nOrder = 0; char **papszMetadataOptions = NULL; char *tmp, *txt; int bInverse = FALSE; int *bSuccess; char **papszTO = NULL; if (nrhs == 2 && mxIsStruct(prhs[1])) { /* -------------------------------------------------- */ /* -------- See for projection stuff ---------------- */ mx_ptr = mxGetField(prhs[1], 0, "SrcProjSRS"); if (mx_ptr != NULL) pszSrcSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "SrcProjWKT"); if (mx_ptr != NULL) pszSrcWKT = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjSRS"); if (mx_ptr != NULL) pszDstSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjWKT"); if (mx_ptr != NULL) pszDstWKT = (char *)mxArrayToString(mx_ptr); /* -------------------------------------------------- */ /* -------- Do we have GCPs? ----------------------- */ mx_ptr = mxGetField(prhs[1], 0, "gcp"); if (mx_ptr != NULL) { nGCPCount = mxGetM(mx_ptr); if (mxGetN(mx_ptr) != 4) mexErrMsgTxt("GDALWARP: GCPs must be a Mx4 array"); ptr_d = mxGetPr(mx_ptr); pasGCPs = (GDAL_GCP *) mxCalloc( nGCPCount, sizeof(GDAL_GCP) ); GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 ); for (i = 0; i < nGCPCount; i++) { pasGCPs[i].dfGCPPixel = ptr_d[i]; pasGCPs[i].dfGCPLine = ptr_d[i+nGCPCount]; pasGCPs[i].dfGCPX = ptr_d[i+2*nGCPCount]; pasGCPs[i].dfGCPY = ptr_d[i+3*nGCPCount]; pasGCPs[i].dfGCPZ = 0; } } /* ---- Have we an order request? --- */ mx_ptr = mxGetField(prhs[1], 0, "order"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); nOrder = (int)*ptr_d; if (nOrder != -1 || nOrder != 0 || nOrder != 1 || nOrder != 2 || nOrder != 3) nOrder = 0; } /* -------------------------------------------------- */ mx_ptr = mxGetField(prhs[1], 0, "inverse"); if (mx_ptr != NULL) bInverse = TRUE; mx_ptr = mxGetField(prhs[1], 0, "ResampleAlg"); if (mx_ptr != NULL) { txt = (char *)mxArrayToString(mx_ptr); if (!strcmp(txt,"nearest")) interpMethod = GRA_NearestNeighbour; else if (!strcmp(txt,"bilinear")) interpMethod = GRA_Bilinear; else if (!strcmp(txt,"cubic") || !strcmp(txt,"bicubic")) interpMethod = GRA_Cubic; else if (!strcmp(txt,"spline")) interpMethod = GRA_CubicSpline; } } else { mexPrintf("Usage: out = gdaltransform_mex(IN,PAR_STRUCT)\n\n"); mexPrintf(" IN is a Mx2 or Mx3 array of doubles with X, Y (,Z)\n"); mexPrintf(" PAR_STRUCT is a structure with at most two of the next fields:\n"); mexPrintf("\t\t'SrcProjSRS', 'SrcProjWKT' -> Source projection string\n"); mexPrintf("\t\t'DstProjSRS', 'DstProjWKT' -> Target projection string\n"); mexPrintf("\t\t\tSRS stands for a string of the type used by proj4\n"); mexPrintf("\t\t\tWKT stands for a string on the 'Well Known Text' format\n\n"); mexPrintf("\t\t\tIf one of the Src or Dst fields is absent a GEOGRAPHIC WGS84 is assumed\n"); mexPrintf("\nOPTIONS\n"); mexPrintf("\t\t'gcp' a [Mx4] array with Ground Control Points\n"); mexPrintf("\t\t'inverse' reverse transformation. e.g from georef to rows-columns\n"); if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); mexPrintf( "The following format drivers are configured and support Create() method:\n" ); for( i = 0; i < GDALGetDriverCount(); i++ ) { hDriver = GDALGetDriver(i); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL) mexPrintf("%s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } return; } if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); /* ----- Check that first argument contains at least a mx2 table */ n_pts = mxGetM (prhs[0]); n_fields = mxGetN(prhs[0]); if (!mxIsNumeric(prhs[0]) || (n_fields < 2)) { mexPrintf("GDALTRANSFORM ERROR: first argument must contain a mx2 (or mx3) table\n"); mexErrMsgTxt(" with the x,y (,z) positions to convert.\n"); } DEBUGA(1); /* ---------- Set the Source projection ---------------------------- */ /* If it was not provided assume it is Geog WGS84 */ if (pszSrcSRS == NULL && pszSrcWKT == NULL) oSrcSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszSrcWKT != NULL) oSrcSRS.importFromWkt( &pszSrcWKT ); else { if( oSrcSRS.SetFromUserInput( pszSrcSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDALTRANSFORM: Translating source SRS failed."); } if (pszSrcWKT == NULL) oSrcSRS.exportToWkt( &pszSrcWKT ); /* ------------------------------------------------------------------ */ DEBUGA(2); /* ---------- Set up the Target coordinate system ------------------- */ /* If it was not provided assume it is Geog WGS84 */ CPLErrorReset(); if (pszDstSRS == NULL && pszDstWKT == NULL) oDstSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszDstWKT != NULL) oDstSRS.importFromWkt( &pszDstWKT ); else { if( oDstSRS.SetFromUserInput( pszDstSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDALTRANSFORM: Translating target SRS failed."); } if (pszDstWKT == NULL) oDstSRS.exportToWkt( &pszDstWKT ); /* ------------------------------------------------------------------ */ /* -------------------------------------------------------------------- */ /* Create a transformation object from the source to */ /* destination coordinate system. */ /* -------------------------------------------------------------------- */ if( nGCPCount != 0 && nOrder == -1 ) { pfnTransformer = GDALTPSTransform; hTransformArg = GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE ); } else if( nGCPCount != 0 ) { DEBUGA(3); pfnTransformer = GDALGCPTransform; hTransformArg = GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE ); } else { pfnTransformer = GDALGenImgProjTransform; //hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, papszTO ); hTransformArg = GDALCreateGenImgProjTransformer( NULL, pszSrcWKT, NULL, pszDstWKT, nGCPCount == 0 ? FALSE : TRUE, 0, nOrder ); } //CSLDestroy( papszTO ); DEBUGA(4); if( hTransformArg == NULL ) mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed."); in_data = (double *)mxGetData(prhs[0]); if (n_pts == 1) { x = &in_data[0]; y = &in_data[1]; bSuccess = &c; } else { x = (double *)mxCalloc(n_pts, sizeof(double)); y = (double *)mxCalloc(n_pts, sizeof(double)); bSuccess = (int *)mxCalloc(n_pts, sizeof(int)); for (j = 0; j < n_pts; j++) { x[j] = in_data[j]; y[j] = in_data[j+n_pts]; } } DEBUGA(5); z = (double *)mxCalloc(n_pts, sizeof(double)); if (n_fields == 3) for (j = 0; j < n_pts; j++) z[j] = in_data[j+2*n_pts]; if ( !pfnTransformer( hTransformArg, bInverse, n_pts, x, y, z, bSuccess ) ) mexPrintf( "Transformation failed.\n" ); DEBUGA(6); if( nGCPCount != 0 && nOrder == -1 ) GDALDestroyTPSTransformer(hTransformArg); else if( nGCPCount != 0 ) GDALDestroyGCPTransformer(hTransformArg); else GDALDestroyGenImgProjTransformer(hTransformArg); /* -------------- Copy the result into plhs --------------------------------- */ plhs[0] = mxCreateDoubleMatrix (n_pts,n_fields, mxREAL); ptr_d = mxGetPr(plhs[0]); for (j = 0; j < n_pts; j++) { ptr_d[j] = x[j]; ptr_d[j+n_pts] = y[j]; } if (n_pts > 1) { mxFree((void *)x); mxFree((void *)y); mxFree((void *)bSuccess); } if (n_fields == 3) { for (j = 0; j < n_pts; j++) ptr_d[j+2*n_pts] = z[j]; } mxFree((void *)z); if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT); if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT); //OGRFree(pszSrcWKT); //OGRFree(pszDstWKT); if (nGCPCount > 0) { GDALDeinitGCPs( nGCPCount, pasGCPs ); // makes this mex crash in the next call mxFree((void *) pasGCPs ); } runed_once = TRUE; /* Signals that next call won't need to call GDALAllRegister() again */ }
void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp ) { /* seek to the end fo the leader file descriptor */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET ); if (poDS->nFileType == level_11) { poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" ); poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" ); } else { poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" ); /* extract equivalent number of looks */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET ); char pszENL[17]; double dfENL; READ_CHAR_FLOAT(dfENL, 16, fp); sprintf( pszENL, "%-16.1f", dfENL ); poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL ); /* extract pixel spacings */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET ); double dfPixelSpacing; double dfLineSpacing; char pszPixelSpacing[33]; char pszLineSpacing[33]; READ_CHAR_FLOAT(dfPixelSpacing, 16, fp); READ_CHAR_FLOAT(dfLineSpacing, 16, fp); sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing ); sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing ); poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing ); poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing ); /* Alphanumeric projection name */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET, SEEK_SET ); char pszProjName[33]; READ_STRING(pszProjName, 32, fp); poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName ); /* Extract corner GCPs */ poDS->nGCPCount = 4; poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP), poDS->nGCPCount ); GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList ); /* setup the GCPs */ int i; for (i = 0; i < poDS->nGCPCount; i++) { char pszID[2]; sprintf( pszID, "%d", i + 1); CPLFree(poDS->pasGCPList[i].pszId); poDS->pasGCPList[i].pszId = CPLStrdup( pszID ); poDS->pasGCPList[i].dfGCPZ = 0.0; } double dfTemp = 0.0; /* seek to start of GCPs */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET ); /* top-left GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[0].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[0].dfGCPX = dfTemp; poDS->pasGCPList[0].dfGCPLine = 0.5; poDS->pasGCPList[0].dfGCPPixel = 0.5; /* top right GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[1].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[1].dfGCPX = dfTemp; poDS->pasGCPList[1].dfGCPLine = 0.5; poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5; /* bottom right GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[2].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[2].dfGCPX = dfTemp; poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5; poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5; /* bottom left GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[3].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[3].dfGCPX = dfTemp; poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5; poDS->pasGCPList[3].dfGCPPixel = 0.5; } /* some generic metadata items */ poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */ poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" ); /* Check if this is a PolSAR dataset */ if ( poDS->GetRasterCount() == 4 ) { /* PALSAR data is only available from JAXA in Scattering Matrix form */ poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } }
CPLErr VRTDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath ) { if( pszVRTPath != NULL ) this->pszVRTPath = CPLStrdup(pszVRTPath); /* -------------------------------------------------------------------- */ /* Check for an SRS node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "SRS", "")) > 0 ) { OGRSpatialReference oSRS; CPLFree( pszProjection ); pszProjection = NULL; if( oSRS.SetFromUserInput( CPLGetXMLValue(psTree, "SRS", "") ) == OGRERR_NONE ) oSRS.exportToWkt( &pszProjection ); } /* -------------------------------------------------------------------- */ /* Check for a GeoTransform node. */ /* -------------------------------------------------------------------- */ if( strlen(CPLGetXMLValue(psTree, "GeoTransform", "")) > 0 ) { const char *pszGT = CPLGetXMLValue(psTree, "GeoTransform", ""); char **papszTokens; papszTokens = CSLTokenizeStringComplex( pszGT, ",", FALSE, FALSE ); if( CSLCount(papszTokens) != 6 ) { CPLError( CE_Warning, CPLE_AppDefined, "GeoTransform node does not have expected six values."); } else { for( int iTA = 0; iTA < 6; iTA++ ) adfGeoTransform[iTA] = atof(papszTokens[iTA]); bGeoTransformSet = TRUE; } CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Check for GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" ); if( psGCPList != NULL ) { CPLXMLNode *psXMLGCP; OGRSpatialReference oSRS; const char *pszRawProj = CPLGetXMLValue(psGCPList, "Projection", ""); CPLFree( pszGCPProjection ); if( strlen(pszRawProj) > 0 && oSRS.SetFromUserInput( pszRawProj ) == OGRERR_NONE ) oSRS.exportToWkt( &pszGCPProjection ); else pszGCPProjection = CPLStrdup(""); // Count GCPs. int nGCPMax = 0; for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) nGCPMax++; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax); for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; psXMLGCP = psXMLGCP->psNext ) { GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psXMLGCP->pszValue,"GCP") || psXMLGCP->eType != CXT_Element ) continue; GDALInitGCPs( 1, psGCP ); CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id","")); CPLFree( psGCP->pszInfo ); psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info","")); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0")); nGCPCount++; } } /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Create dataset mask band. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psChild; /* Parse dataset mask band first */ CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand"); if (psMaskBandNode) psChild = psMaskBandNode->psChild; else psChild = NULL; for( ; psChild != NULL; psChild=psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(psChild->pszValue,"VRTRasterBand") ) { VRTRasterBand *poBand = NULL; const char *pszSubclass = CPLGetXMLValue( psChild, "subclass", "VRTSourcedRasterBand" ); if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( this, 0 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( this, 0 ); else CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); if( poBand != NULL && poBand->XMLInit( psChild, pszVRTPath ) == CE_None ) { SetMaskBand(poBand); break; } else { if( poBand ) delete poBand; return CE_Failure; } } } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int nBands = 0; for( psChild=psTree->psChild; psChild != NULL; psChild=psChild->psNext ) { if( psChild->eType == CXT_Element && EQUAL(psChild->pszValue,"VRTRasterBand") ) { VRTRasterBand *poBand = NULL; const char *pszSubclass = CPLGetXMLValue( psChild, "subclass", "VRTSourcedRasterBand" ); if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( this, nBands+1 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( this, nBands+1 ); else CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); if( poBand != NULL && poBand->XMLInit( psChild, pszVRTPath ) == CE_None ) { SetBand( ++nBands, poBand ); } else { if( poBand ) delete poBand; return CE_Failure; } } } return CE_None; }
MAIN_START(argc, argv) { // Check that we are running against at least GDAL 1.5. // Note to developers: if we use newer API, please change the requirement. if (atoi(GDALVersionInfo("VERSION_NUM")) < 1500) { fprintf(stderr, "At least, GDAL >= 1.5.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); const char *pszSrcFilename = nullptr; const char *pszDstFilename = nullptr; int nOrder = 0; void *hTransformArg; GDALTransformerFunc pfnTransformer = nullptr; int nGCPCount = 0; GDAL_GCP *pasGCPs = nullptr; int bInverse = FALSE; CPLStringList aosTO; int bOutputXY = FALSE; double dfX = 0.0; double dfY = 0.0; double dfZ = 0.0; double dfT = 0.0; bool bCoordOnCommandLine = false; /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( int i = 1; i < argc && argv[i] != nullptr; 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(); } else if( EQUAL(argv[i],"-t_srs") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); const char *pszSRS = argv[++i]; if( !IsValidSRS(pszSRS) ) exit(1); aosTO.SetNameValue("DST_SRS", pszSRS ); } else if( EQUAL(argv[i],"-s_srs") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); const char *pszSRS = argv[++i]; if( !IsValidSRS(pszSRS) ) exit(1); aosTO.SetNameValue("SRC_SRS", pszSRS ); } else if( EQUAL(argv[i],"-ct") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); const char *pszCT = argv[++i]; aosTO.SetNameValue("COORDINATE_OPERATION", pszCT ); } else if( EQUAL(argv[i],"-order") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); nOrder = atoi(argv[++i]); aosTO.SetNameValue("MAX_GCP_ORDER", argv[i] ); } else if( EQUAL(argv[i],"-tps") ) { aosTO.SetNameValue("METHOD", "GCP_TPS" ); nOrder = -1; } else if( EQUAL(argv[i],"-rpc") ) { aosTO.SetNameValue("METHOD", "RPC" ); } else if( EQUAL(argv[i],"-geoloc") ) { aosTO.SetNameValue("METHOD", "GEOLOC_ARRAY" ); } else if( EQUAL(argv[i],"-i") ) { bInverse = TRUE; } else if( EQUAL(argv[i],"-to") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); aosTO.AddString( argv[++i] ); } else if( EQUAL(argv[i],"-gcp") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4); char* endptr = nullptr; /* -gcp pixel line easting northing [elev] */ nGCPCount++; pasGCPs = static_cast<GDAL_GCP *>( CPLRealloc(pasGCPs, sizeof(GDAL_GCP) * nGCPCount)); GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 ); pasGCPs[nGCPCount-1].dfGCPPixel = CPLAtof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPLine = CPLAtof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPX = CPLAtof(argv[++i]); pasGCPs[nGCPCount-1].dfGCPY = CPLAtof(argv[++i]); if( argv[i+1] != nullptr && (CPLStrtod(argv[i+1], &endptr) != 0.0 || argv[i+1][0] == '0') ) { // Check that last argument is really a number and not a // filename looking like a number (see ticket #863). if (endptr && *endptr == 0) pasGCPs[nGCPCount-1].dfGCPZ = CPLAtof(argv[++i]); } /* should set id and info? */ } else if( EQUAL(argv[i],"-output_xy") ) { bOutputXY = TRUE; } else if( EQUAL(argv[i],"-coord") && i + 2 < argc) { bCoordOnCommandLine = true; dfX = CPLAtof(argv[++i]); dfY = CPLAtof(argv[++i]); if( i + 1 < argc && CPLGetValueType(argv[i+1]) != CPL_VALUE_STRING ) dfZ = CPLAtof(argv[++i]); if( i + 1 < argc && CPLGetValueType(argv[i+1]) != CPL_VALUE_STRING ) dfT = CPLAtof(argv[++i]); } else if( argv[i][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", argv[i])); } else if( pszSrcFilename == nullptr ) { pszSrcFilename = argv[i]; } else if( pszDstFilename == nullptr ) { pszDstFilename = argv[i]; } else { Usage("Too many command options."); } } /* -------------------------------------------------------------------- */ /* Open src and destination file, if appropriate. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = nullptr; if( pszSrcFilename != nullptr ) { hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly ); if( hSrcDS == nullptr ) exit( 1 ); } GDALDatasetH hDstDS = nullptr; if( pszDstFilename != nullptr ) { hDstDS = GDALOpen( pszDstFilename, GA_ReadOnly ); if( hDstDS == nullptr ) exit( 1 ); } if( hSrcDS != nullptr && nGCPCount > 0 ) { fprintf(stderr, "Command line GCPs and input file specified, " "specify one or the other.\n"); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create a transformation object from the source to */ /* destination coordinate system. */ /* -------------------------------------------------------------------- */ if( nGCPCount != 0 && nOrder == -1 ) { pfnTransformer = GDALTPSTransform; hTransformArg = GDALCreateTPSTransformer( nGCPCount, pasGCPs, FALSE ); } else if( nGCPCount != 0 ) { pfnTransformer = GDALGCPTransform; hTransformArg = GDALCreateGCPTransformer( nGCPCount, pasGCPs, nOrder, FALSE ); } else { pfnTransformer = GDALGenImgProjTransform; hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, aosTO.List() ); } if( hTransformArg == nullptr ) { exit( 1 ); } /* -------------------------------------------------------------------- */ /* Read points from stdin, transform and write to stdout. */ /* -------------------------------------------------------------------- */ double dfLastT = 0.0; while( bCoordOnCommandLine || !feof(stdin) ) { if( !bCoordOnCommandLine ) { char szLine[1024]; if( fgets( szLine, sizeof(szLine)-1, stdin ) == nullptr ) break; char **papszTokens = CSLTokenizeString(szLine); const int nCount = CSLCount(papszTokens); if( nCount < 2 ) { CSLDestroy(papszTokens); continue; } dfX = CPLAtof(papszTokens[0]); dfY = CPLAtof(papszTokens[1]); if( nCount >= 3 ) dfZ = CPLAtof(papszTokens[2]); else dfZ = 0.0; if( nCount == 4 ) dfT = CPLAtof(papszTokens[3]); else dfT = 0.0; CSLDestroy(papszTokens); } if( dfT != dfLastT && nGCPCount == 0 ) { if( dfT != 0.0 ) { aosTO.SetNameValue("COORDINATE_EPOCH", CPLSPrintf("%g", dfT)); } else { aosTO.SetNameValue("COORDINATE_EPOCH", nullptr); } GDALDestroyGenImgProjTransformer(hTransformArg); hTransformArg = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, aosTO.List() ); } int bSuccess = TRUE; if( pfnTransformer( hTransformArg, bInverse, 1, &dfX, &dfY, &dfZ, &bSuccess ) && bSuccess ) { if( bOutputXY ) CPLprintf( "%.15g %.15g\n", dfX, dfY ); else CPLprintf( "%.15g %.15g %.15g\n", dfX, dfY, dfZ ); } else { printf( "transformation failed.\n" ); } if( bCoordOnCommandLine ) break; dfLastT = dfT; } if( nGCPCount != 0 && nOrder == -1 ) { GDALDestroyTPSTransformer(hTransformArg); } else if( nGCPCount != 0 ) { GDALDestroyGCPTransformer(hTransformArg); } else { GDALDestroyGenImgProjTransformer(hTransformArg); } if (nGCPCount) { GDALDeinitGCPs( nGCPCount, pasGCPs ); CPLFree( pasGCPs ); } if (hSrcDS) GDALClose(hSrcDS); if (hDstDS) GDALClose(hDstDS); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CSLDestroy( argv ); return 0; }
void EnvisatDataset::ScanForGCPs_MERIS() { int nDatasetIndex, nNumDSR, nDSRSize; bool isBrowseProduct ; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? Seach for a */ /* DS_TYPE=A and a name containing "geolocation" or "tie */ /* points". */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "Tie points ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 ) return; /* -------------------------------------------------------------------- */ /* Figure out the tiepoint space, and how many we have. */ /* -------------------------------------------------------------------- */ int nLinesPerTiePoint, nSamplesPerTiePoint; int nTPPerLine, nTPPerColumn = nNumDSR; if( nNumDSR == 0 ) return; nLinesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINES_PER_TIE_PT", 0 ); nSamplesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "SAMPLES_PER_TIE_PT", 0 ); if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 ) return; nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1) / nSamplesPerTiePoint; /* -------------------------------------------------------------------- */ /* Find a Mesurement type dataset to use as a reference raster */ /* band. */ /* -------------------------------------------------------------------- */ int nMDSIndex; for( nMDSIndex = 0; TRUE; nMDSIndex++ ) { char *pszDSType; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nMDSIndex, NULL, &pszDSType, NULL, NULL, NULL, NULL, NULL ) == FAILURE ) { CPLDebug("EnvisatDataset", "Unable to find MDS in Envisat file.") ; return ; } if( EQUAL(pszDSType,"M") ) break; } /* -------------------------------------------------------------------- */ /* Get subset of TP ADS records matching the MDS records */ /* -------------------------------------------------------------------- */ /* get the MDS line sampling time interval */ TimeDelta tdMDSSamplingInterval( 0 , 0 , EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINE_TIME_INTERVAL", 0 ) ); /* get range of TiePoint ADS records matching the measurements */ ADSRangeLastAfter arTP( *hEnvisatFile , nDatasetIndex, nMDSIndex , tdMDSSamplingInterval ) ; /* check if there are any TPs to be used */ if ( arTP.getDSRCount() <= 0 ) { CPLDebug( "EnvisatDataset" , "No tiepoint covering " "the measurement records." ) ; return; /* No TPs - no extraction. */ } /* check if TPs cover the whole range of MDSRs */ if(( arTP.getFirstOffset() < 0 )||( arTP.getLastOffset() < 0 )) { CPLDebug( "EnvisatDataset" , "The tiepoints do not cover " "whole range of measurement records." ) ; /* Not good but we can still extract some of the TPS, can we? */ } /* check TP records spacing */ if ((1+(arTP.getFirstOffset()+arTP.getLastOffset()+GetRasterYSize()-1) / nLinesPerTiePoint ) != arTP.getDSRCount() ) { CPLDebug( "EnvisatDataset", "Not enough tieponts per column! " "received=%d expected=%d", nTPPerColumn , 1 + (arTP.getFirstOffset()+arTP.getLastOffset()+ GetRasterYSize()-1) / nLinesPerTiePoint ) ; return; /* That is far more serious - we risk missplaces TPs. */ } if ( 50*nTPPerLine + 13 == nDSRSize ) /* regular product */ { isBrowseProduct = false ; } else if ( 8*nTPPerLine + 13 == nDSRSize ) /* browse product */ { /* although BPs are rare there is no reason not to support them */ isBrowseProduct = true ; } else { CPLDebug( "EnvisatDataset", "Unexpectd size of 'Tie points ADS' !" " received=%d expected=%d or %d" , nDSRSize , 50*nTPPerLine+13, 8*nTPPerLine+13 ) ; return; } /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize-13); int iGCP; GUInt32 *tpLat = ((GUInt32*)pabyRecord) + nTPPerLine*0 ; /* latitude */ GUInt32 *tpLon = ((GUInt32*)pabyRecord) + nTPPerLine*1 ; /* longitude */ GUInt32 *tpLtc = ((GUInt32*)pabyRecord) + nTPPerLine*4 ; /* lat. DEM correction */ GUInt32 *tpLnc = ((GUInt32*)pabyRecord) + nTPPerLine*5 ; /* lon. DEM correction */ nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc( sizeof(GDAL_GCP), arTP.getDSRCount() * nTPPerLine ); for( int ir = 0 ; ir < arTP.getDSRCount() ; ir++ ) { int iRecord = ir + arTP.getFirstIndex() ; double dfGCPLine = 0.5 + ( iRecord*nLinesPerTiePoint - arTP.getFirstOffset() ) ; if( EnvisatFile_ReadDatasetRecordChunk( hEnvisatFile, nDatasetIndex, iRecord , pabyRecord, 13 , -1 ) != SUCCESS ) continue; for( iGCP = 0; iGCP < nTPPerLine; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); #define INT32(x) ((GInt32)CPL_MSBWORD32(x)) pasGCPList[nGCPCount].dfGCPX = 1e-6*INT32(tpLon[iGCP]) ; pasGCPList[nGCPCount].dfGCPY = 1e-6*INT32(tpLat[iGCP]) ; pasGCPList[nGCPCount].dfGCPZ = 0.0; if( !isBrowseProduct ) /* add DEM corrections */ { pasGCPList[nGCPCount].dfGCPX += 1e-6*INT32(tpLnc[iGCP]) ; pasGCPList[nGCPCount].dfGCPY += 1e-6*INT32(tpLtc[iGCP]) ; } #undef INT32 pasGCPList[nGCPCount].dfGCPLine = dfGCPLine ; pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5; nGCPCount++; } } CPLFree( pabyRecord ); }
void ERSDataset::ReadGCPs() { const char *pszCP = poHeader->Find( "RasterInfo.WarpControl.ControlPoints", NULL ); if( pszCP == NULL ) return; /* -------------------------------------------------------------------- */ /* Parse the control points. They will look something like: */ /* */ /* "1035" Yes No 2344.650885 3546.419458 483270.73 3620906.21 3.105 */ /* -------------------------------------------------------------------- */ char **papszTokens = CSLTokenizeStringComplex( pszCP, "{ \t}", TRUE,FALSE); int nItemsPerLine; int nItemCount = CSLCount(papszTokens); /* -------------------------------------------------------------------- */ /* Work out if we have elevation values or not. */ /* -------------------------------------------------------------------- */ if( nItemCount == 7 ) nItemsPerLine = 7; else if( nItemCount == 8 ) nItemsPerLine = 8; else if( nItemCount < 14 ) { CPLAssert( FALSE ); return; } else if( EQUAL(papszTokens[8],"Yes") || EQUAL(papszTokens[8],"No") ) nItemsPerLine = 7; else if( EQUAL(papszTokens[9],"Yes") || EQUAL(papszTokens[9],"No") ) nItemsPerLine = 8; else { CPLAssert( FALSE ); return; } /* -------------------------------------------------------------------- */ /* Setup GCPs. */ /* -------------------------------------------------------------------- */ int iGCP; CPLAssert( nGCPCount == 0 ); nGCPCount = nItemCount / nItemsPerLine; pasGCPList = (GDAL_GCP *) CPLCalloc(nGCPCount,sizeof(GDAL_GCP)); GDALInitGCPs( nGCPCount, pasGCPList ); for( iGCP = 0; iGCP < nGCPCount; iGCP++ ) { GDAL_GCP *psGCP = pasGCPList + iGCP; CPLFree( psGCP->pszId ); psGCP->pszId = CPLStrdup(papszTokens[iGCP*nItemsPerLine+0]); psGCP->dfGCPPixel = atof(papszTokens[iGCP*nItemsPerLine+3]); psGCP->dfGCPLine = atof(papszTokens[iGCP*nItemsPerLine+4]); psGCP->dfGCPX = atof(papszTokens[iGCP*nItemsPerLine+5]); psGCP->dfGCPY = atof(papszTokens[iGCP*nItemsPerLine+6]); if( nItemsPerLine == 8 ) psGCP->dfGCPZ = atof(papszTokens[iGCP*nItemsPerLine+7]); } CSLDestroy( papszTokens ); /* -------------------------------------------------------------------- */ /* Parse the GCP projection. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; CPLString osProjection = poHeader->Find( "RasterInfo.WarpControl.CoordinateSpace.Projection", "RAW" ); CPLString osDatum = poHeader->Find( "RasterInfo.WarpControl.CoordinateSpace.Datum", "WGS84" ); CPLString osUnits = poHeader->Find( "RasterInfo.WarpControl.CoordinateSpace.Units", "METERS" ); oSRS.importFromERM( osProjection, osDatum, osUnits ); CPLFree( pszGCPProjection ); oSRS.exportToWkt( &pszGCPProjection ); }
CPLErr HDF5ImageDataset::CreateProjections() { #define NBGCPLAT 100 #define NBGCPLON 30 hid_t LatitudeDatasetID = -1; hid_t LongitudeDatasetID = -1; hid_t LatitudeDataspaceID; hid_t LongitudeDataspaceID; float* Latitude; float* Longitude; int i,j; int nDeltaLat; int nDeltaLon; nDeltaLat = nRasterYSize / NBGCPLAT; nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { return CE_None; } /* -------------------------------------------------------------------- */ /* The Lattitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { Latitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); Longitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon; pasGCPList = ( GDAL_GCP * ) CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat; int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon; for( j = 0; j < nYLimit; j+=nDeltaLat ) { for( i = 0; i < nXLimit; i+=nDeltaLon ) { int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0; pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP]; pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } return CE_None; }
/** GDALComputeMatchingPoints. TODO document */ GDAL_GCP CPL_DLL * GDALComputeMatchingPoints( GDALDatasetH hFirstImage, GDALDatasetH hSecondImage, char **papszOptions, int *pnGCPCount ) { *pnGCPCount = 0; /* -------------------------------------------------------------------- */ /* Override default algorithm parameters. */ /* -------------------------------------------------------------------- */ int nOctaveStart, nOctaveEnd; double dfSURFThreshold; nOctaveStart =atoi(CSLFetchNameValueDef(papszOptions, "OCTAVE_START", "2")); nOctaveEnd = atoi(CSLFetchNameValueDef(papszOptions, "OCTAVE_END", "2")); dfSURFThreshold = CPLAtof( CSLFetchNameValueDef(papszOptions, "SURF_THRESHOLD", "0.001")); const double dfMatchingThreshold = CPLAtof( CSLFetchNameValueDef(papszOptions, "MATCHING_THRESHOLD", "0.015")); /* -------------------------------------------------------------------- */ /* Identify the bands to use. For now we are effectively */ /* limited to using RGB input so if we have one band only treat */ /* it as red=green=blue=band 1. Disallow non eightbit imagery. */ /* -------------------------------------------------------------------- */ int anBandMap1[3] = { 1, 1, 1 }; if( GDALGetRasterCount(hFirstImage) >= 3 ) { anBandMap1[1] = 2; anBandMap1[2] = 3; } int anBandMap2[3] = { 1, 1, 1 }; if( GDALGetRasterCount(hSecondImage) >= 3 ) { anBandMap2[1] = 2; anBandMap2[2] = 3; } /* -------------------------------------------------------------------- */ /* Collect reference points on each image. */ /* -------------------------------------------------------------------- */ std::vector<GDALFeaturePoint> *poFPCollection1 = GatherFeaturePoints(reinterpret_cast<GDALDataset *>(hFirstImage), anBandMap1, nOctaveStart, nOctaveEnd, dfSURFThreshold); if( poFPCollection1 == nullptr ) return nullptr; std::vector<GDALFeaturePoint> *poFPCollection2 = GatherFeaturePoints(reinterpret_cast<GDALDataset *>(hSecondImage), anBandMap2, nOctaveStart, nOctaveEnd, dfSURFThreshold); if( poFPCollection2 == nullptr ) { delete poFPCollection1; return nullptr; } /* -------------------------------------------------------------------- */ /* Try to find corresponding locations. */ /* -------------------------------------------------------------------- */ std::vector<GDALFeaturePoint *> oMatchPairs; if( CE_None != GDALSimpleSURF::MatchFeaturePoints( &oMatchPairs, poFPCollection1, poFPCollection2, dfMatchingThreshold )) { delete poFPCollection1; delete poFPCollection2; return nullptr; } *pnGCPCount = static_cast<int>(oMatchPairs.size()) / 2; /* -------------------------------------------------------------------- */ /* Translate these into GCPs - but with the output coordinate */ /* system being pixel/line on the second image. */ /* -------------------------------------------------------------------- */ GDAL_GCP *pasGCPList = static_cast<GDAL_GCP*>(CPLCalloc(*pnGCPCount, sizeof(GDAL_GCP))); GDALInitGCPs(*pnGCPCount, pasGCPList); for( int i=0; i < *pnGCPCount; i++ ) { GDALFeaturePoint *poPoint1 = oMatchPairs[i*2 ]; GDALFeaturePoint *poPoint2 = oMatchPairs[i*2+1]; pasGCPList[i].dfGCPPixel = poPoint1->GetX() + 0.5; pasGCPList[i].dfGCPLine = poPoint1->GetY() + 0.5; pasGCPList[i].dfGCPX = poPoint2->GetX() + 0.5; pasGCPList[i].dfGCPY = poPoint2->GetY() + 0.5; pasGCPList[i].dfGCPZ = 0.0; } // Cleanup the feature point lists. delete poFPCollection1; delete poFPCollection2; /* -------------------------------------------------------------------- */ /* Optionally transform into the georef coordinates of the */ /* output image. */ /* -------------------------------------------------------------------- */ const bool bGeorefOutput = CPLTestBool(CSLFetchNameValueDef(papszOptions, "OUTPUT_GEOREF", "NO")); if( bGeorefOutput ) { double adfGeoTransform[6] = {}; GDALGetGeoTransform( hSecondImage, adfGeoTransform ); for( int i=0; i < *pnGCPCount; i++ ) { GDALApplyGeoTransform(adfGeoTransform, pasGCPList[i].dfGCPX, pasGCPList[i].dfGCPY, &(pasGCPList[i].dfGCPX), &(pasGCPList[i].dfGCPY)); } } return pasGCPList; }
void NITFDensifyGCPs( GDAL_GCP **psGCPs, int *pnGCPCount ) { // Given the four corner points of an extent (UL, UR, LR, LL), this method // will add three points to each line segment and return a total of 16 points // including the four original corner points. if ( (*pnGCPCount != 4) || (psGCPs == NULL) ) return; const int nDensifiedGCPs = 16; GDAL_GCP *psDensifiedGCPs = reinterpret_cast<GDAL_GCP *>( CPLMalloc( sizeof( GDAL_GCP ) * nDensifiedGCPs) ); GDALInitGCPs( nDensifiedGCPs, psDensifiedGCPs ); bool ok = true; double xLeftPt = 0.0; double xMidPt = 0.0; double xRightPt = 0.0; double yLeftPt = 0.0; double yMidPt = 0.0; double yRightPt = 0.0; int count = 0; int idx = 0; for( int ii = 0; ( (ii < *pnGCPCount) && (ok) ) ; ++ii ) { idx = ( ii != 3 ) ? ii+1 : 0; try { psDensifiedGCPs[count].dfGCPX = (*psGCPs)[ii].dfGCPX; psDensifiedGCPs[count].dfGCPY = (*psGCPs)[ii].dfGCPY; xMidPt = ((*psGCPs)[ii].dfGCPX+(*psGCPs)[idx].dfGCPX) * 0.5; yMidPt = ((*psGCPs)[ii].dfGCPY+(*psGCPs)[idx].dfGCPY) * 0.5; xLeftPt = ((*psGCPs)[ii].dfGCPX+xMidPt) * 0.5; yLeftPt = ((*psGCPs)[ii].dfGCPY+yMidPt) * 0.5; xRightPt = (xMidPt+(*psGCPs)[idx].dfGCPX) * 0.5; yRightPt = (yMidPt+(*psGCPs)[idx].dfGCPY) * 0.5; psDensifiedGCPs[count+1].dfGCPX = xLeftPt; psDensifiedGCPs[count+1].dfGCPY = yLeftPt; psDensifiedGCPs[count+2].dfGCPX = xMidPt; psDensifiedGCPs[count+2].dfGCPY = yMidPt; psDensifiedGCPs[count+3].dfGCPX = xRightPt; psDensifiedGCPs[count+3].dfGCPY = yRightPt; count += *pnGCPCount; } catch (...) { ok = false; } } if( !ok ) { GDALDeinitGCPs( nDensifiedGCPs, psDensifiedGCPs ); CPLFree( psDensifiedGCPs ); psDensifiedGCPs = NULL; return; } GDALDeinitGCPs( *pnGCPCount, *psGCPs ); CPLFree( *psGCPs ); *psGCPs = psDensifiedGCPs; *pnGCPCount = nDensifiedGCPs; psDensifiedGCPs = NULL; }
GDALDataset *FASTDataset::Open( GDALOpenInfo * poOpenInfo ) { if( poOpenInfo->nHeaderBytes < 1024) return NULL; if( !EQUALN((const char *) poOpenInfo->pabyHeader + 52, "ACQUISITION DATE =", 18) && !EQUALN((const char *) poOpenInfo->pabyHeader + 36, "ACQUISITION DATE =", 18) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ FASTDataset *poDS = new FASTDataset(); poDS->fpHeader = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (poDS->fpHeader == NULL) { delete poDS; return NULL; } poDS->pszFilename = poOpenInfo->pszFilename; poDS->pszDirname = CPLStrdup( CPLGetDirname( poOpenInfo->pszFilename ) ); /* -------------------------------------------------------------------- */ /* Read the administrative record. */ /* -------------------------------------------------------------------- */ char *pszHeader = static_cast<char *>( CPLMalloc( ADM_HEADER_SIZE + 1 ) ); size_t nBytesRead = 0; if( VSIFSeekL( poDS->fpHeader, 0, SEEK_SET ) >= 0 ) nBytesRead = VSIFReadL( pszHeader, 1, ADM_HEADER_SIZE, poDS->fpHeader ); if ( nBytesRead < ADM_MIN_HEADER_SIZE ) { CPLDebug( "FAST", "Header file too short. Reading failed" ); CPLFree(pszHeader); delete poDS; return NULL; } pszHeader[nBytesRead] = '\0'; // Read acquisition date char *pszTemp = GetValue( pszHeader, ACQUISITION_DATE, ACQUISITION_DATE_SIZE, TRUE ); if (pszTemp == NULL) { CPLDebug( "FAST", "Cannot get ACQUISITION_DATE, using empty value." ); pszTemp = CPLStrdup(""); } poDS->SetMetadataItem( "ACQUISITION_DATE", pszTemp ); CPLFree( pszTemp ); // Read satellite name (will read the first one only) pszTemp = GetValue( pszHeader, SATELLITE_NAME, SATELLITE_NAME_SIZE, TRUE ); if (pszTemp == NULL) { CPLDebug( "FAST", "Cannot get SATELLITE_NAME, using empty value." ); pszTemp = CPLStrdup( "" ); } poDS->SetMetadataItem( "SATELLITE", pszTemp ); if ( STARTS_WITH_CI(pszTemp, "LANDSAT") ) poDS->iSatellite = LANDSAT; // TODO(schwehr): Was this a bug that both are IRS? // else if ( STARTS_WITH_CI(pszTemp, "IRS") ) // poDS->iSatellite = IRS; else poDS->iSatellite = IRS; // TODO(schwehr): Should this be FAST_UNKNOWN? CPLFree( pszTemp ); // Read sensor name (will read the first one only) pszTemp = GetValue( pszHeader, SENSOR_NAME, SENSOR_NAME_SIZE, TRUE ); if (pszTemp == NULL) { CPLDebug( "FAST", "Cannot get SENSOR_NAME, using empty value." ); pszTemp = CPLStrdup(""); } poDS->SetMetadataItem( "SENSOR", pszTemp ); CPLFree( pszTemp ); // Read filenames poDS->nBands = 0; if (strstr( pszHeader, FILENAME ) == NULL) { if (strstr(pszHeader, "GENERATING AGENCY =EUROMAP")) { // If we don't find the FILENAME field, let's try with the Euromap // PAN / LISS3 / WIFS IRS filename convention. if ((EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS 1C") || EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS 1D")) && (EQUAL(poDS->GetMetadataItem("SENSOR"), "PAN") || EQUAL(poDS->GetMetadataItem("SENSOR"), "LISS3") || EQUAL(poDS->GetMetadataItem("SENSOR"), "WIFS"))) { poDS->TryEuromap_IRS_1C_1D_ChannelNameConvention(); } else if (EQUAL(poDS->GetMetadataItem("SATELLITE"), "CARTOSAT-1") && (EQUAL(poDS->GetMetadataItem("SENSOR"), "FORE") || EQUAL(poDS->GetMetadataItem("SENSOR"), "AFT"))) { // See appendix F in // http://www.euromap.de/download/p5fast_20050301.pdf const CPLString osSuffix = CPLGetExtension( poDS->pszFilename ); const char *papszBasenames[] = { "BANDF", "bandf", "BANDA", "banda" }; for ( int i = 0; i < 4; i++ ) { const CPLString osChannelFilename = CPLFormFilename( poDS->pszDirname, papszBasenames[i], osSuffix ); if( poDS->OpenChannel( osChannelFilename, 0 ) ) { poDS->nBands = 1; break; } } } else if( EQUAL(poDS->GetMetadataItem("SATELLITE"), "IRS P6") ) { // If BANDS_PRESENT="2345", the file bands are "BAND2.DAT", // "BAND3.DAT", etc. pszTemp = GetValue( pszHeader, BANDS_PRESENT, BANDS_PRESENT_SIZE, TRUE ); if (pszTemp) { for( int i=0; pszTemp[i] != '\0'; i++ ) { if( pszTemp[i] >= '2' && pszTemp[i] <= '5' ) { if( poDS->FOpenChannel( poDS->pszFilename, poDS->nBands, pszTemp[i] - '0')) poDS->nBands++; } } CPLFree( pszTemp ); } } } } // If the previous lookup for band files didn't success, fallback to the // standard way of finding them, either by the FILENAME field, either with // the usual patterns like bandX.dat, etc. if( !poDS->nBands ) { pszTemp = pszHeader; for ( int i = 0; i < 7; i++ ) { char *pszFilename = NULL ; if ( pszTemp ) pszTemp = strstr( pszTemp, FILENAME ); if ( pszTemp ) { // Skip the parameter name pszTemp += strlen(FILENAME); // Skip whitespaces and equal signs while ( *pszTemp == ' ' ) pszTemp++; while ( *pszTemp == '=' ) pszTemp++; pszFilename = CPLScanString( pszTemp, FILENAME_SIZE, TRUE, FALSE ); } else pszTemp = NULL; if ( poDS->FOpenChannel( pszFilename, poDS->nBands, poDS->nBands + 1 ) ) poDS->nBands++; if ( pszFilename ) CPLFree( pszFilename ); } } if ( !poDS->nBands ) { CPLError( CE_Failure, CPLE_NotSupported, "Failed to find and open band data files." ); CPLFree(pszHeader); delete poDS; return NULL; } // Read number of pixels/lines and bit depth pszTemp = GetValue( pszHeader, PIXELS, PIXELS_SIZE, FALSE ); if ( pszTemp ) { poDS->nRasterXSize = atoi( pszTemp ); CPLFree( pszTemp ); } else { CPLDebug( "FAST", "Failed to find number of pixels in line." ); CPLFree(pszHeader); delete poDS; return NULL; } pszTemp = GetValue( pszHeader, LINES1, LINES_SIZE, FALSE ); if ( !pszTemp ) pszTemp = GetValue( pszHeader, LINES2, LINES_SIZE, FALSE ); if ( pszTemp ) { poDS->nRasterYSize = atoi( pszTemp ); CPLFree( pszTemp ); } else { CPLDebug( "FAST", "Failed to find number of lines in raster." ); CPLFree(pszHeader); delete poDS; return NULL; } if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { CPLFree(pszHeader); delete poDS; return NULL; } pszTemp = GetValue( pszHeader, BITS_PER_PIXEL, BITS_PER_PIXEL_SIZE, FALSE ); if ( pszTemp ) { switch( atoi(pszTemp) ) { case 8: default: poDS->eDataType = GDT_Byte; break; // For a strange reason, some Euromap products declare 10 bits // output, but are 16 bits. case 10: case 16: poDS->eDataType = GDT_UInt16; break; } CPLFree( pszTemp ); } else { poDS->eDataType = GDT_Byte; } /* -------------------------------------------------------------------- */ /* Read radiometric record. */ /* -------------------------------------------------------------------- */ const char *pszFirst = NULL; const char *pszSecond = NULL; // Read gains and biases. This is a trick! pszTemp = strstr( pszHeader, "BIASES" );// It may be "BIASES AND GAINS" // or "GAINS AND BIASES" const char* pszGains = strstr( pszHeader, "GAINS" ); if( pszTemp == NULL || pszGains == NULL ) { CPLDebug( "FAST", "No BIASES and/or GAINS" ); CPLFree( pszHeader ); delete poDS; return NULL; } if ( pszTemp > pszGains ) { pszFirst = "GAIN%d"; pszSecond = "BIAS%d"; } else { pszFirst = "BIAS%d"; pszSecond = "GAIN%d"; } // Now search for the first number occurrence after that string. for ( int i = 1; i <= poDS->nBands; i++ ) { char *pszValue = NULL; size_t nValueLen = VALUE_SIZE; pszTemp = strpbrk( pszTemp, "-.0123456789" ); if ( pszTemp ) { nValueLen = strspn( pszTemp, "+-.0123456789" ); pszValue = CPLScanString( pszTemp, static_cast<int>(nValueLen), TRUE, TRUE ); poDS->SetMetadataItem( CPLSPrintf(pszFirst, i ), pszValue ); CPLFree( pszValue ); } pszTemp += nValueLen; pszTemp = strpbrk( pszTemp, "-.0123456789" ); if ( pszTemp ) { nValueLen = strspn( pszTemp, "+-.0123456789" ); pszValue = CPLScanString( pszTemp, static_cast<int>(nValueLen), TRUE, TRUE ); poDS->SetMetadataItem( CPLSPrintf(pszSecond, i ), pszValue ); CPLFree( pszValue ); } pszTemp += nValueLen; } /* -------------------------------------------------------------------- */ /* Read geometric record. */ /* -------------------------------------------------------------------- */ // Coordinates of pixel's centers double dfULX = 0.0; double dfULY = 0.0; double dfURX = 0.0; double dfURY = 0.0; double dfLLX = 0.0; double dfLLY = 0.0; double dfLRX = 0.0; double dfLRY = 0.0; // Read projection name pszTemp = GetValue( pszHeader, PROJECTION_NAME, PROJECTION_NAME_SIZE, FALSE ); long iProjSys = 0; if ( pszTemp && !EQUAL( pszTemp, "" ) ) iProjSys = USGSMnemonicToCode( pszTemp ); else iProjSys = 1L; // UTM by default CPLFree( pszTemp ); // Read ellipsoid name pszTemp = GetValue( pszHeader, ELLIPSOID_NAME, ELLIPSOID_NAME_SIZE, FALSE ); long iDatum = 0; // Clarke, 1866 (NAD1927) by default. if ( pszTemp && !EQUAL( pszTemp, "" ) ) iDatum = USGSEllipsoidToCode( pszTemp ); CPLFree( pszTemp ); // Read zone number. pszTemp = GetValue( pszHeader, ZONE_NUMBER, ZONE_NUMBER_SIZE, FALSE ); long iZone = 0; if ( pszTemp && !EQUAL( pszTemp, "" ) ) iZone = atoi( pszTemp ); CPLFree( pszTemp ); // Read 15 USGS projection parameters double adfProjParms[15] = { 0.0 }; pszTemp = strstr( pszHeader, USGS_PARAMETERS ); if ( pszTemp && !EQUAL( pszTemp, "" ) ) { pszTemp += strlen( USGS_PARAMETERS ); for ( int i = 0; i < 15; i++ ) { pszTemp = strpbrk( pszTemp, "-.0123456789" ); if ( pszTemp ) adfProjParms[i] = CPLScanDouble( pszTemp, VALUE_SIZE ); pszTemp = strpbrk( pszTemp, " \t" ); } } // Coordinates should follow the word "PROJECTION", otherwise we can // be confused by other occurrences of the corner keywords. char *pszGeomRecord = strstr( pszHeader, "PROJECTION" ); // Read corner coordinates pszTemp = strstr( pszGeomRecord, CORNER_UPPER_LEFT ); if ( pszTemp && !EQUAL( pszTemp, "" ) ) { pszTemp += strlen( CORNER_UPPER_LEFT ) + 28; dfULX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); pszTemp += CORNER_VALUE_SIZE + 1; dfULY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); } pszTemp = strstr( pszGeomRecord, CORNER_UPPER_RIGHT ); if ( pszTemp && !EQUAL( pszTemp, "" ) ) { pszTemp += strlen( CORNER_UPPER_RIGHT ) + 28; dfURX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); pszTemp += CORNER_VALUE_SIZE + 1; dfURY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); } pszTemp = strstr( pszGeomRecord, CORNER_LOWER_LEFT ); if ( pszTemp && !EQUAL( pszTemp, "" ) ) { pszTemp += strlen( CORNER_LOWER_LEFT ) + 28; dfLLX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); pszTemp += CORNER_VALUE_SIZE + 1; dfLLY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); } pszTemp = strstr( pszGeomRecord, CORNER_LOWER_RIGHT ); if ( pszTemp && !EQUAL( pszTemp, "" ) ) { pszTemp += strlen( CORNER_LOWER_RIGHT ) + 28; dfLRX = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); pszTemp += CORNER_VALUE_SIZE + 1; dfLRY = CPLScanDouble( pszTemp, CORNER_VALUE_SIZE ); } if ( dfULX != 0.0 && dfULY != 0.0 && dfURX != 0.0 && dfURY != 0.0 && dfLLX != 0.0 && dfLLY != 0.0 && dfLRX != 0.0 && dfLRY != 0.0 ) { // Strip out zone number from the easting values, if either if ( dfULX >= 1000000.0 ) dfULX -= static_cast<double>( iZone ) * 1000000.0; if ( dfURX >= 1000000.0 ) dfURX -= static_cast<double>( iZone ) * 1000000.0; if ( dfLLX >= 1000000.0 ) dfLLX -= static_cast<double>( iZone ) * 1000000.0; if ( dfLRX >= 1000000.0 ) dfLRX -= static_cast<double>( iZone ) * 1000000.0; // In EOSAT FAST Rev C, the angles are in decimal degrees // otherwise they are in packed DMS format. const int bAnglesInPackedDMSFormat = strstr( pszHeader, "REV C" ) == NULL; // Create projection definition OGRSpatialReference oSRS; OGRErr eErr = oSRS.importFromUSGS( iProjSys, iZone, adfProjParms, iDatum, bAnglesInPackedDMSFormat ); if ( eErr != OGRERR_NONE ) CPLDebug( "FAST", "Import projection from USGS failed: %d", eErr ); oSRS.SetLinearUnits( SRS_UL_METER, 1.0 ); // Read datum name pszTemp = GetValue( pszHeader, DATUM_NAME, DATUM_NAME_SIZE, FALSE ); if ( pszTemp ) { if ( EQUAL( pszTemp, "WGS84" ) ) oSRS.SetWellKnownGeogCS( "WGS84" ); else if ( EQUAL( pszTemp, "NAD27" ) ) oSRS.SetWellKnownGeogCS( "NAD27" ); else if ( EQUAL( pszTemp, "NAD83" ) ) oSRS.SetWellKnownGeogCS( "NAD83" ); CPLFree( pszTemp ); } else { // Reasonable fallback oSRS.SetWellKnownGeogCS( "WGS84" ); } if ( poDS->pszProjection ) CPLFree( poDS->pszProjection ); eErr = oSRS.exportToWkt( &poDS->pszProjection ); if ( eErr != OGRERR_NONE ) CPLDebug("FAST", "Export projection to WKT USGS failed: %d", eErr); // Generate GCPs GDAL_GCP *pasGCPList = static_cast<GDAL_GCP *>( CPLCalloc( sizeof( GDAL_GCP ), 4 ) ); GDALInitGCPs( 4, pasGCPList ); CPLFree(pasGCPList[0].pszId); CPLFree(pasGCPList[1].pszId); CPLFree(pasGCPList[2].pszId); CPLFree(pasGCPList[3].pszId); /* Let's order the GCP in TL, TR, BR, BL order to benefit from the */ /* GDALGCPsToGeoTransform optimization */ pasGCPList[0].pszId = CPLStrdup("UPPER_LEFT"); pasGCPList[0].dfGCPX = dfULX; pasGCPList[0].dfGCPY = dfULY; pasGCPList[0].dfGCPZ = 0.0; pasGCPList[0].dfGCPPixel = 0.5; pasGCPList[0].dfGCPLine = 0.5; pasGCPList[1].pszId = CPLStrdup("UPPER_RIGHT"); pasGCPList[1].dfGCPX = dfURX; pasGCPList[1].dfGCPY = dfURY; pasGCPList[1].dfGCPZ = 0.0; pasGCPList[1].dfGCPPixel = poDS->nRasterXSize-0.5; pasGCPList[1].dfGCPLine = 0.5; pasGCPList[2].pszId = CPLStrdup("LOWER_RIGHT"); pasGCPList[2].dfGCPX = dfLRX; pasGCPList[2].dfGCPY = dfLRY; pasGCPList[2].dfGCPZ = 0.0; pasGCPList[2].dfGCPPixel = poDS->nRasterXSize-0.5; pasGCPList[2].dfGCPLine = poDS->nRasterYSize-0.5; pasGCPList[3].pszId = CPLStrdup("LOWER_LEFT"); pasGCPList[3].dfGCPX = dfLLX; pasGCPList[3].dfGCPY = dfLLY; pasGCPList[3].dfGCPZ = 0.0; pasGCPList[3].dfGCPPixel = 0.5; pasGCPList[3].dfGCPLine = poDS->nRasterYSize-0.5; // Calculate transformation matrix, if accurate const bool transform_ok = CPL_TO_BOOL( GDALGCPsToGeoTransform( 4, pasGCPList, poDS->adfGeoTransform, 0 ) ); if( !transform_ok ) { poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; if ( poDS->pszProjection ) CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(""); } GDALDeinitGCPs(4, pasGCPList); CPLFree(pasGCPList); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ const int nPixelOffset = GDALGetDataTypeSize(poDS->eDataType) / 8; const int nLineOffset = poDS->nRasterXSize * nPixelOffset; for( int i = 1; i <= poDS->nBands; i++ ) { poDS->SetBand( i, new FASTRasterBand( poDS, i, poDS->fpChannels[i - 1], 0, nPixelOffset, nLineOffset, poDS->eDataType, TRUE)); } CPLFree( pszHeader ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); // opens overviews. poDS->oOvManager.Initialize(poDS, poDS->pszFilename); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The FAST driver does not support update access to existing" " datasets." ); return NULL; } return poDS; }
void EnvisatDataset::ScanForGCPs_MERIS() { int nDatasetIndex, nNumDSR, nDSRSize, iRecord; /* -------------------------------------------------------------------- */ /* Do we have a meaningful geolocation grid? Seach for a */ /* DS_TYPE=A and a name containing "geolocation" or "tie */ /* points". */ /* -------------------------------------------------------------------- */ nDatasetIndex = EnvisatFile_GetDatasetIndex( hEnvisatFile, "Tie points ADS" ); if( nDatasetIndex == -1 ) return; if( EnvisatFile_GetDatasetInfo( hEnvisatFile, nDatasetIndex, NULL, NULL, NULL, NULL, NULL, &nNumDSR, &nDSRSize ) != SUCCESS ) return; if( nNumDSR == 0 ) return; /* -------------------------------------------------------------------- */ /* Figure out the tiepoint space, and how many we have. */ /* -------------------------------------------------------------------- */ int nLinesPerTiePoint, nSamplesPerTiePoint; int nTPPerLine, nTPPerColumn = nNumDSR; if( nNumDSR == 0 ) return; nLinesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "LINES_PER_TIE_PT", 0 ); nSamplesPerTiePoint = EnvisatFile_GetKeyValueAsInt( hEnvisatFile, SPH, "SAMPLES_PER_TIE_PT", 0 ); if( nLinesPerTiePoint == 0 || nSamplesPerTiePoint == 0 ) return; nTPPerLine = (GetRasterXSize() + nSamplesPerTiePoint - 1) / nSamplesPerTiePoint; if( (GetRasterYSize() + nLinesPerTiePoint - 1) / nLinesPerTiePoint != nTPPerColumn ) { CPLDebug( "EnvisatDataset", "Got %d instead of %d nTPPerColumn.", (GetRasterYSize()+nLinesPerTiePoint-1)/nLinesPerTiePoint, nTPPerColumn ); return; } if( 50*nTPPerLine + 13 != nDSRSize ) { CPLDebug( "EnvisatDataset", "DSRSize=%d instead of expected %d for tiepoints ADS.", nDSRSize, 50*nTPPerLine + 13 ); return; } /* -------------------------------------------------------------------- */ /* Collect the first GCP set from each record. */ /* -------------------------------------------------------------------- */ GByte *pabyRecord = (GByte *) CPLMalloc(nDSRSize); int iGCP; GUInt32 unValue; nGCPCount = 0; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nNumDSR * nTPPerLine); for( iRecord = 0; iRecord < nNumDSR; iRecord++ ) { if( EnvisatFile_ReadDatasetRecord( hEnvisatFile, nDatasetIndex, iRecord, pabyRecord ) != SUCCESS ) continue; memcpy( &unValue, pabyRecord + 13, 4 ); for( iGCP = 0; iGCP < nTPPerLine; iGCP++ ) { char szId[128]; GDALInitGCPs( 1, pasGCPList + nGCPCount ); CPLFree( pasGCPList[nGCPCount].pszId ); sprintf( szId, "%d", nGCPCount+1 ); pasGCPList[nGCPCount].pszId = CPLStrdup( szId ); memcpy( &unValue, pabyRecord + 13 + nTPPerLine*4 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPX = ((int)CPL_MSBWORD32(unValue))*0.000001; memcpy( &unValue, pabyRecord + 13 + iGCP*4, 4 ); pasGCPList[nGCPCount].dfGCPY = ((int)CPL_MSBWORD32(unValue))*0.000001; pasGCPList[nGCPCount].dfGCPZ = 0.0; pasGCPList[nGCPCount].dfGCPLine = iRecord*nLinesPerTiePoint + 0.5; pasGCPList[nGCPCount].dfGCPPixel = iGCP*nSamplesPerTiePoint + 0.5; nGCPCount++; } } CPLFree( pabyRecord ); }
/* Matlab Gateway routine */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { int nXYSize; double adfGeoTransform[6] = {0,1,0,0,0,1}, adfDstGeoTransform[6]; char *pszSRS_WKT = NULL; char **papszWarpOptions = NULL; GDALDatasetH hSrcDS, hDstDS; GDALDriverH hDriver; GDALRasterBandH hBand; GDALColorTableH hColorTable = NULL; OGRSpatialReference oSrcSRS, oDstSRS; GDALResampleAlg interpMethod = GRA_NearestNeighbour; GDALTransformerFunc pfnTransformer = NULL; CPLErr eErr; GDAL_GCP *pasGCPs = NULL; static int runed_once = FALSE; /* It will be set to true if reaches end of main */ const int *dim_array; int nx, ny, i, j, m, n, c, nBands, registration = 1; int n_dims, typeCLASS, nBytes; char *pszSrcSRS = NULL, *pszSrcWKT = NULL; char *pszDstSRS = NULL, *pszDstWKT = NULL; void *in_data; mxArray *mx_ptr; unsigned char *tmpByte, *outByte; unsigned short int *tmpUI16, *outUI16; short int *tmpI16, *outI16; int *tmpI32, *outI32; int nPixels=0, nLines=0, nForceWidth=0, nForceHeight=0; int nGCPCount = 0, nOrder = 0; unsigned int *tmpUI32, *outUI32; float *tmpF32, *outF32; double *tmpF64, *outF64, *ptr_d; double dfMinX=0, dfMaxX=0, dfMinY=0, dfMaxY=0, dfResX=0, dfResY=0; double adfExtent[4]; double dfXRes=0.0, dfYRes=0.0; double dfWarpMemoryLimit = 0.0; double *pdfDstNodata = NULL; char **papszMetadataOptions = NULL; char *tmp, *txt; if (nrhs == 2 && mxIsStruct(prhs[1])) { mx_ptr = mxGetField(prhs[1], 0, "ULx"); if (mx_ptr == NULL) mexErrMsgTxt("GDALWARP 'ULx' field not provided"); ptr_d = mxGetPr(mx_ptr); adfGeoTransform[0] = *ptr_d; mx_ptr = mxGetField(prhs[1], 0, "Xinc"); if (mx_ptr == NULL) mexErrMsgTxt("GDALWARP 'Xinc' field not provided"); ptr_d = mxGetPr(mx_ptr); adfGeoTransform[1] = *ptr_d; mx_ptr = mxGetField(prhs[1], 0, "ULy"); if (mx_ptr == NULL) mexErrMsgTxt("GDALWARP 'ULy' field not provided"); ptr_d = mxGetPr(mx_ptr); adfGeoTransform[3] = *ptr_d; mx_ptr = mxGetField(prhs[1], 0, "Yinc"); if (mx_ptr == NULL) mexErrMsgTxt("GDALWARP 'Yinc' field not provided"); ptr_d = mxGetPr(mx_ptr); adfGeoTransform[5] = -*ptr_d; /* -------- See for resolution requests ------------ */ mx_ptr = mxGetField(prhs[1], 0, "t_size"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); if (mxGetN(mx_ptr) == 2) { nForceWidth = (int)ptr_d[0]; nForceHeight = (int)ptr_d[1]; } else if (mxGetN(mx_ptr) == 1) { /* pick max(nrow,ncol) */ if (mxGetM(prhs[0]) > getNK(prhs[0],1)) nForceHeight = mxGetM(prhs[0]); else nForceWidth = getNK(prhs[0], 1); } else { nForceHeight = mxGetM(prhs[0]); nForceWidth = getNK(prhs[0], 1); } } mx_ptr = mxGetField(prhs[1], 0, "t_res"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); if (mxGetN(mx_ptr) == 2) { dfXRes = ptr_d[0]; dfYRes = ptr_d[1]; } else if (mxGetN(mx_ptr) == 1) { dfXRes = dfYRes = ptr_d[0]; } } /* -------------------------------------------------- */ /* -------- Change Warping cache size? ------------ */ mx_ptr = mxGetField(prhs[1], 0, "wm"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); dfWarpMemoryLimit = *ptr_d * 1024 * 1024; } /* -------------------------------------------------- */ /* -------- Have a nodata value order? -------------- */ mx_ptr = mxGetField(prhs[1], 0, "nodata"); if (mx_ptr != NULL) { pdfDstNodata = mxGetPr(mx_ptr); } /* -------------------------------------------------- */ /* -------- See for projection stuff ---------------- */ mx_ptr = mxGetField(prhs[1], 0, "SrcProjSRS"); if (mx_ptr != NULL) pszSrcSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "SrcProjWKT"); if (mx_ptr != NULL) pszSrcWKT = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjSRS"); if (mx_ptr != NULL) pszDstSRS = (char *)mxArrayToString(mx_ptr); mx_ptr = mxGetField(prhs[1], 0, "DstProjWKT"); if (mx_ptr != NULL) pszDstWKT = (char *)mxArrayToString(mx_ptr); /* -------------------------------------------------- */ /* -------- Do we have GCPs? ----------------------- */ mx_ptr = mxGetField(prhs[1], 0, "gcp"); if (mx_ptr != NULL) { nGCPCount = mxGetM(mx_ptr); if (mxGetN(mx_ptr) != 4) mexErrMsgTxt("GDALWARP: GCPs must be a Mx4 array"); ptr_d = mxGetPr(mx_ptr); pasGCPs = (GDAL_GCP *) mxCalloc( nGCPCount, sizeof(GDAL_GCP) ); GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 ); for (i = 0; i < nGCPCount; i++) { pasGCPs[i].dfGCPPixel = ptr_d[i]; pasGCPs[i].dfGCPLine = ptr_d[i+nGCPCount]; pasGCPs[i].dfGCPX = ptr_d[i+2*nGCPCount]; pasGCPs[i].dfGCPY = ptr_d[i+3*nGCPCount]; pasGCPs[i].dfGCPZ = 0; } } /* ---- Have we an order request? --- */ mx_ptr = mxGetField(prhs[1], 0, "order"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); nOrder = (int)*ptr_d; if (nOrder != -1 || nOrder != 0 || nOrder != 1 || nOrder != 2 || nOrder != 3) nOrder = 0; } /* -------------------------------------------------- */ mx_ptr = mxGetField(prhs[1], 0, "ResampleAlg"); if (mx_ptr != NULL) { txt = (char *)mxArrayToString(mx_ptr); if (!strcmp(txt,"nearest")) interpMethod = GRA_NearestNeighbour; else if (!strcmp(txt,"bilinear")) interpMethod = GRA_Bilinear; else if (!strcmp(txt,"cubic") || !strcmp(txt,"bicubic")) interpMethod = GRA_Cubic; else if (!strcmp(txt,"spline")) interpMethod = GRA_CubicSpline; } /* If grid limits were in grid registration, convert them to pixel reg */ mx_ptr = mxGetField(prhs[1], 0, "Reg"); if (mx_ptr != NULL) { ptr_d = mxGetPr(mx_ptr); registration = (int)ptr_d[0]; } if (registration == 0) { adfGeoTransform[0] -= adfGeoTransform[1]/2.; adfGeoTransform[3] -= adfGeoTransform[5]/2.; } } else { mexPrintf("Usage: B = gdalwarp_mex(IMG,HDR_STRUCT)\n\n"); mexPrintf("\tIMG -> is a Mx2 or Mx3 array with an grid/image data to reproject\n"); mexPrintf("\tHDR_STRUCT -> is a structure with the following fields:\n"); mexPrintf("\t\t'ULx' X coordinate of the uper left corner\n"); mexPrintf("\t\t'ULy' Y coordinate of the uper left corner\n"); mexPrintf("\t\t'Xinc' distance between columns in target grid/image coordinates\n"); mexPrintf("\t\t'Yinc' distance between rows in target grid/image coordinates\n"); mexPrintf("\t\t'SrcProjSRS', 'SrcProjWKT' -> Source projection string\n"); mexPrintf("\t\t'DstProjSRS', 'DstProjWKT' -> Target projection string\n"); mexPrintf("\t\t\tSRS stands for a string of the type used by proj4\n"); mexPrintf("\t\t\tWKT stands for a string on the 'Well Known Text' format\n\n"); mexPrintf("\t\t\tIf one of the Src or Dst fields is absent a GEOGRAPHIC WGS84 is assumed\n"); mexPrintf("\nOPTIONS\n"); mexPrintf("\t\t'gcp' a [Mx4] array with Ground Control Points\n"); mexPrintf("\t\t't_size' a [width height] vector to set output file size in pixels\n"); mexPrintf("\t\t't_res' a [xres yres] vector to set output file resolution (in target georeferenced units)\n"); mexPrintf("\t\t'wm' amount of memory (in megabytes) that the warp API is allowed to use for caching\n"); mexPrintf("\t\t'nodata' Set nodata values for output bands.\n"); mexPrintf("\t\t'ResampleAlg' To set up the algorithm used during warp operation. Options are: \n"); mexPrintf("\t\t\t'nearest' Use nearest neighbour resampling (default, fastest algorithm, worst interpolation quality).\n"); mexPrintf("\t\t\t'bilinear' Use bilinear resampling.\n"); mexPrintf("\t\t\t'cubic' Use cubic resampling.\n"); mexPrintf("\t\t\t'spline' Use cubic spline resampling.\n\n"); if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); mexPrintf( "The following format drivers are configured and support Create() method:\n" ); for( i = 0; i < GDALGetDriverCount(); i++ ) { hDriver = GDALGetDriver(i); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL) mexPrintf("%s: %s\n", GDALGetDriverShortName(hDriver), GDALGetDriverLongName(hDriver)); } return; } n_dims = mxGetNumberOfDimensions(prhs[0]); dim_array=mxGetDimensions(prhs[0]); ny = dim_array[0]; nx = dim_array[1]; nBands = dim_array[2]; if (n_dims == 2) /* Otherwise it would stay undefined */ nBands = 1; /* Find out in which data type was given the input array */ if (mxIsUint8(prhs[0])) { typeCLASS = GDT_Byte; nBytes = 1; outByte = (unsigned char *)mxMalloc (nx*ny * sizeof(unsigned char)); } else if (mxIsUint16(prhs[0])) { typeCLASS = GDT_UInt16; nBytes = 2; outUI16 = (unsigned short int *)mxMalloc (nx*ny * sizeof(short int)); } else if (mxIsInt16(prhs[0])) { typeCLASS = GDT_Int16; nBytes = 2; outI16 = (short int *)mxMalloc (nx*ny * sizeof(short int)); } else if (mxIsInt32(prhs[0])) { typeCLASS = GDT_Int32; nBytes = 4; outI32 = (int *)mxMalloc (nx*ny * sizeof(int)); } else if (mxIsUint32(prhs[0])) { typeCLASS = GDT_UInt32; nBytes = 4; outUI32 = (unsigned int *)mxMalloc (nx*ny * sizeof(int)); } else if (mxIsSingle(prhs[0])) { typeCLASS = GDT_Float32; nBytes = 4; outF32 = (float *)mxMalloc (nx*ny * sizeof(float)); } else if (mxIsDouble(prhs[0])) { typeCLASS = GDT_Float64; nBytes = 8; outF64 = (double *)mxMalloc (nx*ny * sizeof(double)); } else mexErrMsgTxt("GDALWARP Unknown input data class!"); in_data = (void *)mxGetData(prhs[0]); if (!runed_once) /* Do next call only at first time this MEX is loaded */ GDALAllRegister(); hDriver = GDALGetDriverByName( "MEM" ); hSrcDS = GDALCreate( hDriver, "mem", nx, ny, nBands, (GDALDataType)typeCLASS, NULL ); if (hSrcDS == NULL) { mexPrintf ("GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg()); return; } GDALSetGeoTransform( hSrcDS, adfGeoTransform ); /* ---------- Set the Source projection ---------------------------- */ /* If it was not provided assume it is Geog WGS84 */ if (pszSrcSRS == NULL && pszSrcWKT == NULL) oSrcSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszSrcWKT != NULL) oSrcSRS.importFromWkt( &pszSrcWKT ); else { if( oSrcSRS.SetFromUserInput( pszSrcSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDAL_WARP_MEX: Translating source SRS failed."); } if (pszSrcWKT == NULL) oSrcSRS.exportToWkt( &pszSrcWKT ); GDALSetProjection( hSrcDS, pszSrcWKT ); //pszSrcWKT = (char *)GDALGetProjectionRef( hSrcDS ); CPLAssert( pszSrcWKT != NULL && strlen(pszSrcWKT) > 0 ); /* ------------------------------------------------------------------ */ /* -------------- Copy input data into the hSrcDS dataset ----------- */ for (i = 1; i <= nBands; i++) { hBand = GDALGetRasterBand( hSrcDS, i ); nXYSize = (i-1)*nx*ny; switch( typeCLASS ) { case GDT_Byte: tmpByte = (unsigned char *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outByte[c++] = tmpByte[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outByte, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_UInt16: tmpUI16 = (unsigned short int *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outUI16[c++] = tmpUI16[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_Int16: tmpI16 = (short int *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outI16[c++] = tmpI16[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_UInt32: tmpUI32 = (unsigned int *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outUI32[c++] = tmpUI32[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_Int32: tmpI32 = (int *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outI32[c++] = tmpI32[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_Float32: tmpF32 = (float *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outF32[c++] = tmpF32[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF32, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; case GDT_Float64: tmpF64 = (double *)in_data; for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++) outF64[c++] = tmpF64[m + n*ny + nXYSize]; GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF64, nx, ny, (GDALDataType)typeCLASS, 0, 0 ); break; } } /* ---------- Set up the Target coordinate system ------------------- */ /* If it was not provided assume it is Geog WGS84 */ CPLErrorReset(); if (pszDstSRS == NULL && pszDstWKT == NULL) oDstSRS.SetWellKnownGeogCS( "WGS84" ); else if (pszDstWKT != NULL) oDstSRS.importFromWkt( &pszDstWKT ); else { if( oDstSRS.SetFromUserInput( pszDstSRS ) != OGRERR_NONE ) mexErrMsgTxt("GDAL_WARP_MEX: Translating target SRS failed."); } if (pszDstWKT == NULL) oDstSRS.exportToWkt( &pszDstWKT ); /* ------------------------------------------------------------------ */ if ( nGCPCount != 0 ) { if (GDALSetGCPs(hSrcDS, nGCPCount, pasGCPs, "") != CE_None) mexPrintf("GDALWARP WARNING: writing GCPs failed.\n"); } /* Create a transformer that maps from source pixel/line coordinates to destination georeferenced coordinates (not destination pixel line) We do that by omitting the destination dataset handle (setting it to NULL). */ void *hTransformArg; hTransformArg = GDALCreateGenImgProjTransformer(hSrcDS, pszSrcWKT, NULL, pszDstWKT, nGCPCount == 0 ? FALSE : TRUE, 0, nOrder); if( hTransformArg == NULL ) mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed."); GDALTransformerInfo *psInfo = (GDALTransformerInfo*)hTransformArg; /* -------------------------------------------------------------------------- */ /* Get approximate output georeferenced bounds and resolution for file /* -------------------------------------------------------------------------- */ if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, adfDstGeoTransform, &nPixels, &nLines, adfExtent, 0) != CE_None ) { GDALClose(hSrcDS); mexErrMsgTxt("GDALWARP: GDALSuggestedWarpOutput2 failed."); } if (CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", NULL ) == NULL) { double MinX = adfExtent[0]; double MaxX = adfExtent[2]; double MaxY = adfExtent[3]; double MinY = adfExtent[1]; int bSuccess = TRUE; /* Check that the the edges of the target image are in the validity area */ /* of the target projection */ #define N_STEPS 20 for (i = 0; i <= N_STEPS && bSuccess; i++) { for (j = 0; j <= N_STEPS && bSuccess; j++) { double dfRatioI = i * 1.0 / N_STEPS; double dfRatioJ = j * 1.0 / N_STEPS; double expected_x = (1 - dfRatioI) * MinX + dfRatioI * MaxX; double expected_y = (1 - dfRatioJ) * MinY + dfRatioJ * MaxY; double x = expected_x; double y = expected_y; double z = 0; /* Target SRS coordinates to source image pixel coordinates */ if (!psInfo->pfnTransform(hTransformArg, TRUE, 1, &x, &y, &z, &bSuccess) || !bSuccess) bSuccess = FALSE; /* Source image pixel coordinates to target SRS coordinates */ if (!psInfo->pfnTransform(hTransformArg, FALSE, 1, &x, &y, &z, &bSuccess) || !bSuccess) bSuccess = FALSE; if (fabs(x - expected_x) > (MaxX - MinX) / nPixels || fabs(y - expected_y) > (MaxY - MinY) / nLines) bSuccess = FALSE; } } /* If not, retry with CHECK_WITH_INVERT_PROJ=TRUE that forces ogrct.cpp */ /* to check the consistency of each requested projection result with the */ /* invert projection */ if (!bSuccess) { CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" ); CPLDebug("WARP", "Recompute out extent with CHECK_WITH_INVERT_PROJ=TRUE"); if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, adfDstGeoTransform, &nPixels, &nLines, adfExtent, 0) != CE_None ) { GDALClose(hSrcDS); mexErrMsgTxt("GDALWARO: GDALSuggestedWarpOutput2 failed."); } } } /* -------------------------------------------------------------------- */ /* Expand the working bounds to include this region, ensure the */ /* working resolution is no more than this resolution. */ /* -------------------------------------------------------------------- */ if( dfMaxX == 0.0 && dfMinX == 0.0 ) { dfMinX = adfExtent[0]; dfMaxX = adfExtent[2]; dfMaxY = adfExtent[3]; dfMinY = adfExtent[1]; dfResX = adfDstGeoTransform[1]; dfResY = ABS(adfDstGeoTransform[5]); } else { dfMinX = MIN(dfMinX,adfExtent[0]); dfMaxX = MAX(dfMaxX,adfExtent[2]); dfMaxY = MAX(dfMaxY,adfExtent[3]); dfMinY = MIN(dfMinY,adfExtent[1]); dfResX = MIN(dfResX,adfDstGeoTransform[1]); dfResY = MIN(dfResY,ABS(adfDstGeoTransform[5])); } GDALDestroyGenImgProjTransformer( hTransformArg ); /* -------------------------------------------------------------------- */ /* Turn the suggested region into a geotransform and suggested */ /* number of pixels and lines. */ /* -------------------------------------------------------------------- */ adfDstGeoTransform[0] = dfMinX; adfDstGeoTransform[1] = dfResX; adfDstGeoTransform[2] = 0.0; adfDstGeoTransform[3] = dfMaxY; adfDstGeoTransform[4] = 0.0; adfDstGeoTransform[5] = -1 * dfResY; nPixels = (int) ((dfMaxX - dfMinX) / dfResX + 0.5); nLines = (int) ((dfMaxY - dfMinY) / dfResY + 0.5); /* -------------------------------------------------------------------- */ /* Did the user override some parameters? */ /* -------------------------------------------------------------------- */ if( dfXRes != 0.0 && dfYRes != 0.0 ) { dfMinX = adfDstGeoTransform[0]; dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels; dfMaxY = adfDstGeoTransform[3]; dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines; nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes); nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes); adfDstGeoTransform[0] = dfMinX; adfDstGeoTransform[3] = dfMaxY; adfDstGeoTransform[1] = dfXRes; adfDstGeoTransform[5] = -dfYRes; } else if( nForceWidth != 0 && nForceHeight != 0 ) { dfXRes = (dfMaxX - dfMinX) / nForceWidth; dfYRes = (dfMaxY - dfMinY) / nForceHeight; adfDstGeoTransform[0] = dfMinX; adfDstGeoTransform[3] = dfMaxY; adfDstGeoTransform[1] = dfXRes; adfDstGeoTransform[5] = -dfYRes; nPixels = nForceWidth; nLines = nForceHeight; } else if( nForceWidth != 0) { dfXRes = (dfMaxX - dfMinX) / nForceWidth; dfYRes = dfXRes; adfDstGeoTransform[0] = dfMinX; adfDstGeoTransform[3] = dfMaxY; adfDstGeoTransform[1] = dfXRes; adfDstGeoTransform[5] = -dfYRes; nPixels = nForceWidth; nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes); } else if( nForceHeight != 0) { dfYRes = (dfMaxY - dfMinY) / nForceHeight; dfXRes = dfYRes; adfDstGeoTransform[0] = dfMinX; adfDstGeoTransform[3] = dfMaxY; adfDstGeoTransform[1] = dfXRes; adfDstGeoTransform[5] = -dfYRes; nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes); nLines = nForceHeight; } /* --------------------- Create the output --------------------------- */ hDstDS = GDALCreate( hDriver, "mem", nPixels, nLines, GDALGetRasterCount(hSrcDS), (GDALDataType)typeCLASS, NULL ); CPLAssert( hDstDS != NULL ); /* -------------- Write out the projection definition ---------------- */ GDALSetProjection( hDstDS, pszDstWKT ); GDALSetGeoTransform( hDstDS, adfDstGeoTransform ); /* --------------------- Setup warp options -------------------------- */ GDALWarpOptions *psWO = GDALCreateWarpOptions(); psWO->hSrcDS = hSrcDS; psWO->hDstDS = hDstDS; psWO->nBandCount = nBands; psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) ); psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) ); for( i = 0; i < nBands; i++ ) { psWO->panSrcBands[i] = i+1; psWO->panDstBands[i] = i+1; } if( dfWarpMemoryLimit != 0.0 ) psWO->dfWarpMemoryLimit = dfWarpMemoryLimit; /* --------------------- Setup the Resampling Algo ------------------- */ psWO->eResampleAlg = interpMethod; /* --------------------- Setup NODATA options ------------------------ */ papszWarpOptions = CSLSetNameValue(papszWarpOptions, "INIT_DEST", "NO_DATA" ); if ( pdfDstNodata == NULL && (typeCLASS == GDT_Float32 || typeCLASS == GDT_Float64) ) { pdfDstNodata = (double *) mxCalloc((size_t)1, sizeof(double)); *pdfDstNodata = mxGetNaN(); } else if (pdfDstNodata != NULL) { #define CLAMP(val,type,minval,maxval) \ do { if (val < minval) { val = minval; } \ else if (val > maxval) { val = maxval; } \ else if (val != (type)val) { val = (type)(val + 0.5); } } \ while(0) switch( typeCLASS ) { case GDT_Byte: CLAMP(pdfDstNodata[0], GByte, 0.0, 255.0); break; case GDT_UInt16: CLAMP(pdfDstNodata[0], GInt16, -32768.0, 32767.0); break; case GDT_Int16: CLAMP(pdfDstNodata[0], GUInt16, 0.0, 65535.0); break; case GDT_UInt32: CLAMP(pdfDstNodata[0], GInt32, -2147483648.0, 2147483647.0); break; case GDT_Int32: CLAMP(pdfDstNodata[0], GUInt32, 0.0, 4294967295.0); break; default: break; } } psWO->papszWarpOptions = CSLDuplicate(papszWarpOptions); if (pdfDstNodata != NULL) { psWO->padfDstNoDataReal = (double *) CPLMalloc(psWO->nBandCount*sizeof(double)); psWO->padfDstNoDataImag = (double *) CPLMalloc(psWO->nBandCount*sizeof(double)); for (i = 0; i < nBands; i++) { psWO->padfDstNoDataReal[i] = pdfDstNodata[0]; psWO->padfDstNoDataImag[i] = 0.0; GDALSetRasterNoDataValue( GDALGetRasterBand(hDstDS, i+1), pdfDstNodata[0]); } } /* ------------ Establish reprojection transformer ------------------- */ psWO->pTransformerArg = GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef(hSrcDS), hDstDS, GDALGetProjectionRef(hDstDS), nGCPCount == 0 ? FALSE : TRUE, 0.0, nOrder ); psWO->pfnTransformer = GDALGenImgProjTransform; /* ----------- Initialize and execute the warp operation ------------- */ GDALWarpOperation oOperation; oOperation.Initialize( psWO ); eErr = oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ), GDALGetRasterYSize( hDstDS ) ); CPLAssert( eErr == CE_None ); GDALDestroyGenImgProjTransformer( psWO->pTransformerArg ); GDALDestroyWarpOptions( psWO ); GDALClose( hSrcDS ); /* ------------ Free memory used to fill the hSrcDS dataset ---------- */ switch( typeCLASS ) { case GDT_Byte: mxFree((void *)outByte); break; case GDT_UInt16: mxFree((void *)outUI16); break; case GDT_Int16: mxFree((void *)outI16); break; case GDT_UInt32: mxFree((void *)outUI32); break; case GDT_Int32: mxFree((void *)outI32); break; case GDT_Float32: mxFree((void *)outF32); break; case GDT_Float64: mxFree((void *)outF64); break; } int out_dims[3]; out_dims[0] = nLines; out_dims[1] = nPixels; out_dims[2] = nBands; plhs[0] = mxCreateNumericArray (n_dims,out_dims,mxGetClassID(prhs[0]), mxREAL); tmp = (char *)mxCalloc(nPixels * nLines, nBytes); /* ------ Allocate memory to be used in filling the hDstDS dataset ---- */ switch( typeCLASS ) { case GDT_Byte: outByte = (unsigned char *)mxGetData(plhs[0]); break; case GDT_UInt16: outUI16 = (unsigned short int *)mxGetData(plhs[0]); break; case GDT_Int16: outI16 = (short int *)mxGetData(plhs[0]); break; case GDT_UInt32: outUI32 = (unsigned int *)mxGetData(plhs[0]); break; case GDT_Int32: outI32 = (int *)mxGetData(plhs[0]); break; case GDT_Float32: outF32 = (float *)mxGetData(plhs[0]); break; case GDT_Float64: outF64 = (double *)mxGetData(plhs[0]); break; } /* ----------- Copy the output hSrcDS dataset data into plhs ---------- */ for (i = 1; i <= nBands; i++) { hBand = GDALGetRasterBand( hDstDS, i ); GDALRasterIO( hBand, GF_Read, 0, 0, nPixels, nLines, tmp, nPixels, nLines, (GDALDataType)typeCLASS, 0, 0 ); nXYSize = (i-1) * nPixels * nLines; switch( typeCLASS ) { case GDT_Byte: for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outByte[m + n*nLines + nXYSize] = tmp[c++]; break; case GDT_UInt16: tmpUI16 = (GUInt16 *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outUI16[m + n*nLines + nXYSize] = tmpUI16[c++]; break; case GDT_Int16: tmpI16 = (GInt16 *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outI16[m + n*nLines + nXYSize] = tmpI16[c++]; break; case GDT_UInt32: tmpUI32 = (GUInt32 *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outUI32[m + n*nLines + nXYSize] = tmpUI32[c++]; break; case GDT_Int32: tmpI32 = (GInt32 *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outI32[m + n*nLines + nXYSize] = tmpI32[c++]; break; case GDT_Float32: tmpF32 = (float *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outF32[m + n*nLines + nXYSize] = tmpF32[c++]; break; case GDT_Float64: tmpF64 = (double *) tmp; for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++) outF64[m + n*nLines + nXYSize] = tmpF64[c++]; break; } } mxFree(tmp); if (nGCPCount) { GDALDeinitGCPs( nGCPCount, pasGCPs ); /* makes this mex crash in the next call - Is it still true??? */ mxFree((void *) pasGCPs ); } if (nlhs == 2) plhs[1] = populate_metadata_struct (hDstDS, 1); runed_once = TRUE; /* Signals that next call won't need to call GDALAllRegister() again */ /*GDALDestroyDriverManager(); OGRFree(pszDstWKT);*/ GDALClose( hDstDS ); CSLDestroy( papszWarpOptions ); if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT); if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT); }