static int msContourLayerReadRaster(layerObj *layer, rectObj rect) { mapObj *map = layer->map; char **bands; char pointer[64], memDSPointer[128]; int band = 1; double adfGeoTransform[6], adfInvGeoTransform[6]; double llx, lly, urx, ury; rectObj copyRect, mapRect; int dst_xsize, dst_ysize; int virtual_grid_step_x, virtual_grid_step_y; int src_xoff, src_yoff, src_xsize, src_ysize; double map_cellsize_x, map_cellsize_y, dst_cellsize_x, dst_cellsize_y; GDALRasterBandH hBand = NULL; CPLErr eErr; contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; if (layer->debug) msDebug("Entering msContourLayerReadRaster().\n"); if (clinfo == NULL || clinfo->hOrigDS == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", "msContourLayerReadRaster()"); return MS_FAILURE; } bands = CSLTokenizeStringComplex( CSLFetchNameValue(layer->processing,"BANDS"), " ,", FALSE, FALSE ); if (CSLCount(bands) > 0) { band = atoi(bands[0]); if (band < 1 || band > GDALGetRasterCount(clinfo->hOrigDS)) { msSetError( MS_IMGERR, "BANDS PROCESSING directive includes illegal band '%d', should be from 1 to %d.", "msContourLayerReadRaster()", band, GDALGetRasterCount(clinfo->hOrigDS)); CSLDestroy(bands); return MS_FAILURE; } } CSLDestroy(bands); hBand = GDALGetRasterBand(clinfo->hOrigDS, band); if (hBand == NULL) { msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerReadRaster()", band); return MS_FAILURE; } if (layer->projection.numargs > 0 && EQUAL(layer->projection.args[0], "auto")) { const char *wkt; wkt = GDALGetProjectionRef(clinfo->hOrigDS); if (wkt != NULL && strlen(wkt) > 0) { if (msOGCWKT2ProjectionObj(wkt, &(layer->projection), layer->debug) != MS_SUCCESS) { char msg[MESSAGELENGTH*2]; errorObj *ms_error = msGetErrorObj(); snprintf( msg, sizeof(msg), "%s\n" "PROJECTION AUTO cannot be used for this " "GDAL raster (`%s').", ms_error->message, layer->data); msg[MESSAGELENGTH-1] = '\0'; msSetError(MS_OGRERR, "%s","msDrawRasterLayer()", msg); return MS_FAILURE; } } } /* * Compute the georeferenced window of overlap, and read the source data * downsampled to match output resolution, or at full resolution if * output resolution is lower than the source resolution. * * A large portion of this overlap calculation code was borrowed from * msDrawRasterLayerGDAL(). * Would be possible to move some of this to a reusable function? * * Note: This code works only if no reprojection is involved. It would * need rework to support cases where output projection differs from source * data file projection. */ src_xsize = GDALGetRasterXSize(clinfo->hOrigDS); src_ysize = GDALGetRasterYSize(clinfo->hOrigDS); /* set the Dataset extent */ msGetGDALGeoTransform(clinfo->hOrigDS, map, layer, adfGeoTransform); clinfo->extent.minx = adfGeoTransform[0]; clinfo->extent.maxy = adfGeoTransform[3]; clinfo->extent.maxx = adfGeoTransform[0] + src_xsize * adfGeoTransform[1]; clinfo->extent.miny = adfGeoTransform[3] + src_ysize * adfGeoTransform[5]; if (layer->transform) { if (layer->debug) msDebug("msContourLayerReadRaster(): Entering transform.\n"); InvGeoTransform(adfGeoTransform, adfInvGeoTransform); mapRect = rect; map_cellsize_x = map_cellsize_y = map->cellsize; #ifdef USE_PROJ /* if necessary, project the searchrect to source coords */ if (msProjectionsDiffer( &(map->projection), &(layer->projection))) { if ( msProjectRect(&map->projection, &layer->projection, &mapRect) != MS_SUCCESS ) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CELLSIZE(mapRect.minx, mapRect.maxx, map->width); map_cellsize_y = MS_CELLSIZE(mapRect.miny, mapRect.maxy, map->height); /* if the projection failed to project the extent requested, we need to calculate the cellsize to preserve the initial map cellsize ratio */ if ( (mapRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) || (mapRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) || (mapRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) || (mapRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) ) { int src_unit, dst_unit; src_unit = GetMapserverUnitUsingProj(&map->projection); dst_unit = GetMapserverUnitUsingProj(&layer->projection); if (src_unit == -1 || dst_unit == -1) { msDebug("msContourLayerReadRaster(%s): unable to reproject map request rectangle into layer projection, canceling.\n", layer->name); return MS_FAILURE; } map_cellsize_x = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.minx, rect.maxx, map->width)); map_cellsize_y = MS_CONVERT_UNIT(src_unit, dst_unit, MS_CELLSIZE(rect.miny, rect.maxy, map->height)); } } #endif if (map_cellsize_x == 0 || map_cellsize_y == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): Cellsize can't be 0.\n"); return MS_FAILURE; } /* Adjust MapServer pixel model to GDAL pixel model */ mapRect.minx -= map_cellsize_x*0.5; mapRect.maxx += map_cellsize_x*0.5; mapRect.miny -= map_cellsize_y*0.5; mapRect.maxy += map_cellsize_y*0.5; /* * If raw data cellsize (from geotransform) is larger than output map_cellsize * then we want to extract only enough data to match the output map resolution * which means that GDAL will automatically sample the data on read. * * To prevent bad contour effects on tile edges, we adjust the target cellsize * to align the extracted window with a virtual grid based on the origin of the * raw data and a virtual grid step size corresponding to an integer sampling step. * * If source data has a greater cellsize (i.e. lower res) that requested ouptut map * then we use the raw data cellsize as target cellsize since there is no point in * interpolating the data for contours in this case. */ virtual_grid_step_x = (int)floor(map_cellsize_x / ABS(adfGeoTransform[1])); if (virtual_grid_step_x < 1) virtual_grid_step_x = 1; /* Do not interpolate data if grid sampling step < 1 */ virtual_grid_step_y = (int)floor(map_cellsize_y / ABS(adfGeoTransform[5])); if (virtual_grid_step_y < 1) virtual_grid_step_y = 1; /* Do not interpolate data if grid sampling step < 1 */ /* target cellsize is a multiple of raw data cellsize based on grid step*/ dst_cellsize_x = ABS(adfGeoTransform[1]) * virtual_grid_step_x; dst_cellsize_y = ABS(adfGeoTransform[5]) * virtual_grid_step_y; /* Compute overlap between source and target views */ copyRect = mapRect; if (copyRect.minx < GEO_TRANS(adfGeoTransform,0,src_ysize)) copyRect.minx = GEO_TRANS(adfGeoTransform,0,src_ysize); if (copyRect.maxx > GEO_TRANS(adfGeoTransform,src_xsize,0)) copyRect.maxx = GEO_TRANS(adfGeoTransform,src_xsize,0); if (copyRect.miny < GEO_TRANS(adfGeoTransform+3,0,src_ysize)) copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_ysize); if (copyRect.maxy > GEO_TRANS(adfGeoTransform+3,src_xsize,0)) copyRect.maxy = GEO_TRANS(adfGeoTransform+3,src_xsize,0); if (copyRect.minx >= copyRect.maxx || copyRect.miny >= copyRect.maxy) { if (layer->debug) msDebug("msContourLayerReadRaster(): No overlap.\n"); return MS_SUCCESS; } /* * Convert extraction window to raster coordinates */ llx = GEO_TRANS(adfInvGeoTransform+0,copyRect.minx,copyRect.miny); lly = GEO_TRANS(adfInvGeoTransform+3,copyRect.minx,copyRect.miny); urx = GEO_TRANS(adfInvGeoTransform+0,copyRect.maxx,copyRect.maxy); ury = GEO_TRANS(adfInvGeoTransform+3,copyRect.maxx,copyRect.maxy); /* * Align extraction window with virtual grid * (keep in mind raster coordinates origin is at upper-left) * We also add an extra buffer to fix tile boundarie issues when zoomed */ llx = floor(llx / virtual_grid_step_x) * virtual_grid_step_x - (virtual_grid_step_x*5); urx = ceil(urx / virtual_grid_step_x) * virtual_grid_step_x + (virtual_grid_step_x*5); ury = floor(ury / virtual_grid_step_y) * virtual_grid_step_y - (virtual_grid_step_x*5); lly = ceil(lly / virtual_grid_step_y) * virtual_grid_step_y + (virtual_grid_step_x*5); src_xoff = MS_MAX(0,(int) floor(llx+0.5)); src_yoff = MS_MAX(0,(int) floor(ury+0.5)); src_xsize = MS_MIN(MS_MAX(0,(int) (urx - llx + 0.5)), GDALGetRasterXSize(clinfo->hOrigDS) - src_xoff); src_ysize = MS_MIN(MS_MAX(0,(int) (lly - ury + 0.5)), GDALGetRasterYSize(clinfo->hOrigDS) - src_yoff); /* Update the geographic extent (buffer added) */ /* TODO: a better way to go the geo_trans */ copyRect.minx = GEO_TRANS(adfGeoTransform+0,src_xoff,0); copyRect.maxx = GEO_TRANS(adfGeoTransform+0,src_xoff+src_xsize,0); copyRect.miny = GEO_TRANS(adfGeoTransform+3,0,src_yoff+src_ysize); copyRect.maxy = GEO_TRANS(adfGeoTransform+3,0,src_yoff); /* * If input window is to small then stop here */ if (src_xsize < 2 || src_ysize < 2) { if (layer->debug) msDebug("msContourLayerReadRaster(): input window too small, or no apparent overlap between map view and this window(1).\n"); return MS_SUCCESS; } /* Target buffer size */ dst_xsize = (int)ceil((copyRect.maxx - copyRect.minx) / dst_cellsize_x); dst_ysize = (int)ceil((copyRect.maxy - copyRect.miny) / dst_cellsize_y); if (dst_xsize == 0 || dst_ysize == 0) { if (layer->debug) msDebug("msContourLayerReadRaster(): no apparent overlap between map view and this window(2).\n"); return MS_SUCCESS; } if (layer->debug) msDebug( "msContourLayerReadRaster(): src=%d,%d,%d,%d, dst=%d,%d,%d,%d\n", src_xoff, src_yoff, src_xsize, src_ysize, 0, 0, dst_xsize, dst_ysize ); } else { src_xoff = 0; src_yoff = 0; dst_xsize = src_xsize = MS_MIN(map->width,src_xsize); dst_ysize = src_ysize = MS_MIN(map->height,src_ysize); copyRect.minx = copyRect.miny = 0; copyRect.maxx = map->width; copyRect.maxy = map->height; dst_cellsize_y = dst_cellsize_x = 1; } /* -------------------------------------------------------------------- */ /* Allocate buffer, and read data into it. */ /* -------------------------------------------------------------------- */ clinfo->buffer = (double *) malloc(sizeof(double) * dst_xsize * dst_ysize); if (clinfo->buffer == NULL) { msSetError(MS_MEMERR, "Malloc(): Out of memory.", "msContourLayerReadRaster()"); return MS_FAILURE; } eErr = GDALRasterIO(hBand, GF_Read, src_xoff, src_yoff, src_xsize, src_ysize, clinfo->buffer, dst_xsize, dst_ysize, GDT_Float64, 0, 0); if (eErr != CE_None) { msSetError( MS_IOERR, "GDALRasterIO() failed: %s", "msContourLayerReadRaster()", CPLGetLastErrorMsg() ); free(clinfo->buffer); return MS_FAILURE; } memset(pointer, 0, sizeof(pointer)); CPLPrintPointer(pointer, clinfo->buffer, sizeof(pointer)); sprintf(memDSPointer,"MEM:::DATAPOINTER=%s,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=Float64", pointer, dst_xsize, dst_ysize); clinfo->hDS = GDALOpen(memDSPointer, GA_ReadOnly); if (clinfo->hDS == NULL) { msSetError(MS_IMGERR, "Unable to open GDAL Memory dataset.", "msContourLayerReadRaster()"); free(clinfo->buffer); return MS_FAILURE; } adfGeoTransform[0] = copyRect.minx; adfGeoTransform[1] = dst_cellsize_x; adfGeoTransform[2] = 0; adfGeoTransform[3] = copyRect.maxy; adfGeoTransform[4] = 0; adfGeoTransform[5] = -dst_cellsize_y; clinfo->cellsize = MS_MAX(dst_cellsize_x, dst_cellsize_y); { char buf[64]; sprintf(buf, "%lf", clinfo->cellsize); msInsertHashTable(&layer->metadata, "__data_cellsize__", buf); } GDALSetGeoTransform(clinfo->hDS, adfGeoTransform); return MS_SUCCESS; }
char **CPL_STDCALL GDALLoadRPCFile( const char *pszFilename, char **papszSiblingFiles ) { /* -------------------------------------------------------------------- */ /* Try to identify the RPC file in upper or lower case. */ /* -------------------------------------------------------------------- */ CPLString osTarget; /* Is this already a _RPC.TXT file ? */ if (strlen(pszFilename) > 8 && EQUAL(pszFilename + strlen(pszFilename) - 8, "_RPC.TXT")) osTarget = pszFilename; else { CPLString osSrcPath = pszFilename; CPLString soPt("."); size_t found = osSrcPath.rfind(soPt); if (found == CPLString::npos) return NULL; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.txt"); CPLString osTarget = osSrcPath; if( papszSiblingFiles == NULL ) { VSIStatBufL sStatBuf; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_RPC.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osSrcPath = pszFilename; osSrcPath.replace (found, osSrcPath.size() - found, "_rpc.TXT"); osTarget = osSrcPath; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { return NULL; } } } } else { int iSibling = CSLFindString( papszSiblingFiles, CPLGetFilename(osTarget) ); if( iSibling < 0 ) return NULL; osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling])); osTarget += papszSiblingFiles[iSibling]; } } /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ char **papszLines = CSLLoad2( osTarget, 100, 100, NULL ); if(!papszLines) return NULL; char **papszMD = NULL; /* From LINE_OFF to HEIGHT_SCALE */ for(size_t i = 0; i < 19; i += 2 ) { const char *pszRPBVal = CSLFetchNameValue(papszLines, apszRPBMap[i] ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), apszRPBMap[i]); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], pszRPBVal ); } } /* For LINE_NUM_COEFF, LINE_DEN_COEFF, SAMP_NUM_COEFF, SAMP_DEN_COEFF */ /* parameters that have 20 values each */ for(size_t i = 20; apszRPBMap[i] != NULL; i += 2 ) { CPLString soVal; for(int j = 1; j <= 20; j++) { CPLString soRPBMapItem; soRPBMapItem.Printf("%s_%d", apszRPBMap[i], j); const char *pszRPBVal = CSLFetchNameValue(papszLines, soRPBMapItem.c_str() ); if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s file found, but missing %s field (and possibly others).", osTarget.c_str(), soRPBMapItem.c_str() ); CSLDestroy( papszMD ); CSLDestroy( papszLines ); return NULL; } else { soVal += pszRPBVal; soVal += " "; } } papszMD = CSLSetNameValue( papszMD, apszRPBMap[i], soVal.c_str() ); } CSLDestroy( papszLines ); return papszMD; }
static int GDAL_IMD_AA2R( char ***ppapszIMD ) { char **papszIMD = *ppapszIMD; /* -------------------------------------------------------------------- */ /* Verify that we have a new format file. */ /* -------------------------------------------------------------------- */ const char *pszValue = CSLFetchNameValue( papszIMD, "version" ); if( pszValue == NULL ) return FALSE; if( EQUAL(pszValue,"\"R\"") ) return TRUE; if( !EQUAL(pszValue,"\"AA\"") ) { CPLDebug( "IMD", "The file is not the expected 'version = \"AA\"' format.\nProceeding, but file may be corrupted." ); } /* -------------------------------------------------------------------- */ /* Fix the version line. */ /* -------------------------------------------------------------------- */ papszIMD = CSLSetNameValue( papszIMD, "version", "\"R\"" ); /* -------------------------------------------------------------------- */ /* remove a bunch of fields. */ /* -------------------------------------------------------------------- */ int iKey; static const char *apszToRemove[] = { "productCatalogId", "childCatalogId", "productType", "numberOfLooks", "effectiveBandwidth", "mode", "scanDirection", "cloudCover", "productGSD", NULL }; for( iKey = 0; apszToRemove[iKey] != NULL; iKey++ ) { int iTarget = CSLFindName( papszIMD, apszToRemove[iKey] ); if( iTarget != -1 ) papszIMD = CSLRemoveStrings( papszIMD, iTarget, 1, NULL ); } /* -------------------------------------------------------------------- */ /* Replace various min/mean/max with just the mean. */ /* -------------------------------------------------------------------- */ static const char *keylist[] = { "CollectedRowGSD", "CollectedColGSD", "SunAz", "SunEl", "SatAz", "SatEl", "InTrackViewAngle", "CrossTrackViewAngle", "OffNadirViewAngle", NULL }; for( iKey = 0; keylist[iKey] != NULL; iKey++ ) { CPLString osTarget; int iTarget; osTarget.Printf( "IMAGE_1.min%s", keylist[iKey] ); iTarget = CSLFindName( papszIMD, osTarget ); if( iTarget != -1 ) papszIMD = CSLRemoveStrings( papszIMD, iTarget, 1, NULL ); osTarget.Printf( "IMAGE_1.max%s", keylist[iKey] ); iTarget = CSLFindName( papszIMD, osTarget ); if( iTarget != -1 ) papszIMD = CSLRemoveStrings( papszIMD, iTarget, 1, NULL ); osTarget.Printf( "IMAGE_1.mean%s", keylist[iKey] ); iTarget = CSLFindName( papszIMD, osTarget ); if( iTarget != -1 ) { CPLString osValue = CSLFetchNameValue( papszIMD, osTarget ); CPLString osLine; osTarget.Printf( "IMAGE_1.%c%s", tolower(keylist[iKey][0]), keylist[iKey]+1 ); osLine = osTarget + "=" + osValue; CPLFree( papszIMD[iTarget] ); papszIMD[iTarget] = CPLStrdup(osLine); } } *ppapszIMD = papszIMD; return TRUE; }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return nullptr; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return nullptr; } const int nBands = poSrcDS->GetRasterCount(); if( nBands != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 && nBands != 4 #endif ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 "or 4 (RGBA) " #endif "bands.", nBands ); return nullptr; } const GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return nullptr; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != nullptr ) { fQuality = static_cast<float>( CPLAtof(pszQUALITY) ); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return nullptr; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef( papszOptions, "PRESET", "DEFAULT" ); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return nullptr; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return nullptr; } // TODO: Get rid of this macro in a reasonable way. #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != nullptr) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return nullptr; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX-1); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = static_cast<float>(CPLAtof(pszPSNR)); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return nullptr; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); #if WEBP_ENCODER_ABI_VERSION >= 0x0002 FETCH_AND_SET_OPTION_INT("PARTITION_LIMIT", partition_limit, 0, 100); #endif #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sConfig.lossless = CPLFetchBool(papszOptions, "LOSSLESS", false); if (sConfig.lossless) sPicture.use_argb = 1; #endif if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return nullptr; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer = reinterpret_cast<GByte *>( VSIMalloc( nBands * nXSize * nYSize ) ); if (pabyBuffer == nullptr) { return nullptr; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == nullptr ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return nullptr; } WebPUserData sUserData; sUserData.fp = fpImage; sUserData.pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress; sUserData.pProgressData = pProgressData; /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = &sUserData; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sPicture.progress_hook = WEBPDatasetProgressHook; #endif if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return nullptr; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, nBands, nullptr, nBands, nBands * nXSize, 1, nullptr ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ #if WEBP_ENCODER_ABI_VERSION >= 0x0100 if (eErr == CE_None && nBands == 4) { if (!WebPPictureImportRGBA(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError( CE_Failure, CPLE_AppDefined, "WebPPictureImportRGBA() failed" ); eErr = CE_Failure; } } else #endif if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { #if WEBP_ENCODER_ABI_VERSION >= 0x0100 const char* pszErrorMsg = nullptr; switch(sPicture.error_code) { case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break; case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break; case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break; case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break; case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break; case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less " "SEGMENTS, or increase PARTITION_LIMIT value"; break; case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break; case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while flushing bytes"; break; case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break; case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; default: CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode returned an unknown error code: %d", sPicture.error_code); pszErrorMsg = "Unknown WebP error type."; break; } CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed : %s", pszErrorMsg); #else CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); #endif eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return nullptr; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If writing to stdout, we can't reopen it, so return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = reinterpret_cast<WEBPDataset*>( WEBPDataset::Open( &oOpenInfo ) ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return nullptr; }
OGRLayer * OGRMySQLDataSource::ICreateLayer( const char * pszLayerNameIn, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { MYSQL_RES *hResult=NULL; CPLString osCommand; const char *pszGeometryType; const char *pszGeomColumnName; const char *pszExpectedFIDName; char *pszLayerName; // int nDimension = 3; // MySQL only supports 2d currently /* -------------------------------------------------------------------- */ /* Make sure there isn't an active transaction already. */ /* -------------------------------------------------------------------- */ InterruptLongResult(); if( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ) pszLayerName = LaunderName( pszLayerNameIn ); else pszLayerName = CPLStrdup( pszLayerNameIn ); // if( wkbFlatten(eType) == eType ) // nDimension = 2; CPLDebug("MYSQL","Creating layer %s.", pszLayerName); /* -------------------------------------------------------------------- */ /* Do we already have this layer? If so, should we blow it */ /* away? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { if( CSLFetchNameValue( papszOptions, "OVERWRITE" ) != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"OVERWRITE"),"NO") ) { DeleteLayer( iLayer ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n" "Use the layer creation option OVERWRITE=YES to " "replace it.", pszLayerName ); CPLFree( pszLayerName ); return NULL; } } } pszGeomColumnName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME" ); if (!pszGeomColumnName) pszGeomColumnName="SHAPE"; pszExpectedFIDName = CSLFetchNameValue( papszOptions, "FID" ); if (!pszExpectedFIDName) pszExpectedFIDName = CSLFetchNameValue( papszOptions, "MYSQL_FID" ); if (!pszExpectedFIDName) pszExpectedFIDName="OGR_FID"; int bFID64 = CSLFetchBoolean(papszOptions, "FID64", FALSE); const char* pszFIDType = bFID64 ? "BIGINT": "INT"; CPLDebug("MYSQL","Geometry Column Name %s.", pszGeomColumnName); CPLDebug("MYSQL","FID Column Name %s.", pszExpectedFIDName); if( wkbFlatten(eType) == wkbNone ) { osCommand.Printf( "CREATE TABLE `%s` ( " " %s %s UNIQUE NOT NULL AUTO_INCREMENT )", pszLayerName, pszExpectedFIDName, pszFIDType ); } else { osCommand.Printf( "CREATE TABLE `%s` ( " " %s %s UNIQUE NOT NULL AUTO_INCREMENT, " " %s GEOMETRY NOT NULL )", pszLayerName, pszExpectedFIDName, pszFIDType, pszGeomColumnName ); } if( CSLFetchNameValue( papszOptions, "ENGINE" ) != NULL ) { osCommand += " ENGINE = "; osCommand += CSLFetchNameValue( papszOptions, "ENGINE" ); } if( !mysql_query(GetConn(), osCommand ) ) { if( mysql_field_count( GetConn() ) == 0 ) CPLDebug("MYSQL","Created table %s.", pszLayerName); else { ReportError( osCommand ); return NULL; } } else { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; // Calling this does no harm InitializeMetadataTables(); /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ int nSRSId = -1; if( poSRS != NULL ) nSRSId = FetchSRSId( poSRS ); /* -------------------------------------------------------------------- */ /* Sometimes there is an old crufty entry in the geometry_columns */ /* table if things were not properly cleaned up before. We make */ /* an effort to clean out such cruft. */ /* */ /* -------------------------------------------------------------------- */ osCommand.Printf( "DELETE FROM geometry_columns WHERE f_table_name = '%s'", pszLayerName ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; /* -------------------------------------------------------------------- */ /* Attempt to add this table to the geometry_columns table, if */ /* it is a spatial layer. */ /* -------------------------------------------------------------------- */ if( eType != wkbNone ) { int nCoordDimension; if( eType == wkbFlatten(eType) ) nCoordDimension = 2; else nCoordDimension = 3; pszGeometryType = OGRToOGCGeomType(eType); if( nSRSId == -1 ) osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " TYPE) values " " ('%s', '%s', %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, pszGeometryType ); else osCommand.Printf( "INSERT INTO geometry_columns " " (F_TABLE_NAME, " " F_GEOMETRY_COLUMN, " " COORD_DIMENSION, " " SRID, " " TYPE) values " " ('%s', '%s', %d, %d, '%s')", pszLayerName, pszGeomColumnName, nCoordDimension, nSRSId, pszGeometryType ); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; } /* -------------------------------------------------------------------- */ /* Create the spatial index. */ /* */ /* We're doing this before we add geometry and record to the table */ /* so this may not be exactly the best way to do it. */ /* -------------------------------------------------------------------- */ const char *pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" ); if( eType != wkbNone && (pszSI == NULL || CPLTestBool(pszSI)) ) { osCommand.Printf( "ALTER TABLE `%s` ADD SPATIAL INDEX(`%s`) ", pszLayerName, pszGeomColumnName); if( mysql_query(GetConn(), osCommand ) ) { ReportError( osCommand ); return NULL; } // make sure to attempt to free results of successful queries hResult = mysql_store_result( GetConn() ); if( hResult != NULL ) mysql_free_result( hResult ); hResult = NULL; } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRMySQLTableLayer *poLayer; OGRErr eErr; poLayer = new OGRMySQLTableLayer( this, pszLayerName, TRUE, nSRSId ); eErr = poLayer->Initialize(pszLayerName); if (eErr == OGRERR_FAILURE) return NULL; if( eType != wkbNone ) poLayer->GetLayerDefn()->GetGeomFieldDefn(0)->SetNullable(FALSE); poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRMySQLLayer **) CPLRealloc( papoLayers, sizeof(OGRMySQLLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszLayerName ); return poLayer; }
OGRLayer * OGRShapeDataSource::CreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { SHPHandle hSHP; DBFHandle hDBF; int nShapeType; /* -------------------------------------------------------------------- */ /* Verify we are in update mode. */ /* -------------------------------------------------------------------- */ if( !bDSUpdate ) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Data source %s opened read-only.\n" "New layer %s cannot be created.\n", pszName, pszLayerName ); return NULL; } /* -------------------------------------------------------------------- */ /* Figure out what type of layer we need. */ /* -------------------------------------------------------------------- */ if( eType == wkbUnknown || eType == wkbLineString ) nShapeType = SHPT_ARC; else if( eType == wkbPoint ) nShapeType = SHPT_POINT; else if( eType == wkbPolygon ) nShapeType = SHPT_POLYGON; else if( eType == wkbMultiPoint ) nShapeType = SHPT_MULTIPOINT; else if( eType == wkbPoint25D ) nShapeType = SHPT_POINTZ; else if( eType == wkbLineString25D ) nShapeType = SHPT_ARCZ; else if( eType == wkbMultiLineString ) nShapeType = SHPT_ARC; else if( eType == wkbMultiLineString25D ) nShapeType = SHPT_ARCZ; else if( eType == wkbPolygon25D ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbMultiPolygon ) nShapeType = SHPT_POLYGON; else if( eType == wkbMultiPolygon25D ) nShapeType = SHPT_POLYGONZ; else if( eType == wkbMultiPoint25D ) nShapeType = SHPT_MULTIPOINTZ; else if( eType == wkbNone ) nShapeType = SHPT_NULL; else nShapeType = -1; /* -------------------------------------------------------------------- */ /* Has the application overridden this with a special creation */ /* option? */ /* -------------------------------------------------------------------- */ const char *pszOverride = CSLFetchNameValue( papszOptions, "SHPT" ); if( pszOverride == NULL ) /* ignore */; else if( EQUAL(pszOverride,"POINT") ) { nShapeType = SHPT_POINT; eType = wkbPoint; } else if( EQUAL(pszOverride,"ARC") ) { nShapeType = SHPT_ARC; eType = wkbLineString; } else if( EQUAL(pszOverride,"POLYGON") ) { nShapeType = SHPT_POLYGON; eType = wkbPolygon; } else if( EQUAL(pszOverride,"MULTIPOINT") ) { nShapeType = SHPT_MULTIPOINT; eType = wkbMultiPoint; } else if( EQUAL(pszOverride,"POINTZ") ) { nShapeType = SHPT_POINTZ; eType = wkbPoint25D; } else if( EQUAL(pszOverride,"ARCZ") ) { nShapeType = SHPT_ARCZ; eType = wkbLineString25D; } else if( EQUAL(pszOverride,"POLYGONZ") ) { nShapeType = SHPT_POLYGONZ; eType = wkbPolygon25D; } else if( EQUAL(pszOverride,"MULTIPOINTZ") ) { nShapeType = SHPT_MULTIPOINTZ; eType = wkbMultiPoint25D; } else if( EQUAL(pszOverride,"NONE") ) { nShapeType = SHPT_NULL; } else { CPLError( CE_Failure, CPLE_NotSupported, "Unknown SHPT value of `%s' passed to Shapefile layer\n" "creation. Creation aborted.\n", pszOverride ); return NULL; } if( nShapeType == -1 ) { CPLError( CE_Failure, CPLE_NotSupported, "Geometry type of `%s' not supported in shapefiles.\n" "Type can be overridden with a layer creation option\n" "of SHPT=POINT/ARC/POLYGON/MULTIPOINT/POINTZ/ARCZ/POLYGONZ/MULTIPOINTZ.\n", OGRGeometryTypeToName(eType) ); return NULL; } /* -------------------------------------------------------------------- */ /* What filename do we use, excluding the extension? */ /* -------------------------------------------------------------------- */ char *pszBasename; if( bSingleNewFile && nLayers == 0 ) { char *pszPath = CPLStrdup(CPLGetPath(pszName)); char *pszFBasename = CPLStrdup(CPLGetBasename(pszName)); pszBasename = CPLStrdup(CPLFormFilename(pszPath, pszFBasename, NULL)); CPLFree( pszFBasename ); CPLFree( pszPath ); } else if( bSingleNewFile ) { char *pszPath = CPLStrdup(CPLGetPath(pszName)); pszBasename = CPLStrdup(CPLFormFilename(pszPath,pszLayerName,NULL)); CPLFree( pszPath ); } else pszBasename = CPLStrdup(CPLFormFilename(pszName,pszLayerName,NULL)); /* -------------------------------------------------------------------- */ /* Create the shapefile. */ /* -------------------------------------------------------------------- */ char *pszFilename; if( nShapeType != SHPT_NULL ) { pszFilename = CPLStrdup(CPLFormFilename( NULL, pszBasename, "shp" )); hSHP = SHPCreate( pszFilename, nShapeType ); if( hSHP == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open Shapefile `%s'.\n", pszFilename ); CPLFree( pszFilename ); CPLFree( pszBasename ); return NULL; } CPLFree( pszFilename ); } else hSHP = NULL; /* -------------------------------------------------------------------- */ /* Create a DBF file. */ /* -------------------------------------------------------------------- */ pszFilename = CPLStrdup(CPLFormFilename( NULL, pszBasename, "dbf" )); hDBF = DBFCreate( pszFilename ); if( hDBF == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open Shape DBF file `%s'.\n", pszFilename ); CPLFree( pszFilename ); CPLFree( pszBasename ); return NULL; } CPLFree( pszFilename ); /* -------------------------------------------------------------------- */ /* Create the .prj file, if required. */ /* -------------------------------------------------------------------- */ if( poSRS != NULL ) { char *pszWKT = NULL; CPLString osPrjFile = CPLFormFilename( NULL, pszBasename, "prj"); FILE *fp; /* the shape layer needs it's own copy */ poSRS = poSRS->Clone(); poSRS->morphToESRI(); if( poSRS->exportToWkt( &pszWKT ) == OGRERR_NONE && (fp = VSIFOpen( osPrjFile, "wt" )) != NULL ) { VSIFWrite( pszWKT, strlen(pszWKT), 1, fp ); VSIFClose( fp ); } CPLFree( pszWKT ); poSRS->morphFromESRI(); } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRShapeLayer *poLayer; poLayer = new OGRShapeLayer( pszBasename, hSHP, hDBF, poSRS, TRUE, eType ); poLayer->InitializeIndexSupport( pszBasename ); CPLFree( pszBasename ); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRShapeLayer **) CPLRealloc( papoLayers, sizeof(OGRShapeLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; return poLayer; }
int OGRGMLDataSource::Create( const char *pszFilename, char **papszOptions ) { if( fpOutput != NULL || poReader != NULL ) { CPLAssert( FALSE ); return FALSE; } /* -------------------------------------------------------------------- */ /* Create the output file. */ /* -------------------------------------------------------------------- */ pszName = CPLStrdup( pszFilename ); if( EQUAL(pszFilename,"stdout") ) fpOutput = stdout; else fpOutput = VSIFOpen( pszFilename, "wt+" ); if( fpOutput == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create GML file %s.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Write out "standard" header. */ /* -------------------------------------------------------------------- */ VSIFPrintf( fpOutput, "%s", "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" ); nSchemaInsertLocation = VSIFTell( fpOutput ); VSIFPrintf( fpOutput, "%s", "<ogr:FeatureCollection\n" ); /* -------------------------------------------------------------------- */ /* Write out schema info if provided in creation options. */ /* -------------------------------------------------------------------- */ const char *pszSchemaURI = CSLFetchNameValue(papszOptions,"XSISCHEMAURI"); const char *pszSchemaOpt = CSLFetchNameValue( papszOptions, "XSISCHEMA" ); if( pszSchemaURI != NULL ) { VSIFPrintf( fpOutput, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xsi:schemaLocation=\"%s\"\n", CSLFetchNameValue( papszOptions, "XSISCHEMAURI" ) ); } else if( pszSchemaOpt == NULL || EQUAL(pszSchemaOpt,"EXTERNAL") ) { char *pszBasename = CPLStrdup(CPLGetBasename( pszName )); VSIFPrintf( fpOutput, " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xsi:schemaLocation=\"http://ogr.maptools.org/ %s\"\n", CPLResetExtension( pszBasename, "xsd" ) ); CPLFree( pszBasename ); } VSIFPrintf( fpOutput, "%s", " xmlns:ogr=\"http://ogr.maptools.org/\"\n" ); VSIFPrintf( fpOutput, "%s", " xmlns:gml=\"http://www.opengis.net/gml\">\n" ); /* -------------------------------------------------------------------- */ /* Should we initialize an area to place the boundedBy element? */ /* We will need to seek back to fill it in. */ /* -------------------------------------------------------------------- */ if( CSLFetchBoolean( papszOptions, "BOUNDEDBY", TRUE ) ) { nBoundedByLocation = VSIFTell( fpOutput ); if( nBoundedByLocation != -1 ) VSIFPrintf( fpOutput, "%280s\n", "" ); } else nBoundedByLocation = -1; return TRUE; }
int msUVRASTERLayerWhichShapes(layerObj *layer, rectObj rect, int isQuery) { uvRasterLayerInfo *uvlinfo = (uvRasterLayerInfo *) layer->layerinfo; imageObj *image_tmp; mapObj map_tmp; unsigned int spacing; int width, height, u_src_off, v_src_off, i, x, y; char **alteredProcessing = NULL; char **savedProcessing = NULL; if (layer->debug) msDebug("Entering msUVRASTERLayerWhichShapes().\n"); if( uvlinfo == NULL ) return MS_FAILURE; /* QUERY NOT SUPPORTED YET */ if (isQuery == MS_TRUE) { msSetError( MS_MISCERR, "Query is not supported for UV layer.", "msUVRASTERLayerWhichShapes()" ); return MS_FAILURE; } if( CSLFetchNameValue( layer->processing, "BANDS" ) == NULL ) { msSetError( MS_MISCERR, "BANDS processing option is required for UV layer. You have to specified 2 bands.", "msUVRASTERLayerWhichShapes()" ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Determine desired spacing. Default to 30 if not otherwise set */ /* -------------------------------------------------------------------- */ spacing = 30; if( CSLFetchNameValue( layer->processing, "UV_SPACING" ) != NULL ) { spacing = atoi(CSLFetchNameValue( layer->processing, "UV_SPACING" )); } width = (int)ceil(layer->map->width/spacing); height = (int)ceil(layer->map->height/spacing); map_tmp.cellsize = layer->map->cellsize*spacing; if (layer->debug) msDebug("msUVRASTERLayerWhichShapes(): width: %d, height: %d, cellsize: %g\n", width, height, map_tmp.cellsize); /* Initialize our dummy map */ MS_INIT_COLOR(map_tmp.imagecolor, 255,255,255,255); map_tmp.resolution = layer->map->resolution; map_tmp.defresolution = layer->map->defresolution; map_tmp.outputformat = (outputFormatObj *) msSmallCalloc(1,sizeof(outputFormatObj)); uvlinfo->band_count = map_tmp.outputformat->bands = 2; map_tmp.outputformat->name = NULL; map_tmp.outputformat->driver = NULL; map_tmp.outputformat->refcount = 0; map_tmp.outputformat->vtable = NULL; map_tmp.outputformat->device = NULL; map_tmp.outputformat->renderer = MS_RENDER_WITH_RAWDATA; map_tmp.outputformat->imagemode = MS_IMAGEMODE_FLOAT32; map_tmp.mappath = layer->map->mappath; map_tmp.shapepath = layer->map->shapepath; map_tmp.extent.minx = layer->map->extent.minx-(0.5*layer->map->cellsize)+(0.5*map_tmp.cellsize); map_tmp.extent.miny = layer->map->extent.miny-(0.5*layer->map->cellsize)+(0.5*map_tmp.cellsize); map_tmp.extent.maxx = map_tmp.extent.minx+((width-1)*map_tmp.cellsize); map_tmp.extent.maxy = map_tmp.extent.miny+((height-1)*map_tmp.cellsize); map_tmp.gt.rotation_angle = 0.0; msInitProjection(&map_tmp.projection); msCopyProjection(&map_tmp.projection, &layer->map->projection); if (layer->debug == 5) msDebug("msUVRASTERLayerWhichShapes(): extent: %g %d %g %g\n", map_tmp.extent.minx, map_tmp.extent.miny, map_tmp.extent.maxx, map_tmp.extent.maxy); /* important to use that function, to compute map geotransform, used by the resampling*/ msMapSetSize(&map_tmp, width, height); if (layer->debug == 5) msDebug("msUVRASTERLayerWhichShapes(): geotransform: %g %g %g %g %g %g\n", map_tmp.gt.geotransform[0], map_tmp.gt.geotransform[1], map_tmp.gt.geotransform[2], map_tmp.gt.geotransform[3], map_tmp.gt.geotransform[4], map_tmp.gt.geotransform[5]); uvlinfo->extent = map_tmp.extent; image_tmp = msImageCreate(width, height, map_tmp.outputformat, NULL, NULL, map_tmp.resolution, map_tmp.defresolution, &(map_tmp.imagecolor)); /* Default set to AVERAGE resampling */ if( CSLFetchNameValue( layer->processing, "RESAMPLE" ) == NULL ) { alteredProcessing = CSLDuplicate( layer->processing ); alteredProcessing = CSLSetNameValue( alteredProcessing, "RESAMPLE", "AVERAGE"); savedProcessing = layer->processing; layer->processing = alteredProcessing; } if (msDrawRasterLayerLow(&map_tmp, layer, image_tmp, NULL ) == MS_FAILURE) { msSetError(MS_MISCERR, "Unable to draw raster data.", NULL, "msUVRASTERLayerWhichShapes()" ); return MS_FAILURE; } /* restore the saved processing */ if (alteredProcessing != NULL) layer->processing = savedProcessing; /* free old query arrays */ if (uvlinfo->u) { for (i=0; i<uvlinfo->width; ++i) { free(uvlinfo->u[i]); } free(uvlinfo->u); } if (uvlinfo->v) { for (i=0; i<uvlinfo->height; ++i) { free(uvlinfo->v[i]); } free(uvlinfo->v); } /* Update our uv layer structure */ uvlinfo->width = width; uvlinfo->height = height; uvlinfo->query_results = width*height; uvlinfo->u = (float **)msSmallMalloc(sizeof(float *)*width); uvlinfo->v = (float **)msSmallMalloc(sizeof(float *)*width); for (x = 0; x < width; ++x) { uvlinfo->u[x] = (float *)msSmallMalloc(height * sizeof(float)); uvlinfo->v[x] = (float *)msSmallMalloc(height * sizeof(float)); for (y = 0; y < height; ++y) { u_src_off = v_src_off = x + y * width; v_src_off += width*height; uvlinfo->u[x][y] = image_tmp->img.raw_float[u_src_off]; uvlinfo->v[x][y] = image_tmp->img.raw_float[v_src_off]; /* null vector? update the number of results */ if (uvlinfo->u[x][y] == 0 && uvlinfo->v[x][y] == 0) --uvlinfo->query_results; } } msFreeImage(image_tmp); /* we do not need the imageObj anymore */ uvlinfo->which_rect = map_tmp.extent; uvlinfo->next_shape = 0; return MS_SUCCESS; }
GDALDataset *NDFDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* The user must select the header file (ie. .H1). */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 50 ) return NULL; if( !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=2",14) && !EQUALN((const char *)poOpenInfo->pabyHeader,"NDF_REVISION=0",14) ) return NULL; /* -------------------------------------------------------------------- */ /* Read and process the header into a local name/value */ /* stringlist. We just take off the trailing semicolon. The */ /* keyword is already seperated from the value by an equal */ /* sign. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fp == NULL) return NULL; const char *pszLine; const int nHeaderMax = 1000; int nHeaderLines = 0; char **papszHeader = (char **) CPLMalloc(sizeof(char *) * (nHeaderMax+1)); while( nHeaderLines < nHeaderMax && (pszLine = CPLReadLineL( fp )) != NULL && !EQUAL(pszLine,"END_OF_HDR;") ) { char *pszFixed; if( strstr(pszLine,"=") == NULL ) break; pszFixed = CPLStrdup( pszLine ); if( pszFixed[strlen(pszFixed)-1] == ';' ) pszFixed[strlen(pszFixed)-1] = '\0'; papszHeader[nHeaderLines++] = pszFixed; papszHeader[nHeaderLines] = NULL; } VSIFCloseL(fp); fp = NULL; if( CSLFetchNameValue( papszHeader, "PIXELS_PER_LINE" ) == NULL || CSLFetchNameValue( papszHeader, "LINES_PER_DATA_FILE" ) == NULL || CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL" ) == NULL || CSLFetchNameValue( papszHeader, "PIXEL_FORMAT" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Dataset appears to be NDF but is missing a required field."); CSLDestroy( papszHeader ); return NULL; } if( !EQUAL(CSLFetchNameValue( papszHeader, "PIXEL_FORMAT"), "BYTE" ) || !EQUAL(CSLFetchNameValue( papszHeader, "BITS_PER_PIXEL"),"8") ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently NDF driver supports only 8bit BYTE format." ); CSLDestroy( papszHeader ); return NULL; } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CSLDestroy( papszHeader ); CPLError( CE_Failure, CPLE_NotSupported, "The NDF driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ NDFDataset *poDS; poDS = new NDFDataset(); poDS->papszHeader = papszHeader; poDS->nRasterXSize = atoi(poDS->Get("PIXELS_PER_LINE","")); poDS->nRasterYSize = atoi(poDS->Get("LINES_PER_DATA_FILE","")); /* -------------------------------------------------------------------- */ /* Create a raw raster band for each file. */ /* -------------------------------------------------------------------- */ int iBand; const char* pszBand = CSLFetchNameValue(papszHeader, "NUMBER_OF_BANDS_IN_VOLUME"); if (pszBand == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find band count"); delete poDS; return NULL; } int nBands = atoi(pszBand); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBands, FALSE)) { delete poDS; return NULL; } for( iBand = 0; iBand < nBands; iBand++ ) { char szKey[100]; CPLString osFilename; sprintf( szKey, "BAND%d_FILENAME", iBand+1 ); osFilename = poDS->Get(szKey,""); // NDF1 file do not include the band filenames. if( osFilename.size() == 0 ) { char szBandExtension[15]; sprintf( szBandExtension, "I%d", iBand+1 ); osFilename = CPLResetExtension( poOpenInfo->pszFilename, szBandExtension ); } else { CPLString osBasePath = CPLGetPath(poOpenInfo->pszFilename); osFilename = CPLFormFilename( osBasePath, osFilename, NULL); } VSILFILE *fpRaw = VSIFOpenL( osFilename, "rb" ); if( fpRaw == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to open band file: %s", osFilename.c_str() ); delete poDS; return NULL; } poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, osFilename ); RawRasterBand *poBand = new RawRasterBand( poDS, iBand+1, fpRaw, 0, 1, poDS->nRasterXSize, GDT_Byte, TRUE, TRUE ); sprintf( szKey, "BAND%d_NAME", iBand+1 ); poBand->SetDescription( poDS->Get(szKey, "") ); sprintf( szKey, "BAND%d_WAVELENGTHS", iBand+1 ); poBand->SetMetadataItem( "WAVELENGTHS", poDS->Get(szKey,"") ); sprintf( szKey, "BAND%d_RADIOMETRIC_GAINS/BIAS", iBand+1 ); poBand->SetMetadataItem( "RADIOMETRIC_GAINS_BIAS", poDS->Get(szKey,"") ); poDS->SetBand( iBand+1, poBand ); } /* -------------------------------------------------------------------- */ /* Fetch and parse USGS projection parameters. */ /* -------------------------------------------------------------------- */ double adfUSGSParms[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; char **papszParmTokens = CSLTokenizeStringComplex( poDS->Get( "USGS_PROJECTION_NUMBER", "" ), ",", FALSE, TRUE ); if( CSLCount( papszParmTokens ) >= 15 ) { int i; for( i = 0; i < 15; i++ ) adfUSGSParms[i] = atof(papszParmTokens[i]); } CSLDestroy(papszParmTokens); papszParmTokens = NULL; /* -------------------------------------------------------------------- */ /* Minimal georef support ... should add full USGS style */ /* support at some point. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; int nUSGSProjection = atoi(poDS->Get( "USGS_PROJECTION_NUMBER", "" )); int nZone = atoi(poDS->Get("USGS_MAP_ZONE","0")); oSRS.importFromUSGS( nUSGSProjection, nZone, adfUSGSParms, 12 ); CPLString osDatum = poDS->Get( "HORIZONTAL_DATUM", "" ); if( EQUAL(osDatum,"WGS84") || EQUAL(osDatum,"NAD83") || EQUAL(osDatum,"NAD27") ) { oSRS.SetWellKnownGeogCS( osDatum ); } else if( EQUALN(osDatum,"NAD27",5) ) { oSRS.SetWellKnownGeogCS( "NAD27" ); } else { CPLError( CE_Warning, CPLE_AppDefined, "Unrecognised datum name in NLAPS/NDF file:%s, assuming WGS84.", osDatum.c_str() ); oSRS.SetWellKnownGeogCS( "WGS84" ); } if( oSRS.GetRoot() != NULL ) { CPLFree( poDS->pszProjection ); poDS->pszProjection = NULL; oSRS.exportToWkt( &(poDS->pszProjection) ); } /* -------------------------------------------------------------------- */ /* Get geotransform. */ /* -------------------------------------------------------------------- */ char **papszUL = CSLTokenizeString2( poDS->Get("UPPER_LEFT_CORNER",""), ",", 0 ); char **papszUR = CSLTokenizeString2( poDS->Get("UPPER_RIGHT_CORNER",""), ",", 0 ); char **papszLL = CSLTokenizeString2( poDS->Get("LOWER_LEFT_CORNER",""), ",", 0 ); if( CSLCount(papszUL) == 4 && CSLCount(papszUR) == 4 && CSLCount(papszLL) == 4 ) { poDS->adfGeoTransform[0] = atof(papszUL[2]); poDS->adfGeoTransform[1] = (atof(papszUR[2]) - atof(papszUL[2])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[2] = (atof(papszUR[3]) - atof(papszUL[3])) / (poDS->nRasterXSize-1); poDS->adfGeoTransform[3] = atof(papszUL[3]); poDS->adfGeoTransform[4] = (atof(papszLL[2]) - atof(papszUL[2])) / (poDS->nRasterYSize-1); poDS->adfGeoTransform[5] = (atof(papszLL[3]) - atof(papszUL[3])) / (poDS->nRasterYSize-1); // Move origin up-left half a pixel. poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[4] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[2] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5; } CSLDestroy( papszUL ); CSLDestroy( papszLL ); CSLDestroy( papszUR ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
void *GDALCreateTPSTransformerInt( int nGCPCount, const GDAL_GCP *pasGCPList, int bReversed, char** papszOptions ) { TPSTransformInfo *psInfo; int iGCP; /* -------------------------------------------------------------------- */ /* Allocate transform info. */ /* -------------------------------------------------------------------- */ psInfo = (TPSTransformInfo *) CPLCalloc(sizeof(TPSTransformInfo),1); psInfo->pasGCPList = GDALDuplicateGCPs( nGCPCount, pasGCPList ); psInfo->nGCPCount = nGCPCount; psInfo->bReversed = bReversed; psInfo->poForward = new VizGeorefSpline2D( 2 ); psInfo->poReverse = new VizGeorefSpline2D( 2 ); memcpy( psInfo->sTI.abySignature, GDAL_GTI2_SIGNATURE, strlen(GDAL_GTI2_SIGNATURE) ); psInfo->sTI.pszClassName = "GDALTPSTransformer"; psInfo->sTI.pfnTransform = GDALTPSTransform; psInfo->sTI.pfnCleanup = GDALDestroyTPSTransformer; psInfo->sTI.pfnSerialize = GDALSerializeTPSTransformer; psInfo->sTI.pfnCreateSimilar = GDALCreateSimilarTPSTransformer; /* -------------------------------------------------------------------- */ /* Attach all the points to the transformation. */ /* -------------------------------------------------------------------- */ std::map< std::pair<double, double>, int > oMapPixelLineToIdx; std::map< std::pair<double, double>, int > oMapXYToIdx; for( iGCP = 0; iGCP < nGCPCount; iGCP++ ) { double afPL[2], afXY[2]; afPL[0] = pasGCPList[iGCP].dfGCPPixel; afPL[1] = pasGCPList[iGCP].dfGCPLine; afXY[0] = pasGCPList[iGCP].dfGCPX; afXY[1] = pasGCPList[iGCP].dfGCPY; std::map< std::pair<double, double>, int >::iterator oIter; oIter = oMapPixelLineToIdx.find( std::pair<double,double>(afPL[0], afPL[1]) ); if( oIter != oMapPixelLineToIdx.end() ) { if( afXY[0] == pasGCPList[oIter->second].dfGCPX && afXY[1] == pasGCPList[oIter->second].dfGCPY ) { continue; } else { CPLError(CE_Warning, CPLE_AppDefined, "GCP %d and %d have same (pixel,line)=(%f,%f) but different (X,Y): (%f,%f) vs (%f,%f)", iGCP + 1, oIter->second, afPL[0], afPL[1], afXY[0], afXY[1], pasGCPList[oIter->second].dfGCPX, pasGCPList[oIter->second].dfGCPY); } } else { oMapPixelLineToIdx[ std::pair<double,double>(afPL[0], afPL[1]) ] = iGCP; } oIter = oMapXYToIdx.find( std::pair<double,double>(afXY[0], afXY[1]) ); if( oIter != oMapXYToIdx.end() ) { CPLError(CE_Warning, CPLE_AppDefined, "GCP %d and %d have same (x,y)=(%f,%f) but different (pixel,line): (%f,%f) vs (%f,%f)", iGCP + 1, oIter->second, afXY[0], afXY[1], afPL[0], afPL[1], pasGCPList[oIter->second].dfGCPPixel, pasGCPList[oIter->second].dfGCPLine); } else { oMapXYToIdx[ std::pair<double,double>(afXY[0], afXY[1]) ] = iGCP; } bool bOK = true; if( bReversed ) { bOK &= psInfo->poReverse->add_point( afPL[0], afPL[1], afXY ); bOK &= psInfo->poForward->add_point( afXY[0], afXY[1], afPL ); } else { bOK &= psInfo->poForward->add_point( afPL[0], afPL[1], afXY ); bOK &= psInfo->poReverse->add_point( afXY[0], afXY[1], afPL ); } if( !bOK ) { GDALDestroyTPSTransformer(psInfo); return NULL; } } psInfo->nRefCount = 1; int nThreads = 1; if( nGCPCount > 100 ) { const char* pszWarpThreads = CSLFetchNameValue(papszOptions, "NUM_THREADS"); if (pszWarpThreads == NULL) pszWarpThreads = CPLGetConfigOption("GDAL_NUM_THREADS", "1"); if (EQUAL(pszWarpThreads, "ALL_CPUS")) nThreads = CPLGetNumCPUs(); else nThreads = atoi(pszWarpThreads); } if( nThreads > 1 ) { /* Compute direct and reverse transforms in parallel */ CPLJoinableThread* hThread = CPLCreateJoinableThread(GDALTPSComputeForwardInThread, psInfo); psInfo->bReverseSolved = psInfo->poReverse->solve() != 0; if( hThread != NULL ) CPLJoinThread(hThread); else psInfo->bForwardSolved = psInfo->poForward->solve() != 0; } else { psInfo->bForwardSolved = psInfo->poForward->solve() != 0; psInfo->bReverseSolved = psInfo->poReverse->solve() != 0; } if( !psInfo->bForwardSolved || !psInfo->bReverseSolved ) { GDALDestroyTPSTransformer(psInfo); return NULL; } return psInfo; }
GDALDataset *ISIS2Dataset::Create(const char* pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char** papszParmList) { /* Verify settings. In Isis 2 core pixel values can be represented in * three different ways : 1, 2 4, or 8 Bytes */ if( eType != GDT_Byte && eType != GDT_Int16 && eType != GDT_Float32 && eType != GDT_UInt16 && eType != GDT_Float64 ){ CPLError(CE_Failure, CPLE_AppDefined, "The ISIS2 driver does not supporting creating files of type %s.", GDALGetDataTypeName( eType ) ); return nullptr; } /* (SAMPLE, LINE, BAND) - Band Sequential (BSQ) - default choice (SAMPLE, BAND, LINE) - Band Interleaved by Line (BIL) (BAND, SAMPLE, LINE) - Band Interleaved by Pixel (BIP) */ const char *pszInterleaving = "(SAMPLE,LINE,BAND)"; const char *pszInterleavingParam = CSLFetchNameValue( papszParmList, "INTERLEAVE" ); if ( pszInterleavingParam ) { if ( STARTS_WITH_CI(pszInterleavingParam, "bip") ) pszInterleaving = "(BAND,SAMPLE,LINE)"; else if ( STARTS_WITH_CI(pszInterleavingParam, "bil") ) pszInterleaving = "(SAMPLE,BAND,LINE)"; else pszInterleaving = "(SAMPLE,LINE,BAND)"; } /* default labeling method is attached */ bool bAttachedLabelingMethod = true; /* check if labeling method is set : check the all three first chars */ const char *pszLabelingMethod = CSLFetchNameValue( papszParmList, "LABELING_METHOD" ); if ( pszLabelingMethod ){ if ( STARTS_WITH_CI( pszLabelingMethod, "det" /* "detached" */ ) ){ bAttachedLabelingMethod = false; } if ( STARTS_WITH_CI( pszLabelingMethod, "att" /* attached" */ ) ){ bAttachedLabelingMethod = true; } } /* set the label and data files */ CPLString osLabelFile, osRasterFile, osOutFile; if( bAttachedLabelingMethod ) { osLabelFile = ""; osRasterFile = pszFilename; osOutFile = osRasterFile; } else { CPLString sExtension = "cub"; const char* pszExtension = CSLFetchNameValue( papszParmList, "IMAGE_EXTENSION" ); if( pszExtension ){ sExtension = pszExtension; } if( EQUAL(CPLGetExtension( pszFilename ), sExtension) ) { CPLError( CE_Failure, CPLE_AppDefined, "IMAGE_EXTENSION (%s) cannot match LABEL file extension.", sExtension.c_str() ); return nullptr; } osLabelFile = pszFilename; osRasterFile = CPLResetExtension( osLabelFile, sExtension ); osOutFile = osLabelFile; } const char *pszObject = CSLFetchNameValue( papszParmList, "OBJECT" ); CPLString sObject = "QUBE"; // default choice if (pszObject) { if ( EQUAL( pszObject, "IMAGE") ){ sObject = "IMAGE"; } if ( EQUAL( pszObject, "SPECTRAL_QUBE")){ sObject = "SPECTRAL_QUBE"; } } GUIntBig iRecords = ISIS2Dataset::RecordSizeCalculation(nXSize, nYSize, nBands, eType); GUIntBig iLabelRecords(2); CPLDebug("ISIS2","irecord = %i",static_cast<int>(iRecords)); if( bAttachedLabelingMethod ) { ISIS2Dataset::WriteLabel(osRasterFile, "", sObject, nXSize, nYSize, nBands, eType, iRecords, pszInterleaving, iLabelRecords, true); } else { ISIS2Dataset::WriteLabel(osLabelFile, osRasterFile, sObject, nXSize, nYSize, nBands, eType, iRecords, pszInterleaving, iLabelRecords); } if( !ISIS2Dataset::WriteRaster(osRasterFile, bAttachedLabelingMethod, iRecords, iLabelRecords, eType, pszInterleaving) ) return nullptr; return reinterpret_cast<GDALDataset *>( GDALOpen( osOutFile, GA_Update ) ); }
CPLErr VRTWarpedDataset::ProcessBlock( int iBlockX, int iBlockY ) { if( poWarper == NULL ) return CE_Failure; const GDALWarpOptions *psWO = poWarper->GetOptions(); /* -------------------------------------------------------------------- */ /* Allocate block of memory large enough to hold all the bands */ /* for this block. */ /* -------------------------------------------------------------------- */ int iBand; GByte *pabyDstBuffer; int nDstBufferSize; int nWordSize = (GDALGetDataTypeSize(psWO->eWorkingDataType) / 8); // FIXME? : risk of overflow in multiplication if nBlockXSize or nBlockYSize are very large nDstBufferSize = nBlockXSize * nBlockYSize * psWO->nBandCount * nWordSize; pabyDstBuffer = (GByte *) VSIMalloc(nDstBufferSize); if( pabyDstBuffer == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory allocating %d byte buffer in VRTWarpedDataset::ProcessBlock()", nDstBufferSize ); return CE_Failure; } memset( pabyDstBuffer, 0, nDstBufferSize ); /* -------------------------------------------------------------------- */ /* Process INIT_DEST option to initialize the buffer prior to */ /* warping into it. */ /* NOTE:The following code is 99% similar in gdalwarpoperation.cpp and */ /* vrtwarped.cpp. Be careful to keep it in sync ! */ /* -------------------------------------------------------------------- */ const char *pszInitDest = CSLFetchNameValue( psWO->papszWarpOptions, "INIT_DEST" ); if( pszInitDest != NULL && !EQUAL(pszInitDest, "") ) { char **papszInitValues = CSLTokenizeStringComplex( pszInitDest, ",", FALSE, FALSE ); int nInitCount = CSLCount(papszInitValues); for( iBand = 0; iBand < psWO->nBandCount; iBand++ ) { double adfInitRealImag[2]; GByte *pBandData; int nBandSize = nBlockXSize * nBlockYSize * nWordSize; const char *pszBandInit = papszInitValues[MIN(iBand,nInitCount-1)]; if( EQUAL(pszBandInit,"NO_DATA") && psWO->padfDstNoDataReal != NULL ) { adfInitRealImag[0] = psWO->padfDstNoDataReal[iBand]; adfInitRealImag[1] = psWO->padfDstNoDataImag[iBand]; } else { CPLStringToComplex( pszBandInit, adfInitRealImag + 0, adfInitRealImag + 1); } pBandData = ((GByte *) pabyDstBuffer) + iBand * nBandSize; if( psWO->eWorkingDataType == GDT_Byte ) memset( pBandData, MAX(0,MIN(255,(int)adfInitRealImag[0])), nBandSize); else if( adfInitRealImag[0] == 0.0 && adfInitRealImag[1] == 0 ) { memset( pBandData, 0, nBandSize ); } else if( adfInitRealImag[1] == 0.0 ) { GDALCopyWords( &adfInitRealImag, GDT_Float64, 0, pBandData,psWO->eWorkingDataType,nWordSize, nBlockXSize * nBlockYSize ); } else { GDALCopyWords( &adfInitRealImag, GDT_CFloat64, 0, pBandData,psWO->eWorkingDataType,nWordSize, nBlockXSize * nBlockYSize ); } } CSLDestroy( papszInitValues ); } /* -------------------------------------------------------------------- */ /* Warp into this buffer. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = poWarper->WarpRegionToBuffer( iBlockX * nBlockXSize, iBlockY * nBlockYSize, nBlockXSize, nBlockYSize, pabyDstBuffer, psWO->eWorkingDataType ); if( eErr != CE_None ) { VSIFree( pabyDstBuffer ); return eErr; } /* -------------------------------------------------------------------- */ /* Copy out into cache blocks for each band. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < psWO->nBandCount; iBand++ ) { GDALRasterBand *poBand; GDALRasterBlock *poBlock; poBand = GetRasterBand(iBand+1); poBlock = poBand->GetLockedBlockRef( iBlockX, iBlockY, TRUE ); CPLAssert( poBlock != NULL && poBlock->GetDataRef() != NULL ); GDALCopyWords( pabyDstBuffer + iBand*nBlockXSize*nBlockYSize*nWordSize, psWO->eWorkingDataType, nWordSize, poBlock->GetDataRef(), poBlock->GetDataType(), GDALGetDataTypeSize(poBlock->GetDataType())/8, nBlockXSize * nBlockYSize ); poBlock->DropLock(); } VSIFree( pabyDstBuffer ); return CE_None; }
OGRLayer * OGRCSVDataSource::ICreateLayer( const char *pszLayerName, OGRSpatialReference *poSpatialRef, OGRwkbGeometryType eGType, char ** papszOptions ) { /* -------------------------------------------------------------------- */ /* Verify we are in update mode. */ /* -------------------------------------------------------------------- */ if (!bUpdate) { CPLError( CE_Failure, CPLE_NoWriteAccess, "Data source %s opened read-only.\n" "New layer %s cannot be created.\n", pszName, pszLayerName ); return NULL; } /* -------------------------------------------------------------------- */ /* Verify that the datasource is a directory. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( strncmp(pszName, "/vsizip/", 8) == 0) { /* Do nothing */ } else if( !EQUAL(pszName, "/vsistdout/") && (VSIStatL( pszName, &sStatBuf ) != 0 || !VSI_ISDIR( sStatBuf.st_mode )) ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create csv layer (file) against a non-directory datasource." ); return NULL; } /* -------------------------------------------------------------------- */ /* What filename would we use? */ /* -------------------------------------------------------------------- */ CPLString osFilename; if( osDefaultCSVName != "" ) { osFilename = CPLFormFilename( pszName, osDefaultCSVName, NULL ); osDefaultCSVName = ""; } else { osFilename = CPLFormFilename( pszName, pszLayerName, "csv" ); } /* -------------------------------------------------------------------- */ /* Does this directory/file already exist? */ /* -------------------------------------------------------------------- */ if( VSIStatL( osFilename, &sStatBuf ) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create layer %s, but %s already exists.", pszLayerName, osFilename.c_str() ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the empty file. */ /* -------------------------------------------------------------------- */ const char *pszDelimiter = CSLFetchNameValue( papszOptions, "SEPARATOR"); char chDelimiter = ','; if (pszDelimiter != NULL) { if (EQUAL(pszDelimiter, "COMMA")) chDelimiter = ','; else if (EQUAL(pszDelimiter, "SEMICOLON")) chDelimiter = ';'; else if (EQUAL(pszDelimiter, "TAB")) chDelimiter = '\t'; else { CPLError( CE_Warning, CPLE_AppDefined, "SEPARATOR=%s not understood, use one of COMMA, SEMICOLON or TAB.", pszDelimiter ); } } /* -------------------------------------------------------------------- */ /* Create a layer. */ /* -------------------------------------------------------------------- */ nLayers++; papoLayers = (OGRCSVLayer **) CPLRealloc(papoLayers, sizeof(void*) * nLayers); papoLayers[nLayers-1] = new OGRCSVLayer( pszLayerName, NULL, osFilename, TRUE, TRUE, chDelimiter, NULL, NULL ); /* -------------------------------------------------------------------- */ /* Was a partiuclar CRLF order requested? */ /* -------------------------------------------------------------------- */ const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); int bUseCRLF; if( pszCRLFFormat == NULL ) { #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } else if( EQUAL(pszCRLFFormat,"CRLF") ) bUseCRLF = TRUE; else if( EQUAL(pszCRLFFormat,"LF") ) bUseCRLF = FALSE; else { CPLError( CE_Warning, CPLE_AppDefined, "LINEFORMAT=%s not understood, use one of CRLF or LF.", pszCRLFFormat ); #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } papoLayers[nLayers-1]->SetCRLF( bUseCRLF ); /* -------------------------------------------------------------------- */ /* Should we write the geometry ? */ /* -------------------------------------------------------------------- */ const char *pszGeometry = CSLFetchNameValue( papszOptions, "GEOMETRY"); if( bEnableGeometryFields ) { papoLayers[nLayers-1]->SetWriteGeometry(eGType, OGR_CSV_GEOM_AS_WKT); } else if (pszGeometry != NULL) { if (EQUAL(pszGeometry, "AS_WKT")) { papoLayers[nLayers-1]->SetWriteGeometry(eGType, OGR_CSV_GEOM_AS_WKT); } else if (EQUAL(pszGeometry, "AS_XYZ") || EQUAL(pszGeometry, "AS_XY") || EQUAL(pszGeometry, "AS_YX")) { if (eGType == wkbUnknown || wkbFlatten(eGType) == wkbPoint) { papoLayers[nLayers-1]->SetWriteGeometry(eGType, EQUAL(pszGeometry, "AS_XYZ") ? OGR_CSV_GEOM_AS_XYZ : EQUAL(pszGeometry, "AS_XY") ? OGR_CSV_GEOM_AS_XY : OGR_CSV_GEOM_AS_YX); } else { CPLError( CE_Warning, CPLE_AppDefined, "Geometry type %s is not compatible with GEOMETRY=AS_XYZ.", OGRGeometryTypeToName(eGType) ); } } else { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported value %s for creation option GEOMETRY", pszGeometry ); } } /* -------------------------------------------------------------------- */ /* Should we create a CSVT file ? */ /* -------------------------------------------------------------------- */ const char *pszCreateCSVT = CSLFetchNameValue( papszOptions, "CREATE_CSVT"); if (pszCreateCSVT) papoLayers[nLayers-1]->SetCreateCSVT(CSLTestBoolean(pszCreateCSVT)); /* -------------------------------------------------------------------- */ /* Should we write a UTF8 BOM ? */ /* -------------------------------------------------------------------- */ const char *pszWriteBOM = CSLFetchNameValue( papszOptions, "WRITE_BOM"); if (pszWriteBOM) papoLayers[nLayers-1]->SetWriteBOM(CSLTestBoolean(pszWriteBOM)); return papoLayers[nLayers-1]; }
static int msContourLayerGenerateContour(layerObj *layer) { OGRSFDriverH hDriver; OGRFieldDefnH hFld; OGRLayerH hLayer; const char *elevItem; char *option; double interval = 1.0, levels[1000]; int levelCount = 0; GDALRasterBandH hBand = NULL; CPLErr eErr; contourLayerInfo *clinfo = (contourLayerInfo *) layer->layerinfo; OGRRegisterAll(); if (clinfo == NULL) { msSetError(MS_MISCERR, "Assertion failed: Contour layer not opened!!!", "msContourLayerCreateOGRDataSource()"); return MS_FAILURE; } if (!clinfo->hDS) { /* no overlap */ return MS_SUCCESS; } hBand = GDALGetRasterBand(clinfo->hDS, 1); if (hBand == NULL) { msSetError(MS_IMGERR, "Band %d does not exist on dataset.", "msContourLayerGenerateContour()", 1); return MS_FAILURE; } /* Create the OGR DataSource */ hDriver = OGRGetDriverByName("Memory"); if (hDriver == NULL) { msSetError(MS_OGRERR, "Unable to get OGR driver 'Memory'.", "msContourLayerCreateOGRDataSource()"); return MS_FAILURE; } clinfo->hOGRDS = OGR_Dr_CreateDataSource(hDriver, "", NULL); if (clinfo->hOGRDS == NULL) { msSetError(MS_OGRERR, "Unable to create OGR DataSource.", "msContourLayerCreateOGRDataSource()"); return MS_FAILURE; } hLayer = OGR_DS_CreateLayer(clinfo->hOGRDS, clinfo->ogrLayer.name, NULL, wkbLineString, NULL ); hFld = OGR_Fld_Create("ID", OFTInteger); OGR_Fld_SetWidth(hFld, 8); OGR_L_CreateField(hLayer, hFld, FALSE); OGR_Fld_Destroy(hFld); /* Check if we have a coutour item specified */ elevItem = CSLFetchNameValue(layer->processing,"CONTOUR_ITEM"); if (elevItem && strlen(elevItem) > 0) { hFld = OGR_Fld_Create(elevItem, OFTReal); OGR_Fld_SetWidth(hFld, 12); OGR_Fld_SetPrecision(hFld, 3); OGR_L_CreateField(hLayer, hFld, FALSE); OGR_Fld_Destroy(hFld); } else { elevItem = NULL; } option = msContourGetOption(layer, "CONTOUR_INTERVAL"); if (option) { interval = atof(option); free(option); } option = msContourGetOption(layer, "CONTOUR_LEVELS"); if (option) { int i,c; char **levelsTmp; levelsTmp = CSLTokenizeStringComplex(option, ",", FALSE, FALSE); c = CSLCount(levelsTmp); for (i=0;i<c && i<(int)(sizeof(levels)/sizeof(double)) ;++i) levels[levelCount++] = atof(levelsTmp[i]); CSLDestroy(levelsTmp); free(option); } eErr = GDALContourGenerate( hBand, interval, 0.0, levelCount, levels, FALSE, 0.0, hLayer, OGR_FD_GetFieldIndex(OGR_L_GetLayerDefn( hLayer), "ID" ), (elevItem == NULL) ? -1 : OGR_FD_GetFieldIndex(OGR_L_GetLayerDefn( hLayer), elevItem ), NULL, NULL ); if (eErr != CE_None) { msSetError( MS_IOERR, "GDALContourGenerate() failed: %s", "msContourLayerGenerateContour()", CPLGetLastErrorMsg() ); return MS_FAILURE; } msConnPoolRegister(&clinfo->ogrLayer, clinfo->hOGRDS, msContourOGRCloseConnection); return MS_SUCCESS; }
int NITFDESExtractShapefile(NITFDES* psDES, const char* pszRadixFileName) { NITFSegmentInfo* psSegInfo; const char* apszExt[3]; int anOffset[4]; int iShpFile; char* pszFilename; if ( CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE_USE") == NULL ) return FALSE; psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment; apszExt[0] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_NAME"); anOffset[0] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_START")); apszExt[1] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_NAME"); anOffset[1] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_START")); apszExt[2] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_NAME"); anOffset[2] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_START")); anOffset[3] = (int) psSegInfo->nSegmentSize; for(iShpFile = 0; iShpFile < 3; iShpFile ++) { if (!EQUAL(apszExt[iShpFile], "SHP") && !EQUAL(apszExt[iShpFile], "SHX") && !EQUAL(apszExt[iShpFile], "DBF")) return FALSE; if (anOffset[iShpFile] < 0 || anOffset[iShpFile] >= anOffset[iShpFile+1]) return FALSE; } pszFilename = (char*) VSIMalloc(strlen(pszRadixFileName) + 4 + 1); if (pszFilename == NULL) return FALSE; for(iShpFile = 0; iShpFile < 3; iShpFile ++) { VSILFILE* fp; GByte* pabyBuffer; int nSize = anOffset[iShpFile+1] - anOffset[iShpFile]; pabyBuffer = (GByte*) VSIMalloc(nSize); if (pabyBuffer == NULL) { VSIFree(pszFilename); return FALSE; } VSIFSeekL(psDES->psFile->fp, psSegInfo->nSegmentStart + anOffset[iShpFile], SEEK_SET); if (VSIFReadL(pabyBuffer, 1, nSize, psDES->psFile->fp) != nSize) { VSIFree(pabyBuffer); VSIFree(pszFilename); return FALSE; } sprintf(pszFilename, "%s.%s", pszRadixFileName, apszExt[iShpFile]); fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) { VSIFree(pabyBuffer); VSIFree(pszFilename); return FALSE; } VSIFWriteL(pabyBuffer, 1, nSize, fp); VSIFCloseL(fp); VSIFree(pabyBuffer); } VSIFree(pszFilename); return TRUE; }
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"); double dfDPI = CPLAtof(CSLFetchNameValueDef(papszOptions, "DPI", "72")); if (dfDPI < 72.0) dfDPI = 72.0; 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"); int bWriteOGRAttributes = CSLFetchBoolean(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 == NULL ) { 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 = nWidth * dfRatio; } else { nHeight = 1024; nWidth = nHeight / dfRatio; } GDALDataset* poSrcDS = MEMDataset::Create( "MEM:::", nWidth, nHeight, 0, GDT_Byte, NULL ); 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 = NULL; poSRS->exportToWkt(&pszWKT); poSrcDS->SetProjection(pszWKT); CPLFree(pszWKT); } oWriter.SetInfo(poSrcDS, papszOptions); oWriter.StartPage(poSrcDS, dfDPI, 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; }
GDALDataset * ARGDataset::CreateCopy( const char * pszFilename, GDALDataset * poSrcDS, CPL_UNUSED int bStrict, CPL_UNUSED char ** papszOptions, CPL_UNUSED GDALProgressFunc pfnProgress, CPL_UNUSED void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); int nXBlockSize, nYBlockSize, nPixelOffset = 0; GDALDataType eType; CPLString osJSONFilename; CPLString pszDataType; json_object * poJSONObject = NULL; double adfTransform[6]; GDALRasterBand * poSrcBand = NULL; RawRasterBand * poDstBand = NULL; VSILFILE * fpImage = NULL; void * pabyData; OGRSpatialReference oSRS; char * pszWKT = NULL; char ** pszTokens = NULL; const char * pszLayer = NULL; int nSrs = 0; OGRErr nErr = OGRERR_NONE; CPLErr eErr; if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support %d bands. Must be 1 band.", nBands ); return NULL; } eType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eType == GDT_Unknown || eType == GDT_CInt16 || eType == GDT_CInt32 || eType == GDT_CFloat32 || eType == GDT_CFloat64 ) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver doesn't support data type %s.", GDALGetDataTypeName(eType) ); return NULL; } else if (eType == GDT_Int16) { pszDataType = "int16"; nPixelOffset = 2; } else if (eType == GDT_Int32) { pszDataType = "int32"; nPixelOffset = 4; } else if (eType == GDT_Byte) { pszDataType = "uint8"; nPixelOffset = 1; } else if (eType == GDT_UInt16) { pszDataType = "uint16"; nPixelOffset = 2; } else if (eType == GDT_UInt32) { pszDataType = "uint32"; nPixelOffset = 4; } else if (eType == GDT_Float32) { pszDataType = "float32"; nPixelOffset = 4; } else if (eType == GDT_Float64) { pszDataType = "float64"; nPixelOffset = 8; } poSrcDS->GetGeoTransform( adfTransform ); pszWKT = (char *)poSrcDS->GetProjectionRef(); nErr = oSRS.importFromWkt(&pszWKT); if (nErr != OGRERR_NONE) { CPLError( CE_Failure, CPLE_NotSupported, "Cannot import spatial reference WKT from source dataset."); return NULL; } if (oSRS.GetAuthorityCode("PROJCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("PROJCS")); } else if (oSRS.GetAuthorityCode("GEOGCS") != NULL) { nSrs = atoi(oSRS.GetAuthorityCode("GEOGCS")); } else { // could not determine projected or geographic code // default to EPSG:3857 if no code could be found nSrs = 3857; } /********************************************************************/ /* Create JSON companion file. */ /********************************************************************/ osJSONFilename = GetJsonFilename(pszFilename); poJSONObject = json_object_new_object(); pszTokens = poSrcDS->GetMetadata(); pszLayer = CSLFetchNameValue(pszTokens, "LAYER"); if ( pszLayer == NULL) { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( CPLGetBasename(osJSONFilename) )); } else { // Set the layer json_object_object_add(poJSONObject, "layer", json_object_new_string( pszLayer )); } // Set the type json_object_object_add(poJSONObject, "type", json_object_new_string("arg")); // Set the datatype json_object_object_add(poJSONObject, "datatype", json_object_new_string(pszDataType)); // Set the number of rows json_object_object_add(poJSONObject, "rows", json_object_new_int(nYSize)); // Set the number of columns json_object_object_add(poJSONObject, "cols", json_object_new_int(nXSize)); // Set the xmin json_object_object_add(poJSONObject, "xmin", json_object_new_double(adfTransform[0])); // Set the ymax json_object_object_add(poJSONObject, "ymax", json_object_new_double(adfTransform[3])); // Set the cellwidth json_object_object_add(poJSONObject, "cellwidth", json_object_new_double(adfTransform[1])); // Set the cellheight json_object_object_add(poJSONObject, "cellheight", json_object_new_double(-adfTransform[5])); // Set the xmax json_object_object_add(poJSONObject, "xmax", json_object_new_double(adfTransform[0] + nXSize * adfTransform[1])); // Set the ymin json_object_object_add(poJSONObject, "ymin", json_object_new_double(adfTransform[3] + nYSize * adfTransform[5])); // Set the xskew json_object_object_add(poJSONObject, "xskew", json_object_new_double(adfTransform[2])); // Set the yskew json_object_object_add(poJSONObject, "yskew", json_object_new_double(adfTransform[4])); if (nSrs > 0) { // Set the epsg json_object_object_add(poJSONObject, "epsg", json_object_new_int(nSrs)); } if (json_object_to_file((char *)osJSONFilename.c_str(), poJSONObject) < 0) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't write companion file."); json_object_put(poJSONObject); poJSONObject = NULL; return NULL; } json_object_put(poJSONObject); poJSONObject = NULL; fpImage = VSIFOpenL(pszFilename, "wb"); if (fpImage == NULL) { CPLError( CE_Failure, CPLE_NotSupported, "ARG driver can't create data file %s.", pszFilename); // remove JSON file VSIUnlink( osJSONFilename.c_str() ); return NULL; } // only 1 raster band poSrcBand = poSrcDS->GetRasterBand( 1 ); #ifdef CPL_LSB int bNative = FALSE; #else int bNative = TRUE; #endif poDstBand = new RawRasterBand( fpImage, 0, nPixelOffset, nPixelOffset * nXSize, eType, bNative, nXSize, nYSize, TRUE, FALSE); poSrcBand->GetBlockSize(&nXBlockSize, &nYBlockSize); pabyData = CPLMalloc(nXBlockSize * nPixelOffset); // convert any blocks into scanlines for (int nYBlock = 0; nYBlock * nYBlockSize < nYSize; nYBlock++) { for (int nYScanline = 0; nYScanline < nYBlockSize; nYScanline++) { if ((nYScanline+1) + nYBlock * nYBlockSize > poSrcBand->GetYSize() ) { continue; } for (int nXBlock = 0; nXBlock * nXBlockSize < nXSize; nXBlock++) { int nXValid; if( (nXBlock+1) * nXBlockSize > poSrcBand->GetXSize() ) nXValid = poSrcBand->GetXSize() - nXBlock * nXBlockSize; else nXValid = nXBlockSize; eErr = poSrcBand->RasterIO(GF_Read, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error reading."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } eErr = poDstBand->RasterIO(GF_Write, nXBlock * nXBlockSize, nYBlock * nYBlockSize + nYScanline, nXValid, 1, pabyData, nXBlockSize, 1, eType, 0, 0, NULL); if (eErr != CE_None) { CPLError(CE_Failure, CPLE_AppDefined, "Error writing."); CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return NULL; } } } } CPLFree( pabyData ); delete poDstBand; VSIFCloseL( fpImage ); return (GDALDataset *)GDALOpen( pszFilename, GA_ReadOnly ); }
/** * LoadMetadata() */ void GDALMDReaderLandsat::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osIMDSourceFilename.empty()) { m_papszIMDMD = GDALLoadIMDFile( m_osIMDSourceFilename ); } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ODL"); m_bIsMetadataLoad = true; // date/time // DATE_ACQUIRED = 2013-04-07 // SCENE_CENTER_TIME = 15:47:03.0882620Z // L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID const char* pszSatId = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } // L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER"); if(NULL != pszCloudCover) { double fCC = CPLAtofM(pszCloudCover); if(fCC < 0) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", int(fCC))); } } // L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME // L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME const char* pszDate = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE"); if(NULL == pszDate) { pszDate = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED"); } if(NULL != pszDate) { const char* pszTime = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME"); if(NULL == pszTime) { pszTime = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME"); } if(NULL == pszTime) pszTime = "00:00:00.000000Z"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } }
OGRLayer * OGRPGDumpDataSource::ICreateLayer( const char * pszLayerName, OGRSpatialReference *poSRS, OGRwkbGeometryType eType, char ** papszOptions ) { CPLString osCommand; const char *pszGeomType = NULL; char *pszTableName = NULL; char *pszSchemaName = NULL; int bHavePostGIS = TRUE; int GeometryTypeFlags = 0; const char* pszFIDColumnNameIn = CSLFetchNameValue(papszOptions, "FID"); CPLString osFIDColumnName, osFIDColumnNameEscaped; if (pszFIDColumnNameIn == NULL) osFIDColumnName = "ogc_fid"; else { if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) ) { char* pszLaunderedFid = OGRPGCommonLaunderName(pszFIDColumnNameIn, "PGDump"); osFIDColumnName = pszLaunderedFid; CPLFree(pszLaunderedFid); } else { osFIDColumnName = pszFIDColumnNameIn; } } osFIDColumnNameEscaped = OGRPGDumpEscapeColumnName(osFIDColumnName); if (STARTS_WITH(pszLayerName, "pg")) { CPLError(CE_Warning, CPLE_AppDefined, "The layer name should not begin by 'pg' as it is a reserved prefix"); } //bHavePostGIS = CSLFetchBoolean(papszOptions,"POSTGIS", TRUE); int bCreateTable = CSLFetchBoolean(papszOptions,"CREATE_TABLE", TRUE); int bCreateSchema = CSLFetchBoolean(papszOptions,"CREATE_SCHEMA", TRUE); const char* pszDropTable = CSLFetchNameValueDef(papszOptions,"DROP_TABLE", "IF_EXISTS"); if( OGR_GT_HasZ((OGRwkbGeometryType)eType) ) GeometryTypeFlags |= OGRGeometry::OGR_G_3D; if( OGR_GT_HasM((OGRwkbGeometryType)eType) ) GeometryTypeFlags |= OGRGeometry::OGR_G_MEASURED; int ForcedGeometryTypeFlags = -1; const char* pszDim = CSLFetchNameValue( papszOptions, "DIM"); if( pszDim != NULL ) { if( EQUAL(pszDim, "XY") || EQUAL(pszDim, "2") ) { GeometryTypeFlags = 0; ForcedGeometryTypeFlags = GeometryTypeFlags; } else if( EQUAL(pszDim, "XYZ") || EQUAL(pszDim, "3") ) { GeometryTypeFlags = OGRGeometry::OGR_G_3D; ForcedGeometryTypeFlags = GeometryTypeFlags; } else if( EQUAL(pszDim, "XYM") ) { GeometryTypeFlags = OGRGeometry::OGR_G_MEASURED; ForcedGeometryTypeFlags = GeometryTypeFlags; } else if( EQUAL(pszDim, "XYZM") || EQUAL(pszDim, "4") ) { GeometryTypeFlags = OGRGeometry::OGR_G_3D | OGRGeometry::OGR_G_MEASURED; ForcedGeometryTypeFlags = GeometryTypeFlags; } else { CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for DIM"); } } const int nDimension = 2 + ((GeometryTypeFlags & OGRGeometry::OGR_G_3D) ? 1 : 0) + ((GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) ? 1 : 0); /* Should we turn layers with None geometry type as Unknown/GEOMETRY */ /* so they are still recorded in geometry_columns table ? (#4012) */ int bNoneAsUnknown = CPLTestBool(CSLFetchNameValueDef( papszOptions, "NONE_AS_UNKNOWN", "NO")); if (bNoneAsUnknown && eType == wkbNone) eType = wkbUnknown; else if (eType == wkbNone) bHavePostGIS = FALSE; int bExtractSchemaFromLayerName = CPLTestBool(CSLFetchNameValueDef( papszOptions, "EXTRACT_SCHEMA_FROM_LAYER_NAME", "YES")); /* Postgres Schema handling: Extract schema name from input layer name or passed with -lco SCHEMA. Set layer name to "schema.table" or to "table" if schema == current_schema() Usage without schema name is backwards compatible */ const char* pszDotPos = strstr(pszLayerName,"."); if ( pszDotPos != NULL && bExtractSchemaFromLayerName ) { int length = static_cast<int>(pszDotPos - pszLayerName); pszSchemaName = (char*)CPLMalloc(length+1); strncpy(pszSchemaName, pszLayerName, length); pszSchemaName[length] = '\0'; if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) ) pszTableName = OGRPGCommonLaunderName( pszDotPos + 1, "PGDump" ); //skip "." else pszTableName = CPLStrdup( pszDotPos + 1 ); //skip "." } else { pszSchemaName = NULL; if( CSLFetchBoolean(papszOptions,"LAUNDER", TRUE) ) pszTableName = OGRPGCommonLaunderName( pszLayerName, "PGDump" ); //skip "." else pszTableName = CPLStrdup( pszLayerName ); //skip "." } LogCommit(); /* -------------------------------------------------------------------- */ /* Set the default schema for the layers. */ /* -------------------------------------------------------------------- */ if( CSLFetchNameValue( papszOptions, "SCHEMA" ) != NULL ) { CPLFree(pszSchemaName); pszSchemaName = CPLStrdup(CSLFetchNameValue( papszOptions, "SCHEMA" )); if (bCreateSchema) { osCommand.Printf("CREATE SCHEMA \"%s\"", pszSchemaName); Log(osCommand); } } if ( pszSchemaName == NULL) { pszSchemaName = CPLStrdup("public"); } /* -------------------------------------------------------------------- */ /* Do we already have this layer? */ /* -------------------------------------------------------------------- */ int iLayer; for( iLayer = 0; iLayer < nLayers; iLayer++ ) { if( EQUAL(pszLayerName,papoLayers[iLayer]->GetLayerDefn()->GetName()) ) { CPLError( CE_Failure, CPLE_AppDefined, "Layer %s already exists, CreateLayer failed.\n", pszLayerName ); CPLFree( pszTableName ); CPLFree( pszSchemaName ); return NULL; } } if (bCreateTable && (EQUAL(pszDropTable, "YES") || EQUAL(pszDropTable, "ON") || EQUAL(pszDropTable, "TRUE") || EQUAL(pszDropTable, "IF_EXISTS"))) { if (EQUAL(pszDropTable, "IF_EXISTS")) osCommand.Printf("DROP TABLE IF EXISTS \"%s\".\"%s\" CASCADE", pszSchemaName, pszTableName ); else osCommand.Printf("DROP TABLE \"%s\".\"%s\" CASCADE", pszSchemaName, pszTableName ); Log(osCommand); } /* -------------------------------------------------------------------- */ /* Handle the GEOM_TYPE option. */ /* -------------------------------------------------------------------- */ pszGeomType = CSLFetchNameValue( papszOptions, "GEOM_TYPE" ); if( pszGeomType == NULL ) { pszGeomType = "geometry"; } if( !EQUAL(pszGeomType,"geometry") && !EQUAL(pszGeomType, "geography")) { CPLError( CE_Failure, CPLE_AppDefined, "GEOM_TYPE in PostGIS enabled databases must be 'geometry' or 'geography'.\n" "Creation of layer %s with GEOM_TYPE %s has failed.", pszLayerName, pszGeomType ); CPLFree( pszTableName ); CPLFree( pszSchemaName ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to get the SRS Id of this spatial reference system, */ /* adding tot the srs table if needed. */ /* -------------------------------------------------------------------- */ int nUnknownSRSId = -1; const char* pszPostgisVersion = CSLFetchNameValue( papszOptions, "POSTGIS_VERSION" ); int nPostGISMajor = 1; int nPostGISMinor = 5; if( pszPostgisVersion != NULL && atoi(pszPostgisVersion) >= 2 ) { nPostGISMajor = atoi(pszPostgisVersion); if( strchr(pszPostgisVersion, '.') ) nPostGISMinor = atoi(strchr(pszPostgisVersion, '.')+1); else nPostGISMinor = 0; nUnknownSRSId = 0; } int nSRSId = nUnknownSRSId; int nForcedSRSId = -2; if( CSLFetchNameValue( papszOptions, "SRID") != NULL ) { nSRSId = atoi(CSLFetchNameValue( papszOptions, "SRID")); nForcedSRSId = nSRSId; } else { if (poSRS) { const char* pszAuthorityName = poSRS->GetAuthorityName(NULL); if( pszAuthorityName != NULL && EQUAL( pszAuthorityName, "EPSG" ) ) { /* Assume the EPSG Id is the SRS ID. Might be a wrong guess ! */ nSRSId = atoi( poSRS->GetAuthorityCode(NULL) ); } else { const char* pszGeogCSName = poSRS->GetAttrValue("GEOGCS"); if (pszGeogCSName != NULL && EQUAL(pszGeogCSName, "GCS_WGS_1984")) nSRSId = 4326; } } } CPLString osEscapedTableNameSingleQuote = OGRPGDumpEscapeString(pszTableName); const char* pszEscapedTableNameSingleQuote = osEscapedTableNameSingleQuote.c_str(); const char *pszGeometryType = OGRToOGCGeomType(eType); const char *pszGFldName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME"); if( bHavePostGIS && !EQUAL(pszGeomType, "geography")) { if( pszGFldName == NULL ) pszGFldName = "wkb_geometry"; if( nPostGISMajor < 2 ) { /* Sometimes there is an old cruft entry in the geometry_columns * table if things were not properly cleaned up before. We make * an effort to clean out such cruft. * Note: PostGIS 2.0 defines geometry_columns as a view (no clean up is needed) */ osCommand.Printf( "DELETE FROM geometry_columns WHERE f_table_name = %s AND f_table_schema = '%s'", pszEscapedTableNameSingleQuote, pszSchemaName ); if (bCreateTable) Log(osCommand); } } LogStartTransaction(); /* -------------------------------------------------------------------- */ /* Create a basic table with the FID. Also include the */ /* geometry if this is not a PostGIS enabled table. */ /* -------------------------------------------------------------------- */ int bFID64 = CSLFetchBoolean(papszOptions, "FID64", FALSE); const char* pszSerialType = bFID64 ? "BIGSERIAL": "SERIAL"; CPLString osCreateTable; int bTemporary = CSLFetchBoolean( papszOptions, "TEMPORARY", FALSE ); if (bTemporary) { CPLFree(pszSchemaName); pszSchemaName = CPLStrdup("pg_temp_1"); osCreateTable.Printf("CREATE TEMPORARY TABLE \"%s\"", pszTableName); } else osCreateTable.Printf("CREATE TABLE%s \"%s\".\"%s\"", CSLFetchBoolean( papszOptions, "UNLOGGED", FALSE ) ? " UNLOGGED": "", pszSchemaName, pszTableName); if( !bHavePostGIS ) { if (eType == wkbNone) osCommand.Printf( "%s ( " " %s %s, " " CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )", osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszTableName, osFIDColumnNameEscaped.c_str() ); else osCommand.Printf( "%s ( " " %s %s, " " WKB_GEOMETRY %s, " " CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )", osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGeomType, pszTableName, osFIDColumnNameEscaped.c_str() ); } else if ( EQUAL(pszGeomType, "geography") ) { if( CSLFetchNameValue( papszOptions, "GEOMETRY_NAME") != NULL ) pszGFldName = CSLFetchNameValue( papszOptions, "GEOMETRY_NAME"); else pszGFldName = "the_geog"; const char *suffix = ""; if( (GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) && (GeometryTypeFlags & OGRGeometry::OGR_G_3D) ) { suffix = "ZM"; } else if( (GeometryTypeFlags & OGRGeometry::OGR_G_MEASURED) ) { suffix = "M"; } else if( (GeometryTypeFlags & OGRGeometry::OGR_G_3D) ) { suffix = "Z"; } if (nSRSId) osCommand.Printf( "%s ( %s %s, \"%s\" geography(%s%s,%d), CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )", osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGFldName, pszGeometryType, suffix, nSRSId, pszTableName, osFIDColumnNameEscaped.c_str() ); else osCommand.Printf( "%s ( %s %s, \"%s\" geography(%s%s), CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )", osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszGFldName, pszGeometryType, suffix, pszTableName, osFIDColumnNameEscaped.c_str() ); } else { osCommand.Printf( "%s ( %s %s, CONSTRAINT \"%s_pk\" PRIMARY KEY (%s) )", osCreateTable.c_str(), osFIDColumnNameEscaped.c_str(), pszSerialType, pszTableName, osFIDColumnNameEscaped.c_str() ); } if (bCreateTable) Log(osCommand); /* -------------------------------------------------------------------- */ /* Eventually we should be adding this table to a table of */ /* "geometric layers", capturing the WKT projection, and */ /* perhaps some other housekeeping. */ /* -------------------------------------------------------------------- */ if( bCreateTable && bHavePostGIS && !EQUAL(pszGeomType, "geography")) { const char *suffix = ""; if( GeometryTypeFlags == static_cast<int>(OGRGeometry::OGR_G_MEASURED) && wkbFlatten(eType) != wkbUnknown ) { suffix = "M"; } osCommand.Printf( "SELECT AddGeometryColumn('%s',%s,'%s',%d,'%s%s',%d)", pszSchemaName, pszEscapedTableNameSingleQuote, pszGFldName, nSRSId, pszGeometryType, suffix, nDimension ); Log(osCommand); } const char *pszSI = CSLFetchNameValue( papszOptions, "SPATIAL_INDEX" ); int bCreateSpatialIndex = ( pszSI == NULL || CPLTestBool(pszSI) ); if( bCreateTable && bHavePostGIS && bCreateSpatialIndex ) { /* -------------------------------------------------------------------- */ /* Create the spatial index. */ /* */ /* We're doing this before we add geometry and record to the table */ /* so this may not be exactly the best way to do it. */ /* -------------------------------------------------------------------- */ osCommand.Printf("CREATE INDEX \"%s_%s_geom_idx\" " "ON \"%s\".\"%s\" " "USING GIST (\"%s\")", pszTableName, pszGFldName, pszSchemaName, pszTableName, pszGFldName); Log(osCommand); } /* -------------------------------------------------------------------- */ /* Create the layer object. */ /* -------------------------------------------------------------------- */ OGRPGDumpLayer *poLayer; int bWriteAsHex = !CSLFetchBoolean(papszOptions,"WRITE_EWKT_GEOM",FALSE); poLayer = new OGRPGDumpLayer( this, pszSchemaName, pszTableName, osFIDColumnName, bWriteAsHex, bCreateTable ); poLayer->SetLaunderFlag( CSLFetchBoolean(papszOptions,"LAUNDER",TRUE) ); poLayer->SetPrecisionFlag( CSLFetchBoolean(papszOptions,"PRECISION",TRUE)); const char* pszOverrideColumnTypes = CSLFetchNameValue( papszOptions, "COLUMN_TYPES" ); poLayer->SetOverrideColumnTypes(pszOverrideColumnTypes); poLayer->SetUnknownSRSId(nUnknownSRSId); poLayer->SetForcedSRSId(nForcedSRSId); poLayer->SetCreateSpatialIndexFlag(bCreateSpatialIndex); poLayer->SetPostGISVersion(nPostGISMajor, nPostGISMinor); poLayer->SetForcedGeometryTypeFlags(ForcedGeometryTypeFlags); const char* pszDescription = CSLFetchNameValue(papszOptions, "DESCRIPTION"); if( pszDescription != NULL ) poLayer->SetForcedDescription( pszDescription ); if( bHavePostGIS ) { OGRGeomFieldDefn oTmp( pszGFldName, eType ); OGRPGDumpGeomFieldDefn *poGeomField = new OGRPGDumpGeomFieldDefn(&oTmp); poGeomField->nSRSId = nSRSId; poGeomField->GeometryTypeFlags = GeometryTypeFlags; poLayer->GetLayerDefn()->AddGeomFieldDefn(poGeomField, FALSE); } else if( pszGFldName ) poLayer->SetGeometryFieldName(pszGFldName); /* -------------------------------------------------------------------- */ /* Add layer to data source layer list. */ /* -------------------------------------------------------------------- */ papoLayers = (OGRPGDumpLayer **) CPLRealloc( papoLayers, sizeof(OGRPGDumpLayer *) * (nLayers+1) ); papoLayers[nLayers++] = poLayer; CPLFree( pszTableName ); CPLFree( pszSchemaName ); return poLayer; }
int OGRGPXDataSource::Create( const char *pszFilename, char **papszOptions ) { if( fpOutput != NULL) { CPLAssert( FALSE ); return FALSE; } if (strcmp(pszFilename, "/dev/stdout") == 0) pszFilename = "/vsistdout/"; /* -------------------------------------------------------------------- */ /* Do not override exiting file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) == 0 ) { CPLError(CE_Failure, CPLE_NotSupported, "You have to delete %s before being able to create it with the GPX driver", pszFilename); return FALSE; } /* -------------------------------------------------------------------- */ /* Create the output file. */ /* -------------------------------------------------------------------- */ pszName = CPLStrdup( pszFilename ); if( strcmp(pszName, "/vsistdout/") == 0 ) { bIsBackSeekable = FALSE; fpOutput = VSIFOpenL( pszFilename, "w" ); } else fpOutput = VSIFOpenL( pszFilename, "w+" ); if( fpOutput == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create GPX file %s.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* End of line character. */ /* -------------------------------------------------------------------- */ const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); int bUseCRLF; if( pszCRLFFormat == NULL ) { #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } else if( EQUAL(pszCRLFFormat,"CRLF") ) bUseCRLF = TRUE; else if( EQUAL(pszCRLFFormat,"LF") ) bUseCRLF = FALSE; else { CPLError( CE_Warning, CPLE_AppDefined, "LINEFORMAT=%s not understood, use one of CRLF or LF.", pszCRLFFormat ); #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } pszEOL = (bUseCRLF) ? "\r\n" : "\n"; /* -------------------------------------------------------------------- */ /* Look at use extensions options. */ /* -------------------------------------------------------------------- */ const char* pszUseExtensions = CSLFetchNameValue( papszOptions, "GPX_USE_EXTENSIONS"); const char* pszExtensionsNSURL = NULL; if (pszUseExtensions && CSLTestBoolean(pszUseExtensions)) { bUseExtensions = TRUE; const char* pszExtensionsNSOption = CSLFetchNameValue( papszOptions, "GPX_EXTENSIONS_NS"); const char* pszExtensionsNSURLOption = CSLFetchNameValue( papszOptions, "GPX_EXTENSIONS_NS_URL"); if (pszExtensionsNSOption && pszExtensionsNSURLOption) { pszExtensionsNS = CPLStrdup(pszExtensionsNSOption); pszExtensionsNSURL = pszExtensionsNSURLOption; } else { pszExtensionsNS = CPLStrdup("ogr"); pszExtensionsNSURL = "http://osgeo.org/gdal"; } } /* -------------------------------------------------------------------- */ /* Output header of GPX file. */ /* -------------------------------------------------------------------- */ PrintLine("<?xml version=\"1.0\"?>"); VSIFPrintfL(fpOutput, "<gpx version=\"1.1\" creator=\"GDAL " GDAL_RELEASE_NAME "\" "); VSIFPrintfL(fpOutput, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "); if (bUseExtensions) VSIFPrintfL(fpOutput, "xmlns:%s=\"%s\" ", pszExtensionsNS, pszExtensionsNSURL); VSIFPrintfL(fpOutput, "xmlns=\"http://www.topografix.com/GPX/1/1\" "); PrintLine("xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">"); if (bIsBackSeekable) { /* Reserve space for <metadata><bounds/></metadata> */ char szMetadata[SPACE_FOR_METADATA+1]; memset(szMetadata, ' ', SPACE_FOR_METADATA); szMetadata[SPACE_FOR_METADATA] = '\0'; nOffsetBounds = (int) VSIFTellL(fpOutput); PrintLine("%s", szMetadata); } return TRUE; }
void OGRGMLDataSource::InsertHeader() { FILE *fpSchema; int nSchemaStart = 0; if( fpOutput == NULL || fpOutput == stdout ) return; /* -------------------------------------------------------------------- */ /* Do we want to write the schema within the GML instance doc */ /* or to a separate file? For now we only support external. */ /* -------------------------------------------------------------------- */ const char *pszSchemaURI = CSLFetchNameValue(papszCreateOptions, "XSISCHEMAURI"); const char *pszSchemaOpt = CSLFetchNameValue( papszCreateOptions, "XSISCHEMA" ); if( pszSchemaURI != NULL ) return; if( pszSchemaOpt == NULL || EQUAL(pszSchemaOpt,"EXTERNAL") ) { const char *pszXSDFilename = CPLResetExtension( pszName, "xsd" ); fpSchema = VSIFOpen( pszXSDFilename, "wt" ); if( fpSchema == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open file %.500s for schema output.", pszXSDFilename ); return; } fprintf( fpSchema, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); } else if( EQUAL(pszSchemaOpt,"INTERNAL") ) { nSchemaStart = VSIFTell( fpOutput ); fpSchema = fpOutput; } else return; /* ==================================================================== */ /* Write the schema section at the end of the file. Once */ /* complete, we will read it back in, and then move the whole */ /* file "down" enough to insert the schema at the beginning. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Emit the start of the schema section. */ /* -------------------------------------------------------------------- */ const char *pszTargetNameSpace = "http://ogr.maptools.org/"; const char *pszPrefix = "ogr"; VSIFPrintf( fpSchema, "<xs:schema targetNamespace=\"%s\" xmlns:%s=\"%s\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:gml=\"http://www.opengis.net/gml\" elementFormDefault=\"qualified\" version=\"1.0\">\n", pszTargetNameSpace, pszPrefix, pszTargetNameSpace ); VSIFPrintf( fpSchema, "<xs:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://schemas.opengeospatial.net/gml/2.1.2/feature.xsd\"/>" ); /* -------------------------------------------------------------------- */ /* Define the FeatureCollection */ /* -------------------------------------------------------------------- */ VSIFPrintf( fpSchema, "<xs:element name=\"FeatureCollection\" type=\"%s:FeatureCollectionType\" substitutionGroup=\"gml:_FeatureCollection\"/>\n", pszPrefix ); VSIFPrintf( fpSchema, "<xs:complexType name=\"FeatureCollectionType\">\n" " <xs:complexContent>\n" " <xs:extension base=\"gml:AbstractFeatureCollectionType\">\n" " <xs:attribute name=\"lockId\" type=\"xs:string\" use=\"optional\"/>\n" " <xs:attribute name=\"scope\" type=\"xs:string\" use=\"optional\"/>\n" " </xs:extension>\n" " </xs:complexContent>\n" "</xs:complexType>\n" ); /* ==================================================================== */ /* Define the schema for each layer. */ /* ==================================================================== */ int iLayer; for( iLayer = 0; iLayer < GetLayerCount(); iLayer++ ) { OGRFeatureDefn *poFDefn = GetLayer(iLayer)->GetLayerDefn(); /* -------------------------------------------------------------------- */ /* Emit initial stuff for a feature type. */ /* -------------------------------------------------------------------- */ VSIFPrintf( fpSchema, "<xs:element name=\"%s\" type=\"%s:%s_Type\" substitutionGroup=\"gml:_Feature\"/>\n", poFDefn->GetName(), pszPrefix, poFDefn->GetName() ); VSIFPrintf( fpSchema, "<xs:complexType name=\"%s_Type\">\n" " <xs:complexContent>\n" " <xs:extension base=\"gml:AbstractFeatureType\">\n" " <xs:sequence>\n", poFDefn->GetName() ); /* -------------------------------------------------------------------- */ /* Define the geometry attribute. For now I always use the */ /* generic geometry type, but eventually we should express */ /* particulars if available. */ /* -------------------------------------------------------------------- */ VSIFPrintf( fpSchema, "<xs:element name=\"geometryProperty\" type=\"gml:GeometryPropertyType\" nillable=\"true\" minOccurs=\"1\" maxOccurs=\"1\"/>\n" ); /* -------------------------------------------------------------------- */ /* Emit each of the attributes. */ /* -------------------------------------------------------------------- */ for( int iField = 0; iField < poFDefn->GetFieldCount(); iField++ ) { OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField); if( poFieldDefn->GetType() == OFTInteger ) { int nWidth; if( poFieldDefn->GetWidth() > 0 ) nWidth = poFieldDefn->GetWidth(); else nWidth = 16; VSIFPrintf( fpSchema, " <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n" " <xs:simpleType>\n" " <xs:restriction base=\"xs:integer\">\n" " <xs:totalDigits value=\"%d\"/>\n" " </xs:restriction>\n" " </xs:simpleType>\n" " </xs:element>\n", poFieldDefn->GetNameRef(), nWidth ); } else if( poFieldDefn->GetType() == OFTReal ) { int nWidth, nDecimals; if( poFieldDefn->GetPrecision() == 0 ) nDecimals = 0; else nDecimals = poFieldDefn->GetPrecision(); if( poFieldDefn->GetWidth() > 0 ) nWidth = poFieldDefn->GetWidth(); else nWidth = 33; VSIFPrintf( fpSchema, " <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n" " <xs:simpleType>\n" " <xs:restriction base=\"xs:decimal\">\n" " <xs:totalDigits value=\"%d\"/>\n" " <xs:fractionDigits value=\"%d\"/>\n" " </xs:restriction>\n" " </xs:simpleType>\n" " </xs:element>\n", poFieldDefn->GetNameRef(), nWidth, nDecimals ); } else if( poFieldDefn->GetType() == OFTString ) { char szMaxLength[48]; if( poFieldDefn->GetWidth() == 0 ) sprintf( szMaxLength, "unbounded" ); else sprintf( szMaxLength, "%d", poFieldDefn->GetWidth() ); VSIFPrintf( fpSchema, " <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n" " <xs:simpleType>\n" " <xs:restriction base=\"xs:string\">\n" " <xs:maxLength value=\"%s\"/>\n" " </xs:restriction>\n" " </xs:simpleType>\n" " </xs:element>\n", poFieldDefn->GetNameRef(), szMaxLength ); } else if( poFieldDefn->GetType() == OFTDate || poFieldDefn->GetType() == OFTDateTime ) { VSIFPrintf( fpSchema, " <xs:element name=\"%s\" nillable=\"true\" minOccurs=\"0\" maxOccurs=\"1\">\n" " <xs:simpleType>\n" " <xs:restriction base=\"xs:string\">\n" " <xs:maxLength value=\"unbounded\"/>\n" " </xs:restriction>\n" " </xs:simpleType>\n" " </xs:element>\n", poFieldDefn->GetNameRef() ); } else { /* TODO */ } } /* next field */ /* -------------------------------------------------------------------- */ /* Finish off feature type. */ /* -------------------------------------------------------------------- */ VSIFPrintf( fpSchema, " </xs:sequence>\n" " </xs:extension>\n" " </xs:complexContent>\n" "</xs:complexType>\n" ); } /* next layer */ VSIFPrintf( fpSchema, "</xs:schema>\n" ); /* ==================================================================== */ /* Move schema to the start of the file. */ /* ==================================================================== */ if( fpSchema == fpOutput ) { /* -------------------------------------------------------------------- */ /* Read the schema into memory. */ /* -------------------------------------------------------------------- */ int nSchemaSize = VSIFTell( fpOutput ) - nSchemaStart; char *pszSchema = (char *) CPLMalloc(nSchemaSize+1); VSIFSeek( fpOutput, nSchemaStart, SEEK_SET ); VSIFRead( pszSchema, 1, nSchemaSize, fpOutput ); pszSchema[nSchemaSize] = '\0'; /* -------------------------------------------------------------------- */ /* Move file data down by "schema size" bytes from after <?xml> */ /* header so we have room insert the schema. Move in pretty */ /* big chunks. */ /* -------------------------------------------------------------------- */ int nChunkSize = MIN(nSchemaStart-nSchemaInsertLocation,250000); char *pszChunk = (char *) CPLMalloc(nChunkSize); int nEndOfUnmovedData = nSchemaStart; for( nEndOfUnmovedData = nSchemaStart; nEndOfUnmovedData > nSchemaInsertLocation; ) { int nBytesToMove = MIN(nChunkSize, nEndOfUnmovedData - nSchemaInsertLocation ); VSIFSeek( fpOutput, nEndOfUnmovedData - nBytesToMove, SEEK_SET ); VSIFRead( pszChunk, 1, nBytesToMove, fpOutput ); VSIFSeek( fpOutput, nEndOfUnmovedData - nBytesToMove + nSchemaSize, SEEK_SET ); VSIFWrite( pszChunk, 1, nBytesToMove, fpOutput ); nEndOfUnmovedData -= nBytesToMove; } CPLFree( pszChunk ); /* -------------------------------------------------------------------- */ /* Write the schema in the opened slot. */ /* -------------------------------------------------------------------- */ VSIFSeek( fpOutput, nSchemaInsertLocation, SEEK_SET ); VSIFWrite( pszSchema, 1, nSchemaSize, fpOutput ); VSIFSeek( fpOutput, 0, SEEK_END ); nBoundedByLocation += nSchemaSize; } /* -------------------------------------------------------------------- */ /* Close external schema files. */ /* -------------------------------------------------------------------- */ else VSIFClose( fpSchema ); }
/** * \brief Fetch a document from an url and return in a string. * * @param pszURL valid URL recognized by underlying download library (libcurl) * @param papszOptions option list as a NULL-terminated array of strings. May be NULL. * The following options are handled : * <ul> * <li>TIMEOUT=val, where val is in seconds</li> * <li>HEADERS=val, where val is an extra header to use when getting a web page. * For example "Accept: application/x-ogcwkt" * <li>HTTPAUTH=[BASIC/NTLM/GSSNEGOTIATE/ANY] to specify an authentication scheme to use. * <li>USERPWD=userid:password to specify a user and password for authentication * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server * with a POST request. * <li>PROXY=val, to make requests go through a proxy server, where val is of the * form proxy.server.com:port_number * <li>PROXYUSERPWD=val, where val is of the form username:password * <li>PROXYAUTH=[BASIC/NTLM/DIGEST/ANY] to specify an proxy authentication scheme to use. * <li>NETRC=[YES/NO] to enable or disable use of $HOME/.netrc, default YES. * <li>CUSTOMREQUEST=val, where val is GET, PUT, POST, DELETE, etc.. (GDAL >= 1.9.0) * <li>COOKIE=val, where val is formatted as COOKIE1=VALUE1; COOKIE2=VALUE2; ... * <li>MAX_RETRY=val, where val is the maximum number of retry attempts if a 503 or * 504 HTTP error occurs. Default is 0. (GDAL >= 2.0) * <li>RETRY_DELAY=val, where val is the number of seconds between retry attempts. * Default is 30. (GDAL >= 2.0) * </ul> * * Alternatively, if not defined in the papszOptions arguments, the PROXY, * PROXYUSERPWD, PROXYAUTH, NETRC, MAX_RETRY and RETRY_DELAY values are searched in the configuration * options named GDAL_HTTP_PROXY, GDAL_HTTP_PROXYUSERPWD, GDAL_PROXY_AUTH, * GDAL_HTTP_NETRC, GDAL_HTTP_MAX_RETRY and GDAL_HTTP_RETRY_DELAY. * * @return a CPLHTTPResult* structure that must be freed by * CPLHTTPDestroyResult(), or NULL if libcurl support is disabled */ CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions ) { if( strncmp(pszURL, "/vsimem/", strlen("/vsimem/")) == 0 && /* Disabled by default for potential security issues */ CSLTestBoolean(CPLGetConfigOption("CPL_CURL_ENABLE_VSIMEM", "FALSE")) ) { CPLString osURL(pszURL); const char* pszPost = CSLFetchNameValue( papszOptions, "POSTFIELDS" ); if( pszPost != NULL ) /* Hack: we append post content to filename */ { osURL += "&POSTFIELDS="; osURL += pszPost; } vsi_l_offset nLength = 0; CPLHTTPResult* psResult = (CPLHTTPResult* )CPLCalloc(1, sizeof(CPLHTTPResult)); GByte* pabyData = VSIGetMemFileBuffer( osURL, &nLength, FALSE ); if( pabyData == NULL ) { CPLDebug("HTTP", "Cannot find %s", osURL.c_str()); psResult->nStatus = 1; psResult->pszErrBuf = CPLStrdup(CPLSPrintf("HTTP error code : %d", 404)); CPLError( CE_Failure, CPLE_AppDefined, "%s", psResult->pszErrBuf ); } else if( nLength != 0 ) { psResult->nDataLen = (size_t)nLength; psResult->pabyData = (GByte*) CPLMalloc((size_t)nLength + 1); memcpy(psResult->pabyData, pabyData, (size_t)nLength); psResult->pabyData[(size_t)nLength] = 0; } if( psResult->pabyData != NULL && strncmp((const char*)psResult->pabyData, "Content-Type: ", strlen("Content-Type: ")) == 0 ) { const char* pszContentType = (const char*)psResult->pabyData + strlen("Content-type: "); const char* pszEOL = strchr(pszContentType, '\r'); if( pszEOL ) pszEOL = strchr(pszContentType, '\n'); if( pszEOL ) { int nLength = pszEOL - pszContentType; psResult->pszContentType = (char*)CPLMalloc(nLength + 1); memcpy(psResult->pszContentType, pszContentType, nLength); psResult->pszContentType[nLength] = 0; } } return psResult; } #ifndef HAVE_CURL (void) papszOptions; (void) pszURL; CPLError( CE_Failure, CPLE_NotSupported, "GDAL/OGR not compiled with libcurl support, remote requests not supported." ); return NULL; #else /* -------------------------------------------------------------------- */ /* Are we using a persistent named session? If so, search for */ /* or create it. */ /* */ /* Currently this code does not attempt to protect against */ /* multiple threads asking for the same named session. If that */ /* occurs it will be in use in multiple threads at once which */ /* might have bad consequences depending on what guarantees */ /* libcurl gives - which I have not investigated. */ /* -------------------------------------------------------------------- */ CURL *http_handle = NULL; const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" ); const char *pszClosePersistent = CSLFetchNameValue( papszOptions, "CLOSE_PERSISTENT" ); if (pszPersistent) { CPLString osSessionName = pszPersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); if( poSessionMap == NULL ) poSessionMap = new std::map<CPLString,CURL*>; if( poSessionMap->count( osSessionName ) == 0 ) { (*poSessionMap)[osSessionName] = curl_easy_init(); CPLDebug( "HTTP", "Establish persistent session named '%s'.", osSessionName.c_str() ); } http_handle = (*poSessionMap)[osSessionName]; } /* -------------------------------------------------------------------- */ /* Are we requested to close a persistent named session? */ /* -------------------------------------------------------------------- */ else if (pszClosePersistent) { CPLString osSessionName = pszClosePersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); if( poSessionMap ) { std::map<CPLString,CURL*>::iterator oIter = poSessionMap->find( osSessionName ); if( oIter != poSessionMap->end() ) { curl_easy_cleanup(oIter->second); poSessionMap->erase(oIter); if( poSessionMap->size() == 0 ) { delete poSessionMap; poSessionMap = NULL; } CPLDebug( "HTTP", "Ended persistent session named '%s'.", osSessionName.c_str() ); } else { CPLDebug( "HTTP", "Could not find persistent session named '%s'.", osSessionName.c_str() ); } } return NULL; } else http_handle = curl_easy_init(); /* -------------------------------------------------------------------- */ /* Setup the request. */ /* -------------------------------------------------------------------- */ char szCurlErrBuf[CURL_ERROR_SIZE+1]; CPLHTTPResult *psResult; struct curl_slist *headers=NULL; const char* pszArobase = strchr(pszURL, '@'); const char* pszSlash = strchr(pszURL, '/'); const char* pszColon = (pszSlash) ? strchr(pszSlash, ':') : NULL; if (pszArobase != NULL && pszColon != NULL && pszArobase - pszColon > 0) { /* http://user:[email protected] */ char* pszSanitizedURL = CPLStrdup(pszURL); pszSanitizedURL[pszColon-pszURL] = 0; CPLDebug( "HTTP", "Fetch(%s:#password#%s)", pszSanitizedURL, pszArobase ); CPLFree(pszSanitizedURL); } else { CPLDebug( "HTTP", "Fetch(%s)", pszURL ); } psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult)); curl_easy_setopt(http_handle, CURLOPT_URL, pszURL ); CPLHTTPSetOptions(http_handle, papszOptions); // turn off SSL verification, accept all servers with ssl curl_easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, FALSE); /* Set Headers.*/ const char *pszHeaders = CSLFetchNameValue( papszOptions, "HEADERS" ); if( pszHeaders != NULL ) { CPLDebug ("HTTP", "These HTTP headers were set: %s", pszHeaders); headers = curl_slist_append(headers, pszHeaders); curl_easy_setopt(http_handle, CURLOPT_HTTPHEADER, headers); } // are we making a head request const char* pszNoBody = NULL; if ((pszNoBody = CSLFetchNameValue( papszOptions, "NO_BODY" )) != NULL) { if (CSLTestBoolean(pszNoBody)) { CPLDebug ("HTTP", "HEAD Request: %s", pszURL); curl_easy_setopt(http_handle, CURLOPT_NOBODY, 1L); } } // capture response headers curl_easy_setopt(http_handle, CURLOPT_HEADERDATA, psResult); curl_easy_setopt(http_handle, CURLOPT_HEADERFUNCTION, CPLHdrWriteFct); curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, psResult ); curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, CPLWriteFct ); szCurlErrBuf[0] = '\0'; curl_easy_setopt(http_handle, CURLOPT_ERRORBUFFER, szCurlErrBuf ); static int bHasCheckVersion = FALSE; static int bSupportGZip = FALSE; if (!bHasCheckVersion) { bSupportGZip = strstr(curl_version(), "zlib/") != NULL; bHasCheckVersion = TRUE; } int bGZipRequested = FALSE; if (bSupportGZip && CSLTestBoolean(CPLGetConfigOption("CPL_CURL_GZIP", "YES"))) { bGZipRequested = TRUE; curl_easy_setopt(http_handle, CURLOPT_ENCODING, "gzip"); } /* -------------------------------------------------------------------- */ /* If 502, 503 or 504 status code retry this HTTP call until max */ /* retry has been rearched */ /* -------------------------------------------------------------------- */ const char *pszRetryDelay = CSLFetchNameValue( papszOptions, "RETRY_DELAY" ); if( pszRetryDelay == NULL ) pszRetryDelay = CPLGetConfigOption( "GDAL_HTTP_RETRY_DELAY", "30" ); const char *pszMaxRetries = CSLFetchNameValue( papszOptions, "MAX_RETRY" ); if( pszMaxRetries == NULL ) pszMaxRetries = CPLGetConfigOption( "GDAL_HTTP_MAX_RETRY", "0" ); int nRetryDelaySecs = atoi(pszRetryDelay); int nMaxRetries = atoi(pszMaxRetries); int nRetryCount = 0; bool bRequestRetry; do { bRequestRetry = FALSE; /* -------------------------------------------------------------------- */ /* Execute the request, waiting for results. */ /* -------------------------------------------------------------------- */ psResult->nStatus = (int) curl_easy_perform( http_handle ); /* -------------------------------------------------------------------- */ /* Fetch content-type if possible. */ /* -------------------------------------------------------------------- */ psResult->pszContentType = NULL; curl_easy_getinfo( http_handle, CURLINFO_CONTENT_TYPE, &(psResult->pszContentType) ); if( psResult->pszContentType != NULL ) psResult->pszContentType = CPLStrdup(psResult->pszContentType); /* -------------------------------------------------------------------- */ /* Have we encountered some sort of error? */ /* -------------------------------------------------------------------- */ if( strlen(szCurlErrBuf) > 0 ) { int bSkipError = FALSE; /* Some servers such as http://115.113.193.14/cgi-bin/world/qgis_mapserv.fcgi?VERSION=1.1.1&SERVICE=WMS&REQUEST=GetCapabilities */ /* invalidly return Content-Length as the uncompressed size, with makes curl to wait for more data */ /* and time-out finally. If we got the expected data size, then we don't emit an error */ /* but turn off GZip requests */ if (bGZipRequested && strstr(szCurlErrBuf, "transfer closed with") && strstr(szCurlErrBuf, "bytes remaining to read")) { const char* pszContentLength = CSLFetchNameValue(psResult->papszHeaders, "Content-Length"); if (pszContentLength && psResult->nDataLen != 0 && atoi(pszContentLength) == psResult->nDataLen) { const char* pszCurlGZIPOption = CPLGetConfigOption("CPL_CURL_GZIP", NULL); if (pszCurlGZIPOption == NULL) { CPLSetConfigOption("CPL_CURL_GZIP", "NO"); CPLDebug("HTTP", "Disabling CPL_CURL_GZIP, because %s doesn't support it properly", pszURL); } psResult->nStatus = 0; bSkipError = TRUE; } } if (!bSkipError) { psResult->pszErrBuf = CPLStrdup(szCurlErrBuf); CPLError( CE_Failure, CPLE_AppDefined, "%s", szCurlErrBuf ); } } else { /* HTTP errors do not trigger curl errors. But we need to */ /* propagate them to the caller though */ long response_code = 0; curl_easy_getinfo(http_handle, CURLINFO_RESPONSE_CODE, &response_code); if (response_code >= 400 && response_code < 600) { /* If HTTP 502, 503 or 504 gateway timeout error retry after a pause */ if ((response_code >= 502 && response_code <= 504) && nRetryCount < nMaxRetries) { CPLError(CE_Warning, CPLE_AppDefined, "HTTP error code: %d - %s. Retrying again in %d secs", (int)response_code, pszURL, nRetryDelaySecs); CPLSleep(nRetryDelaySecs); nRetryCount++; CPLFree(psResult->pszContentType); psResult->pszContentType = NULL; CSLDestroy(psResult->papszHeaders); psResult->papszHeaders = NULL; CPLFree(psResult->pabyData); psResult->pabyData = NULL; psResult->nDataLen = 0; psResult->nDataAlloc = 0; bRequestRetry = TRUE; } else { psResult->pszErrBuf = CPLStrdup(CPLSPrintf("HTTP error code : %d", (int)response_code)); CPLError( CE_Failure, CPLE_AppDefined, "%s", psResult->pszErrBuf ); } } } } while (bRequestRetry); if (!pszPersistent) curl_easy_cleanup( http_handle ); curl_slist_free_all(headers); return psResult; #endif /* def HAVE_CURL */ }
int OGRMySQLDataSource::Open( const char * pszNewName, char** papszOpenOptionsIn, int bUpdate ) { CPLAssert( nLayers == 0 ); /* -------------------------------------------------------------------- */ /* Use options process to get .my.cnf file contents. */ /* -------------------------------------------------------------------- */ int nPort = 0; char **papszTableNames=NULL; std::string oHost, oPassword, oUser, oDB; CPLString osNewName(pszNewName); const char* apszOpenOptions[] = { "dbname", "port", "user", "password", "host", "tables" }; for(int i=0; i <(int)(sizeof(apszOpenOptions)/sizeof(char*)); i++) { const char* pszVal = CSLFetchNameValue(papszOpenOptionsIn, apszOpenOptions[i]); if( pszVal ) { if( osNewName[osNewName.size()-1] != ':' ) osNewName += ","; if( i > 0 ) { osNewName += apszOpenOptions[i]; osNewName += "="; } if( EQUAL(apszOpenOptions[i], "tables") ) { for( ; *pszVal; ++pszVal ) { if( *pszVal == ',' ) osNewName += ";"; else osNewName += *pszVal; } } else osNewName += pszVal; } } /* -------------------------------------------------------------------- */ /* Parse out connection information. */ /* -------------------------------------------------------------------- */ char **papszItems = CSLTokenizeString2( osNewName+6, ",", CSLT_HONOURSTRINGS ); if( CSLCount(papszItems) < 1 ) { CSLDestroy( papszItems ); CPLError( CE_Failure, CPLE_AppDefined, "MYSQL: request missing databasename." ); return FALSE; } oDB = papszItems[0]; for( int i = 1; papszItems[i] != NULL; i++ ) { if( STARTS_WITH_CI(papszItems[i], "user="******"password="******"host=") ) oHost = papszItems[i] + 5; else if( STARTS_WITH_CI(papszItems[i], "port=") ) nPort = atoi(papszItems[i] + 5); else if( STARTS_WITH_CI(papszItems[i], "tables=") ) { CSLDestroy(papszTableNames); papszTableNames = CSLTokenizeStringComplex( papszItems[i] + 7, ";", FALSE, FALSE ); } else CPLError( CE_Warning, CPLE_AppDefined, "'%s' in MYSQL datasource definition not recognised and ignored.", papszItems[i] ); } CSLDestroy( papszItems ); /* -------------------------------------------------------------------- */ /* Try to establish connection. */ /* -------------------------------------------------------------------- */ hConn = mysql_init( NULL ); if( hConn == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "mysql_init() failed." ); } /* -------------------------------------------------------------------- */ /* Set desired options on the connection: charset and timeout. */ /* -------------------------------------------------------------------- */ if( hConn ) { const char *pszTimeoutLength = CPLGetConfigOption( "MYSQL_TIMEOUT", "0" ); unsigned int timeout = atoi(pszTimeoutLength); mysql_options(hConn, MYSQL_OPT_CONNECT_TIMEOUT, (char*)&timeout); mysql_options(hConn, MYSQL_SET_CHARSET_NAME, "utf8" ); } /* -------------------------------------------------------------------- */ /* Perform connection. */ /* -------------------------------------------------------------------- */ if( hConn && mysql_real_connect( hConn, oHost.length() ? oHost.c_str() : NULL, oUser.length() ? oUser.c_str() : NULL, oPassword.length() ? oPassword.c_str() : NULL, oDB.length() ? oDB.c_str() : NULL, nPort, NULL, CLIENT_INTERACTIVE ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "MySQL connect failed for: %s\n%s", pszNewName + 6, mysql_error( hConn ) ); mysql_close( hConn ); hConn = NULL; } if( hConn == NULL ) { CSLDestroy( papszTableNames ); return FALSE; } else { // Enable automatic reconnection // Must be called after mysql_real_connect() on MySQL < 5.0.19 // and at any point on more recent versions. my_bool reconnect = 1; mysql_options(hConn, MYSQL_OPT_RECONNECT, &reconnect); } pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; /* -------------------------------------------------------------------- */ /* Get a list of available tables. */ /* -------------------------------------------------------------------- */ if( papszTableNames == NULL ) { MYSQL_RES *hResultSet; MYSQL_ROW papszRow; if( mysql_query( hConn, "SHOW TABLES" ) ) { ReportError( "SHOW TABLES Failed" ); return FALSE; } hResultSet = mysql_store_result( hConn ); if( hResultSet == NULL ) { ReportError( "mysql_store_result() failed on SHOW TABLES result."); return FALSE; } while( (papszRow = mysql_fetch_row( hResultSet )) != NULL ) { if( papszRow[0] == NULL ) continue; if( EQUAL(papszRow[0],"spatial_ref_sys") || EQUAL(papszRow[0],"geometry_columns") ) continue; papszTableNames = CSLAddString(papszTableNames, papszRow[0] ); } mysql_free_result( hResultSet ); } /* -------------------------------------------------------------------- */ /* Get the schema of the available tables. */ /* -------------------------------------------------------------------- */ int iRecord; for( iRecord = 0; papszTableNames != NULL && papszTableNames[iRecord] != NULL; iRecord++ ) { // FIXME: This should be fixed to deal with tables // for which we can't open because the name is bad/ OpenTable( papszTableNames[iRecord], bUpdate ); } CSLDestroy( papszTableNames ); return nLayers > 0 || bUpdate; }
GDALDataset *ROIPACDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Confirm that the header is compatible with a ROIPAC dataset. */ /* -------------------------------------------------------------------- */ if ( !Identify(poOpenInfo) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Open the .rsc file */ /* -------------------------------------------------------------------- */ CPLString osRscFilename = getRscFilename( poOpenInfo ); if ( osRscFilename.empty() ) { return NULL; } VSILFILE *fpRsc; if ( poOpenInfo->eAccess == GA_Update ) { fpRsc = VSIFOpenL( osRscFilename, "r+" ); } else { fpRsc = VSIFOpenL( osRscFilename, "r" ); } if ( fpRsc == NULL ) { return NULL; } /* -------------------------------------------------------------------- */ /* Load the .rsc information. */ /* -------------------------------------------------------------------- */ char **papszRsc = NULL; while ( true ) { const char *pszLine; char **papszTokens; pszLine = CPLReadLineL( fpRsc ); if (pszLine == NULL) { break; } papszTokens = CSLTokenizeString2( pszLine, " \t", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES | CSLT_PRESERVEQUOTES | CSLT_PRESERVEESCAPES ); if ( papszTokens == NULL || papszTokens[0] == NULL || papszTokens[1] == NULL ) { CSLDestroy ( papszTokens ); break; } papszRsc = CSLSetNameValue( papszRsc, papszTokens[0], papszTokens[1] ); CSLDestroy ( papszTokens ); } /* -------------------------------------------------------------------- */ /* Fetch required fields. */ /* -------------------------------------------------------------------- */ int nWidth = 0, nFileLength = 0; if ( CSLFetchNameValue( papszRsc, "WIDTH" ) == NULL || CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) == NULL ) { CSLDestroy( papszRsc ); VSIFCloseL( fpRsc ); return NULL; } nWidth = atoi( CSLFetchNameValue( papszRsc, "WIDTH" ) ); nFileLength = atoi( CSLFetchNameValue( papszRsc, "FILE_LENGTH" ) ); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ROIPACDataset *poDS; poDS = new ROIPACDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nFileLength; poDS->eAccess = poOpenInfo->eAccess; poDS->fpRsc = fpRsc; poDS->pszRscFilename = CPLStrdup( osRscFilename.c_str() ); /* -------------------------------------------------------------------- */ /* Reopen file in update mode if necessary. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); } else { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); } if( poDS->fpImage == NULL ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to re-open %s within ROI_PAC driver.\n", poOpenInfo->pszFilename ); CSLDestroy( papszRsc ); return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType; int nBands; enum Interleave { LINE, PIXEL } eInterleave; const char *pszExtension = CPLGetExtension(poOpenInfo->pszFilename); if ( strcmp( pszExtension, "raw" ) == 0 ) { /* ------------------------------------------------------------ */ /* TODO: ROI_PAC raw images are what would be GDT_CInt8 typed, */ /* but since that type do not exist, we will have to implement */ /* a specific case in the RasterBand to convert it to */ /* GDT_CInt16 for example */ /* ------------------------------------------------------------ */ #if 0 eDataType = GDT_CInt8; nBands = 1; eInterleave = PIXEL; #else CPLError( CE_Failure, CPLE_NotSupported, "Reading ROI_PAC raw files is not supported yet." ); delete poDS; CSLDestroy( papszRsc ); return NULL; #endif } else if ( strcmp( pszExtension, "int" ) == 0 || strcmp( pszExtension, "slc" ) == 0 ) { eDataType = GDT_CFloat32; nBands = 1; eInterleave = PIXEL; } else if ( strcmp( pszExtension, "amp" ) == 0 ) { eDataType = GDT_Float32; nBands = 2; eInterleave = PIXEL; } else if ( strcmp( pszExtension, "cor" ) == 0 || strcmp( pszExtension, "hgt" ) == 0 || strcmp( pszExtension, "unw" ) == 0 || strcmp( pszExtension, "msk" ) == 0 || strcmp( pszExtension, "trans" ) == 0 ) { eDataType = GDT_Float32; nBands = 2; eInterleave = LINE; } else if ( strcmp( pszExtension, "dem" ) == 0 ) { eDataType = GDT_Int16; nBands = 1; eInterleave = PIXEL; } else { /* Eeek */ delete poDS; CSLDestroy( papszRsc ); return NULL; } int nPixelOffset; int nLineOffset; int nBandOffset; if (eInterleave == LINE) { nPixelOffset = GDALGetDataTypeSize(eDataType)/8; nLineOffset = nPixelOffset * nWidth * nBands; nBandOffset = GDALGetDataTypeSize(eDataType)/8 * nWidth; } else { /* PIXEL */ nPixelOffset = GDALGetDataTypeSize(eDataType)/8 * nBands; nLineOffset = nPixelOffset * nWidth * nBands; nBandOffset = GDALGetDataTypeSize(eDataType)/8; } poDS->nBands = nBands; for (int b = 0; b < nBands; b++) { poDS->SetBand( b + 1, new ROIPACRasterBand( poDS, b + 1, poDS->fpImage, nBandOffset * b, nPixelOffset, nLineOffset, eDataType, TRUE, TRUE, FALSE ) ); } /* -------------------------------------------------------------------- */ /* Interpret georeferencing, if present. */ /* -------------------------------------------------------------------- */ if ( CSLFetchNameValue( papszRsc, "X_FIRST" ) != NULL && CSLFetchNameValue( papszRsc, "X_STEP" ) != NULL && CSLFetchNameValue( papszRsc, "Y_FIRST" ) != NULL && CSLFetchNameValue( papszRsc, "Y_STEP" ) != NULL ) { poDS->adfGeoTransform[0] = CPLAtof( CSLFetchNameValue( papszRsc, "X_FIRST" ) ); poDS->adfGeoTransform[1] = CPLAtof( CSLFetchNameValue( papszRsc, "X_STEP" ) ); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = CPLAtof( CSLFetchNameValue( papszRsc, "Y_FIRST" ) ); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = CPLAtof( CSLFetchNameValue( papszRsc, "Y_STEP" ) ); poDS->bValidGeoTransform = true; } if ( CSLFetchNameValue( papszRsc, "PROJECTION" ) != NULL ) { /* ------------------------------------------------------------ */ /* In ROI_PAC, images are georeferenced either with lat/long or */ /* UTM projection. However, using UTM projection is dangerous */ /* because there is no North/South field, or use of latitude */ /* bands! */ /* ------------------------------------------------------------ */ OGRSpatialReference oSRS; if ( strcmp( CSLFetchNameValue( papszRsc, "PROJECTION" ), "LL" ) == 0 ) { if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL ) { oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, "DATUM" ) ); } else { oSRS.SetWellKnownGeogCS( "WGS84" ); } } else if( strncmp( CSLFetchNameValue( papszRsc, "PROJECTION" ), "UTM", 3 ) == 0 ) { const char *pszZone = CSLFetchNameValue( papszRsc, "PROJECTION" ) + 3; oSRS.SetUTM( atoi( pszZone ), TRUE ); /* FIXME: north/south? */ if ( CSLFetchNameValue( papszRsc, "DATUM" ) != NULL ) { oSRS.SetWellKnownGeogCS( CSLFetchNameValue( papszRsc, "DATUM" ) ); } else { oSRS.SetWellKnownGeogCS( "NAD27" ); } } oSRS.exportToWkt( &poDS->pszProjection ); } /* -------------------------------------------------------------------- */ /* Set all the other header metadata into the ROI_PAC domain */ /* -------------------------------------------------------------------- */ for (int i = 0; i < CSLCount( papszRsc ); i++) { char **papszTokens; papszTokens = CSLTokenizeString2( papszRsc[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "FILE_LENGTH" ) == 0 || strcmp( papszTokens[0], "X_FIRST" ) == 0 || strcmp( papszTokens[0], "X_STEP" ) == 0 || strcmp( papszTokens[0], "Y_FIRST" ) == 0 || strcmp( papszTokens[0], "Y_STEP" ) == 0 || strcmp( papszTokens[0], "PROJECTION" ) == 0 || strcmp( papszTokens[0], "DATUM" ) == 0 ) { CSLDestroy( papszTokens ); continue; } poDS->SetMetadataItem(papszTokens[0], papszTokens[1], "ROI_PAC"); CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Free papszRsc */ /* -------------------------------------------------------------------- */ CSLDestroy( papszRsc ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int VICARKeywordHandler::Ingest( VSILFILE *fp, GByte *pabyHeader ) { /* -------------------------------------------------------------------- */ /* Read in buffer till we find END all on it's own line. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( fp, 0, SEEK_SET ) != 0 ) return FALSE; // Find LBLSIZE Entry char* pszLBLSIZE = strstr((char*)pabyHeader,"LBLSIZE"); int nOffset = 0; if (pszLBLSIZE) nOffset = pszLBLSIZE - (const char *)pabyHeader; char *pch1 = strstr((char*)pabyHeader+nOffset, "="); if( pch1 == NULL ) return FALSE; ++pch1; char *pch2 = strstr((char*)pabyHeader+nOffset, " "); if( pch2 == NULL ) return FALSE; char keyval[100]; strncpy( keyval, pch1, MAX( pch2-pch1, 99 ) ); keyval[MAX(pch2-pch1, 99)] = '\0'; LabelSize = atoi( keyval ); if( LabelSize > 10 * 1024 * 124 ) return FALSE; char* pszChunk = (char*) VSIMalloc( LabelSize + 1 ); if( pszChunk == NULL ) return FALSE; int nBytesRead = VSIFReadL( pszChunk, 1, LabelSize, fp ); pszChunk[LabelSize] = 0; osHeaderText += pszChunk ; VSIFree( pszChunk ); pszHeaderNext = osHeaderText.c_str(); /* -------------------------------------------------------------------- */ /* Process name/value pairs, keeping track of a "path stack". */ /* -------------------------------------------------------------------- */ if( !ReadGroup("") ) return FALSE; /* -------------------------------------------------------------------- */ /* Now check for the Vicar End-of-Dataset Label... */ /* -------------------------------------------------------------------- */ const char *pszResult = CSLFetchNameValue( papszKeywordList, "EOL" ); if( pszResult == NULL ) return FALSE; if( !EQUAL(pszResult,"1") ) return TRUE; /* -------------------------------------------------------------------- */ /* There is a EOL! e.G. h4231_0000.nd4.06 */ /* -------------------------------------------------------------------- */ long int nPixelOffset=0; if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "BYTE" )) { nPixelOffset = 1; } else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "HALF" )) { nPixelOffset = 2; } else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "FULL" )) { nPixelOffset = 4; } else if (EQUAL( CSLFetchNameValue(papszKeywordList,"FORMAT" ), "REAL" )) { nPixelOffset = 4; } const long int nCols = atoi( CSLFetchNameValue( papszKeywordList, "NS" ) ); const long int nRows = atoi( CSLFetchNameValue( papszKeywordList, "NL" ) ); const int nBands = atoi( CSLFetchNameValue( papszKeywordList, "NB" ) ); const int nBB = atoi( CSLFetchNameValue( papszKeywordList, "NBB" ) ); long int nLineOffset = nPixelOffset * nCols + nBB ; long int nBandOffset = nLineOffset * nRows; long int starteol = LabelSize + nBandOffset * nBands; if( VSIFSeekL( fp, starteol, SEEK_SET ) != 0 ) { printf("Error seeking to EOL!\n"); return FALSE; } char szChunk[100]; nBytesRead = VSIFReadL( szChunk, 1, 30, fp ); szChunk[nBytesRead] = '\0'; pszLBLSIZE = strstr( szChunk, "LBLSIZE" ); nOffset = 0; if (pszLBLSIZE) nOffset = pszLBLSIZE - (const char *)szChunk; pch1 = strstr( (char*)szChunk + nOffset,"=" ) + 1; pch2 = strstr( (char*)szChunk + nOffset, " " ); strncpy( keyval, pch1, pch2-pch1 ); int EOLabelSize = atoi( keyval ); if( EOLabelSize > 99 ) EOLabelSize = 99; if( VSIFSeekL( fp, starteol, SEEK_SET ) != 0 ) { printf("Error seeking again to EOL!\n"); return FALSE; } nBytesRead = VSIFReadL( szChunk, 1, EOLabelSize, fp ); szChunk[nBytesRead] = '\0'; osHeaderText += szChunk ; osHeaderText.append("END"); pszHeaderNext = osHeaderText.c_str(); return ReadGroup( "" ); }
int NITFDESGetTRE( NITFDES* psDES, int nOffset, char szTREName[7], char** ppabyTREData, int* pnFoundTRESize) { char szTREHeader[12]; char szTRETempName[7]; NITFSegmentInfo* psSegInfo; VSILFILE* fp; int nTRESize; memset(szTREName, '\0', 7); if (ppabyTREData) *ppabyTREData = NULL; if (pnFoundTRESize) *pnFoundTRESize = 0; if (nOffset < 0) return FALSE; if (psDES == NULL) return FALSE; if (CSLFetchNameValue(psDES->papszMetadata, "NITF_DESOFLW") == NULL) return FALSE; psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment; fp = psDES->psFile->fp; if (nOffset >= psSegInfo->nSegmentSize) return FALSE; VSIFSeekL(fp, psSegInfo->nSegmentStart + nOffset, SEEK_SET); if (VSIFReadL(szTREHeader, 1, 11, fp) != 11) { /* Some files have a nSegmentSize larger than what is is in reality */ /* So exit silently if we're at end of file */ VSIFSeekL(fp, 0, SEEK_END); if (VSIFTellL(fp) == psSegInfo->nSegmentStart + nOffset) return FALSE; CPLError(CE_Failure, CPLE_FileIO, "Cannot get 11 bytes at offset " CPL_FRMT_GUIB ".", psSegInfo->nSegmentStart + nOffset ); return FALSE; } szTREHeader[11] = '\0'; memcpy(szTRETempName, szTREHeader, 6); szTRETempName[6] = '\0'; nTRESize = atoi(szTREHeader + 6); if (nTRESize < 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid size (%d) for TRE %s", nTRESize, szTRETempName); return FALSE; } if (nOffset + 11 + nTRESize > psSegInfo->nSegmentSize) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read %s TRE. Not enough bytes : remaining %d, expected %d", szTRETempName, (int)(psSegInfo->nSegmentSize - (nOffset + 11)), nTRESize); return FALSE; } if (ppabyTREData) { /* Allocate one extra byte for the NULL terminating character */ *ppabyTREData = (char*) VSIMalloc(nTRESize + 1); if (*ppabyTREData == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate %d bytes for TRE %s", nTRESize, szTRETempName); return FALSE; } (*ppabyTREData)[nTRESize] = '\0'; if ((int)VSIFReadL(*ppabyTREData, 1, nTRESize, fp) != nTRESize) { CPLError(CE_Failure, CPLE_FileIO, "Cannot get %d bytes at offset " CPL_FRMT_GUIB ".", nTRESize, VSIFTellL(fp) ); VSIFree(*ppabyTREData); *ppabyTREData = NULL; return FALSE; } } strcpy(szTREName, szTRETempName); if (pnFoundTRESize) *pnFoundTRESize = nTRESize; return TRUE; }
CPLErr CPL_STDCALL GDALWriteRPBFile( const char *pszFilename, char **papszMD ) { CPLString osRPBFilename = CPLResetExtension( pszFilename, "RPB" ); /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osRPBFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create %s for writing.\n%s", osRPBFilename.c_str(), CPLGetLastErrorMsg() ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Write the prefix information. */ /* -------------------------------------------------------------------- */ VSIFPrintfL( fp, "%s", "satId = \"QB02\";\n" ); VSIFPrintfL( fp, "%s", "bandId = \"P\";\n" ); VSIFPrintfL( fp, "%s", "SpecId = \"RPC00B\";\n" ); VSIFPrintfL( fp, "%s", "BEGIN_GROUP = IMAGE\n" ); VSIFPrintfL( fp, "%s", "\terrBias = 0.0;\n" ); VSIFPrintfL( fp, "%s", "\terrRand = 0.0;\n" ); /* -------------------------------------------------------------------- */ /* Write RPC values from our RPC metadata. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; apszRPBMap[i] != NULL; i += 2 ) { const char *pszRPBVal = CSLFetchNameValue( papszMD, apszRPBMap[i] ); const char *pszRPBTag; if( pszRPBVal == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s field missing in metadata, %s file not written.", apszRPBMap[i], osRPBFilename.c_str() ); VSIFCloseL( fp ); VSIUnlink( osRPBFilename ); return CE_Failure; } pszRPBTag = apszRPBMap[i+1]; if( EQUALN(pszRPBTag,"IMAGE.",6) ) pszRPBTag += 6; if( strstr(apszRPBMap[i], "COEF" ) == NULL ) { VSIFPrintfL( fp, "\t%s = %s;\n", pszRPBTag, pszRPBVal ); } else { // Reformat in brackets with commas over multiple lines. VSIFPrintfL( fp, "\t%s = (\n", pszRPBTag ); char **papszItems = CSLTokenizeStringComplex( pszRPBVal, " ,", FALSE, FALSE ); if( CSLCount(papszItems) != 20 ) { CPLError( CE_Failure, CPLE_AppDefined, "%s field is corrupt (not 20 values), %s file not written.\n%s = %s", apszRPBMap[i], osRPBFilename.c_str(), apszRPBMap[i], pszRPBVal ); VSIFCloseL( fp ); VSIUnlink( osRPBFilename ); return CE_Failure; } int j; for( j = 0; j < 20; j++ ) { if( j < 19 ) VSIFPrintfL( fp, "\t\t\t%s,\n", papszItems[j] ); else VSIFPrintfL( fp, "\t\t\t%s);\n", papszItems[j] ); } CSLDestroy( papszItems ); } } /* -------------------------------------------------------------------- */ /* Write end part */ /* -------------------------------------------------------------------- */ VSIFPrintfL( fp, "%s", "END_GROUP = IMAGE\n" ); VSIFPrintfL( fp, "END;\n" ); VSIFCloseL( fp ); return CE_None; }
NITFDES *NITFDESAccess( NITFFile *psFile, int iSegment ) { NITFDES *psDES; char *pachHeader; NITFSegmentInfo *psSegInfo; char szDESID[26]; int nOffset; int bHasDESOFLW; int nDESSHL; /* -------------------------------------------------------------------- */ /* Verify segment, and return existing DES accessor if there */ /* is one. */ /* -------------------------------------------------------------------- */ if( iSegment < 0 || iSegment >= psFile->nSegmentCount ) return NULL; psSegInfo = psFile->pasSegmentInfo + iSegment; if( !EQUAL(psSegInfo->szSegmentType,"DE") ) return NULL; if( psSegInfo->hAccess != NULL ) return (NITFDES *) psSegInfo->hAccess; /* -------------------------------------------------------------------- */ /* Read the DES subheader. */ /* -------------------------------------------------------------------- */ if (psSegInfo->nSegmentHeaderSize < 200) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); return NULL; } pachHeader = (char*) VSIMalloc(psSegInfo->nSegmentHeaderSize); if (pachHeader == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory for segment header"); return NULL; } retry: if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentHeaderStart, SEEK_SET ) != 0 || VSIFReadL( pachHeader, 1, psSegInfo->nSegmentHeaderSize, psFile->fp ) != psSegInfo->nSegmentHeaderSize ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %u byte DES subheader from " CPL_FRMT_GUIB ".", psSegInfo->nSegmentHeaderSize, psSegInfo->nSegmentHeaderStart ); CPLFree(pachHeader); return NULL; } if (!EQUALN(pachHeader, "DE", 2)) { if (EQUALN(pachHeader + 4, "DERegistered", 12)) { /* BAO_46_Ed1/rpf/conc/concz10/000fz010.ona and cie are buggy */ CPLDebug("NITF", "Patching nSegmentHeaderStart and nSegmentStart for DE segment %d", iSegment); psSegInfo->nSegmentHeaderStart += 4; psSegInfo->nSegmentStart += 4; goto retry; } CPLError(CE_Failure, CPLE_AppDefined, "Invalid segment prefix for DE segment %d", iSegment); CPLFree(pachHeader); return NULL; } /* -------------------------------------------------------------------- */ /* Initialize DES object. */ /* -------------------------------------------------------------------- */ psDES = (NITFDES *) CPLCalloc(sizeof(NITFDES),1); psDES->psFile = psFile; psDES->iSegment = iSegment; psDES->pachHeader = pachHeader; psSegInfo->hAccess = psDES; /* -------------------------------------------------------------------- */ /* Collect a variety of information as metadata. */ /* -------------------------------------------------------------------- */ #define GetMD( length, name ) \ do { NITFExtractMetadata( &(psDES->papszMetadata), pachHeader, \ nOffset, length, \ "NITF_" #name ); \ nOffset += length; } while(0) nOffset = 2; GetMD( 25, DESID ); GetMD( 2, DESVER ); GetMD( 1, DECLAS ); GetMD( 2, DESCLSY ); GetMD( 11, DESCODE ); GetMD( 2, DESCTLH ); GetMD( 20, DESREL ); GetMD( 2, DESDCTP ); GetMD( 8, DESDCDT ); GetMD( 4, DESDCXM ); GetMD( 1, DESDG ); GetMD( 8, DESDGDT ); GetMD( 43, DESCLTX ); GetMD( 1, DESCATP ); GetMD( 40, DESCAUT ); GetMD( 1, DESCRSN ); GetMD( 8, DESSRDT ); GetMD( 15, DESCTLN ); /* Load DESID */ NITFGetField( szDESID, pachHeader, 2, 25); /* For NITF < 02.10, we cannot rely on DESID=TRE_OVERFLOW to detect */ /* if DESOFLW and DESITEM are present. So if the next 4 bytes are non */ /* numeric, we'll assume that DESOFLW is there */ bHasDESOFLW = EQUALN(szDESID, "TRE_OVERFLOW", strlen("TRE_OVERFLOW")) || (!((pachHeader[nOffset+0] >= '0' && pachHeader[nOffset+0] <= '9') && (pachHeader[nOffset+1] >= '0' && pachHeader[nOffset+1] <= '9') && (pachHeader[nOffset+2] >= '0' && pachHeader[nOffset+2] <= '9') && (pachHeader[nOffset+3] >= '0' && pachHeader[nOffset+3] <= '9'))); if (bHasDESOFLW) { if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 6 + 3 ) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } GetMD( 6, DESOFLW ); GetMD( 3, DESITEM ); } if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 4 ) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } GetMD( 4, DESSHL ); nDESSHL = atoi(CSLFetchNameValue( psDES->papszMetadata, "NITF_DESSHL" ) ); if (nDESSHL < 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for DESSHL"); NITFDESDeaccess(psDES); return NULL; } if ( (int)psSegInfo->nSegmentHeaderSize < nOffset + nDESSHL) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } if (EQUALN(szDESID, "CSSHPA DES", strlen("CSSHPA DES"))) { if ( nDESSHL != 62 && nDESSHL != 80) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid DESSHL for CSSHPA DES"); NITFDESDeaccess(psDES); return NULL; } GetMD( 25, SHAPE_USE ); GetMD( 10, SHAPE_CLASS ); if (nDESSHL == 80) GetMD( 18, CC_SOURCE ); GetMD( 3, SHAPE1_NAME ); GetMD( 6, SHAPE1_START ); GetMD( 3, SHAPE2_NAME ); GetMD( 6, SHAPE2_START ); GetMD( 3, SHAPE3_NAME ); GetMD( 6, SHAPE3_START ); } else if (EQUALN(szDESID, "XML_DATA_CONTENT", strlen("XML_DATA_CONTENT"))) { /* TODO : handle nDESSHL = 0005 and 0283 */ if (nDESSHL >= 5) { GetMD( 5, DESCRC ); if (nDESSHL >= 283) { GetMD( 8, DESSHFT ); GetMD( 20, DESSHDT ); GetMD( 40, DESSHRP ); GetMD( 60, DESSHSI ); GetMD( 10, DESSHSV ); GetMD( 20, DESSHSD ); GetMD( 120, DESSHTN ); if (nDESSHL >= 773) { GetMD( 125, DESSHLPG ); GetMD( 25, DESSHLPT ); GetMD( 20, DESSHLI ); GetMD( 120, DESSHLIN ); GetMD( 200, DESSHABS ); } } } } else if (EQUALN(szDESID, "CSATTA DES", strlen("CSATTA DES")) && nDESSHL == 52) { GetMD( 12, ATT_TYPE ); GetMD( 14, DT_ATT ); GetMD( 8, DATE_ATT ); GetMD( 13, T0_ATT ); GetMD( 5, NUM_ATT ); } else if (nDESSHL > 0) GetMD( nDESSHL, DESSHF ); if ((int)psSegInfo->nSegmentHeaderSize > nOffset) { char* pszEscapedDESDATA = CPLEscapeString( pachHeader + nOffset, (int)psSegInfo->nSegmentHeaderSize - nOffset, CPLES_BackslashQuotable ); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA", pszEscapedDESDATA ); CPLFree(pszEscapedDESDATA); } else { char* pachData = (char*)VSIMalloc((size_t)psSegInfo->nSegmentSize); if (pachData == NULL ) { CPLDebug("NITF", "Cannot allocate " CPL_FRMT_GUIB " bytes DES data", psSegInfo->nSegmentSize); } else if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentStart, SEEK_SET ) != 0 || VSIFReadL( pachData, 1, (size_t)psSegInfo->nSegmentSize, psFile->fp ) != psSegInfo->nSegmentSize ) { CPLDebug("NITF", "Failed to read " CPL_FRMT_GUIB" bytes DES data from " CPL_FRMT_GUIB ".", psSegInfo->nSegmentSize, psSegInfo->nSegmentStart ); } else { char* pszEscapedDESDATA = CPLEscapeString( pachData, (int)psSegInfo->nSegmentSize, CPLES_BackslashQuotable ); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA", pszEscapedDESDATA ); CPLFree(pszEscapedDESDATA); } #ifdef notdef /* Disabled because might generate a huge amount of elements */ if (EQUALN(szDESID, "CSATTA DES", strlen("CSATTA DES"))) { int nNumAtt = atoi(CSLFetchNameValueDef(psDES->papszMetadata, "NITF_NUM_ATT", "0")); if (nNumAtt * 8 * 4 == psSegInfo->nSegmentSize) { int nMDSize = CSLCount(psDES->papszMetadata); char** papszMD = (char**)VSIRealloc(psDES->papszMetadata, (nMDSize + nNumAtt * 4 + 1) * sizeof(char*)); if (papszMD) { int i, j; const GByte* pachDataIter = pachData; psDES->papszMetadata = papszMD; for(i=0;i<nNumAtt;i++) { char szAttrNameValue[64+1+256+1]; double dfVal; for(j=0;j<4;j++) { memcpy(&dfVal, pachDataIter, 8); CPL_MSBPTR64(&dfVal); pachDataIter += 8; sprintf(szAttrNameValue, "NITF_ATT_Q%d_%d=%.16g", j+1, i, dfVal); papszMD[nMDSize + i * 4 + j] = CPLStrdup(szAttrNameValue); } } papszMD[nMDSize + nNumAtt * 4] = NULL; } } } #endif CPLFree(pachData); } return psDES; }
char ** CPL_STDCALL GDALLoadIMDFile( const char *pszFilename, char **papszSiblingFiles ) { /* -------------------------------------------------------------------- */ /* Try to identify the IMD file in upper or lower case. */ /* -------------------------------------------------------------------- */ CPLString osTarget = CPLResetExtension( pszFilename, "IMD" ); /* Is this already a IMD file ? */ if (EQUAL(CPLGetExtension(pszFilename), "IMD")) osTarget = pszFilename; else if( papszSiblingFiles == NULL ) { VSIStatBufL sStatBuf; if( VSIStatL( osTarget, &sStatBuf ) != 0 ) { osTarget = CPLResetExtension( pszFilename, "imd" ); if( VSIStatL( osTarget, &sStatBuf ) != 0 ) return NULL; } } else { int iSibling = CSLFindString( papszSiblingFiles, CPLGetFilename(osTarget) ); if( iSibling < 0 ) return NULL; osTarget.resize(osTarget.size() - strlen(papszSiblingFiles[iSibling])); osTarget += papszSiblingFiles[iSibling]; } /* -------------------------------------------------------------------- */ /* Read file and parse. */ /* -------------------------------------------------------------------- */ CPLKeywordParser oParser; VSILFILE *fp = VSIFOpenL( osTarget, "r" ); if( fp == NULL ) return NULL; if( !oParser.Ingest( fp ) ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Consider version changing. */ /* -------------------------------------------------------------------- */ char **papszIMD = CSLDuplicate( oParser.GetAllKeywords() ); const char *pszVersion = CSLFetchNameValue( papszIMD, "version" ); if( pszVersion == NULL ) { /* ? */; } else if( EQUAL(pszVersion,"\"AA\"") ) { GDAL_IMD_AA2R( &papszIMD ); } return papszIMD; }
/** * LoadMetadata() */ void GDALMDReaderKompsat::LoadMetadata() { if(m_bIsMetadataLoad) return; if(!m_osIMDSourceFilename.empty()) { m_papszIMDMD = ReadTxtToList( ); } if(!m_osRPBSourceFilename.empty()) { m_papszRPCMD = GDALLoadRPCFile( m_osRPBSourceFilename ); } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "KARI"); m_bIsMetadataLoad = true; const char* pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "AUX_SATELLITE_NAME"); const char* pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "AUX_SATELLITE_SENSOR"); if(nullptr != pszSatId1 && nullptr != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLSPrintf( "%s %s", CPLStripQuotes(pszSatId1).c_str(), CPLStripQuotes(pszSatId2).c_str())); } else if(nullptr != pszSatId1 && nullptr == pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId1)); } else if(nullptr == pszSatId1 && nullptr != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId2)); } const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "AUX_CLOUD_STATUS"); if(nullptr != pszCloudCover) { int nCC = atoi(pszCloudCover); if(nCC > 100 || nCC < 0) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", nCC)); } } const char* pszDate = CSLFetchNameValue(m_papszIMDMD, "AUX_STRIP_ACQ_DATE_UT"); if(nullptr != pszDate) { const char* pszTime = CSLFetchNameValue(m_papszIMDMD, "AUX_STRIP_ACQ_START_UT"); if(nullptr == pszTime) pszTime = "000000.000000"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } }