-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using gcps with rio.reproject #339
Comments
gcps support could definitely be improved. Using the transform.from_gcps method in open_rasterio might be a path forward on that. |
@mraspaud also had interest in using gcps with rioxarray. |
Yes I do, also for sentinel 1 data |
To be clear, I need the gcps both for reading and writing. The software I'm developing for processing the Sentinel1 SAR data (satpy) needs to be able to write the gcps to the resulting geotiff file. At the moment I we do that by passing the gcps to the |
@oarcher the image link gives a 404. |
Is there a reason you need the gcps versus the transform? I ask because it would be relatively simple to get the transform/crs from the gcps and then use that within Portential method for rioxarray to get transform from gcps in the file in import rasterio
file_path = "s1a-iw-grd-vh-20160121t001321-20160121t001346-009585-00df26-002.tiff"
with rasterio.open(file_path) as rds:
gcps, crs = rds.get_gcps()
transform = rasterio.transform.from_gcps(gcps) Current method for writing transform from gcps: import rioxarray
rds = ...
gcps = [...]
transform = rasterio.transform.from_gcps(gcps)
rds.rio.write_transform(transform, inplace=True) |
@snowman2 , I've found that using rasterio.transform.from_gcps is not very accurate on big image with many gcps. For example, we can have a 600 meters errors when applying the transform to the same gcps (for a 10m pixel, and a image 15000*25000). Probably because the transorm is affine, and very small error on coefficients gave large error on large image. Using bi-linear interpolation from the gcps give more accurate results. |
oops, fixed. |
That is good to know. I wonder how to accurately generate coordinates for a data array from gcps? |
Generally gdalwarp with the thin plate spline option (-tps) will give better geocoding results for Sentinel1 images (but still approximate). I don't think It would be nice though to have some sort of |
IIRC, the Sentinel1 documentation recommends bilinear interpolation to expand the GCPs to full lon/lat arrays. We do this in satpy using a daskified version of scipy's interp2d function right now. However, Sentinel 1 is not the only use case for GCPs and the GDAL documentation says:
( https://gdal.org/user/raster_data_model.html#gcps ) So in my opinion, rioxarray should expose the GCPs but leave the interpolation scheme to the application. How to do the interpolation (what coordinate system, which order, which interpolation) is highly dependent both on the data at hand and the application the user has, so we would be opening a can of worms here if this was to be implemented in rioxarray. Just my 2 cents. |
Have y'all tried
from rasterio.enums import Resampling
from rasterio.vrt import WarpedVRT
import rasterio
with rasterio.open("m_3907617_ne_18_1_20130924.tif") as src:
with WarpedVRT(src, crs=src.crs, resampling=Resampling.bilinear) as vrt:
rds = rioxarray.open_rasterio(vrt) @oarcher this should enable loading in the image lazily with dask. Here is an example: ref. |
Nevermind. Seems like |
@snowman2 would it be possible then to also get access to untransformed gcps from rioxarray? |
Yes, that will also be something I think would be important. Changes that will likely be needed:
|
If I am not mistaken, GCPs are directly linked to given lines and columns in the raster, and as such are a subset of a full array of say lons and lats. While geojson would certainly work, I'm wondering if it would be an idea to express the GCPs as lons, lats, and z coordinates of the original raster array somehow? In turn they would have coordinates that are a subset of lines and columns. Or is that too complex? |
What benefit do you see storing GCPs that way? Original GCPs: [GroundControlPoint(row=0.0, col=0.0, x=-1.3712442422120068, y=48.818122749035496, z=1.9444833537563682, id='1', info=''), GroundControlPoint(...] Coordinate Structure
JSON StructureGrid mapping coordinate: Attributes:
crs_wkt: ....
gcps: '[{"row": 0.0, "col": 0.0, "x": -1.3712442422120068, "y": 48.818122749035496, "z": 1.9444833537563682, "id": "1","info": ""}, {...]' |
I can open up an issue, should have done it while back while exploring this very use case ;) I realize GCPs show up for all kinds of datasets, but I wanted to loop in @alexamici and @aurghs who have been putting thought into about how to best represent GCPs in xarray for sentinel-1: see https://github.com/bopen/xarray-sentinel#open-gcp-dataset and bopen/xarray-sentinel#54 |
I was thinking making is more xarray-ish. Indeed the geojson is more compact, but I was thinking the gcps are really an auxiliary coordinate. However, I'm not even sure xarray would let me do that now... |
Related: rasterio/rasterio#2193 |
With #351: from rasterio.enums import Resampling
from rasterio.vrt import WarpedVRT
import rasterio
import rioxarray
with rasterio.open("s1a-iw-grd-vh-20160121t001321-20160121t001346-009585-00df26-002.tiff") as src:
gcps, crs = rds.get_gcps()
with WarpedVRT(src, src_crs=crs, resampling=Resampling.bilinear) as vrt:
rds = rioxarray.open_rasterio(vrt) Once this is added to rasterio: with rasterio.open("s1a-iw-grd-vh-20160121t001321-20160121t001346-009585-00df26-002.tiff") as src:
with WarpedVRT(src, resampling=Resampling.bilinear) as vrt:
rds = rioxarray.open_rasterio(vrt)
# specify dimensions
with rasterio.open("s1a-iw-grd-vh-20160121t001321-20160121t001346-009585-00df26-002.tiff") as src:
with WarpedVRT(src, width=5000, height=5000, resampling=Resampling.bilinear) as vrt:
rds = rioxarray.open_rasterio(vrt) |
@mraspaud did you have any more thoughts on how to store the GCPS into an xarray object? |
Hi, this is my first question here:
I'd like to be able to use gcps for reproject, like rasterio is able to do.
My goal is to plot a sentinel-1 image on a map, with geoviews.
My first guess was to use:
But this doesn't works, because the tiff has no transform. However, it has some gcps, and it is correctly mapped in qgis.
I was not able to find any solution to do the reprojection with rioxarray, so I've ended in a pure rasterio solution, converting to rioxarray at the end:
My input image is pretty big (25000 * 15000), so ideally, the reprojection should be done with dask (#119)
The text was updated successfully, but these errors were encountered: