# Path: s2p/common.py
# def remove(target):
# def garbage_cleanup():
# def tmpfile(ext=''):
# def run(cmd, env=os.environ):
# def mkdir_p(path):
# def shellquote(s):
# def matrix_translation(x, y):
# def image_size_gdal(im):
# def gdal_read_as_array_with_nans(im):
# def image_zoom_out_morpho(im, f):
# def rasterio_write(path, array, profile={}, tags={}):
# def image_apply_homography(out, im, H, w, h):
# def image_qauto(im, out=None):
# def points_apply_homography(H, pts):
# def bounding_box2D(pts):
# def image_crop_gdal(im, x, y, w, h, out=None):
# def run_binary_on_list_of_points(points, binary, option=None, env_var=None):
# def get_rectangle_coordinates(im):
# def get_roi_coordinates(img, preview):
# def cargarse_basura(inputf, outputf):
# def print_elapsed_time(since_first_call=False):
# class RunFailure(Exception):
# 
# Path: s2p/rpc_utils.py
# def find_corresponding_point(model_a, model_b, x, y, z):
# def compute_height(model_a, model_b, x1, y1, x2, y2):
# def geodesic_bounding_box(rpc, x, y, w, h):
# def altitude_range_coarse(rpc, scale_factor=1):
# def min_max_heights_from_bbx(im, lon_m, lon_M, lat_m, lat_M, rpc):
# def altitude_range(rpc, x, y, w, h, margin_top=0, margin_bottom=0):
# def utm_zone(rpc, x, y, w, h):
# def utm_roi_to_img_roi(rpc, roi):
# def kml_roi_process(rpc, kml):
# def generate_point_mesh(col_range, row_range, alt_range):
# def ground_control_points(rpc, x, y, w, h, m, M, n):
# def corresponding_roi(rpc1, rpc2, x, y, w, h):
# def matches_from_rpc(rpc1, rpc2, x, y, w, h, n):
# def alt_to_disp(rpc1, rpc2, x, y, alt, H1, H2, A=None):
# def exogenous_disp_range_estimation(rpc1, rpc2, x, y, w, h, H1, H2, A=None,
#                                     margin_top=0, margin_bottom=0):
# def altitude_range_to_disp_range(m, M, rpc1, rpc2, x, y, w, h, H1, H2, A=None,
#                                  margin_top=0, margin_bottom=0):
# def rpc_from_geotiff(geotiff_path, outrpcfile='.rpc'):
#     HSTEP = 1
#     M = rpc.altOff + rpc.altScale
#     M = rpc.altOff + scale_factor * rpc.altScale
# 
# Path: s2p/masking.py
# def cloud_water_image_domain(x, y, w, h, rpc, roi_gml=None, cld_gml=None,
#                              wat_msk=None):
# def erosion(out, msk, radius):
#     H = common.matrix_translation(-x, -y)
# 
# Path: s2p/parallel.py
# def show_progress(a):
# def tilewise_wrapper(fun, *args, **kwargs):
# def launch_calls(fun, list_of_args, nb_workers, *extra_args):
# def launch_calls_simple(fun, list_of_args, nb_workers, *extra_args):


import os
import sys
import utm
import json
import copy
import shutil
import warnings
import numpy as np
            import tempfile     # TODO: fix for common.tmpfile failure
from s2p import common
from s2p import rpc_utils
from s2p import masking
from s2p import parallel
from s2p.config import cfg
    return tile

def tiles_full_info(tw, th, tiles_txt, create_masks=False):
    """
    List the tiles to process and prepare their output directories structures.

    Most of the time is spent discarding tiles that are masked by water
    (according to exogenous dem).

    Returns:
        a list of dictionaries. Each dictionary contains the image coordinates
        and the output directory path of a tile.
    """
    rpc = cfg['images'][0]['rpc']
    roi_msk = cfg['images'][0]['roi']
    cld_msk = cfg['images'][0]['cld']
    wat_msk = cfg['images'][0]['wat']
    rx = cfg['roi']['x']
    ry = cfg['roi']['y']
    rw = cfg['roi']['w']
    rh = cfg['roi']['h']

    # build a tile dictionary for all non-masked tiles and store them in a list
    tiles = []
    # list tiles coordinates
    tiles_coords, neighborhood_coords_dict = compute_tiles_coordinates(rx, ry, rw, rh, tw, th)

    if os.path.exists(tiles_txt) is False or create_masks is True:
        print('\ndiscarding masked tiles...')
        # compute all masks in parallel as numpy arrays

# Path: s2p/common.py
# def remove(target):
# def garbage_cleanup():
# def tmpfile(ext=''):
# def run(cmd, env=os.environ):
# def mkdir_p(path):
# def shellquote(s):
# def matrix_translation(x, y):
# def image_size_gdal(im):
# def gdal_read_as_array_with_nans(im):
# def image_zoom_out_morpho(im, f):
# def rasterio_write(path, array, profile={}, tags={}):
# def image_apply_homography(out, im, H, w, h):
# def image_qauto(im, out=None):
# def points_apply_homography(H, pts):
# def bounding_box2D(pts):
# def image_crop_gdal(im, x, y, w, h, out=None):
# def run_binary_on_list_of_points(points, binary, option=None, env_var=None):
# def get_rectangle_coordinates(im):
# def get_roi_coordinates(img, preview):
# def cargarse_basura(inputf, outputf):
# def print_elapsed_time(since_first_call=False):
# class RunFailure(Exception):
# 
# Path: s2p/rpc_utils.py
# def find_corresponding_point(model_a, model_b, x, y, z):
# def compute_height(model_a, model_b, x1, y1, x2, y2):
# def geodesic_bounding_box(rpc, x, y, w, h):
# def altitude_range_coarse(rpc, scale_factor=1):
# def min_max_heights_from_bbx(im, lon_m, lon_M, lat_m, lat_M, rpc):
# def altitude_range(rpc, x, y, w, h, margin_top=0, margin_bottom=0):
# def utm_zone(rpc, x, y, w, h):
# def utm_roi_to_img_roi(rpc, roi):
# def kml_roi_process(rpc, kml):
# def generate_point_mesh(col_range, row_range, alt_range):
# def ground_control_points(rpc, x, y, w, h, m, M, n):
# def corresponding_roi(rpc1, rpc2, x, y, w, h):
# def matches_from_rpc(rpc1, rpc2, x, y, w, h, n):
# def alt_to_disp(rpc1, rpc2, x, y, alt, H1, H2, A=None):
# def exogenous_disp_range_estimation(rpc1, rpc2, x, y, w, h, H1, H2, A=None,
#                                     margin_top=0, margin_bottom=0):
# def altitude_range_to_disp_range(m, M, rpc1, rpc2, x, y, w, h, H1, H2, A=None,
#                                  margin_top=0, margin_bottom=0):
# def rpc_from_geotiff(geotiff_path, outrpcfile='.rpc'):
#     HSTEP = 1
#     M = rpc.altOff + rpc.altScale
#     M = rpc.altOff + scale_factor * rpc.altScale
# 
# Path: s2p/masking.py
# def cloud_water_image_domain(x, y, w, h, rpc, roi_gml=None, cld_gml=None,
#                              wat_msk=None):
# def erosion(out, msk, radius):
#     H = common.matrix_translation(-x, -y)
# 
# Path: s2p/parallel.py
# def show_progress(a):
# def tilewise_wrapper(fun, *args, **kwargs):
# def launch_calls(fun, list_of_args, nb_workers, *extra_args):
# def launch_calls_simple(fun, list_of_args, nb_workers, *extra_args):


# Path: s2p/initialization.py
import os
import sys
import utm
import json
import copy
import shutil
import warnings
import numpy as np
            import tempfile     # TODO: fix for common.tmpfile failure
from s2p import common
from s2p import rpc_utils
from s2p import masking
from s2p import parallel
from s2p.config import cfg

    return tile

def tiles_full_info(tw, th, tiles_txt, create_masks=False):
    """
    List the tiles to process and prepare their output directories structures.

    Most of the time is spent discarding tiles that are masked by water
    (according to exogenous dem).

    Returns:
        a list of dictionaries. Each dictionary contains the image coordinates
        and the output directory path of a tile.
    """
    rpc = cfg['images'][0]['rpc']
    roi_msk = cfg['images'][0]['roi']
    cld_msk = cfg['images'][0]['cld']
    wat_msk = cfg['images'][0]['wat']
    rx = cfg['roi']['x']
    ry = cfg['roi']['y']
    rw = cfg['roi']['w']
    rh = cfg['roi']['h']

    # build a tile dictionary for all non-masked tiles and store them in a list
    tiles = []
    # list tiles coordinates
    tiles_coords, neighborhood_coords_dict = compute_tiles_coordinates(rx, ry, rw, rh, tw, th)

    if os.path.exists(tiles_txt) is False or create_masks is True:
        print('\ndiscarding masked tiles...')
        # compute all masks in parallel as numpy arrays

        tiles_masks = parallel.launch_calls_simple(masking.cloud_water_image_domain,