Closed Plantain closed 2 years ago
What resolution gdalwarp computes if you do not define it with -tr
?
I tried it myself with a test image that I created with gdal_create
gdal_create -a_srs space.prj -outsize 18408 19008 -a_ullr -4701999.973 4501999.974 4501999.974 -5001999.971 space.tif
gdalwarp -t_srs epsg:3857 -r lanczos space.tif space_warped.tif
Gdalwarp prints errors ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.
but it does create an output that has a pixel size of
Pixel Size = (1650.183828510722833,-1650.183828510722833)
@jratike80 1650.183862530689794
I uploaded the original input data here if anyone wants to try: http://static2.skysight.io/demo/himawari-sat.tiff
gdalinfo out.tiff
Driver: GTiff/GeoTIFF
Files: out.tiff
Size is 24285, 10507
Coordinate System is:
PROJCRS["WGS 84 / Pseudo-Mercator",
BASEGEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
ID["EPSG",4326]],
CONVERSION["Popular Visualisation Pseudo-Mercator",
METHOD["Popular Visualisation Pseudo Mercator",
ID["EPSG",1024]],
PARAMETER["Latitude of natural origin",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8801]],
PARAMETER["Longitude of natural origin",0,
ANGLEUNIT["degree",0.0174532925199433],
ID["EPSG",8802]],
PARAMETER["False easting",0,
LENGTHUNIT["metre",1],
ID["EPSG",8806]],
PARAMETER["False northing",0,
LENGTHUNIT["metre",1],
ID["EPSG",8807]]],
CS[Cartesian,2],
AXIS["easting (X)",east,
ORDER[1],
LENGTHUNIT["metre",1]],
AXIS["northing (Y)",north,
ORDER[2],
LENGTHUNIT["metre",1]],
USAGE[
SCOPE["Web mapping and visualisation."],
AREA["World between 85.06°S and 85.06°N."],
BBOX[-85.06,-180,85.06,180]],
ID["EPSG",3857]]
Data axis to CRS axis mapping: 1,2
Origin = (-20037508.325681626796722,7446961.240155051462352)
Pixel Size = (1650.183862530689794,-1650.183862530689794)
Metadata:
AREA_OR_POINT=Area
TIFFTAG_DATETIME=2022:03:27 21:00:00
Image Structure Metadata:
INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left (-20037508.326, 7446961.240) (180d 0' 0.00"W, 55d26' 9.83"N)
Lower Left (-20037508.326,-9891520.603) (180d 0' 0.00"W, 66d 3'12.82"S)
Upper Right (20037206.776, 7446961.240) (179d59'50.25"E, 55d26' 9.83"N)
Lower Right (20037206.776,-9891520.603) (179d59'50.25"E, 66d 3'12.82"S)
Center ( -150.775,-1222279.682) ( 0d 0' 4.88"W, 10d54'47.99"S)
Band 1 Block=24285x1 Type=Byte, ColorInterp=Red
Mask Flags: PER_DATASET ALPHA
Band 2 Block=24285x1 Type=Byte, ColorInterp=Green
Mask Flags: PER_DATASET ALPHA
Band 3 Block=24285x1 Type=Byte, ColorInterp=Blue
Mask Flags: PER_DATASET ALPHA
Band 4 Block=24285x1 Type=Byte, ColorInterp=Alpha
I also get similar errors: ERROR 1: Point outside of projection domain ERROR 1: Point outside of projection domain ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds. Warning 1: Unable to compute source region for output window 7156,0,7156,12384, skipping. ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds. Warning 1: Unable to compute source region for output window 7156,12384,7156,12385, skipping. ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds. Warning 1: Unable to compute source region for output window 14312,0,14313,24769, skipping. ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds. Warning 1: Unable to compute source region for output window 28625,0,7156,12384, skipping. ERROR 1: Too many points (529 out of 529) failed to transform, unable to compute output bounds.
But for a COG, there is no way to manually specify output bounds/resolution with GoogleMapsCompatible.
@Plantain maybe what you can do, is first create a VRT (with the resolution you want) and then create a COG 🤷(I know this doesn't fix the issue, if one, but it should give you want you want)
@vincentsarago that's approximately what I do at the moment to work around this - gdal_warp to epsg:3857, then gdal_translate to a GoogleMapsCompatible COG. I don't completely understand the handling of the VRT as to whether this is actually introducing another reprojection step with loss of precision / wasted computation or not compared to how this 'should'/could work all in one step?
Incidentally I've found if I actually do the projection to epsg:3857 (gdalwarp -t_srs EPSG:3785 -tr 700 700 in.tiff out.tiff; gdal_translate -of COG out.tiff out_cog.tiff) rather than outputting a VRT and translating that, that the whole operation completes much faster, and I don't really understand why that would be because as I understand it that will definitely be doing two reprojections.
Web Mercator tiling scheme is using EPSG:3857 so why would there be two reprojections?
I believe that the real difficulty with this image is somehow related to the coordinate system. The size of the original image is 18408, 19008 and when it is warped to EPSG:3857 with defaults the size of the resulting image is 24285, 10507. If the width goes down from 19008 to 10507 then there must happen quality loss. I think this in not normal for gdalwarp.
The ZOOM_LEVEL_STRATEGY=UPPER already forces GDAL to do oversampling compared to what it considers to be the optimal resolution. Making an option to force even more oversampling feels like trying to fix an error that happens in some other place but maybe something like ZOOM_LEVEL_STRATEGY=UPPER+1 could be supported even in normal cases it only balloons the file size without any improvement to quality.
VRT idea is good. These commands give a COG with pixel size of 611.5 m (means the next Web Mercator zoom level).
gdalwarp -of VRT -tr 700 700 -t_srs epsg:3857 space.tif space.vrt
gdal_translate -of COG -co TILING_SCHEME=GoogleMapsCompatible -r lanczos -co BLOCKSIZE=512 -co ZOOM_LEVEL_STRATEGY=UPPER space.vrt space_cog4.tif
Web Mercator tiling scheme is using EPSG:3857 so why would there be two projections?
Is GDAL clever enough pad the alignment for GoogleMapsCompatible (to make tiles align with Web Mercator tiles) without any more warping? I don't know enough about the internals of GDAL.
The ZOOM_LEVEL_STRATEGY=UPPER already forces GDAL to do oversampling compared to what it considers to be the optimal resolution. Making an option to force even more oversampling feels like trying to fix an error that happens in some other place
I think the root problem is GDAL doesn't know how to calculate the optimal resolution of space projected imagery? I agree that twiddling ZOOM_LEVEL_STRATEGY sounds like a hacky fix.
I think the root problem is GDAL doesn't know how to calculate the optimal resolution of space projected imagery?
that's a bit deeper than that. Neither the Geostationary Satellite projection nor the WebMercator projection are equal-area projection. Consequently the actual area on the ellipsoid of let's say a square of 700x700 meter is generally not 700x700 squared meters, except at the lines of true scale of the projections, and elsewhere it might be much larger or smaller. Consequently, and this is the general case even for equal-area projections, GDAL uses a strategy that tries to preserve the number of pixels, while outputing square pixels in the target projection : 18408 19008 = 349 899 264 and 32768 14336 = 469 762 048 are not so far in this regard. This is a compromise between getting the best quality possible (that could lead to an enormous output image) and preserving the average amount of information. The Geostationary Satellite projection, when used with images that incorporate portions of the sky, is of course a bad case for this heuristics as a significant portion of the pixels of the source image will not participate to the target image... That said being able to specify a desired target zoom level is a reasonable way forward.
Expected behavior and actual behavior.
Observe the significant loss in fidelity between left and right.
Zoomed further:
Left is the XYZ tile 7/116/76 as generated with gdalwarp -t_srs EPSG:3785 -tr 700 700 -r lanczos /gdal_translate to MBTILES/gdaladdo
Right is the same tile from the GoogleMapsCompatible COG generated via gdal_translate -of COG himawari-sat.tiff -co TILING_SCHEME=GoogleMapsCompatible -r lanczos -co BLOCKSIZE=512 -co ZOOM_LEVEL_STRATEGY=UPPER
The goal is to reproject GeoTIFF's of satellite imagery into GoogleMapsCompatible COG's, preserving the input resolution/fidelity
I suspect that GDALSuggestedWarpOutput is suggesting a bad output resolution because it is struggling with the space projection, which is not overridable when generating COG's like it is with most other outputs. The calculated pixelsize of 1222.99 is considerably less than the input resolution.
It should be possible to set a target zoom level, or specify an output resolution when generating a GoogleMapsCompatible COG, so that the correct resolution can be used on satellite data. Or, the correct output resolution should be calculated.
Original data:
Left (gdalwarp -t_srs EPSG:3785 -tr 700 700 -r lanczos):
Right:
Operating system
Ubuntu 21.10
GDAL version and provenance
This example was generated GDAL 3.2.2, released 2021/03/05 Same behaviour also observed with GDAL 3.4.1.