[gdal-dev] Dataset's ReadRaster/WriteRaster throws exception on c#
Tamas Szekeres
szekerest at gmail.com
Mon Nov 12 10:05:05 PST 2018
You did not count the band size when allocating memory for the buffer.
That should be:
byte[] readRaster = new byte[tileSize * tileSize * 4];
Or alternatively use Band.ReadRaster to read just a specific band.
Best regards,
Tamas
Gigas002 <gigas002 at yandex.ru> ezt írta (időpont: 2018. nov. 12., H, 17:34):
> Hi all.
> I've rewritten some python code from gdal2tiles.py on c#, using GDAL.NET
> nuget package (ver. 2.3.1). Here you can see the working python code:
>
> def create_overview_tiles(input_file, output_file):
> tile_driver = 'PNG'
> tile_size = 256
> tilebands = 4
> resampling = 'bilinear'
>
> mem_driver = gdal.GetDriverByName('MEM')
> out_driver = gdal.GetDriverByName(tile_driver)
>
> dsquery = mem_driver.Create('', 2 * tile_size, 2 * tile_size,
> tilebands)
> dstile = mem_driver.Create('', tile_size, tile_size, tilebands)
> dsquerytile = gdal.Open(input_file, gdal.GA_ReadOnly)
>
> dsquery.WriteRaster(0, 0, tile_size, tile_size,
> dsquerytile.ReadRaster(0,
> 0, tile_size, tile_size), band_list=list(range(1, tilebands + 1)))
> scale_query_to_tile(dsquery, dstile, resampling)
> out_driver.CreateCopy(output_file, dstile, strict=0)
>
>
> def scale_query_to_tile(dsquery, dstile, resampling):
> querysize = dsquery.RasterXSize
> tilesize = dstile.RasterXSize
>
> if resampling == 'near':
> gdal_resampling = gdal.GRA_NearestNeighbour
>
> elif resampling == 'bilinear':
> gdal_resampling = gdal.GRA_Bilinear
>
> elif resampling == 'cubic':
> gdal_resampling = gdal.GRA_Cubic
>
> elif resampling == 'cubicspline':
> gdal_resampling = gdal.GRA_CubicSpline
>
> dsquery.SetGeoTransform((0.0, tilesize / float(querysize), 0.0, 0.0,
> 0.0, tilesize / float(querysize)))
> dstile.SetGeoTransform((0.0, 1.0, 0.0, 0.0, 0.0, 1.0))
>
> gdal.ReprojectImage(dsquery, dstile, None, None, gdal_resampling)
>
>
> And here's rewritten code on c#:
>
> private static void BuildOverview(string inputFile, string
> outputFile)
> {
> const string tileDriver = "PNG";
> const int tileSize = 256;
> const int tileBands = 4;
> const string resampling = "bilinear";
>
> Driver memDriver = Gdal.GetDriverByName("MEM");
> Driver outDriver = Gdal.GetDriverByName(tileDriver);
>
> Dataset dsQuery = memDriver.Create("", 2 * tileSize, 2 *
> tileSize, tileBands, DataType.GDT_Byte, null);
> Dataset dsTile = memDriver.Create("", tileSize, tileSize,
> tileBands, DataType.GDT_Byte, null);
> Dataset dsQueryTile = Gdal.Open(inputFile, Access.GA_ReadOnly);
>
> byte[] readRaster = new byte[tileSize * tileSize];
> dsQueryTile.ReadRaster(0, 0, tileSize, tileSize, readRaster,
> tileSize, tileSize,
> tileBands, Enumerable.Range(1, tileBands + 1).ToArray(), 0,
> 0, 0);
> dsQuery.WriteRaster(0, 0, tileSize, tileSize, readRaster,
> tileSize, tileSize,
> tileBands, Enumerable.Range(1, tileBands + 1).ToArray(), 0,
> 0, 0);
>
> ScaleQueryToTile(dsQuery, dsTile, resampling);
> outDriver.CreateCopy(outputFile, dsTile, 0, null, null, null);
> }
>
> private static void ScaleQueryToTile(Dataset dsQuery, Dataset
> dsTile, string resampling)
> {
> int querySize = dsQuery.RasterXSize;
> int tileSize = dsTile.RasterXSize;
>
> ResampleAlg gdalResampling;
> switch (resampling)
> {
> case "near":
> gdalResampling = ResampleAlg.GRA_NearestNeighbour;
> break;
> case "bilinear":
> gdalResampling = ResampleAlg.GRA_Bilinear;
> break;
> case "cubicspline":
> gdalResampling = ResampleAlg.GRA_CubicSpline;
> break;
> default:
> gdalResampling = ResampleAlg.GRA_Cubic;
> break;
> }
>
> dsQuery.SetGeoTransform(new[] {0.0, tileSize / (float)
> querySize, 0, 0, 0, tileSize / (float) querySize});
> dsTile.SetGeoTransform(new[] { 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 });
>
> Gdal.ReprojectImage(dsQuery, dsTile, null, null,
> gdalResampling,
> 0, 0, null, null, null);
> }
>
>
> I use these methods to create upper tile (in my case create 10 lvl tile
> from
> 11 lvl tile). Python version works without problem, but c#'s throws
> "System.AccessViolationException" (Additional information on exception from
> VS: Attempted to read or write protected memory. This is often an
> indication
> that other memory is corrupt) on "dsQueryTile.ReadRaster(..." line in
> runtime.
> I suppose the exception is thrown because ReadRaster try to create pointer
> to byte[] and somehow fails.
>
> I uploaded the 11 lvl png tile, named "z_x_y.png", and good 10 lvl tile,
> done by python. I'm using VS2017, Win10x64 and writing on .net framework
> 4.7.2.
> Hope anyone knows how to fix it!
>
> 11_2200_1621.png
> <http://osgeo-org.1560.x6.nabble.com/file/t384059/11_2200_1621.png>
> 10_1100_810.png
> <http://osgeo-org.1560.x6.nabble.com/file/t384059/10_1100_810.png>
>
>
>
> --
> Sent from: http://osgeo-org.1560.x6.nabble.com/GDAL-Dev-f3742093.html
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/gdal-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20181112/23ef3ada/attachment-0001.html>
More information about the gdal-dev
mailing list