ESA-PhiLab / iris

Semi-automatic tool for manual segmentation of multi-spectral and geo-spatial imagery.
GNU General Public License v3.0
135 stars 41 forks source link

Bing Maps view: no coordinates returned for GeoTIFF #59

Open ario101 opened 3 months ago

ario101 commented 3 months ago

When using Bing Maps view the coordinates with GeoTIFF images, the coordinates from GeoTIFF file are not returned correctly - for every image it is (0, 0).

aliFrancis commented 3 months ago

Hi @ario101

The implementation for Bing maps coordinates is a bit dumb at the moment - there is no reading of the geotiff header info to find where an image is. Instead, we use a separate metadata file for each sample to specify the centroid. It would be nice to have an automatic mode for geotiffs but obviously sometimes people use non georeferenced image formats, so the metadata file is a way to normalise behaviour across different image file types. An example of the metadata file can be found here. You can also check out the demo config to see how to point to a metadata file for each sample.

Let me know if problems persist.

Ali

ario101 commented 3 months ago

Thanks for a prompt answer! As a quick solution to use Bing Maps based on your comment I created a small Python script to create metadata for each file. It extracts centroid for every image and creates metadata files with centroid values for every image. Metadata is also to be enabled in IRIS config file with respective path to it (in case of this script: "images/metadata/{id}.json"). The script implies that input GeoTIFF files are in EPSG:3857 and converts centroid coordinates to EPSG:4326, which is suitable for Bing Maps.

import os 
import json
import re
import rasterio 

def centroid_to_metadata(path):
    '''
    Writes .json file with filename and centroid for each .gtiff file and converts coordinates from EPSG:3857 to EPSG:4326.
    Metadata is written to every .json file which is named after image id (this is because IRIS has complicated metadata handling) 

    path: direrctory for all files to create metadata from
    '''

    try:
        json_data = {}
        for file_ in os.listdir(path):
            # checking if file is TIFF file
            if re.findall(".tif", file_):
                filepath_ = os.path.join(path, file_)
                with rasterio.open(filepath_) as src:
                    left, bottom, right, top = src.bounds
                    centroid_x = (left + right) / 2
                    centroid_y = (top + bottom) / 2

                    # converting CRS to epsg:4326
                    proj_from = Proj('epsg:3857')
                    proj_to = Proj('epsg:4326')
                    transformer = Transformer.from_proj(proj_from, proj_to, always_xy=True)
                    lon, lat = transformer.transform(centroid_x, centroid_y)

                    # creating dict of images and coordinates
                    json_data.update({"location":[lat, lon]})

                    # creating subfolder for metadata files if it doesn't exist
                    if not os.path.exists(os.path.join(path, "metadata")):
                        os.makedirs(os.path.join(path, "metadata"))
                    # writing to .json   
                    with open(os.path.join(path, "metadata", f"{file_[:-4]}.json"), 'w') as json_file:
                        json.dump(json_data, json_file, indent=4)
            else:
                continue

        print("Metadata write successful!")
        print(f"Metadata files are in ", os.path.join(path, "metadata"))

    except Exception as e:
        print('Error:', e)
aliFrancis commented 2 months ago

Thanks, this is super helpful. I need to think more how this can be implemented automatically, because sometimes users will be using data that isn't in geotif files, in which case this would break.

I think it might be best to have an option in the BingMaps view config to select where the location comes from (either the geotifs, or the metadata files). Then something like this function can run for each image when loaded, to find the location. Will look into it soon!