azavea / loam

Javascript wrapper for GDAL in the browser
Apache License 2.0
218 stars 16 forks source link

How to rotate image? #89

Closed comoris closed 2 years ago

comoris commented 2 years ago

Is there a way to rotate a georeferenced geotiff? Getting lost in all warp options or should we use GDALSetGeoTransform from gdal.js?

ddohler commented 2 years ago

Hmm, I'm not sure I quite understand the question -- if the geotiff is already correctly georeferenced then rotating it would invalidate the georeferencing. Can you explain a bit more about what you're trying to do?

comoris commented 2 years ago

@ddohler , we are repositioning/georeferencing an image in mapbox, and use the convert() with the repositioned values const dataset = await file.convert(['-of', 'GTiff', '-a_srs', 'EPSG:3857', '-a_ullr', upperLeftX, upperLeftY, lowerRightX, lowerRightY]) and then send the geotiff to mapbox upload service. if we don't georeference the image and just send it as is, no issues. But once we reposition the image, then create the geotiff and then upload, the service complains: error creating Mapnik data Datasource: Invalid raster: Invalid pixelsize in geotransform array.

Is it possible to change the rotation properties of the geotransform? I see examples online where SetGeoTransform is being used but I don’t think this function is exposed in loam.js

ddohler commented 2 years ago

Thanks @comoris , that's really helpful, I think I understand now. So basically you've got some sort of image that's not georeferenced and you're lining it up with a basemap in Mapbox, and then extracting the corner coordinates and using Loam to output a georeferenced GeoTIFF.

A few things I want to double-check before moving further:

If you're doing both of those, then the next thing I would try to do is to experiment by hand with gdal_translate on the command line; if you can find a call to gdal_translate that works for your use, you should be able to translate it directly to Loam, just drop the input / output filenames from the end. And vice-versa; if it works with gdal_translate but not Loam, you can console.log() the arguments to convert() and paste them into the command-line to run gdal_translate directly and see what's going wrong.

I will also say that I've done something similar in the past, but we used convert() to set GCPs and then used warp() to reproject to EPSG:3857. Looking around, I'm seeing some other folks using a similar two-step approach, so it might also be worth trying that to see if warp() helps everything to line up, e.g. const dataset = await file.convert('-of', 'GTiff', '-a_srs', 'EPSG:4326', '-a_ullr', ...]).warp(['-of', 'GTiff', '-t_srs', 'EPSG:3857'])

Hope one of those helps, let me know how it goes!

comoris commented 2 years ago

Nice, thanks a lot for the comment, was really helpful. One of the mistakes we made was the initial CRS we defined in the convert() (gdal_translate). We now extract GCPs in EPSG:4326 and use warp() to convert to EPSG:3857. Its quite a challenge to get to know how gdal actually works. Doing it in the frontend makes it so much easier, thanks for the wrapper! const dataset = await file .convert(['-of', 'GTiff', '-a_srs', 'EPSG:4326', ...gcps]) .warp(['-of', 'GTiff', '-t_srs', 'EPSG:3857', '-dstalpha', '-r', 'cubic', '-co', 'COMPRESS=LZW', '-co', 'TILED=YES', '-co', 'PREDICTOR=2']);