Downloading Images

Many modules in BrailsPlusPlus rely on images, and to facilitate this, dedicated modules are available for image retrieval. Currently, the following two modules are supported:

  1. GoogleSatellite

  2. GoogleStreetview

The example below demonstrates how to use both modules. Building on the footprint generation examples, this workflow takes a footprint scraper and a specified location as input. An AssetInventory is generated, from which a random subset is selected. Satellite and street-view images are then retrieved for the selected inventory.

  1# Written: fmk 4/23
  2# Modified: bacetiner 11/21
  3# License: BSD-3
  4
  5"""
  6brails_download_images.py
  7=========================
  8
  9Purpose:
 101) Test the `get_class` method of the Importer module.
 112) Test the `get_footprints` method of the scraper modules.
 123) Test the `get_images` and `print_info` methods of GoogleSatellite and
 13    GoogleStreetview.
 14
 15This script demonstrates the use of BRAILS modules to download images for a
 16specified region.
 17"""
 18
 19import os
 20import argparse
 21from brails.utils.importer import Importer
 22
 23
 24# Function to load the API key from a file:
 25def load_api_key(api_key_path):
 26    """
 27    Load the API key from the specified file.
 28
 29    Args:
 30        api_key_path (str):
 31            Path to the file containing the API key.
 32
 33    Returns:
 34        str:
 35            Google API key for accessing street-level image metadata.
 36
 37    Raises:
 38        FileNotFoundError:
 39            If the API key file does not exist.
 40        ValueError:
 41            If the API key file is empty.
 42    """
 43    if not os.path.exists(api_key_path):
 44        raise FileNotFoundError(f"API key file not found at {api_key_path}")
 45
 46    with open(api_key_path, 'r', encoding='utf-8') as file:
 47        api_key = file.readline().strip()
 48
 49    if not api_key:
 50        raise ValueError("API key file is empty.")
 51
 52    return api_key
 53
 54
 55# Main function for downloading images:
 56def download_images(location, scraper, api_key):
 57    """
 58    Download aerial/street-level images for a location using specified scraper.
 59
 60    Args:
 61        api_key (str):
 62            Google API key for accessing street-level image metadata.
 63        scraper (str):
 64            Name of the footprint scraper to use.
 65        location (str):
 66            Name of the location to analyze.
 67    """
 68    # Create the importer:
 69    importer = Importer()
 70
 71    # Select a region and create its RegionBoundary:
 72    region_boundary_class = importer.get_class('RegionBoundary')
 73    region_boundary_object = region_boundary_class(
 74        {'type': 'locationName', 'data': location})
 75
 76    scraper_class = importer.get_class(scraper)
 77    scraper = scraper_class({"length": "ft"})
 78    inventory = scraper.get_footprints(region_boundary_object)
 79    print(f'Number of assets found: {len(inventory.inventory)} for {location} '
 80          'using {scraper}')
 81
 82    # Subsample the assets for quick processing:
 83    small_inventory = inventory.get_random_sample(20, 40)
 84
 85    # Get aerial imagery using GoogleSatellite:
 86    google_satellite_class = importer.get_class('GoogleSatellite')
 87    google_satellite = google_satellite_class()
 88    images_satellite = google_satellite.get_images(
 89        small_inventory, 'tmp/satellite/')
 90
 91    # Get street-level imagery using GoogleStreetview:
 92    google_street_class = importer.get_class('GoogleStreetview')
 93    google_street = google_street_class({'apiKey': api_key})
 94    images_street = google_street.get_images(small_inventory, 'tmp/street/')
 95
 96    # Print inventory info
 97    inventory.print_info()
 98
 99    return small_inventory, images_satellite, images_street
100
101
102# Entry point
103if __name__ == "__main__":
104    # Default API key file path:
105    API_KEY_DIR = '../api_key.txt'
106
107    # Set up command-line arguments:
108    parser = argparse.ArgumentParser(description='Download images for a '
109                                     'location using the specified footprint '
110                                     'scraper.')
111    parser.add_argument('scraper', type=str, nargs='?',
112                        default='USA_FootprintScraper',
113                        help="Name of the footprint scraper.")
114    parser.add_argument('location', type=str, nargs='?', default='Tiburon, CA',
115                        help="Name of the location to analyze.")
116    parser.add_argument('--api_key_path', type=str, default=API_KEY_DIR,
117                        help="Path to the Google API key file.")
118
119    # Parse the command-line arguments:
120    args = parser.parse_args()
121    print(args)
122    try:
123        # Load the API key:
124        parsed_api_key = load_api_key(args.api_key_path)
125
126        # Run the main function
127        fp_inventory, aerial_im, street_im = download_images(
128            args.location, args.scraper, parsed_api_key)
129    except Exception as e:
130        print(f'Error{e}')

Note

  1. To run the script you will need to obtain a Google API key.

  2. There are no costs associated with downloading images using these modules.

  3. Downloading and processing images requires time and computational resources. To mitigate this for test runs, the get_random_sample() method can be used to select a subset of assets. Subsequently, for any assets with missing processed data, data imputation techniques can be applied to address the gaps.