CPLErr TSXRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { int nRequestYSize; /* Check if the last strip is partial so we can avoid over-requesting */ if ( (nBlockYOff + 1) * nBlockYSize > nRasterYSize ) { nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize; memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) * nBlockXSize * nBlockYSize); } else { nRequestYSize = nBlockYSize; } /* Read Complex Data */ if ( eDataType == GDT_CInt16 ) { return poBand->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nBlockXSize, nRequestYSize, pImage, nBlockXSize, nRequestYSize, GDT_CInt16, 1, NULL, 4, nBlockXSize * 4, 0, NULL ); } // Detected Product return poBand->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nBlockXSize, nRequestYSize, pImage, nBlockXSize, nRequestYSize, GDT_UInt16, 1, NULL, 2, nBlockXSize * 2, 0, NULL ); }
// Read from a RAM Tiff. This is rather generic CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img) { CPLString fname = uniq_memfname("mrf_tif_read"); VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false); // Comes back opened, but we can't use it if (fp) VSIFCloseL(fp); else { CPLError(CE_Failure,CPLE_AppDefined, CPLString().Printf("MRF: TIFF, can't open %s as a temp file", fname.c_str())); return CE_Failure; } GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly)); if (!fp) { CPLError(CE_Failure,CPLE_AppDefined, CPLString().Printf("MRF: TIFF, can't open page as a Tiff")); return CE_Failure; } CPLErr ret; // Bypass the GDAL caching if (img.pagesize.c == 1) { ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer); } else { ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y, dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, NULL, 0,0,0); } GDALClose(poTiff); if (CE_None != ret) return ret; VSIUnlink(fname); return CE_None; }
CPLErr GDALOverviewDataset::IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, GSpacing nPixelSpace, GSpacing nLineSpace, GSpacing nBandSpace, GDALRasterIOExtraArg* psExtraArg) { int iBandIndex; CPLErr eErr = CE_None; /* In case the overview bands are really linked to a dataset, then issue */ /* the request to that dataset */ if( poOvrDS != NULL ) { return poOvrDS->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace, psExtraArg); } GDALProgressFunc pfnProgressGlobal = psExtraArg->pfnProgress; void *pProgressDataGlobal = psExtraArg->pProgressData; for( iBandIndex = 0; iBandIndex < nBandCount && eErr == CE_None; iBandIndex++ ) { GDALOverviewBand *poBand = (GDALOverviewBand*) GetRasterBand(panBandMap[iBandIndex]); GByte *pabyBandData; if (poBand == NULL) { eErr = CE_Failure; break; } pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace; psExtraArg->pfnProgress = GDALScaledProgress; psExtraArg->pProgressData = GDALCreateScaledProgress( 1.0 * iBandIndex / nBandCount, 1.0 * (iBandIndex + 1) / nBandCount, pfnProgressGlobal, pProgressDataGlobal ); eErr = poBand->IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, (void *) pabyBandData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg ); GDALDestroyScaledProgress( psExtraArg->pProgressData ); } psExtraArg->pfnProgress = pfnProgressGlobal; psExtraArg->pProgressData = pProgressDataGlobal; return eErr; }
// // Uses GDAL to create a temporary TIF file, using the band create options // copies the content to the destination buffer then erases the temp TIF // static CPLErr CompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img, char **papszOptions) { CPLErr ret; GDALDriver *poTiffDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); VSIStatBufL statb; CPLString fname = uniq_memfname("mrf_tif_write"); GDALDataset *poTiff = poTiffDriver->Create(fname, img.pagesize.x, img.pagesize.y, img.pagesize.c, img.dt, papszOptions ); // Read directly to avoid double caching in GDAL // Unfortunately not possible for multiple bands if (img.pagesize.c == 1) { ret = poTiff->GetRasterBand(1)->WriteBlock(0,0,src.buffer); } else { ret = poTiff->RasterIO(GF_Write, 0,0,img.pagesize.x,img.pagesize.y, src.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, NULL, 0,0,0 #if GDAL_VERSION_MAJOR >= 2 ,NULL #endif ); } if (CE_None != ret) return ret; GDALClose(poTiff); // Check that we can read the file if (VSIStatL(fname, &statb)) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't stat %s", fname.c_str()); return CE_Failure; } if (size_t(statb.st_size) > dst.size) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, Tiff generated is too large"); return CE_Failure; } VSILFILE *pf = VSIFOpenL(fname,"rb"); if (pf == NULL) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't open %s", fname.c_str()); return CE_Failure; } VSIFReadL(dst.buffer, static_cast<size_t>(statb.st_size), 1, pf); dst.size = static_cast<size_t>(statb.st_size); VSIFCloseL(pf); VSIUnlink(fname); return CE_None; }
static GDALDataset* createDataSetFromImage(const osg::Image* image, double minX, double minY, double maxX, double maxY, const std::string &projection) { //Clone the incoming image osg::ref_ptr<osg::Image> clonedImage = new osg::Image(*image); //Flip the image clonedImage->flipVertical(); GDALDataset* srcDS = createMemDS(image->s(), image->t(), minX, minY, maxX, maxY, projection); //Write the image data into the memory dataset //If the image is already RGBA, just read all 4 bands in one call if (image->getPixelFormat() == GL_RGBA) { srcDS->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), (void*)clonedImage->data(), clonedImage->s(), clonedImage->t(), GDT_Byte, 4, NULL, 4, 4 * image->s(), 1); } else if (image->getPixelFormat() == GL_RGB) { //OE_NOTICE << "[osgEarth::GeoData] Reprojecting RGB " << std::endl; //Read the read, green and blue bands srcDS->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), (void*)clonedImage->data(), clonedImage->s(), clonedImage->t(), GDT_Byte, 3, NULL, 3, 3 * image->s(), 1); //Initialize the alpha values to 255. unsigned char *alpha = new unsigned char[clonedImage->s() * clonedImage->t()]; memset(alpha, 255, clonedImage->s() * clonedImage->t()); GDALRasterBand* alphaBand = srcDS->GetRasterBand(4); alphaBand->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), alpha, clonedImage->s(),clonedImage->t(), GDT_Byte, 0, 0); delete[] alpha; } else { OE_WARN << LC << "createDataSetFromImage: unsupported pixel format " << std::hex << image->getPixelFormat() << std::endl; } srcDS->FlushCache(); return srcDS; }
// Read from a RAM Tiff. This is rather generic static CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img) { CPLString fname = uniq_memfname("mrf_tif_read"); VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false); // Comes back opened, but we can't use it if (fp) VSIFCloseL(fp); else { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't open %s as a temp file", fname.c_str()); return CE_Failure; } #if GDAL_VERSION_MAJOR >= 2 const char* const apszAllowedDrivers[] = { "GTiff", NULL }; GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpenEx(fname, GDAL_OF_RASTER, apszAllowedDrivers, NULL, NULL)); #else GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly)); #endif if (poTiff == NULL) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: TIFF, can't open page as a Tiff"); VSIUnlink(fname); return CE_Failure; } CPLErr ret; // Bypass the GDAL caching if (img.pagesize.c == 1) { ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer); } else { ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y, dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, NULL, 0,0,0 #if GDAL_VERSION_MAJOR >= 2 ,NULL #endif ); } GDALClose(poTiff); VSIUnlink(fname); return ret; }
CPLErr PDSDataset::IRasterIO( GDALRWFlag eRWFlag, int nXOff, int nYOff, int nXSize, int nYSize, void * pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int *panBandMap, int nPixelSpace, int nLineSpace, int nBandSpace) { if( poCompressedDS != NULL ) return poCompressedDS->RasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace ); else return RawDataset::IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace ); }
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; }
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 maxBands = 3; 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 fprintf(stderr, "[%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 ); fprintf(stderr, "[%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); // (GDALDataset *) GDALOpen(filename, GA_ReadOnly); 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 fprintf(stderr, "[%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{ std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; exit(-1); } 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; //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", kx, ky, xImageSize/nxProcs, new_y); 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; //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d, x_off = %d", kx, ky, new_x, yImageSize/nyProcs, x_off); 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 fprintf(stderr, "[%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); //Moved to above for loop // get local image portion //? same logic as before, except this time we know that the row and column are 0 //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 offset_y = max(min(y_off,yOffset),-y_off); // //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", 0, 0, xImageSize/nxProcs, new_y); // dataset->RasterIO(GF_Read, 0, y_off + offset_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 offset_x = max(min(x_off,xOffset),-x_off); // //fprintf(stderr, "xImageSize = %d, xTotalSize = %d, yImageSize = %d, yTotalSize = %d", xImageSize, xTotalSize, yImageSize, yTotalSize); // //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d", // //0, 0, new_x, yImageSize/nyProcs); // dataset->RasterIO(GF_Read, x_off + offset_x, 0, new_x, yImageSize/nyProcs, buf, nx, ny, // GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), // bandsInFile*nx*sizeof(float),sizeof(float)); // } //} //else { // //fprintf(stderr,"just checking"); // dataset->RasterIO(GF_Read, xOffset, yOffset, nx, ny, buf, nx, ny, // GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float)); //} //GDALClose(dataset); } #else fprintf(stderr, GDAL_CONFIG_ERR_STR); exit(1); #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{ std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n"; exit(-1); } for( int n=0; n<numTotal; n++ ) { buf[n] *= fac; } } } return status; }
int main(int argc, char* argv[]) { int i; int nThreads = CPLGetNumCPUs(); std::vector<CPLJoinableThread*> apsThreads; Strategy eStrategy = STRATEGY_RANDOM; int bNewDatasetOption = FALSE; int nXSize = 5000; int nYSize = 5000; int nBands = 4; char** papszOptions = NULL; int bOnDisk = FALSE; std::vector<ThreadDescription> asThreadDescription; int bMemDriver = FALSE; GDALDataset* poMEMDS = NULL; int bMigrate = FALSE; int nMaxRequests = -1; argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); GDALAllRegister(); for(i = 1; i < argc; i++) { if( EQUAL(argv[i], "-threads") && i + 1 < argc) { i ++; nThreads = atoi(argv[i]); } else if( EQUAL(argv[i], "-loops") && i + 1 < argc) { i ++; nLoops = atoi(argv[i]); if( nLoops <= 0 ) nLoops = INT_MAX; } else if( EQUAL(argv[i], "-max_requests") && i + 1 < argc) { i ++; nMaxRequests = atoi(argv[i]); } else if( EQUAL(argv[i], "-strategy") && i + 1 < argc) { i ++; if( EQUAL(argv[i], "random") ) eStrategy = STRATEGY_RANDOM; else if( EQUAL(argv[i], "line") ) eStrategy = STRATEGY_LINE; else if( EQUAL(argv[i], "block") ) eStrategy = STRATEGY_BLOCK; else Usage(); } else if( EQUAL(argv[i], "-xsize") && i + 1 < argc) { i ++; nXSize = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-ysize") && i + 1 < argc) { i ++; nYSize = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-bands") && i + 1 < argc) { i ++; nBands = atoi(argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-co") && i + 1 < argc) { i ++; papszOptions = CSLAddString(papszOptions, argv[i]); bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-ondisk")) { bOnDisk = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-check")) { bCheck = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-memdriver")) { bMemDriver = TRUE; bNewDatasetOption = TRUE; } else if( EQUAL(argv[i], "-migrate")) bMigrate = TRUE; else if( argv[i][0] == '-' ) Usage(); else if( pszDataset == NULL ) pszDataset = argv[i]; else { Usage(); } } if( pszDataset != NULL && bNewDatasetOption ) Usage(); CPLDebug("TEST", "Using %d threads", nThreads); int bCreatedDataset = FALSE; if( pszDataset == NULL ) { bCreatedDataset = TRUE; if( bOnDisk ) pszDataset = "/tmp/tmp.tif"; else pszDataset = "/vsimem/tmp.tif"; GDALDataset* poDS = ((GDALDriver*)GDALGetDriverByName((bMemDriver) ? "MEM" : "GTiff"))->Create(pszDataset, nXSize, nYSize, nBands, GDT_Byte, papszOptions); if( bCheck ) { GByte* pabyLine = (GByte*) VSIMalloc(nBands * nXSize); for(int iY=0;iY<nYSize;iY++) { for(int iX=0;iX<nXSize;iX++) { for(int iBand=0;iBand<nBands;iBand++) { unsigned long seed = iBand * nXSize * nYSize + iY * nXSize + iX; pabyLine[iBand * nXSize + iX] = (GByte)(myrand_r(&seed) & 0xff); } } CPL_IGNORE_RET_VAL(poDS->RasterIO(GF_Write, 0, iY, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, 0, 0, 0 #ifdef GDAL_COMPILATION , NULL #endif )); } VSIFree(pabyLine); } if( bMemDriver ) poMEMDS = poDS; else GDALClose(poDS); } else { bCheck = FALSE; } CSLDestroy(papszOptions); papszOptions = NULL; Request* psGlobalRequestLast = NULL; for(i = 0; i < nThreads; i++ ) { GDALDataset* poDS; // Since GDAL 2.0, the MEM driver is thread-safe, i.e. does not use the block // cache, but only for operations not involving resampling, which is // the case here if( poMEMDS ) poDS = poMEMDS; else { poDS = (GDALDataset*)GDALOpen(pszDataset, GA_ReadOnly); if( poDS == NULL ) exit(1); } if( bMigrate ) { Resource* psResource = (Resource*)CPLMalloc(sizeof(Resource)); psResource->poDS = poDS; int nBufferSize; if( eStrategy == STRATEGY_RANDOM ) nBufferSize = CreateRandomStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); else if( eStrategy == STRATEGY_LINE ) nBufferSize = CreateLineStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); else nBufferSize = CreateBlockStrategyRequests( poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast); psResource->pBuffer = CPLMalloc(nBufferSize); PutResourceAtEnd(psResource); } else { ThreadDescription sThreadDescription; sThreadDescription.poDS = poDS; sThreadDescription.psRequestList = NULL; Request* psRequestLast = NULL; if( eStrategy == STRATEGY_RANDOM ) sThreadDescription.nBufferSize = CreateRandomStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); else if( eStrategy == STRATEGY_LINE ) sThreadDescription.nBufferSize = CreateLineStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); else sThreadDescription.nBufferSize = CreateBlockStrategyRequests( poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast); asThreadDescription.push_back(sThreadDescription); } } if( bCreatedDataset && poMEMDS == NULL && bOnDisk ) { CPLPushErrorHandler(CPLQuietErrorHandler); VSIUnlink(pszDataset); CPLPopErrorHandler(); } if( bMigrate ) { psLock = CPLCreateLock(LOCK_SPIN); } for(i = 0; i < nThreads; i++ ) { CPLJoinableThread* pThread; if( bMigrate ) pThread = CPLCreateJoinableThread(ThreadFuncWithMigration, NULL); else pThread = CPLCreateJoinableThread(ThreadFuncDedicatedDataset, &(asThreadDescription[i])); apsThreads.push_back(pThread); } for(i = 0; i < nThreads; i++ ) { CPLJoinThread(apsThreads[i]); if( !bMigrate && poMEMDS == NULL ) GDALClose(asThreadDescription[i].poDS); } while( psGlobalResourceList != NULL ) { CPLFree( psGlobalResourceList->pBuffer); if( poMEMDS == NULL ) GDALClose(psGlobalResourceList->poDS); Resource* psNext = psGlobalResourceList->psNext; CPLFree( psGlobalResourceList ); psGlobalResourceList = psNext; } if( psLock ) { CPLDestroyLock( psLock ); } if( bCreatedDataset && poMEMDS == NULL ) { CPLPushErrorHandler(CPLQuietErrorHandler); VSIUnlink(pszDataset); CPLPopErrorHandler(); } if( poMEMDS ) GDALClose(poMEMDS); assert( GDALGetCacheUsed64() == 0 ); GDALDestroyDriverManager(); CSLDestroy( argv ); return 0; }
int download(region regionFlag, satellite satFlag, data_layer dataFlag, data_format typeFlag){ GDALDataset *poDataset = NULL; Mat imageBuffer, outputBuffer; double pixel2geo[6]; double geo2pixel[6]; uint64_t xmin, ymin; uint64_t xsize, ysize; char GIBS_XML[1000]; char outFileName[100]; int numChannel; // Get the data sprintf(GIBS_XML, wms_format, /* Region name */ (regionFlag==NORTH)?"arctic":((regionFlag==NORMAL)?"geo":"antarctic"), /*Satellite name */ (satFlag==TERRA)?"Terra":"Aqua", /*Data layer name */ (dataFlag==REFLECTANCE)?"CorrectedReflectance_TrueColor":"Data_No_Data", year, month, day, /*Region EPSG code*/ (regionFlag==NORTH)?"EPSG3413":((regionFlag==NORMAL)?"EPSG4326":"EPSG3031"), /*Data Format */ (typeFlag==JPG)?"jpg":"png", /*Region EPSG code*/ (regionFlag==NORTH)?arctic_bounds:((regionFlag==NORMAL)?normal_bounds:antarctic_bounds), /*Region EPSG code*/ (regionFlag==NORTH)?"EPSG:3413":((regionFlag==NORMAL)?"EPSG:4326":"EPSG:3031"), (typeFlag==JPG)?3:4); printf("%s\n\n", GIBS_XML); // Open file poDataset = (GDALDataset*) GDALOpen(GIBS_XML, GA_ReadOnly); if(!poDataset){ fprintf(stderr,"File cannot be opened!\n");return 1; } // Print some metadata xsize = poDataset->GetRasterXSize(); ysize = poDataset->GetRasterYSize(); numChannel = poDataset->GetRasterCount(); // Calculate coordinates poDataset->GetGeoTransform(pixel2geo); GDALInvGeoTransform(pixel2geo, geo2pixel); double lat_offset, lon_offset; switch(regionFlag){ case NORTH: xmin = (col-1)*4096; ymin = (6-row)*4096; break; case NORMAL: GDALApplyGeoTransform(geo2pixel, (col-20)*9.0, (row-9)*9.0, &lon_offset, &lat_offset); xmin = (int) lon_offset; ymin = (int) lat_offset; break; case SOUTH: xmin = (col-1)*4096; ymin = (6-row)*4096; break; } printf("Offset=(%lf,%lf)\n",lon_offset,lat_offset); // Read Image data ysize = 4096; xsize = 4096; imageBuffer.create(ysize, xsize, CV_8UC1); outputBuffer.create(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4); outputBuffer.zeros(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4); int bandArray[1]; for(int i=0;i<((typeFlag==JPG)?3:4);i++){ bandArray[0] = i+1; imageBuffer.zeros(ysize, xsize, CV_8U); poDataset->RasterIO(GF_Read, xmin, ymin, xsize, ysize, (void*) imageBuffer.ptr(0), xsize, ysize, GDT_Byte, 1, bandArray, 0, 0, 0); for(int x=0;x<xsize;x++){ for(int y=0;y<ysize;y++){ ((uint8_t*)(outputBuffer.data))[(y*xsize+x)*numChannel+(numChannel-i-1)] = ((uint8_t*)(imageBuffer.data))[y*xsize+x]; } } } if(typeFlag==PNG){ outputBuffer = (outputBuffer==0); outputBuffer.convertTo(outputBuffer, CV_8UC1, 1, 0); } sprintf(outFileName, "%s_r%02dc%02d.%04d%03d.%s%s250m.%s", (regionFlag==NORTH)?"RRArctic":((regionFlag==NORMAL)?"RRGlobal":"RRAntarctic"), row, col, year, daynum, (satFlag==TERRA)?"terra":"aqua", (dataFlag==REFLECTANCE)?".":".opaque.", (typeFlag==JPG)?"jpg":"png"); imwrite(outFileName, outputBuffer); printf("File %s is written\n", outFileName); return 0; }
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel) { wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset); if(!pRaster) return; IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation(); OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference(); OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference(); bool IsSpaRefSame(true); if(pDisplaySpatialReference && pDisplaySpatialReference) IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference); OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds(); OGREnvelope* pRasterExtent = pRaster->GetEnvelope(); OGREnvelope RasterEnvelope, DisplayEnvelope; if(!IsSpaRefSame) { RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference); } else { RasterEnvelope = *pRasterExtent; } bool IsZoomIn(false); //IsZoomIn = RasterEnvelope.Contains(VisibleBounds); IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY; if(IsZoomIn) { //intersect bounds OGREnvelope DrawBounds; DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX); DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY); DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX); DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY); OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = DrawBounds.MinX; OGRRawPoints[0].y = DrawBounds.MinY; OGRRawPoints[1].x = DrawBounds.MaxX; OGRRawPoints[1].y = DrawBounds.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; wxDELETEA(pDCPoints); if(nWidth <= 20 || nHeight <= 20) return; GDALDataset* pGDALDataset = pRaster->GetRaster(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 }; CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform); bool bNoTransform(false); if(err != CE_None) { bNoTransform = true; } else { int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform ); } //2. get image data from raster - draw part of the raster if(IsSpaRefSame) { double rMinX, rMinY, rMaxX, rMaxY; int nXSize = pGDALDataset->GetRasterXSize(); int nYSize = pGDALDataset->GetRasterYSize(); if(bNoTransform) { rMinX = DrawBounds.MinX; rMaxX = DrawBounds.MaxX; rMaxY = nYSize - DrawBounds.MinY; rMinY = nYSize - DrawBounds.MaxY; } else { GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY ); GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY ); } //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY; //rRealMinX = MIN(rMinX, rMaxX); //rRealMinY = MIN(rMinY, rMaxY); //rRealMaxX = MAX(rMinX, rMaxX); //rRealMaxY = MAX(rMinY, rMaxY); double rImgWidth = rMaxX - rMinX; double rImgHeight = rMaxY - rMinY; int nImgWidth = ceil(rImgWidth) + 1; int nImgHeight = ceil(rImgHeight) + 1; //read in buffer int nMinX = floor(rMinX); int nMinY = floor(rMinY); if(nMinX < 0) nMinX = 0; if(nMinY < 0) nMinY = 0; if(nImgWidth > nXSize - nMinX) nImgWidth -= 1; if(nImgHeight > nYSize - nMinY) nImgHeight -= 1; //create buffer int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0 /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/; int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0 /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/; double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth; double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight; unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3]; err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data);//delete[](data); return; } //scale pTempData to data using interpolation methods pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig); wxDELETEA(data); } else { //void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 ); //GDALDestroyGenImgProjTransformer( hTransformArg ); //// //get new envelope - it may rotate //// OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference); ////// get real envelope ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY); ////// poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY); //// OCTDestroyCoordinateTransformation(poCT); } } else { //1. convert newrasterenvelope to DC OGRRawPoint OGRRawPoints[2]; OGRRawPoints[0].x = RasterEnvelope.MinX; OGRRawPoints[0].y = RasterEnvelope.MinY; OGRRawPoints[1].x = RasterEnvelope.MaxX; OGRRawPoints[1].y = RasterEnvelope.MaxY; wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2); //2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster if(!pDCPoints) { wxDELETEA(pDCPoints); return; } int nDCXOrig = pDCPoints[0].x; int nDCYOrig = pDCPoints[1].y; int nWidth = pDCPoints[1].x - pDCPoints[0].x; int nHeight = pDCPoints[0].y - pDCPoints[1].y; delete[](pDCPoints); GDALDataset* pGDALDataset = pRaster->GetRaster(); int nImgWidth = pGDALDataset->GetRasterXSize(); int nImgHeight = pGDALDataset->GetRasterYSize(); int nBandCount = pGDALDataset->GetRasterCount(); //hack! int bands[3]; if(nBandCount < 3) { bands[0] = 1; bands[1] = 1; bands[2] = 1; } else { bands[0] = 1; bands[1] = 2; bands[2] = 3; } //create buffer unsigned char* data = new unsigned char[nWidth * nHeight * 3]; if(IsSpaRefSame) { //read in buffer CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char)); if(err != CE_None) { wxDELETEA(data); return; } } else { //1. calc Width & Height of TempData with same aspect ratio of raster //2. create pTempData buffer unsigned char* pTempData; //3. fill data //4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation //delete[](data); } //3. draw //think about transparancy! wxImage ResultImage(nWidth, nHeight, data); pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig); //delete[](data); } }
/** *\brief Fetch a block from the backing store dataset and keep a copy in the cache * * @xblk The X block number, zero based * @yblk The Y block number, zero based * @param tinfo The return, updated tinfo for this specific tile * */ CPLErr GDALMRFRasterBand::FetchBlock(int xblk, int yblk, void *buffer) { assert(!poDS->source.empty()); CPLDebug("MRF_IB", "FetchBlock %d,%d,0,%d, level %d\n", xblk, yblk, m_band, m_l); if (poDS->clonedSource) // This is a clone return FetchClonedBlock(xblk, yblk, buffer); GDALDataset *poSrcDS; const GInt32 cstride = img.pagesize.c; // 1 if band separate ILSize req(xblk, yblk, 0, m_band / cstride, m_l); GUIntBig infooffset = IdxOffset(req, img); if ( NULL == (poSrcDS = poDS->GetSrcDS())) { CPLError( CE_Failure, CPLE_AppDefined, "MRF: Can't open source file %s", poDS->source.c_str()); return CE_Failure; } // Scale to base resolution double scl = pow(poDS->scale, m_l); if ( 0 == m_l ) scl = 1; // To allow for precision issues // Prepare parameters for RasterIO, they might be different from a full page int vsz = GDALGetDataTypeSize(eDataType)/8; int Xoff = int(xblk * img.pagesize.x * scl + 0.5); int Yoff = int(yblk * img.pagesize.y * scl + 0.5); int readszx = int(img.pagesize.x * scl + 0.5); int readszy = int(img.pagesize.y * scl + 0.5); // Compare with the full size and clip to the right and bottom if needed int clip=0; if (Xoff + readszx > poDS->full.size.x) { clip |= 1; readszx = poDS->full.size.x - Xoff; } if (Yoff + readszy > poDS->full.size.y) { clip |= 1; readszy = poDS->full.size.y - Yoff; } // This is where the whole page fits void *ob = buffer; if (cstride != 1) ob = poDS->GetPBuffer(); // Fill buffer with NoData if clipping if (clip) FillBlock(ob); // Use the dataset RasterIO to read one or all bands if interleaved CPLErr ret = poSrcDS->RasterIO(GF_Read, Xoff, Yoff, readszx, readszy, ob, pcount(readszx, int(scl)), pcount(readszy, int(scl)), eDataType, cstride, (1 == cstride)? &nBand: NULL, vsz * cstride, // pixel, line, band stride vsz * cstride * img.pagesize.x, (cstride != 1) ? vsz : vsz * img.pagesize.x * img.pagesize.y #if GDAL_VERSION_MAJOR >= 2 ,NULL #endif ); if (ret != CE_None) return ret; // Might have the block in the pbuffer, mark it anyhow poDS->tile = req; buf_mgr filesrc; filesrc.buffer = (char *)ob; filesrc.size = static_cast<size_t>(img.pageSizeBytes); if (poDS->bypass_cache) { // No local caching, just return the data if (1 == cstride) return CE_None; return RB(xblk, yblk, filesrc, buffer); } // Test to see if it needs to be written, or just marked as checked int success; double val = GetNoDataValue(&success); if (!success) val = 0.0; // TODO: test band by band if data is interleaved if (isAllVal(eDataType, ob, img.pageSizeBytes, val)) { // Mark it empty and checked, ignore the possible write error poDS->WriteTile((void *)1, infooffset, 0); return CE_None; } // Write the page in the local cache // Have to use a separate buffer for compression output. void *outbuff = VSIMalloc(poDS->pbsize); if (!outbuff) { CPLError(CE_Failure, CPLE_AppDefined, "Can't get buffer for writing page"); // This is not really an error for a cache, the data is fine return CE_Failure; } buf_mgr filedst={(char *)outbuff, poDS->pbsize}; Compress(filedst, filesrc); // Where the output is, in case we deflate void *usebuff = outbuff; if (deflatep) { usebuff = DeflateBlock( filedst, poDS->pbsize - filedst.size, deflate_flags); if (!usebuff) { CPLError(CE_Failure,CPLE_AppDefined, "MRF: Deflate error"); return CE_Failure; } } // Write and update the tile index ret = poDS->WriteTile(usebuff, infooffset, filedst.size); CPLFree(outbuff); // If we hit an error or if unpaking is not needed if (ret != CE_None || cstride == 1) return ret; // data is already in filesrc buffer, deinterlace it in pixel blocks return RB(xblk, yblk, filesrc, buffer); }
int meaningful_change(string cd_map_file, string result_file) { GdalRasterApp cd_map; cd_map.open(cd_map_file.c_str()); int iBandCount = cd_map.nBand(); int iTileCountX = cd_map.getTileCountX(); int iTileCountY = cd_map.getTileCountY(); int iWidth = cd_map.width(); int iHeight = cd_map.height(); GDALDriver *poDriver; //驱动,用于创建新的文件 poDriver=GetGDALDriverManager()->GetDriverByName("GTIFF"); char **papszMetadata = poDriver->GetMetadata();//获取格式类型 GDALDataset *poDatasetNew; // 输出栅格 poDatasetNew = poDriver->Create(result_file.c_str(), iWidth, iHeight, 1, GDT_Byte, papszMetadata);//根据文件路径文件名,图像宽,高,波段数,数据类型,文件类型,创建新的数据集 poDatasetNew->SetProjection(cd_map.getGetProjectionRef()); poDatasetNew->SetGeoTransform(cd_map.getGeoTransform());//坐标赋值,与全色相同 int nCount = 0; double norm_threshold = 20.0; int bgColor = 0; int fgColor = 255; for (int i = 0;i < iTileCountX;++i) { for (int j = 0;j < iTileCountY;++j) { GdalRasterApp::RasterBuf *pBuf = cd_map.getTileData(i, j, iBandCount); int bufWidth = pBuf->iBufWidth; int bufHeight = pBuf->iBufHeight; int bufBand = pBuf->iBandCount; int offsetX, offsetY; cd_map.getTileOffset(i, j, offsetX, offsetY); cv::Mat change_image(cv::Size(bufWidth, bufHeight), CV_8UC1, cv::Scalar(fgColor)); //cv::Mat lbp_change(cv::Size(bufWidth, bufHeight), CV_8UC1); cv::Mat lbp_change = img_int2byte_band(pBuf, 0); //cv::Mat lbp_change = img_float2byte_band(pBuf, 0); //memcpy(lbp_change.data, pBuf->data, bufWidth*bufHeight); //cv::imwrite("E:\\minus.tif", lbp_change); int lbp_change_threshold = cvThresholdOtsu(lbp_change); int step = change_image.step; // change detection for (int row = 0; row < bufHeight; ++row) { for (int col = 0; col < bufWidth; ++col) { int lbp_change_ = lbp_change.data[row*lbp_change.step+col]; // 判断是否变化很小 if (lbp_change_ < lbp_change_threshold) { change_image.data[row*step+col] = bgColor; continue; } std::vector<double> change_vector(pFeatureBuf->iBandCount); for (int k = 0;k < pFeatureBuf->iBandCount;++k) { int pos = row * bufWidth * pFeatureBuf->iBandCount + col*pFeatureBuf->iBandCount + k; change_vector[k] = ((float*)pFeatureBuf->data)[pos]; } //如果变化是否和样本相似 for (int m = 0; m < (int)samples.size(); m++) { double angle_ = samples[m][0] - change_vector[0]; double norm_ = samples[m][1] - change_vector[1]; //double similarity = VectorSimilarity(samples[m], change_vector); //double distance = VectorDistance(samples[m], change_vector); //double angle = VectorAngle(samples[m], change_vector); //if (fabs(similarity) > similarityThreshold && distance < 15.0) //if (fabs(angle) < 10.0 && distance < 20.0) //if (fabs(similarity) < similarityThreshold) if (fabs(angle_) < similarityThreshold && fabs(norm_) < 10.0) //if (fabs(norm) < 10.0) { change_image.data[row*step+col] = bgColor; break; } } } } //RasterBuf2Opencv(pBuf, change_image); //cv::Mat change_image(bufHeight, bufWidth, CV_8U(bufBand)); //int nBandDataSize = GDALGetDataTypeSize( pBuf->eDataType ) / 8; //memcpy(change_image.data, (GByte*)(pBuf->data), bufWidth*bufHeight*bufBand*nBandDataSize); //cvtColor( change_image, change_image, CV_BGR2GRAY ); //int threshold = cvThresholdOtsu(change_image); //threshold = 60; //cv::threshold( change_image, change_image, threshold, 255, CV_THRESH_BINARY); //cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3)); //cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element); //element = cv::getStructuringElement(cv::MORPH_CROSS , cv::Size(7, 7)); //cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element); //element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7, 7)); //cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element); //cv::GaussianBlur(change_image, change_image, cv::Size(5,5), 1.5); //cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element); //cv::imwrite("E:\\test0.tif", change_image); cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2)); //cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element); int nTemplate = sqrt(smallArea); nTemplate = nTemplate / 2 * 2 + 1; cv::medianBlur(change_image, change_image, nTemplate); //cv::imwrite("E:\\test1.tif", change_image); // 先闭运算 nTemplate = nTemplate / 2; element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5)); cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element); // 再开运算 //element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10)); //cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element); //cv::imwrite("E:\\test2.tif", change_image); BinaryRemoveSmall(change_image, change_image, smallArea, bgColor, fgColor); //cv::Mat tmpMat = change_image.clone(); ////cv::GaussianBlur(tmpMat, tmpMat, cv::Size(5,5), 1.5); //std::vector<std::vector<cv::Point> > contours; //std::vector<cv::Vec4i> hierarchy; //cv::findContours(tmpMat, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); ////for (std::vector<std::vector<cv::Point> >::iterator iter_Contours = contours.begin(); iter_Contours != contours.end();++iter_Contours) //int nContours = (int)contours.size(); //for (int iContours = 0; iContours < nContours;++iContours) //{ // std::vector<cv::Point> contour = contours[iContours]; // double tempArea = fabs(cv::contourArea(contour)); // cv::Rect rect = cv::boundingRect(contour); // //当连通域的中心点为白色,而且面积较小时,用黑色进行填充 // if (tempArea < miniArea) // { // int pos_center = step*(rect.y+rect.height/2)+rect.x+rect.width/2; // //if (255 == change_image.data[pos_center]) // { // for(int y = rect.y;y<rect.y+rect.height;y++) // { // for(int x =rect.x;x<rect.x+rect.width;x++) // { // int pos_ = y*step+x; // if(255 == change_image.data[pos_]) // { // change_image.data[pos_] = 0; // } // } // } // } // } //} //cv::imwrite("E:\\test3.tif", change_image); ////cv::imwrite("E:\\test.tif", change_image); if (_changeOutType::raster == outType) { // 输出栅格 CPLErr gdal_err = poDatasetNew->RasterIO(GF_Write, offsetX, offsetY, bufWidth, bufHeight, change_image.data, bufWidth, bufHeight,\ GDT_Byte, 1, 0, 0, 0, 0); } else if (_changeOutType::vector == outType) { // 输出矢量 std::vector<std::vector<cv::Point> > contours; std::vector<cv::Vec4i> hierarchy; cv::findContours(change_image, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) ); addContour2ShapeArea(contours, out_layer_file, raster_minus.getGeoTransform(), raster_minus.getGetProjectionRef(), nCount, raster_minus.getBufInfo()->iBufOffsetX, raster_minus.getBufInfo()->iBufOffsetY); nCount += (int)contours.size(); } pBuf = NULL; } } raster_minus.close(); raster_feature.close(); poDatasetNew->FlushCache(); GDALClose(poDatasetNew); }
CPLErr SAFERasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { /* -------------------------------------------------------------------- */ /* If the last strip is partial, we need to avoid */ /* over-requesting. We also need to initialize the extra part */ /* of the block to zero. */ /* -------------------------------------------------------------------- */ int nRequestYSize; if( (nBlockYOff + 1) * nBlockYSize > nRasterYSize ) { nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize; memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) * nBlockXSize * nBlockYSize ); } else { nRequestYSize = nBlockYSize; } /*-------------------------------------------------------------------- */ /* If the input imagery is tiled, also need to avoid over- */ /* requesting in the X-direction. */ /* ------------------------------------------------------------------- */ int nRequestXSize; if( (nBlockXOff + 1) * nBlockXSize > nRasterXSize ) { nRequestXSize = nRasterXSize - nBlockXOff * nBlockXSize; memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) * nBlockXSize * nBlockYSize ); } else { nRequestXSize = nBlockXSize; } if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 2 ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_Int16, 2, nullptr, 4, nBlockXSize * 4, 2, nullptr ); /* -------------------------------------------------------------------- */ /* File has one sample marked as sample format void, a 32bits. */ /* -------------------------------------------------------------------- */ else if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 1 ) { CPLErr eErr = poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_UInt32, 1, nullptr, 4, nBlockXSize * 4, 0, nullptr ); #ifdef CPL_LSB /* First, undo the 32bit swap. */ GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 ); /* Then apply 16 bit swap. */ GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize * 2, 2 ); #endif return eErr; } /* -------------------------------------------------------------------- */ /* The 16bit case is straight forward. The underlying file */ /* looks like a 16bit unsigned data too. */ /* -------------------------------------------------------------------- */ else if( eDataType == GDT_UInt16 ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_UInt16, 1, nullptr, 2, nBlockXSize * 2, 0, nullptr ); else if ( eDataType == GDT_Byte ) return poBandFile->RasterIO( GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nRequestXSize, nRequestYSize, pImage, nRequestXSize, nRequestYSize, GDT_Byte, 1, nullptr, 1, nBlockXSize, 0, nullptr ); CPLAssert( false ); return CE_Failure; }
CPLErr GDALWMSRasterBand::ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read) { CPLErr ret = CE_None; GDALDataset *ds = 0; GByte *color_table = NULL; int i; //CPLDebug("WMS", "ReadBlockFromFile: to_buffer_band=%d, (x,y)=(%d, %d)", to_buffer_band, x, y); /* expected size */ const int esx = MIN(MAX(0, (x + 1) * nBlockXSize), nRasterXSize) - MIN(MAX(0, x * nBlockXSize), nRasterXSize); const int esy = MIN(MAX(0, (y + 1) * nBlockYSize), nRasterYSize) - MIN(MAX(0, y * nBlockYSize), nRasterYSize); ds = reinterpret_cast<GDALDataset*>(GDALOpen(file_name, GA_ReadOnly)); if (ds != NULL) { int sx = ds->GetRasterXSize(); int sy = ds->GetRasterYSize(); bool accepted_as_no_alpha = false; // if the request is for 4 bands but the wms returns 3 /* Allow bigger than expected so pre-tiled constant size images work on corners */ if ((sx > nBlockXSize) || (sy > nBlockYSize) || (sx < esx) || (sy < esy)) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect size %d x %d of downloaded block, expected %d x %d, max %d x %d.", sx, sy, esx, esy, nBlockXSize, nBlockYSize); ret = CE_Failure; } if (ret == CE_None) { int nDSRasterCount = ds->GetRasterCount(); if (nDSRasterCount != m_parent_dataset->nBands) { /* Maybe its an image with color table */ bool accepted_as_ct = false; if ((eDataType == GDT_Byte) && (ds->GetRasterCount() == 1)) { GDALRasterBand *rb = ds->GetRasterBand(1); if (rb->GetRasterDataType() == GDT_Byte) { GDALColorTable *ct = rb->GetColorTable(); if (ct != NULL) { accepted_as_ct = true; if (!advise_read) { color_table = new GByte[256 * 4]; const int count = MIN(256, ct->GetColorEntryCount()); for (i = 0; i < count; ++i) { GDALColorEntry ce; ct->GetColorEntryAsRGB(i, &ce); color_table[i] = static_cast<GByte>(ce.c1); color_table[i + 256] = static_cast<GByte>(ce.c2); color_table[i + 512] = static_cast<GByte>(ce.c3); color_table[i + 768] = static_cast<GByte>(ce.c4); } for (i = count; i < 256; ++i) { color_table[i] = 0; color_table[i + 256] = 0; color_table[i + 512] = 0; color_table[i + 768] = 0; } } } } } if (nDSRasterCount == 4 && m_parent_dataset->nBands == 3) { /* metacarta TMS service sometimes return a 4 band PNG instead of the expected 3 band... */ } else if (!accepted_as_ct) { if (ds->GetRasterCount()==3 && m_parent_dataset->nBands == 4 && (eDataType == GDT_Byte)) { // WMS returned a file with no alpha so we will fill the alpha band with "opaque" accepted_as_no_alpha = true; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", nDSRasterCount, m_parent_dataset->nBands); ret = CE_Failure; } } } } if (!advise_read) { for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) { if (ret == CE_None) { void *p = NULL; GDALRasterBlock *b = NULL; if ((buffer != NULL) && (ib == to_buffer_band)) { p = buffer; } else { GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib)); if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview)); if (!band->IsBlockInCache(x, y)) { b = band->GetLockedBlockRef(x, y, true); if (b != NULL) { p = b->GetDataRef(); if (p == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL."); ret = CE_Failure; } } } else { //CPLDebug("WMS", "Band %d, block (x,y)=(%d, %d) already in cache", band->GetBand(), x, y); } } if (p != NULL) { int pixel_space = GDALGetDataTypeSize(eDataType) / 8; int line_space = pixel_space * nBlockXSize; if (color_table == NULL) { if( ib <= ds->GetRasterCount()) { if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, &ib, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } } else { // parent expects 4 bands but file only has 3 so generate a all "opaque" 4th band if (accepted_as_no_alpha) { // the file had 3 bands and we are reading band 4 (Alpha) so fill with 255 (no alpha) GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = 255; // fill with opaque } } } else { // we should never get here because this case was caught above CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.", ds->GetRasterCount(), m_parent_dataset->nBands); ret = CE_Failure; } } } else if (ib <= 4) { if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, NULL, pixel_space, line_space, 0) != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block."); ret = CE_Failure; } if (ret == CE_None) { GByte *band_color_table = color_table + 256 * (ib - 1); GByte *byte_buffer = reinterpret_cast<GByte *>(p); for (int y = 0; y < sy; ++y) { for (int x = 0; x < sx; ++x) { const int offset = x + y * line_space; byte_buffer[offset] = band_color_table[byte_buffer[offset]]; } } } } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Color table supports at most 4 components."); ret = CE_Failure; } } if (b != NULL) { b->DropLock(); } } } } GDALClose(ds); } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to open downloaded block."); ret = CE_Failure; } if (color_table != NULL) { delete[] color_table; } return ret; }
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; }
CPLErr GDALRasterizeLayers( GDALDatasetH hDS, int nBandCount, int *panBandList, int nLayerCount, OGRLayerH *pahLayers, GDALTransformerFunc pfnTransformer, void *pTransformArg, double *padfLayerBurnValues, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressArg ) { GDALDataType eType; unsigned char *pabyChunkBuf; GDALDataset *poDS = (GDALDataset *) hDS; if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */ /* Do some rudimentary arg checking. */ /* -------------------------------------------------------------------- */ if( nBandCount == 0 || nLayerCount == 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;*/ } /* -------------------------------------------------------------------- */ /* Establish a chunksize to operate on. The larger the chunk */ /* size the less times we need to make a pass through all the */ /* shapes. */ /* -------------------------------------------------------------------- */ int nYChunkSize, nScanlineBytes; const char *pszYChunkSize = CSLFetchNameValue( papszOptions, "CHUNKYSIZE" ); if( poBand->GetRasterDataType() == GDT_Byte ) eType = GDT_Byte; else eType = GDT_Float32; nScanlineBytes = nBandCount * poDS->GetRasterXSize() * (GDALGetDataTypeSize(eType)/8); if ( pszYChunkSize && (nYChunkSize = atoi(pszYChunkSize)) ) ; else nYChunkSize = GDALGetCacheMax() / nScanlineBytes; if( nYChunkSize < 1 ) nYChunkSize = 1; 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; } /* -------------------------------------------------------------------- */ /* Read the image once for all layers if user requested to render */ /* the whole raster in single chunk. */ /* -------------------------------------------------------------------- */ if ( nYChunkSize == poDS->GetRasterYSize() ) { if ( poDS->RasterIO( GF_Read, 0, 0, poDS->GetRasterXSize(), nYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nYChunkSize, eType, nBandCount, panBandList, 0, 0, 0 ) != CE_None ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to read buffer." ); CPLFree( pabyChunkBuf ); return CE_Failure; } } /* ==================================================================== */ /* Read the specified layers transfoming and rasterizing */ /* geometries. */ /* ==================================================================== */ CPLErr eErr = CE_None; int iLayer; const char *pszBurnAttribute = CSLFetchNameValue( papszOptions, "ATTRIBUTE" ); pfnProgress( 0.0, NULL, pProgressArg ); for( iLayer = 0; iLayer < nLayerCount; iLayer++ ) { int iBurnField = -1; double *padfBurnValues = NULL; OGRLayer *poLayer = (OGRLayer *) pahLayers[iLayer]; if ( !poLayer ) { CPLError( CE_Warning, CPLE_AppDefined, "Layer element number %d is NULL, skipping.\n", iLayer ); continue; } /* -------------------------------------------------------------------- */ /* If the layer does not contain any features just skip it. */ /* Do not force the feature count, so if driver doesn't know */ /* exact number of features, go down the normal way. */ /* -------------------------------------------------------------------- */ if ( poLayer->GetFeatureCount(FALSE) == 0 ) continue; if ( pszBurnAttribute ) { iBurnField = poLayer->GetLayerDefn()->GetFieldIndex( pszBurnAttribute ); if ( iBurnField == -1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to find field %s on layer %s, skipping.\n", pszBurnAttribute, poLayer->GetLayerDefn()->GetName() ); continue; } } else padfBurnValues = padfLayerBurnValues + iLayer * nBandCount; /* -------------------------------------------------------------------- */ /* If we have no transformer, create the one from input file */ /* projection. Note that each layer can be georefernced */ /* separately. */ /* -------------------------------------------------------------------- */ int bNeedToFreeTransformer = FALSE; if( pfnTransformer == NULL ) { char *pszProjection = NULL; bNeedToFreeTransformer = TRUE; OGRSpatialReference *poSRS = poLayer->GetSpatialRef(); if ( !poSRS ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to fetch spatial reference on layer %s " "to build transformer, assuming matching coordinate systems.\n", poLayer->GetLayerDefn()->GetName() ); } else poSRS->exportToWkt( &pszProjection ); pTransformArg = GDALCreateGenImgProjTransformer( NULL, pszProjection, hDS, NULL, FALSE, 0.0, 0 ); pfnTransformer = GDALGenImgProjTransform; CPLFree( pszProjection ); } OGRFeature *poFeat; poLayer->ResetReading(); /* -------------------------------------------------------------------- */ /* Loop over image in designated chunks. */ /* -------------------------------------------------------------------- */ int iY; for( iY = 0; iY < poDS->GetRasterYSize() && eErr == CE_None; iY += nYChunkSize ) { int nThisYChunkSize; nThisYChunkSize = nYChunkSize; if( nThisYChunkSize + iY > poDS->GetRasterYSize() ) nThisYChunkSize = poDS->GetRasterYSize() - iY; // Only re-read image if not a single chunk is being rendered if ( nYChunkSize < poDS->GetRasterYSize() ) { 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; } double *padfAttrValues = (double *) VSIMalloc(sizeof(double) * nBandCount); while( (poFeat = poLayer->GetNextFeature()) != NULL ) { OGRGeometry *poGeom = poFeat->GetGeometryRef(); if ( pszBurnAttribute ) { int iBand; double dfAttrValue; dfAttrValue = poFeat->GetFieldAsDouble( iBurnField ); for (iBand = 0 ; iBand < nBandCount ; iBand++) padfAttrValues[iBand] = dfAttrValue; padfBurnValues = padfAttrValues; } gv_rasterize_one_shape( pabyChunkBuf, iY, poDS->GetRasterXSize(), nThisYChunkSize, nBandCount, eType, bAllTouched, poGeom, padfBurnValues, eBurnValueSource, pfnTransformer, pTransformArg ); delete poFeat; } VSIFree( padfAttrValues ); // Only write image if not a single chunk is being rendered if ( nYChunkSize < poDS->GetRasterYSize() ) { eErr = poDS->RasterIO( GF_Write, 0, iY, poDS->GetRasterXSize(), nThisYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nThisYChunkSize, eType, nBandCount, panBandList, 0, 0, 0 ); } poLayer->ResetReading(); if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()), "", pProgressArg) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } if ( bNeedToFreeTransformer ) { GDALDestroyTransformer( pTransformArg ); pTransformArg = NULL; pfnTransformer = NULL; } } /* -------------------------------------------------------------------- */ /* Write out the image once for all layers if user requested */ /* to render the whole raster in single chunk. */ /* -------------------------------------------------------------------- */ if ( nYChunkSize == poDS->GetRasterYSize() ) { poDS->RasterIO( GF_Write, 0, 0, poDS->GetRasterXSize(), nYChunkSize, pabyChunkBuf, poDS->GetRasterXSize(), nYChunkSize, eType, nBandCount, panBandList, 0, 0, 0 ); } /* -------------------------------------------------------------------- */ /* cleanup */ /* -------------------------------------------------------------------- */ VSIFree( pabyChunkBuf ); return eErr; }
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_Float32; 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; }