- #2565, ST_SummaryStats(tablename, rastercolumn, ...) uses
ST_SummaryStatsAgg()
- #2567, ST_Count(tablename, rastercolumn, ...) uses ST_CountAgg()
+ - By default, PostGIS raster prevents usage of GDAL VRT, WCS, WMS
+ and MEM drivers
* Deprecated signatures *
* to check for pixels with value
* @param count : number of elements in bandNums and exclude_nodata_values
* @param rtn_drv : is set to the GDAL driver object
+ * @param destroy_rtn_drv : if non-zero, caller must destroy the MEM driver
*
* @return GDAL dataset using GDAL MEM driver
*/
uint32_t *bandNums,
int *excludeNodataValues,
int count,
- GDALDriverH *rtn_drv
+ GDALDriverH *rtn_drv, int *destroy_rtn_drv
);
/**
long j;
OGRSFDriverH ogr_drv = NULL;
GDALDriverH gdal_drv = NULL;
+ int destroy_gdal_drv = 0;
GDALDatasetH memdataset = NULL;
GDALRasterBandH gdal_band = NULL;
OGRDataSourceH memdatasource = NULL;
/*****************************************************
* Convert raster to GDAL MEM dataset
*****************************************************/
- memdataset = rt_raster_to_gdal_mem(raster, NULL, bandNums, excludeNodataValues, 1, &gdal_drv);
+ memdataset = rt_raster_to_gdal_mem(raster, NULL, bandNums, excludeNodataValues, 1, &gdal_drv, &destroy_gdal_drv);
if (NULL == memdataset) {
rterror("rt_raster_gdal_polygonize: Couldn't convert raster to GDAL MEM dataset");
return NULL;
if (NULL == memdatasource) {
rterror("rt_raster_gdal_polygonize: Couldn't create a OGR Datasource to store pols");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
return NULL;
}
/* xxx jorgearevalo: what should we do now? */
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGRReleaseDataSource(memdatasource);
return NULL;
rterror("rt_raster_gdal_polygonize: Couldn't create layer to store polygons");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGRReleaseDataSource(memdatasource);
return NULL;
rterror("rt_raster_gdal_polygonize: Couldn't get GDAL band to polygonize");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGR_Fld_Destroy(hFldDfn);
OGR_DS_DeleteLayer(memdatasource, 0);
OGRReleaseDataSource(memdatasource);
rterror("rt_raster_gdal_polygonize: Could not polygonize GDAL band");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGR_Fld_Destroy(hFldDfn);
OGR_DS_DeleteLayer(memdatasource, 0);
OGRReleaseDataSource(memdatasource);
rterror("rt_raster_gdal_polygonize: Could not allocate memory for geomval set");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGR_Fld_Destroy(hFldDfn);
OGR_DS_DeleteLayer(memdatasource, 0);
if (NULL != pszQuery)
OGR_F_Destroy(hFeature);
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
OGR_Fld_Destroy(hFldDfn);
OGR_DS_DeleteLayer(memdatasource, 0);
if (NULL != pszQuery)
RASTER_DEBUG(3, "destroying GDAL MEM raster");
GDALClose(memdataset);
+ if (destroy_gdal_drv) GDALDestroyDriver(gdal_drv);
RASTER_DEBUG(3, "destroying OGR MEM vector");
OGR_Fld_Destroy(hFldDfn);
* for freeing the returned data using CPLFree()
*/
uint8_t*
-rt_raster_to_gdal(rt_raster raster, const char *srs,
- char *format, char **options, uint64_t *gdalsize) {
+rt_raster_to_gdal(
+ rt_raster raster, const char *srs,
+ char *format, char **options, uint64_t *gdalsize
+) {
GDALDriverH src_drv = NULL;
+ int destroy_src_drv = 0;
GDALDatasetH src_ds = NULL;
vsi_l_offset rtn_lenvsi;
RASTER_DEBUGF(3, "output format is %s", format);
/* load raster into a GDAL MEM raster */
- src_ds = rt_raster_to_gdal_mem(raster, srs, NULL, NULL, 0, &src_drv);
+ src_ds = rt_raster_to_gdal_mem(raster, srs, NULL, NULL, 0, &src_drv, &destroy_src_drv);
if (NULL == src_ds) {
rterror("rt_raster_to_gdal: Could not convert raster to GDAL MEM format");
return 0;
if (NULL == rtn_drv) {
rterror("rt_raster_to_gdal: Could not load the output GDAL driver");
GDALClose(src_ds);
+ if (destroy_src_drv) GDALDestroyDriver(src_drv);
return 0;
}
RASTER_DEBUG(3, "Output driver loaded");
NULL, /* progress function */
NULL /* progress data */
);
- if (NULL == rtn_ds) {
- rterror("rt_raster_to_gdal: Could not create the output GDAL dataset");
- GDALClose(src_ds);
- return 0;
- }
/* close source dataset */
GDALClose(src_ds);
+ if (destroy_src_drv) GDALDestroyDriver(src_drv);
RASTER_DEBUG(3, "Closed GDAL MEM raster");
+ if (NULL == rtn_ds) {
+ rterror("rt_raster_to_gdal: Could not create the output GDAL dataset");
+ return 0;
+ }
+
RASTER_DEBUGF(4, "dataset SRS: %s", GDALGetProjectionRef(rtn_ds));
/* close dataset, this also flushes any pending writes */
rt_util_gdal_register_all();
count = GDALGetDriverCount();
+ RASTER_DEBUGF(3, "%d drivers found", count);
+
rtn = (rt_gdaldriver) rtalloc(count * sizeof(struct rt_gdaldriver_t));
if (NULL == rtn) {
rterror("rt_raster_gdal_drivers: Could not allocate memory for gdaldriver structure");
txt_len = strlen(txt);
if (cancc) {
- RASTER_DEBUGF(3, "rt_raster_gdal_driver: driver %s (%d) supports CreateCopy() and VirtualIO()", txt, i);
+ RASTER_DEBUGF(3, "driver %s (%d) supports CreateCopy() and VirtualIO()", txt, i);
}
txt_len = (txt_len + 1) * sizeof(char);
******************************************************************************/
/**
- * Return GDAL dataset using GDAL MEM driver from raster
+ * Return GDAL dataset using GDAL MEM driver from raster.
*
* @param raster : raster to convert to GDAL MEM
* @param srs : the raster's coordinate system in OGC WKT
* ignore nodata values for the band
* @param count : number of elements in bandNums
* @param rtn_drv : is set to the GDAL driver object
+ * @param destroy_rtn_drv : if non-zero, caller must destroy the MEM driver
*
* @return GDAL dataset using GDAL MEM driver
*/
uint32_t *bandNums,
int *excludeNodataValues,
int count,
- GDALDriverH *rtn_drv
+ GDALDriverH *rtn_drv, int *destroy_rtn_drv
) {
GDALDriverH drv = NULL;
GDALDatasetH ds = NULL;
assert(NULL != raster);
assert(NULL != rtn_drv);
+ assert(NULL != destroy_rtn_drv);
+
+ *destroy_rtn_drv = 0;
/* store raster in GDAL MEM raster */
- if (!rt_util_gdal_driver_registered("MEM"))
+ if (!rt_util_gdal_driver_registered("MEM")) {
+ RASTER_DEBUG(4, "Registering MEM driver");
GDALRegister_MEM();
+ *destroy_rtn_drv = 1;
+ }
drv = GDALGetDriverByName("MEM");
if (NULL == drv) {
rterror("rt_raster_to_gdal_mem: Could not load the MEM GDAL driver");
}
*rtn_drv = drv;
+ /* unload driver from GDAL driver manager */
+ if (*destroy_rtn_drv) {
+ RASTER_DEBUG(4, "Deregistering MEM driver");
+ GDALDeregisterDriver(drv);
+ }
+
width = rt_raster_get_width(raster);
height = rt_raster_get_height(raster);
ds = GDALCreate(
CPLErr cplerr;
double _gt[6] = {0};
GDALDriverH _drv = NULL;
+ int unload_drv = 0;
GDALDatasetH _ds = NULL;
GDALRasterBandH _band = NULL;
_dim[0], _dim[1]);
/* load GDAL mem */
- if (!rt_util_gdal_driver_registered("MEM"))
+ if (!rt_util_gdal_driver_registered("MEM")) {
+ RASTER_DEBUG(4, "Registering MEM driver");
GDALRegister_MEM();
+ unload_drv = 1;
+ }
_drv = GDALGetDriverByName("MEM");
if (NULL == _drv) {
rterror("rt_raster_gdal_rasterize: Could not load the MEM GDAL driver");
return NULL;
}
+ /* unload driver from GDAL driver manager */
+ if (unload_drv) {
+ RASTER_DEBUG(4, "Deregistering MEM driver");
+ GDALDeregisterDriver(_drv);
+ }
+
_ds = GDALCreate(_drv, "", _dim[0], _dim[1], 0, GDT_Byte, NULL);
if (NULL == _ds) {
rterror("rt_raster_gdal_rasterize: Could not create a GDALDataset to rasterize the geometry into");
OGR_G_DestroyGeometry(src_geom);
_rti_rasterize_arg_destroy(arg);
/* OGRCleanupAll(); */
+ if (unload_drv) GDALDestroyDriver(_drv);
return NULL;
}
/* OGRCleanupAll(); */
GDALClose(_ds);
+ if (unload_drv) GDALDestroyDriver(_drv);
return NULL;
}
/* OGRCleanupAll(); */
GDALClose(_ds);
+ if (unload_drv) GDALDestroyDriver(_drv);
return NULL;
}
/* OGRCleanupAll(); */
GDALClose(_ds);
+ if (unload_drv) GDALDestroyDriver(_drv);
return NULL;
}
/* OGRCleanupAll(); */
GDALClose(_ds);
+ if (unload_drv) GDALDestroyDriver(_drv);
return NULL;
}
/* OGRCleanupAll(); */
GDALClose(_ds);
+ if (unload_drv) GDALDestroyDriver(_drv);
if (NULL == rast) {
rterror("rt_raster_gdal_rasterize: Could not rasterize geometry");
rt_util_gdal_register_all(void) {
static int registered = 0;
- if (registered)
+ if (registered) {
+ RASTER_DEBUG(3, "Already called once... not calling GDALAllRegister");
return;
+ }
+ RASTER_DEBUG(3, "Calling GDALAllRegister");
GDALAllRegister();
registered = 1;
}
GDALDriverH drv;
GDALDatasetH ds;
char *srs;
+ int destroy_drv;
} src, dst;
GDALWarpOptions *wopts;
}
arg->src.drv = NULL;
+ arg->src.destroy_drv = 0;
arg->src.ds = NULL;
arg->src.srs = NULL;
arg->dst.drv = NULL;
+ arg->dst.destroy_drv = 0;
arg->dst.ds = NULL;
arg->dst.srs = NULL;
if (arg->dst.srs != NULL)
CPLFree(arg->dst.srs);
+ if (arg->dst.drv != NULL && arg->dst.destroy_drv) {
+ GDALDeregisterDriver(arg->dst.drv);
+ GDALDestroyDriver(arg->dst.drv);
+ }
+
if (arg->src.ds != NULL)
GDALClose(arg->src.ds);
if (arg->src.srs != NULL)
CPLFree(arg->src.srs);
+ if (arg->src.drv != NULL && arg->src.destroy_drv) {
+ GDALDeregisterDriver(arg->src.drv);
+ GDALDestroyDriver(arg->src.drv);
+ }
+
if (arg->transform.func == GDALApproxTransform) {
if (arg->transform.arg.imgproj != NULL)
GDALDestroyGenImgProjTransformer(arg->transform.arg.imgproj);
}
/* load raster into a GDAL MEM dataset */
- arg->src.ds = rt_raster_to_gdal_mem(raster, arg->src.srs, NULL, NULL, 0, &(arg->src.drv));
+ arg->src.ds = rt_raster_to_gdal_mem(raster, arg->src.srs, NULL, NULL, 0, &(arg->src.drv), &(arg->src.destroy_drv));
if (NULL == arg->src.ds) {
rterror("rt_raster_gdal_warp: Could not convert raster to GDAL MEM format");
_rti_warp_arg_destroy(arg);
}
/* load VRT driver */
- if (!rt_util_gdal_driver_registered("VRT"))
+ if (!rt_util_gdal_driver_registered("VRT")) {
+ RASTER_DEBUG(3, "Registering VRT driver");
+ RASTER_DEBUGF(4, "VRT registered: %d", rt_util_gdal_driver_registered("VRT"));
GDALRegister_VRT();
+ RASTER_DEBUGF(4, "VRT registered: %d", rt_util_gdal_driver_registered("VRT"));
+ arg->dst.destroy_drv = 1;
+ }
arg->dst.drv = GDALGetDriverByName("VRT");
if (NULL == arg->dst.drv) {
rterror("rt_raster_gdal_warp: Could not load the output GDAL VRT driver");
POSTGIS_RT_DEBUGF(4, "newdrivers = %s", newdrivers);
/* validate new drivers */
+ /* TODO: flesh this out */
/*
CPLSetConfigOption("GDAL_SKIP", newdrivers);
/* Module load callback */
void
_PG_init(void) {
+ const char *gdal_skip;
/* restrict GDAL drivers */
- /* unless over-ridden by GUCs, default to VRT, WMS, WCS and MEM */
- CPLSetConfigOption("GDAL_SKIP", "VRT WMS WCS MEM");
+ /* unless already set, default to VRT, WMS, WCS and MEM */
+ gdal_skip = CPLGetConfigOption("GDAL_SKIP", NULL);
+ if (gdal_skip == NULL)
+ CPLSetConfigOption("GDAL_SKIP", "VRT WMS WCS MEM");
/* Install liblwgeom handlers */
pg_install_lwgeom_handlers();
double value;
GDALDriverH gddrv = NULL;
+ int destroy = 0;
GDALDatasetH gdds = NULL;
raster = rt_raster_new(width, height);
}
}
- gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv);
+ gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv, &destroy);
CU_ASSERT(gddrv != NULL);
+ CU_ASSERT_EQUAL(destroy, 0);
CU_ASSERT(gdds != NULL);
CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width);
CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height);
}
}
- gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv);
+ gdds = rt_raster_to_gdal_mem(raster, NULL, NULL, NULL, 0, &gddrv, &destroy);
CU_ASSERT(gddrv != NULL);
+ CU_ASSERT_EQUAL(destroy, 0);
CU_ASSERT(gdds != NULL);
CU_ASSERT_EQUAL(GDALGetRasterXSize(gdds), width);
CU_ASSERT_EQUAL(GDALGetRasterYSize(gdds), height);
}
GDALClose(gdds);
+ gdds = NULL;
+ gddrv = NULL;
cu_free_raster(rast);
cu_free_raster(raster);
TEST_BUGS = \
bug_test_car5 \
+ permitted_gdal_drivers \
tickets
TEST_LOADER = \
--- /dev/null
+INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +datum=WGS84 +no_defs ');
+INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (3857,'EPSG',3857,'PROJCS["WGS 84 / Pseudo-Mercator",GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Mercator_1SP"],PARAMETER["central_meridian",0],PARAMETER["scale_factor",1],PARAMETER["false_easting",0],PARAMETER["false_northing",0],EXTENSION["PROJ4","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs"],AUTHORITY["EPSG","3857"],AXIS["X",EAST],AXIS["Y",NORTH]]','+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs');
+
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+-- make sure raster transforms still work
+-- warp API requires VRT support
+WITH foo AS (
+ SELECT st_asraster(st_buffer('SRID=3857;POINT(0 0)'::geometry, 8), 0.5, 0.5) AS rast
+),
+transformed AS (
+ SELECT st_transform(rast, 4326) AS rast FROM foo
+)
+SELECT ST_SRID(rast) FROM transformed;
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+-- no VRT permitted by default
+SELECT convert_from(ST_AsGDALRaster(ST_FromGDALRaster('<VRTDataset rasterXSize="1000"
+rasterYSize="1"><VRTRasterBand band="1"
+subClass="VRTRawRasterBand"><SourceFilename>/etc/passwd</SourceFilename></VRTRasterBand></VRTDataset>'::bytea),
+'EHDR')::bytea, 'LATIN1');
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+CREATE TEMP TABLE raster_test AS
+ SELECT
+ 'passwd' AS lbl,
+ '0100000100000000000000F03F000000000000F0BF0000000000000000000000000000000000000000000000000000000000000000110F0000E80301008400003C56525444617461736574207261737465725853697A653D223130303022207261737465725953697A653D2231223E3C56525452617374657242616E642062616E643D22312220737562436C6173733D2256525452617752617374657242616E64223E3C536F7572636546696C656E616D653E2F6574632F7061737377643C2F536F7572636546696C656E616D653E3C2F56525452617374657242616E643E3C2F565254446174617365743E00'::raster AS r
+ UNION ALL
+ SELECT
+ 'inline' AS lbl,
+ '0100000100000000000000F03F000000000000F03F00000000000020C000000000000020C000000000000000000000000000000000110F000010001000440000000000000101010101010000000000000000010101010101010101010000000000010101010101010101010101000000010101010101010101010101010100000101010101010101010101010101000101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010001010101010101010101010101010000010101010101010101010101010100000001010101010101010101010100000000000101010101010101010100000000000000000101010101010000000000'::raster AS r
+;
+
+SELECT count(convert_from(ST_AsGDALRaster(r, 'EHDR')::bytea, 'LATIN1')) as passwd from raster_test where lbl = 'passwd';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT count(convert_from(ST_AsGDALRaster(r, 'EHDR')::bytea, 'LATIN1')) as passwd from raster_test where lbl = 'passwd';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT st_srid(st_transform(r, 4326)) from raster_test where lbl = 'inline';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT st_srid(st_transform(r, 4326)) from raster_test where lbl = 'inline';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT count(convert_from(ST_AsGDALRaster(r, 'EHDR')::bytea, 'LATIN1')) as passwd from raster_test where lbl = 'passwd';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT count(convert_from(ST_AsGDALRaster(r, 'EHDR')::bytea, 'LATIN1')) as passwd from raster_test where lbl = 'passwd';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
+
+SELECT st_srid(st_transform(r, 4326)) from raster_test where lbl = 'inline';
+SELECT short_name FROM st_gdaldrivers() WHERE upper(short_name) = 'VRT';
--- /dev/null
+4326
+ERROR: RASTER_fromGDALRaster: Could not open bytea with GDAL. Check that the bytea is of a GDAL supported format
+ERROR: rt_band_load_offline_data: Cannot open offline raster: <VRTDataset rasterXSize="1000" rasterYSize="1"><VRTRasterBand band="1" subClass="VRTRawRasterBand"><SourceFilename>/etc/passwd</SourceFilename></VRTRasterBand></VRTDataset>
+ERROR: rt_band_load_offline_data: Cannot open offline raster: <VRTDataset rasterXSize="1000" rasterYSize="1"><VRTRasterBand band="1" subClass="VRTRawRasterBand"><SourceFilename>/etc/passwd</SourceFilename></VRTRasterBand></VRTDataset>
+4326
+4326
+ERROR: rt_band_load_offline_data: Cannot open offline raster: <VRTDataset rasterXSize="1000" rasterYSize="1"><VRTRasterBand band="1" subClass="VRTRawRasterBand"><SourceFilename>/etc/passwd</SourceFilename></VRTRasterBand></VRTDataset>
+ERROR: rt_band_load_offline_data: Cannot open offline raster: <VRTDataset rasterXSize="1000" rasterYSize="1"><VRTRasterBand band="1" subClass="VRTRawRasterBand"><SourceFilename>/etc/passwd</SourceFilename></VRTRasterBand></VRTDataset>
+4326