CPLErr GDALRasterizeGeometries( GDALDatasetH hDS, int nBandCount, int *panBandList, int nGeomCount, OGRGeometryH *pahGeometries, GDALTransformerFunc pfnTransformer, void *pTransformArg, double *padfGeomBurnValue, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg ) { GDALDataType eType; int nYChunkSize, nScanlineBytes; unsigned char *pabyChunkBuf; int iY; GDALDataset *poDS = (GDALDataset *) hDS; if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Do some rudimentary arg checking. */ /* -------------------------------------------------------------------- */ if( nBandCount == 0 || nGeomCount == 0 ) return CE_None; // prototype band. GDALRasterBand *poBand = poDS->GetRasterBand( panBandList[0] ); if (poBand == NULL) return CE_Failure; int bAllTouched = CSLFetchBoolean( papszOptions, "ALL_TOUCHED", FALSE ); const char *pszOpt = CSLFetchNameValue( papszOptions, "BURN_VALUE_FROM" ); GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue; if( pszOpt ) { if( EQUAL(pszOpt,"Z")) eBurnValueSource = GBV_Z; /*else if( EQUAL(pszOpt,"M")) eBurnValueSource = GBV_M;*/ } /* -------------------------------------------------------------------- */ /* If we have no transformer, assume the geometries are in file */ /* georeferenced coordinates, and create a transformer to */ /* convert that to pixel/line coordinates. */ /* */ /* We really just need to apply an affine transform, but for */ /* simplicity we use the more general GenImgProjTransformer. */ /* -------------------------------------------------------------------- */ int bNeedToFreeTransformer = FALSE; if( pfnTransformer == NULL ) { bNeedToFreeTransformer = TRUE; pTransformArg = GDALCreateGenImgProjTransformer( NULL, NULL, hDS, NULL, FALSE, 0.0, 0); pfnTransformer = GDALGenImgProjTransform; } /* -------------------------------------------------------------------- */ /* Establish a chunksize to operate on. The larger the chunk */ /* size the less times we need to make a pass through all the */ /* shapes. */ /* -------------------------------------------------------------------- */ if( poBand->GetRasterDataType() == GDT_Byte ) eType = GDT_Byte; else eType = GDT_Float64; nScanlineBytes = nBandCount * poDS->GetRasterXSize() * (GDALGetDataTypeSize(eType)/8); nYChunkSize = 10000000 / nScanlineBytes; if( nYChunkSize > poDS->GetRasterYSize() ) nYChunkSize = poDS->GetRasterYSize(); pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes); if( pabyChunkBuf == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate rasterization buffer." ); return CE_Failure; } /* ==================================================================== */ /* Loop over image in designated chunks. */ /* ==================================================================== */ CPLErr eErr = CE_None; pfnProgress( 0.0, NULL, pProgressArg ); for( iY = 0; iY < poDS->GetRasterYSize() && eErr == CE_None; iY += nYChunkSize ) { int nThisYChunkSize; int iShape; nThisYChunkSize = nYChunkSize; if( nThisYChunkSize + iY > poDS->GetRasterYSize() ) nThisYChunkSize = poDS->GetRasterYSize() - iY; eErr = poDS->RasterIO(GF_Read, 0, iY, poDS->GetRasterXSize(), nThisYChunkSize, pabyChunkBuf,poDS->GetRasterXSize(),nThisYChunkSize, eType, nBandCount, panBandList, 0, 0, 0 ); if( eErr != CE_None ) break; for( iShape = 0; iShape < nGeomCount; iShape++ ) { gv_rasterize_one_shape( pabyChunkBuf, iY, poDS->GetRasterXSize(), nThisYChunkSize, nBandCount, eType, bAllTouched, (OGRGeometry *) pahGeometries[iShape], padfGeomBurnValue + iShape*nBandCount, eBurnValueSource, pfnTransformer, pTransformArg ); } eErr = poDS->RasterIO( GF_Write, 0, iY, poDS->GetRasterXSize(), nThisYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nThisYChunkSize, eType, nBandCount, panBandList, 0, 0, 0 ); if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()), "", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ VSIFree( pabyChunkBuf ); if( bNeedToFreeTransformer ) GDALDestroyTransformer( pTransformArg ); return eErr; }
OGRErr PDFWritableVectorDataset::SyncToDisk() { if (nLayers == 0 || !bModified) return OGRERR_NONE; bModified = FALSE; OGREnvelope sGlobalExtent; int bHasExtent = FALSE; for(int i=0;i<nLayers;i++) { OGREnvelope sExtent; if (papoLayers[i]->GetExtent(&sExtent) == OGRERR_NONE) { bHasExtent = TRUE; sGlobalExtent.Merge(sExtent); } } if (!bHasExtent || sGlobalExtent.MinX == sGlobalExtent.MaxX || sGlobalExtent.MinY == sGlobalExtent.MaxY) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot compute spatial extent of features"); return OGRERR_FAILURE; } PDFCompressMethod eStreamCompressMethod = COMPRESS_DEFLATE; const char* pszStreamCompressMethod = CSLFetchNameValue(papszOptions, "STREAM_COMPRESS"); if (pszStreamCompressMethod) { if( EQUAL(pszStreamCompressMethod, "NONE") ) eStreamCompressMethod = COMPRESS_NONE; else if( EQUAL(pszStreamCompressMethod, "DEFLATE") ) eStreamCompressMethod = COMPRESS_DEFLATE; else { CPLError( CE_Warning, CPLE_NotSupported, "Unsupported value for STREAM_COMPRESS."); } } const char* pszGEO_ENCODING = CSLFetchNameValueDef(papszOptions, "GEO_ENCODING", "ISO32000"); const char* pszDPI = CSLFetchNameValue(papszOptions, "DPI"); double dfDPI = DEFAULT_DPI; if( pszDPI != nullptr ) { dfDPI = CPLAtof(pszDPI); if (dfDPI < DEFAULT_DPI) dfDPI = DEFAULT_DPI; } else { dfDPI = DEFAULT_DPI; } const char* pszWriteUserUnit = CSLFetchNameValue(papszOptions, "WRITE_USERUNIT"); bool bWriteUserUnit; if( pszWriteUserUnit != nullptr ) bWriteUserUnit = CPLTestBool( pszWriteUserUnit ); else bWriteUserUnit = ( pszDPI == nullptr ); const char* pszNEATLINE = CSLFetchNameValue(papszOptions, "NEATLINE"); int nMargin = atoi(CSLFetchNameValueDef(papszOptions, "MARGIN", "0")); PDFMargins sMargins; sMargins.nLeft = nMargin; sMargins.nRight = nMargin; sMargins.nTop = nMargin; sMargins.nBottom = nMargin; const char* pszLeftMargin = CSLFetchNameValue(papszOptions, "LEFT_MARGIN"); if (pszLeftMargin) sMargins.nLeft = atoi(pszLeftMargin); const char* pszRightMargin = CSLFetchNameValue(papszOptions, "RIGHT_MARGIN"); if (pszRightMargin) sMargins.nRight = atoi(pszRightMargin); const char* pszTopMargin = CSLFetchNameValue(papszOptions, "TOP_MARGIN"); if (pszTopMargin) sMargins.nTop = atoi(pszTopMargin); const char* pszBottomMargin = CSLFetchNameValue(papszOptions, "BOTTOM_MARGIN"); if (pszBottomMargin) sMargins.nBottom = atoi(pszBottomMargin); const char* pszExtraImages = CSLFetchNameValue(papszOptions, "EXTRA_IMAGES"); const char* pszExtraStream = CSLFetchNameValue(papszOptions, "EXTRA_STREAM"); const char* pszExtraLayerName = CSLFetchNameValue(papszOptions, "EXTRA_LAYER_NAME"); const char* pszOGRDisplayField = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_FIELD"); const char* pszOGRDisplayLayerNames = CSLFetchNameValue(papszOptions, "OGR_DISPLAY_LAYER_NAMES"); const bool bWriteOGRAttributes = CPLFetchBool(papszOptions, "OGR_WRITE_ATTRIBUTES", true); const char* pszOGRLinkField = CSLFetchNameValue(papszOptions, "OGR_LINK_FIELD"); const char* pszOffLayers = CSLFetchNameValue(papszOptions, "OFF_LAYERS"); const char* pszExclusiveLayers = CSLFetchNameValue(papszOptions, "EXCLUSIVE_LAYERS"); const char* pszJavascript = CSLFetchNameValue(papszOptions, "JAVASCRIPT"); const char* pszJavascriptFile = CSLFetchNameValue(papszOptions, "JAVASCRIPT_FILE"); /* -------------------------------------------------------------------- */ /* Create file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(GetDescription(), "wb"); if( fp == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create PDF file %s.\n", GetDescription() ); return OGRERR_FAILURE; } GDALPDFWriter oWriter(fp); double dfRatio = (sGlobalExtent.MaxY - sGlobalExtent.MinY) / (sGlobalExtent.MaxX - sGlobalExtent.MinX); int nWidth, nHeight; if (dfRatio < 1) { nWidth = 1024; nHeight = static_cast<int>(nWidth * dfRatio); } else { nHeight = 1024; nWidth = static_cast<int>(nHeight / dfRatio); } GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, nullptr ); double adfGeoTransform[6]; adfGeoTransform[0] = sGlobalExtent.MinX; adfGeoTransform[1] = (sGlobalExtent.MaxX - sGlobalExtent.MinX) / nWidth; adfGeoTransform[2] = 0; adfGeoTransform[3] = sGlobalExtent.MaxY; adfGeoTransform[4] = 0; adfGeoTransform[5] = - (sGlobalExtent.MaxY - sGlobalExtent.MinY) / nHeight; poSrcDS->SetGeoTransform(adfGeoTransform); OGRSpatialReference* poSRS = papoLayers[0]->GetSpatialRef(); if (poSRS) { char* pszWKT = nullptr; poSRS->exportToWkt(&pszWKT); poSrcDS->SetProjection(pszWKT); CPLFree(pszWKT); } oWriter.SetInfo(poSrcDS, papszOptions); oWriter.StartPage(poSrcDS, dfDPI, bWriteUserUnit, pszGEO_ENCODING, pszNEATLINE, &sMargins, eStreamCompressMethod, bWriteOGRAttributes); int iObj = 0; char** papszLayerNames = CSLTokenizeString2(pszOGRDisplayLayerNames,",",0); for(int i=0;i<nLayers;i++) { CPLString osLayerName; if (CSLCount(papszLayerNames) < nLayers) osLayerName = papoLayers[i]->GetName(); else osLayerName = papszLayerNames[i]; oWriter.WriteOGRLayer((OGRDataSourceH)this, i, pszOGRDisplayField, pszOGRLinkField, osLayerName, bWriteOGRAttributes, iObj); } CSLDestroy(papszLayerNames); oWriter.EndPage(pszExtraImages, pszExtraStream, pszExtraLayerName, pszOffLayers, pszExclusiveLayers); if (pszJavascript) oWriter.WriteJavascript(pszJavascript); else if (pszJavascriptFile) oWriter.WriteJavascriptFile(pszJavascriptFile); oWriter.Close(); delete poSrcDS; return OGRERR_NONE; }
bool CreateSubRaster( wxGISRasterDatasetSPtr pSrcRasterDataSet, OGREnvelope &Env, const OGRGeometry *pGeom, GDALDriver* pDriver, CPLString &szDstPath, GDALDataType eOutputType, int nBandCount, int *panBandList, double dfOutResX, double dfOutResY, bool bCopyNodata, bool bSkipSourceMetadata, char** papszOptions, ITrackCancel* pTrackCancel ) { GDALDataset* pDset = pSrcRasterDataSet->GetRaster(); if(!pDset) { if(pTrackCancel) pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr); return false; } double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; CPLErr err = pDset->GetGeoTransform(adfGeoTransform); if(err == CE_Fatal) { if(pTrackCancel) pTrackCancel->PutMessage(_("Get raster failed"), -1, enumGISMessageErr); return false; } if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 ) { if(pTrackCancel) pTrackCancel->PutMessage(_("The geotransform is rotated. This configuration is not supported."), -1, enumGISMessageErr); return false; } int anSrcWin[4] = {0, 0, 0, 0}; anSrcWin[0] = floor ((Env.MinX - adfGeoTransform[0]) / adfGeoTransform[1] + 0.001); anSrcWin[1] = floor ((Env.MaxY - adfGeoTransform[3]) / adfGeoTransform[5] + 0.001); anSrcWin[2] = ceil ((Env.MaxX - Env.MinX) / adfGeoTransform[1]); anSrcWin[3] = ceil ((Env.MinY - Env.MaxY) / adfGeoTransform[5]); if(pTrackCancel) pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window %d %d %d %d from geographic window."), anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3] ), -1, enumGISMessageInfo); if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[0] + anSrcWin[2] > pSrcRasterDataSet->GetWidth() || anSrcWin[1] + anSrcWin[3] > pSrcRasterDataSet->GetHeight() ) { if(pTrackCancel) pTrackCancel->PutMessage(wxString::Format(_("Computed source pixel window falls outside raster size of %dx%d."), pSrcRasterDataSet->GetWidth(), pSrcRasterDataSet->GetHeight()), -1, enumGISMessageErr); return false; } int nOXSize = 0, nOYSize = 0; if(IsDoubleEquil(dfOutResX, -1) && IsDoubleEquil(dfOutResY, -1)) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = ceil ((Env.MaxX - Env.MinX) / dfOutResX); nOYSize = ceil ((Env.MinY - Env.MaxY) / (adfGeoTransform[5] < 0 ? dfOutResY * -1 : dfOutResY)); } /* ==================================================================== */ /* Create a virtual dataset. */ /* ==================================================================== */ VRTDataset *poVDS; /* -------------------------------------------------------------------- */ /* Make a virtual clone. */ /* -------------------------------------------------------------------- */ poVDS = (VRTDataset *) VRTCreate( nOXSize, nOYSize ); if( pSrcRasterDataSet->GetSpatialReference() != NULL ) { poVDS->SetProjection( pDset->GetProjectionRef() ); } 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 ); int nGCPs = pDset->GetGCPCount(); if( nGCPs > 0 ) { GDAL_GCP *pasGCPs = GDALDuplicateGCPs( nGCPs, pDset->GetGCPs() ); for(size_t 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, pDset->GetGCPProjection() ); GDALDeinitGCPs( nGCPs, pasGCPs ); CPLFree( pasGCPs ); } /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ if(!bSkipSourceMetadata) poVDS->SetMetadata( pDset->GetMetadata() ); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ for(size_t i = 0; i < nBandCount; ++i ) { VRTSourcedRasterBand *poVRTBand; GDALRasterBand *poSrcBand; GDALDataType eBandType; int nComponent = 0; poSrcBand = pDset->GetRasterBand(panBandList[i]); /* -------------------------------------------------------------------- */ /* 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 ); /* -------------------------------------------------------------------- */ /* Create a simple 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 CPLString pszResampling = CSLFetchNameValueDef(papszOptions, "DEST_RESAMPLING", "near"); poVRTBand->AddSimpleSource( poSrcBand, anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], 0, 0, nOXSize, nOYSize, pszResampling ); /* -------------------------------------------------------------------- */ /* copy some other information of interest. */ /* -------------------------------------------------------------------- */ CopyBandInfo( poSrcBand, poVRTBand, bCopyNodata ); /* -------------------------------------------------------------------- */ /* 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 ); // } //} /* -------------------------------------------------------------------- */ /* Write to the output file using CopyCreate(). */ /* -------------------------------------------------------------------- */ GDALDataset* pOutDS = pDriver->CreateCopy(szDstPath, poVDS, false, papszOptions, GDALDummyProgress, NULL); //hOutDS = GDALCreateCopy( hDriver, pszDest, (GDALDatasetH) poVDS, bStrict, papszCreateOptions, pfnProgress, NULL ); if( pOutDS ) { CPLErrorReset(); GDALFlushCache( pOutDS ); if (CPLGetLastErrorType() != CE_None) { if(pTrackCancel) pTrackCancel->PutMessage(_("GDALFlushCache failed!"), -1, enumGISMessageErr); } GDALClose( pOutDS ); GDALClose( poVDS ); return true; } else { GDALClose( poVDS ); return false; } //CPLFree( panBandList ); // //CPLFree( pszOutputSRS ); //if( !bSubCall ) //{ // GDALDumpOpenDatasets( stderr ); // GDALDestroyDriverManager(); //} //CSLDestroy( papszCreateOptions ); return true; }
/** * Checks the downloaded data to see if it is all valid. */ void ncepNamSurfInitialization::checkForValidData() { //just make up a "dummy" timezone for use here boost::local_time::time_zone_ptr zone(new boost::local_time::posix_time_zone("MST-07")); //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(zone) ); boost::posix_time::ptime pt_low(boost::gregorian::date(1900,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::posix_time::ptime pt_high(boost::gregorian::date(2100,boost::gregorian::Jan,1), boost::posix_time::hours(12)); boost::local_time::local_date_time low_time(pt_low, zone); boost::local_time::local_date_time high_time(pt_high, zone); //check times for(unsigned int i = 0; i < timeList.size(); i++) { if(timeList[i].is_special()) //if time is any special value (not_a_date_time, infinity, etc.) throw badForecastFile("Bad time in forecast file."); if(timeList[i] < low_time || timeList[i] > high_time) throw badForecastFile("Bad time in forecast file."); } // open ds variable by variable GDALDataset *srcDS; std::string temp; std::string srcWkt; int nBands = 0; bool noDataValueExists; bool noDataIsNan; std::vector<std::string> varList = getVariableList(); //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + wxModelFileName + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpen( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) throw badForecastFile("Cannot open forecast file."); srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) throw badForecastFile("Forecast file doesn't have projection information."); //Get total bands (time steps) nBands = srcDS->GetRasterCount(); int nXSize, nYSize; GDALRasterBand *poBand; int pbSuccess; double dfNoData; double *padfScanline; nXSize = srcDS->GetRasterXSize(); nYSize = srcDS->GetRasterYSize(); //loop over all bands for this variable (bands are time steps) for(int j = 1; j <= nBands; j++) { poBand = srcDS->GetRasterBand( j ); pbSuccess = 0; dfNoData = poBand->GetNoDataValue( &pbSuccess ); if( pbSuccess == false ) noDataValueExists = false; else { noDataValueExists = true; noDataIsNan = CPLIsNan(dfNoData); } //set the data padfScanline = new double[nXSize*nYSize]; poBand->RasterIO(GF_Read, 0, 0, nXSize, nYSize, padfScanline, nXSize, nYSize, GDT_Float64, 0, 0); for(int k = 0;k < nXSize*nYSize; k++) { //Check if value is no data (if no data value was defined in file) if(noDataValueExists) { if(noDataIsNan) { if(CPLIsNan(padfScanline[k])) throw badForecastFile("Forecast file contains no_data values."); }else { if(padfScanline[k] == dfNoData) throw badForecastFile("Forecast file contains no_data values."); } } if( varList[i] == "Temperature_height_above_ground" ) //units are Kelvin { if(padfScanline[k] < 180.0 || padfScanline[k] > 340.0) //these are near the most extreme temperatures ever recored on earth throw badForecastFile("Temperature is out of range in forecast file."); } else if( varList[i] == "v-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("V-velocity is out of range in forecast file."); } else if( varList[i] == "u-component_of_wind_height_above_ground" ) //units are m/s { if(std::abs(padfScanline[k]) > 220.0) throw badForecastFile("U-velocity is out of range in forecast file."); } else if( varList[i] == "Total_cloud_cover_entire_atmosphere" ) //units are percent { if(padfScanline[k] < 0.0 || padfScanline[k] > 100.0) throw badForecastFile("Total cloud cover is out of range in forecast file."); } } delete [] padfScanline; } GDALClose((GDALDatasetH) srcDS ); } }
/** * Sets the surface grids based on a ncepNam (surface only!) forecast. * @param input The WindNinjaInputs for misc. info. * @param airGrid The air temperature grid to be filled. * @param cloudGrid The cloud cover grid to be filled. * @param uGrid The u velocity grid to be filled. * @param vGrid The v velocity grid to be filled. * @param wGrid The w velocity grid to be filled (filled with zeros here?). */ void ncepNamSurfInitialization::setSurfaceGrids( WindNinjaInputs &input, AsciiGrid<double> &airGrid, AsciiGrid<double> &cloudGrid, AsciiGrid<double> &uGrid, AsciiGrid<double> &vGrid, AsciiGrid<double> &wGrid ) { int bandNum = -1; //get time list std::vector<boost::local_time::local_date_time> timeList( getTimeList(input.ninjaTimeZone) ); //Search time list for our time to identify our band number for cloud/speed/dir for(unsigned int i = 0; i < timeList.size(); i++) { if(input.ninjaTime == timeList[i]) { bandNum = i + 1; break; } } if(bandNum < 0) throw std::runtime_error("Could not match ninjaTime with a band number in the forecast file."); //get some info from the nam file in input //Acquire a lock to protect the non-thread safe netCDF library #ifdef _OPENMP omp_guard netCDF_guard(netCDF_lock); #endif GDALDataset* poDS; //attempt to grab the projection from the dem? //check for member prjString first std::string dstWkt; dstWkt = input.dem.prjString; if ( dstWkt.empty() ) { //try to open original poDS = (GDALDataset*)GDALOpen( input.dem.fileName.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw(); } dstWkt = poDS->GetProjectionRef(); if( dstWkt.empty() ) { CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()", "Bad projection reference" ); //throw() } GDALClose((GDALDatasetH) poDS ); } poDS = (GDALDataset*)GDALOpen( input.forecastFilename.c_str(), GA_ReadOnly ); if( poDS == NULL ) { CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()", "Bad forecast file" ); } else GDALClose((GDALDatasetH) poDS ); // open ds one by one and warp, then write to grid GDALDataset *srcDS, *wrpDS; std::string temp; std::string srcWkt; std::vector<std::string> varList = getVariableList(); /* * Set the initial values in the warped dataset to no data */ GDALWarpOptions* psWarpOptions; for( unsigned int i = 0;i < varList.size();i++ ) { temp = "NETCDF:" + input.forecastFilename + ":" + varList[i]; srcDS = (GDALDataset*)GDALOpenShared( temp.c_str(), GA_ReadOnly ); if( srcDS == NULL ) { CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()", "Bad forecast file" ); } srcWkt = srcDS->GetProjectionRef(); if( srcWkt.empty() ) { CPLDebug( "ncepNamSurfInitialization::setSurfaceGrids()", "Bad forecast file" ); //throw } /* * Grab the first band to get the nodata value for the variable, * assume all bands have the same ndv */ GDALRasterBand *poBand = srcDS->GetRasterBand( 1 ); int pbSuccess; double dfNoData = poBand->GetNoDataValue( &pbSuccess ); psWarpOptions = GDALCreateWarpOptions(); int nBandCount = srcDS->GetRasterCount(); psWarpOptions->nBandCount = nBandCount; psWarpOptions->panSrcBands = (int*) CPLMalloc( sizeof( int ) * nBandCount ); psWarpOptions->panDstBands = (int*) CPLMalloc( sizeof( int ) * nBandCount ); psWarpOptions->padfDstNoDataReal = (double*) CPLMalloc( sizeof( double ) * nBandCount ); psWarpOptions->padfDstNoDataImag = (double*) CPLMalloc( sizeof( double ) * nBandCount ); for( int b = 0;b < srcDS->GetRasterCount();b++ ) { psWarpOptions->padfDstNoDataReal[b] = dfNoData; psWarpOptions->padfDstNoDataImag[b] = dfNoData; } if( pbSuccess == FALSE ) dfNoData = -9999.0; psWarpOptions->papszWarpOptions = CSLSetNameValue( psWarpOptions->papszWarpOptions, "INIT_DEST", "NO_DATA" ); wrpDS = (GDALDataset*) GDALAutoCreateWarpedVRT( srcDS, srcWkt.c_str(), dstWkt.c_str(), GRA_NearestNeighbour, 1.0, psWarpOptions ); if(wrpDS == NULL) { throw badForecastFile("Could not warp the forecast file, " "possibly non-uniform grid."); } if( varList[i] == "Temperature_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, airGrid ); if( CPLIsNan( dfNoData ) ) { airGrid.set_noDataValue(-9999.0); airGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "v-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, vGrid ); if( CPLIsNan( dfNoData ) ) { vGrid.set_noDataValue(-9999.0); vGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "u-component_of_wind_height_above_ground" ) { GDAL2AsciiGrid( wrpDS, bandNum, uGrid ); if( CPLIsNan( dfNoData ) ) { uGrid.set_noDataValue(-9999.0); uGrid.replaceNan( -9999.0 ); } } else if( varList[i] == "Total_cloud_cover_entire_atmosphere" ) { GDAL2AsciiGrid( wrpDS, bandNum, cloudGrid ); if( CPLIsNan( dfNoData ) ) { cloudGrid.set_noDataValue(-9999.0); cloudGrid.replaceNan( -9999.0 ); } } GDALDestroyWarpOptions( psWarpOptions ); GDALClose((GDALDatasetH) srcDS ); GDALClose((GDALDatasetH) wrpDS ); } cloudGrid /= 100.0; wGrid.set_headerData( uGrid ); wGrid = 0.0; }
int GDALOverviewDataset::GetGCPCount() { return poMainDS->GetGCPCount(); }
const char *GDALOverviewDataset::GetGCPProjection() { return poMainDS->GetGCPProjection(); }
const QString OmgGdal::Gdal2Ascii(const QString theFileName) { std::cout << "Running gdal to ascii conversion..." << std::endl; QFileInfo myFileInfo(theFileName); QString myExt("asc"); QString myOutFileName(QDir::convertSeparators(myFileInfo.dirPath(true)+"/"+myFileInfo.baseName() + "." + myExt)); QFile myFile( myOutFileName ); if ( !myFile.open( IO_WriteOnly ) ) { printf("Opening output file for write failed"); return QString(""); } QTextStream myStream( &myFile ); GDALAllRegister(); GDALDataset *gdalDataset = (GDALDataset *) GDALOpen( theFileName.local8Bit(), GA_ReadOnly ); if ( gdalDataset == NULL ) { std::cout << "Error couldn't open file: " << theFileName << std::endl; return QString(""); } //Write the ascii headers myStream << getAsciiHeader(theFileName); //assume to be working with first band in dataset only GDALRasterBand *myGdalBand = gdalDataset->GetRasterBand( 1 ); //find out the name of the band if any QString myColorInterpretation = GDALGetColorInterpretationName(myGdalBand->GetColorInterpretation()); // get the dimensions of the raster int myColsInt = myGdalBand->GetXSize(); int myRowsInt = myGdalBand->GetYSize(); double myNullValue=myGdalBand->GetNoDataValue(); //allocate a buffer to hold one row of ints int myAllocationSizeInt = sizeof(uint)*myColsInt; uint * myScanlineAllocInt = (uint*) CPLMalloc(myAllocationSizeInt); for (int myCurrentRowInt=0; myCurrentRowInt < myRowsInt;myCurrentRowInt++) { //get a scanline CPLErr myResult = myGdalBand->RasterIO( GF_Read, 0, myCurrentRowInt, myColsInt, 1, myScanlineAllocInt, myColsInt, 1, GDT_UInt32, 0, 0 ); for (int myCurrentColInt=0; myCurrentColInt < myColsInt; myCurrentColInt++) { //get the nth element from the current row double myDouble=myScanlineAllocInt[myCurrentColInt]; myStream << myDouble << " "; //pixel value } //end of column wise loop myStream << "\r\n"; //dos style new line } //end of row wise loop CPLFree(myScanlineAllocInt); myFile.close(); std::cout << "The output ascii file is: " << myOutFileName << std::endl; return myOutFileName; }
int FindSRS( const char *pszInput, OGRSpatialReference &oSRS ) { int bGotSRS = FALSE; VSILFILE *fp = NULL; GDALDataset *poGDALDS = NULL; OGRDataSource *poOGRDS = NULL; OGRLayer *poLayer = NULL; char *pszProjection = NULL; CPLErrorHandler oErrorHandler = NULL; int bIsFile = FALSE; OGRErr eErr = CE_None; int bDebug = FALSE; /* temporarily supress error messages we may get from xOpen() */ bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF")); if ( ! bDebug ) oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler ); /* Test if argument is a file */ fp = VSIFOpenL( pszInput, "r" ); if ( fp ) { bIsFile = TRUE; VSIFCloseL( fp ); CPLDebug( "gdalsrsinfo", "argument is a file" ); } /* try to open with GDAL */ CPLDebug( "gdalsrsinfo", "trying to open with GDAL" ); poGDALDS = (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly ); if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) { pszProjection = (char *) poGDALDS->GetProjectionRef( ); if( oSRS.importFromWkt( &pszProjection ) == CE_None ) { CPLDebug( "gdalsrsinfo", "got SRS from GDAL" ); bGotSRS = TRUE; } GDALClose( (GDALDatasetH) poGDALDS ); if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with GDAL" ); } #ifdef OGR_ENABLED /* if unsuccessful, try to open with OGR */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to open with OGR" ); poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL ); if( poOGRDS != NULL ) { poLayer = poOGRDS->GetLayer( 0 ); if ( poLayer != NULL ) { OGRSpatialReference *poSRS = poLayer->GetSpatialRef( ); if ( poSRS != NULL ) { CPLDebug( "gdalsrsinfo", "got SRS from OGR" ); bGotSRS = TRUE; OGRSpatialReference* poSRSClone = poSRS->Clone(); oSRS = *poSRSClone; OGRSpatialReference::DestroySpatialReference( poSRSClone ); } } OGRDataSource::DestroyDataSource( poOGRDS ); poOGRDS = NULL; } if ( ! bGotSRS ) CPLDebug( "gdalsrsinfo", "did not open with OGR" ); } #endif // OGR_ENABLED /* Try ESRI file */ if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from ESRI .prj file [%s]", pszInput ); char **pszTemp; if ( strstr(pszInput,"ESRI::") != NULL ) pszTemp = CSLLoad( pszInput+6 ); else pszTemp = CSLLoad( pszInput ); if( pszTemp ) { eErr = oSRS.importFromESRI( pszTemp ); CSLDestroy( pszTemp ); } else eErr = OGRERR_UNSUPPORTED_SRS; if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" ); bGotSRS = TRUE; } } /* Last resort, try OSRSetFromUserInput() */ if ( ! bGotSRS ) { CPLDebug( "gdalsrsinfo", "trying to get SRS from user input [%s]", pszInput ); eErr = oSRS.SetFromUserInput( pszInput ); if( eErr != OGRERR_NONE ) { CPLDebug( "gdalsrsinfo", "did not get SRS from user input" ); } else { CPLDebug( "gdalsrsinfo", "got SRS from user input" ); bGotSRS = TRUE; } } /* restore error messages */ if ( ! bDebug ) CPLSetErrorHandler ( oErrorHandler ); return bGotSRS; }
int Image::scatterImageFileGDAL(const char * filename, int xOffset, int yOffset, PV::Communicator * comm, const PVLayerLoc * loc, float * buf, bool autoResizeFlag) { int status = 0; #ifdef PV_USE_GDAL const int nxProcs = comm->numCommColumns(); const int nyProcs = comm->numCommRows(); const int icRank = comm->commRank(); const int nx = loc->nx; const int ny = loc->ny; const int numBands = loc->nf; int numTotal; // will be nx*ny*bandsInFile const MPI_Comm mpi_comm = comm->communicator(); GDALDataType dataType; char** metadata; char isBinary = true; if (icRank > 0) { #ifdef PV_USE_MPI const int src = 0; const int tag = 13; MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm); MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm); MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm); #ifdef DEBUG_OUTPUT pvDebug().printf("[%2d]: scatterImageFileGDAL: received from 0, total number of bytes in buffer is %d\n", numTotal); #endif // DEBUG_OUTPUT MPI_Recv(buf, numTotal, MPI_FLOAT, src, tag, mpi_comm, MPI_STATUS_IGNORE); #ifdef DEBUG_OUTPUT int nf=numTotal/(nx*ny); assert( nf*nx*ny == numTotal ); pvDebug().printf("[%2d]: scatterImageFileGDAL: received from 0, nx==%d ny==%d nf==%d size==%d\n", comm->commRank(), nx, ny, nf, numTotal); #endif // DEBUG_OUTPUT #endif // PV_USE_MPI } else { GDALAllRegister(); GDALDataset * dataset = PV_GDALOpen(filename); GDALRasterBand * poBand = dataset->GetRasterBand(1); dataType = poBand->GetRasterDataType(); #ifdef PV_USE_MPI MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm); #endif // PV_USE_MPI // GDAL defines whether a band is binary, not whether the image as a whole is binary. // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1) for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){ GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1); metadata = GDALGetMetadata(hBand, "Image_Structure"); if(CSLCount(metadata) > 0){ bool found = false; for(int i = 0; metadata[i] != NULL; i++){ if(strcmp(metadata[i], "NBITS=1") == 0){ found = true; break; } } if(!found){ isBinary = false; } } else{ isBinary = false; } } #ifdef PV_USE_MPI MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm); #endif // PV_USE_MPI if (dataset==NULL) return 1; // PV_GDALOpen prints an error message. int xImageSize = dataset->GetRasterXSize(); int yImageSize = dataset->GetRasterYSize(); const int bandsInFile = dataset->GetRasterCount(); numTotal = nx * ny * bandsInFile; #ifdef PV_USE_MPI #ifdef DEBUG_OUTPUT pvDebug().printf("[%2d]: scatterImageFileGDAL: broadcast from 0, total number of bytes in buffer is %d\n", numTotal); #endif // DEBUG_OUTPUT MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm); #endif // PV_USE_MPI int xTotalSize = nx * nxProcs; int yTotalSize = ny * nyProcs; // if nf > bands of image, it will copy the gray image to each //band of layer assert(numBands == 1 || numBands == bandsInFile || (numBands > 1 && bandsInFile == 1)); int dest = -1; const int tag = 13; float padValue_conv; if(dataType == GDT_Byte){ padValue_conv = padValue * 255.0f; } else if(dataType == GDT_UInt16){ padValue_conv = padValue * 65535.0f; } else{ pvError() << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; } using std::min; using std::max; for( dest = nyProcs*nxProcs-1; dest >= 0; dest-- ) { //Need to clear buffer before reading, since we're skipping some of the buffer #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for(int i = 0; i < nx * ny * bandsInFile; i++){ //Fill with padValue buf[i] = padValue_conv; } int col = columnFromRank(dest,nyProcs,nxProcs); int row = rowFromRank(dest,nyProcs,nxProcs); int kx = nx * col; int ky = ny * row; //? For the auto resize flag, PV checks which side (x or y) is the shortest, relative to the //? hypercolumn size specified. Then it determines the largest chunk it can possibly take //? from the image with the correct aspect ratio determined by hypercolumn. It then //? determines the offset needed in the long dimension to center the cropped image, //? and reads in that portion of the image. The offset can optionally be translated by //? offset{X,Y} specified in the params file (values can be positive or negative). //? If the specified offset takes the cropped image outside the image file, it uses the //? largest-magnitude offset that stays within the image file's borders. if (autoResizeFlag){ if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){ int new_y = int(round(ny*xImageSize/(double)xTotalSize)); int y_off = int(round((yImageSize - new_y*nyProcs)/2.0)); int jitter_y = max(min(y_off,yOffset),-y_off); kx = xImageSize/nxProcs * col; ky = new_y * row; dataset->RasterIO(GF_Read, kx, ky + y_off + jitter_y, xImageSize/nxProcs, new_y, buf, nx, ny, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); } else{ int new_x = int(round(nx*yImageSize/(double)yTotalSize)); int x_off = int(round((xImageSize - new_x*nxProcs)/2.0)); int jitter_x = max(min(x_off,xOffset),-x_off); kx = new_x * col; ky = yImageSize/nyProcs * row; dataset->RasterIO(GF_Read, kx + x_off + jitter_x, ky, new_x, yImageSize/nyProcs, buf, nx, ny, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float),sizeof(float)); } }//End autoResizeFlag else { //Need to calculate corner image pixels in globalres space //offset is in Image space int img_left = -xOffset; int img_top = -yOffset; int img_right = img_left + xImageSize; int img_bot = img_top + yImageSize; //Check if in bounds if(img_left >= kx+nx || img_right <= kx || img_top >= ky+ny || img_bot <= ky){ //Do mpi_send to keep number of sends correct if(dest > 0){ MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm); } continue; } //start of the buffer on the left/top side int buf_left = img_left > kx ? img_left-kx : 0; int buf_top = img_top > ky ? img_top-ky : 0; int buf_right = img_right < kx+nx ? img_right-kx : nx; int buf_bot = img_bot < ky+ny ? img_bot-ky : ny; int buf_xSize = buf_right - buf_left; int buf_ySize = buf_bot - buf_top; assert(buf_xSize > 0 && buf_ySize > 0); int buf_offset = buf_top * nx * bandsInFile + buf_left * bandsInFile; int img_offset_x = kx+xOffset; int img_offset_y = ky+yOffset; if(img_offset_x < 0){ img_offset_x = 0; } if(img_offset_y < 0){ img_offset_y = 0; } float* buf_start = buf + buf_offset; dataset->RasterIO(GF_Read, img_offset_x, img_offset_y, buf_xSize, buf_ySize, buf_start, buf_xSize, buf_ySize, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); } #ifdef DEBUG_OUTPUT pvDebug().printf("[%2d]: scatterImageFileGDAL: sending to %d xSize==%d" " ySize==%d bandsInFile==%d size==%d total(over all procs)==%d\n", comm->commRank(), dest, nx, ny, bandsInFile, numTotal, nx*ny*comm->commSize()); #endif // DEBUG_OUTPUT #ifdef PV_USE_MPI if(dest > 0){ MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm); } #endif // PV_USE_MPI } GDALClose(dataset); } #else pvError().printf(GDAL_CONFIG_ERR_STR); #endif // PV_USE_GDAL if (status == 0) { if(!isBinary){ float fac; if(dataType == GDT_Byte){ fac = 1.0f / 255.0f; // normalize to 1.0 } else if(dataType == GDT_UInt16){ fac = 1.0f / 65535.0f; // normalize to 1.0 } else{ pvError() << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; } for( int n=0; n<numTotal; n++ ) { buf[n] *= fac; } } } return status; }
int Image::readImageFileGDAL(char const * filename, PVLayerLoc const * loc) { assert(parent->columnId()==0); GDALAllRegister(); GDALDataset * dataset = PV_GDALOpen(filename); if (dataset==NULL) { return PV_FAILURE; } // PV_GDALOpen prints an error message. GDALRasterBand * poBand = dataset->GetRasterBand(1); GDALDataType dataType = poBand->GetRasterDataType(); // GDAL defines whether a band is binary, not whether the image as a whole is binary. // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1) bool isBinary = true; for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){ GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1); char ** metadata = GDALGetMetadata(hBand, "Image_Structure"); if(CSLCount(metadata) > 0){ bool found = false; for(int i = 0; metadata[i] != NULL; i++){ if(strcmp(metadata[i], "NBITS=1") == 0){ found = true; break; } } if(!found){ isBinary = false; } } else{ isBinary = false; } } int const xImageSize = imageLoc.nxGlobal; int const yImageSize = imageLoc.nyGlobal; int const bandsInFile = imageLoc.nf; int numTotal = xImageSize * yImageSize * bandsInFile; dataset->RasterIO(GF_Read, 0, 0, xImageSize, yImageSize, imageData, xImageSize, yImageSize, GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*xImageSize*sizeof(float), sizeof(float)); GDALClose(dataset); if(!isBinary){ pvadata_t fac; if(dataType == GDT_Byte){ fac = 1.0f / 255.0f; // normalize to 1.0 } else if(dataType == GDT_UInt16){ fac = 1.0f / 65535.0f; // normalize to 1.0 } else{ pvError().printf("Image data type %s in file \"%s\" is not implemented.\n", GDALGetDataTypeName(dataType), filename); } for( int n=0; n<numTotal; n++ ) { imageData[n] *= fac; } } return EXIT_SUCCESS; }
int setImageLayerMemoryBuffer(InterColComm * icComm, char const * imageFile, ImageFromMemoryBuffer * imageLayer, uint8_t ** imageBufferPtr, size_t * imageBufferSizePtr) { // Under MPI, only the root process (rank==0) uses imageFile, imageBufferPtr, or imageBufferSizePtr, but nonroot processes need to call it as well, // because the imegeBuffer is scattered to all processes during the call to ImageFromMemoryBuffer::setMemoryBuffer(). int layerNx = imageLayer->getLayerLoc()->nxGlobal; int layerNy = imageLayer->getLayerLoc()->nyGlobal; int layerNf = imageLayer->getLayerLoc()->nf; int bufferNx, bufferNy, bufferNf; const uint8_t zeroVal = (uint8_t) 0; const uint8_t oneVal = (uint8_t) 255; int xStride, yStride, bandStride; int rank = icComm->commRank(); if (rank==0) { // Doubleplusungood: much code duplication from PV::Image::readImage bool usingTempFile = false; char * path = NULL; if (strstr(imageFile, "://") != NULL) { printf("Image from URL \"%s\"\n", imageFile); usingTempFile = true; std::string pathstring = "/tmp/temp.XXXXXX"; const char * ext = strrchr(imageFile, '.'); if (ext) { pathstring += ext; } path = strdup(pathstring.c_str()); int fid; fid=mkstemps(path, strlen(ext)); if (fid<0) { fprintf(stderr,"Cannot create temp image file for image \"%s\".\n", imageFile); exit(EXIT_FAILURE); } close(fid); std::string systemstring; if (strstr(imageFile, "s3://") != NULL) { systemstring = "aws s3 cp \'"; systemstring += imageFile; systemstring += "\' "; systemstring += path; } else { // URLs other than s3:// systemstring = "wget -O "; systemstring += path; systemstring += " \'"; systemstring += imageFile; systemstring += "\'"; } int const numAttempts = MAX_FILESYSTEMCALL_TRIES; for(int attemptNum = 0; attemptNum < numAttempts; attemptNum++){ int status = system(systemstring.c_str()); if(status != 0){ if(attemptNum == numAttempts - 1){ fprintf(stderr, "download command \"%s\" failed: %s. Exiting\n", systemstring.c_str(), strerror(errno)); exit(EXIT_FAILURE); } else{ fprintf(stderr, "download command \"%s\" failed: %s. Retrying %d out of %d.\n", systemstring.c_str(), strerror(errno), attemptNum+1, numAttempts); sleep(1); } } else{ break; } } } else { printf("Image from file \"%s\"\n", imageFile); path = strdup(imageFile); } GDALDataset * gdalDataset = PV_GDALOpen(path); if (gdalDataset==NULL) { fprintf(stderr, "setImageLayerMemoryBuffer: GDALOpen failed for image \"%s\".\n", imageFile); exit(EXIT_FAILURE); } int imageNx= gdalDataset->GetRasterXSize(); int imageNy = gdalDataset->GetRasterYSize(); int imageNf = GDALGetRasterCount(gdalDataset); // Need to rescale so that the the short side of the image equals the short side of the layer // ImageFromMemoryBuffer layer will handle the cropping. double xScaleFactor = (double)layerNx / (double) imageNx; double yScaleFactor = (double)layerNy / (double) imageNy; size_t imageBufferSize = *imageBufferSizePtr; uint8_t * imageBuffer = *imageBufferPtr; if (xScaleFactor < yScaleFactor) /* need to rescale so that bufferNy=layerNy and bufferNx>layerNx */ { bufferNx = (int) round(imageNx * yScaleFactor); bufferNy = layerNy; } else { bufferNx = layerNx; bufferNy = (int) round(imageNy * xScaleFactor); } bufferNf = layerNf; size_t newImageBufferSize = (size_t)bufferNx * (size_t)bufferNy * (size_t)bufferNf; if (imageBuffer==NULL || newImageBufferSize != imageBufferSize) { imageBufferSize = newImageBufferSize; imageBuffer = (uint8_t *) realloc(imageBuffer, imageBufferSize*sizeof(uint8_t)); if (imageBuffer==NULL) { fprintf(stderr, "setImageLayerMemoryBuffer: Unable to resize image buffer to %d-by-%d-by-%d for image \"%s\": %s\n", bufferNx, bufferNy, bufferNf, imageFile, strerror(errno)); exit(EXIT_FAILURE); } } bool isBinary = true; for (int iBand=0;iBand<imageNf; iBand++) { GDALRasterBandH hBand = GDALGetRasterBand(gdalDataset,iBand+1); char ** metadata = GDALGetMetadata(hBand, "Image_Structure"); if(CSLCount(metadata) > 0){ bool found = false; for(int i = 0; metadata[i] != NULL; i++){ if(strcmp(metadata[i], "NBITS=1") == 0){ found = true; isBinary &= true; break; } } if(!found){ isBinary &= false; } } else{ isBinary = false; } GDALDataType dataType = gdalDataset->GetRasterBand(iBand+1)->GetRasterDataType(); // Why are we using both GDALGetRasterBand and GDALDataset::GetRasterBand? if (dataType != GDT_Byte) { fprintf(stderr, "setImageLayerMemoryBuffer: Image file \"%s\", band %d, is not GDT_Byte type.\n", imageFile, iBand+1); exit(EXIT_FAILURE); } } #ifdef PV_USE_OPENMP_THREADS #pragma omp parallel for #endif for (size_t n=0; n < imageBufferSize; n++) { imageBuffer[n] = oneVal; } xStride = bufferNf; yStride = bufferNf * bufferNx; bandStride = 1; gdalDataset->RasterIO(GF_Read, 0/*xOffset*/, 0/*yOffset*/, imageNx, imageNy, imageBuffer, bufferNx, bufferNy, GDT_Byte, layerNf, NULL, xStride*sizeof(uint8_t), yStride*sizeof(uint8_t), bandStride*sizeof(uint8_t)); GDALClose(gdalDataset); if (usingTempFile) { int rmstatus = remove(path); if (rmstatus) { fprintf(stderr, "remove(\"%s\") failed. Exiting.\n", path); exit(EXIT_FAILURE); } } free(path); *imageBufferPtr = imageBuffer; *imageBufferSizePtr = imageBufferSize; int buffersize[3]; buffersize[0] = bufferNx; buffersize[1] = bufferNy; buffersize[2] = bufferNf; MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator()); } else { int buffersize[3]; MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator()); bufferNx = buffersize[0]; bufferNy = buffersize[1]; bufferNf = buffersize[2]; xStride = bufferNf; yStride = bufferNf * bufferNx; bandStride = 1; } imageLayer->setMemoryBuffer(*imageBufferPtr, bufferNy, bufferNx, bufferNf, xStride, yStride, bandStride, zeroVal, oneVal); return PV_SUCCESS; }