[gdal-dev] C# bindings for (fast) reproject, resample, and send to DB
mladen-g at distributel.net
mladen-g at distributel.net
Wed Oct 16 06:41:01 PDT 2019
Hello,
Can you be more specific about what steps you are suggesting I take,
and how that would improve performance?
Are you saying that gdalwarp-ing to gpkg is more performant than
writing to VRT?
I looked at the geopackage docs and it seems that all results are
encoded as ARGB, so in the case where I do not have Float32 rasters, I
think I would have some inefficiency. Also I guess I would have to
specify PNG as the output, since I would have information loss with
JPG? In general I don't understand it enough to try, it would help if
you could expand a bit.
What I have tried so far:
1) Retrieve the dataset using "Gdal.wrapper_GDALWarpDestName(...)"
(which works correctly):
Dataset ds = Gdal.wrapper_GDALWarpDestName(memFilename, 1, dss, new
GDALWarpAppOptions(options), null, null);
2) Retrieve the projection, GeoTransform, and GCPs (GCPs were null)
string projection = ds.GetProjection();
...
double[] geoTransform = new double[6];
ds.GetGeoTransform(resultGeoTransform);
...
GCP[] resGcps = ds.GetGCPs();
3) Retrieve the width and height of band 1 of "ds"
Band band = ds.GetRasterBand(1);
int xSize = band.XSize;
int ySize = band.YSize;
4) Create a new dataset with 1 band of the same width & height as
retrieved in #3 (x size and y size were both 256, I just entered the
literals here).
Dataset newData = Gdal.GetDriverByName("VRT").Create(memFilename, 256,
256, 1, DataType.GDT_Float32, null);
5) Set the projection and Geotransform as retrieved in #2, which seem
to be the only two settable attributes (except GCPs which were null in
the original)
newData.SetProjection(projection);
var newGeoTransform = new double[6];
newGeoTransform[0] =geoTransform[0];
newGeoTransform[1] = geoTransform[1];
newGeoTransform[3] = geoTransform[3];
newGeoTransform[5] = geoTransform[5];
newData.SetGeoTransform(newGeoTransform);
6) Use this dataset as the input to Gdal.wrapper_GDALWarpDestDS(...):
int status = Gdal.wrapper_GDALWarpDestDS(newData, 1, dss, new
GDALWarpAppOptions(options), null, null);
This gave me a result of all null values :/
Not sure where I am going wrong?
Quoting Geospatial Information Technology Solutions
<geospatialsolutions at gmail.com>:
> Why not build an OGC gpkg GEOPACKAGE it supports 4326 tiles
> you can extract the tile_data blob if you need to
>
>
> On Thu, Oct 10, 2019, 5:51 PM <mladen-g at distributel.net> wrote:
>
>> Hello,
>>
>> I've been using GDAL for a while, but I am still a newbie to the API.
>> I see there are some experts on this group, so apologies if I'm asking
>> something simple (my searches did not reveal the answers I was looking
>> for).
>>
>> Here is my problem:
>>
>> I need to take an input raster, split into areas of various sizes,
>> resample each area into a 256x256 tile, reproject to EPSG:4326 and
>> send the resulting pixels to a DB.
>>
>> GDAL is perfect for this, but I am using the C# bindings and I'm not
>> sure what is the most performant way to do it.
>>
>> I used the following two references to create something that works,
>> but I am wondering if it can be improved:
>> https://gis.stackexchange.com/questions/297831/using-gdalwarp-with-c-bindings
>> https://lists.osgeo.org/pipermail/gdal-dev/2017-February/046046.html
>>
>> How I do it right now:
>>
>> 1) Copy the input grid to RAM disk for fast access
>> 2) Invoke Gdal.wrapper_GDALWarpDestName() for reprojection,
>> resampling, and output to a /vsimem/ memory-mapped file
>> 3) Read the memory-mapped file into a Dataset (returned by
>> wrapper_GDALWarpDestName())
>> 4) Write the Dataset values to DB
>>
>> What I would like to know:
>>
>> 1) To skip the /vsimem file creation, how can I use
>> Gdal.wrapper_GDALWarpDestDs() instead of -DestName? It requires a
>> dataset as a parameter, but I am not sure how to initialize it
>> correctly. I've tried Gdal.GetDriverByName("VRT").Create(...) and
>> .GetDriverByName("MEM").Create(...), but all the values end up being 0
>> when I pass the dataset to wrapper_GDALWarpDestDs()?
>>
>> 2) Is there a more direct, efficient way to do what I'm doing? Here
>> is the relevant code
>>
>> <snip>
>> using (Dataset rasterInput = Gdal.Open(inputRasterPath, Access.GA_ReadOnly))
>> {
>> IntPtr[] ptr = {Dataset.getCPtr(inputRasterPath).Handle};
>> GCHandle gcHandle = GCHandle.Alloc(ptr, GCHandleType.Pinned);
>> ...
>> var dss = new
>> SWIGTYPE_p_p_GDALDatasetShadow(gcHandle.AddrOfPinnedObject(), false,
>> null);
>> ..
>> foreach (var tileExtent in overlappingTileExtents) // tileExtent
>> just contains minX/minY/maxX/maxY
>> {
>> ...
>>
>> string vsiMemFilePath =
>> $"/vsimem/{destinationTableName}#{extentName}#tile{indexNumber}.vrt";
>> string[] options = {
>> "-of", "VRT",
>> "-srcnodata", "99999.9",
>> "-dstnodata", "99999.9",
>> "-ot", "Float32",
>> "-t_srs", "EPSG:4326",
>> "-r", "average"),
>> "-te", tileExtent.xmin.ToString(),
>> tileExtent.ymin.ToString(), tileExtent.xmax.ToString(),
>> tileExtent.ymax.ToString(),
>> "-ts", "256", "256"
>> };
>>
>> using (Dataset ds =
>> Gdal.wrapper_GDALWarpDestName(vsiMemFilePath, 1, dss, new
>> GDALWarpAppOptions(options), null, null))
>> {
>> ...
>> //read the geotransform + first band and write each pixel
>> lat/long + value to the DB
>> ...
>> }
>>
>> Gdal.Unlink(vsiMemFilePath)
>>
>> ....
>>
>> Regards,
>> Mladen
>>
>> _______________________________________________
>> 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/20191016/4e581aee/attachment-0001.html>
More information about the gdal-dev
mailing list