4

In my industry, KML/KMZ seems to be the standard spatial data format and it is a HASSLE when converting between typical formats.

I have a large number of KML image overlays and am tasked with converting them to TIFF. Typically through QGIS its easy, however I need to automate this given the volume. I've gotten them all written properly, however the image rotations are not preserved.

from gdal import GetDriverByName, OpenEx

tiff_driver = GetDriverByName("GTiff")

in_ds = OpenEx(KML_PATH) 

primary_band = in_ds.GetRasterBand(1)

projection = ds.GetProjection()

geo_transform = in_ds.GetGeoTransform()

out_ds = tiff_driver.Create(
     out_path,
     primary_band.XSize, 
     primary_band.YSize, 
     in_ds.RasterCount, 
     primary_band.DataType)

out_ds.SetProjection(projection)
out_ds.SetGeoTransform(geo_transform)

for i in range(1, ds.RasterCount + 1):
     in_band = ds.GetRasterBand(i)
     in_data = in_band.ReadAsArray()
     out_band = out_ds.GetRasterBand(i)
     out_band.WriteArray(in_data)

out_ds.FlushCache()
out_ds = None

The resulting .TIFF files are oriented true north. I can see a "rotation" tag in the KML, however can't find any GDAL options for rotating the new image.

Google Earth screenshot of proper rotation, kml format:

enter image description here

QGIS screenshot of non-rotated geotiff: enter image description here

I've tried the following:

  • Replacing the 'rotation' values in the GeoTransform to the KML's rotation in radians
  • This simple change of the GeoTransform (gt[0], gt1 * cos(rot), gt2 * -sin(rot), gt3, gt[4] * sin(rot), gt[5] * cos(rot))

Neither work properly.

I assume this may involve using the Affine library, however a.rotation(ANGLE) isn't giving any useful results.

Another Update:

Using the Affine library, I can get the proper rotation, however each image seems translated. I'm not manually creating the Affine object, importing from GDAL:

gt = in_ds.GetGeoTransform()
aff_gt = Affine.from_gdal(*gt)

aff_gt *= Affine.rotation(-rotation)

out_ds.SetGeoTransform(aff_gt.to_gdal())

This in effect rotates the original GeoTransform via the Affine library, rotation angle seems legit, however still not giving me what I expected as each image is translated:

enter image description here Seriously, any direction helps here!

2
  • Could you share a test image? If your images are not open, create a test case from some open data.
    – user30184
    Commented Feb 26, 2020 at 18:33
  • @user30184 just added a few screenshots and more info! Commented Feb 26, 2020 at 19:02

1 Answer 1

1

OK so after a few days, I finally got a solution:

  • Reading in the KML overlay's bounding box as a polygon and using shapely's affinity rotation to rotate the box
  • Reading in the KML's associated jpeg file with scikit-image, rotating it with resize=True to preserve all values, then writing this new image to the out GDAL data source
  • Using the new rotated shape's bounding box as the geotransform with 0.0 rotation values (since the original geotransform didn't jive well with a non-0 rotation value)

This results in a rotated image which fits the new rotated bounding box without the need for extra geometric transformations:

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.