Merge pull request #2555 from stephend/2.3.x

Throw datasource_exception on GDAL RasterIO() failures
This commit is contained in:
Robert Coup 2014-11-05 18:21:26 +13:00
commit ea61c5728d
3 changed files with 132 additions and 24 deletions

View file

@ -104,6 +104,7 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
GDALRasterBand * blue = 0;
GDALRasterBand * alpha = 0;
GDALRasterBand * grey = 0;
CPLErr raster_io_error = CE_None;
/*
#ifdef MAPNIK_LOG
@ -215,9 +216,12 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
float* imageData = (float*)image.getBytes();
GDALRasterBand * band = dataset_.GetRasterBand(band_);
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
band->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
}
else // working with all bands
{
@ -307,9 +311,12 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
// TODO - we assume here the nodata value for the red band applies to all bands
// more details about this at http://trac.osgeo.org/gdal/ticket/2734
float* imageData = (float*)image.getBytes();
red->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
int len = image.width() * image.height();
for (int i = 0; i < len; ++i)
{
@ -323,12 +330,21 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
}
}
}
red->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
green->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 1,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
raster_io_error = red->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
raster_io_error = green->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 1,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
raster_io_error = blue->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 2,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
}
else if (grey)
{
@ -342,9 +358,12 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: applying nodata value for layer=" << apply_nodata;
// first read the data in and create an alpha channel from the nodata values
float* imageData = (float*)image.getBytes();
grey->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height,
imageData, image.width(), image.height(),
GDT_Float32, 0, 0);
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
int len = image.width() * image.height();
for (int i = 0; i < len; ++i)
{
@ -358,12 +377,21 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
}
}
}
grey->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 1,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 2,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
raster_io_error = grey->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 0,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 1,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
raster_io_error = grey->RasterIO(GF_Read,x_off, y_off, width, height, image.getBytes() + 2,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
if (color_table)
{
@ -394,8 +422,11 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: processing alpha band...";
if (!raster_has_nodata)
{
alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
raster_io_error = alpha->RasterIO(GF_Read, x_off, y_off, width, height, image.getBytes() + 3,
image.width(), image.height(), GDT_Byte, 4, 4 * image.width());
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
}
else
{
@ -426,6 +457,8 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
{
CPLErr raster_io_error = CE_None;
if (band_ > 0)
{
unsigned raster_xsize = dataset_.GetRasterXSize();
@ -453,7 +486,10 @@ feature_ptr gdal_featureset::get_feature_at_point(mapnik::coord2d const& pt)
int raster_has_nodata;
double nodata = band->GetNoDataValue(&raster_has_nodata);
double value;
band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0);
raster_io_error = band->RasterIO(GF_Read, x, y, 1, 1, &value, 1, 1, GDT_Float64, 0, 0);
if (raster_io_error == CE_Failure) {
throw datasource_exception(CPLGetLastErrorMsg());
}
if (! raster_has_nodata || value != nodata)
{
// construct feature

View file

@ -0,0 +1,45 @@
<VRTDataset rasterXSize="2283" rasterYSize="1913">
<SRS>PROJCS[&quot;WGS 84 / UTM zone 30N&quot;,GEOGCS[&quot;WGS 84&quot;,DATUM[&quot;WGS_1984&quot;,SPHEROID[&quot;WGS 84&quot;,6378137,298.257223563,AUTHORITY[&quot;EPSG&quot;,&quot;7030&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;6326&quot;]],PRIMEM[&quot;Greenwich&quot;,0],UNIT[&quot;degree&quot;,0.0174532925199433],AUTHORITY[&quot;EPSG&quot;,&quot;4326&quot;]],PROJECTION[&quot;Transverse_Mercator&quot;],PARAMETER[&quot;latitude_of_origin&quot;,0],PARAMETER[&quot;central_meridian&quot;,-3],PARAMETER[&quot;scale_factor&quot;,0.9996],PARAMETER[&quot;false_easting&quot;,500000],PARAMETER[&quot;false_northing&quot;,0],UNIT[&quot;metre&quot;,1,AUTHORITY[&quot;EPSG&quot;,&quot;9001&quot;]],AUTHORITY[&quot;EPSG&quot;,&quot;32630&quot;]]</SRS>
<GeoTransform> -1.4637000000000000e+04, 5.0000000000000000e+02, 0.0000000000000000e+00, 4.8596780000000000e+06, 0.0000000000000000e+00, -5.0000000000000000e+02</GeoTransform>
<VRTRasterBand dataType="Int16" band="1">
<NoDataValue>-9.99000000000000E+02</NoDataValue>
<HideNoDataValue>0</HideNoDataValue>
<ColorInterp>Palette</ColorInterp>
<ColorTable>
<Entry c1="0" c2="0" c3="0" c4="0"/>
<Entry c1="0" c2="0" c3="255"/>
<Entry c1="0" c2="255" c3="0"/>
<Entry c1="255" c2="0" c3="0"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="128" c2="128" c3="128"/>
<Entry c1="0" c2="0" c3="255"/>
<Entry c1="0" c2="255" c3="0"/>
<Entry c1="255" c2="0" c3="0"/>
</ColorTable>
<ComplexSource>
<SourceFilename relativeToVRT="1">this_file_should_not_exist.tif</SourceFilename>
<SourceBand>1</SourceBand>
<SourceProperties RasterXSize="2283" RasterYSize="1913" DataType="Int16" BlockXSize="256" BlockYSize="256" />
<SrcRect xOff="0" yOff="0" xSize="2283" ySize="1913" />
<DstRect xOff="0" yOff="0" xSize="2283" ySize="1913" />
<NODATA>-999</NODATA>
</ComplexSource>
</VRTRasterBand>
</VRTDataset>

View file

@ -13,6 +13,33 @@ def test_that_datasources_exist():
if len(mapnik.DatasourceCache.plugin_names()) == 0:
print '***NOTICE*** - no datasource plugins have been loaded'
# adapted from raster_symboliser_test#test_dataraster_query_point
def test_vrt_referring_to_missing_files():
srs = '+init=epsg:32630'
if 'gdal' in mapnik.DatasourceCache.plugin_names():
lyr = mapnik.Layer('dataraster')
lyr.datasource = mapnik.Gdal(
file = '../data/raster/missing_raster.vrt',
band = 1,
)
lyr.srs = srs
_map = mapnik.Map(256, 256, srs)
_map.layers.append(lyr)
# center of extent of raster
x, y = 556113.0,4381428.0 # center of extent of raster
_map.zoom_all()
# Should RuntimeError here
try:
_map.query_point(0, x, y).features
except RuntimeError, e:
eq_("this_file_should_not_exist.tif' does not exist in the file system" in str(e), True)
else:
assert False
def test_field_listing():
if 'shape' in mapnik.DatasourceCache.plugin_names():
ds = mapnik.Shapefile(file='../data/shp/poly.shp')