Example #1
0
def get_resampled_image(target_area_def, source_area_def, source_image_data,
                        fill_value=0, nprocs=1, segments=None):
    """Resamples image using nearest neighbour method in cartesian 
    projection coordinate systems.

    :Parameters:
    target_area_def : object 
        Target definition as AreaDefinition object
    source_area_def : object 
        Source definition as AreaDefinition object
    source_image_data : numpy array 
        Source image data
    fill_value : {int, None} optional 
        Set undetermined pixels to this value.
        If fill_value is None a masked array is returned 
        with undetermined pixels masked    
    nprocs : int, optional 
        Number of processor cores to be used
    segments : {int, None} optional
        Number of segments to use when resampling.
        If set to None an estimate will be calculated. 
        
    :Returns:
    image_data : numpy array 
        Resampled image data    
    """
    
    if not isinstance(target_area_def, geometry.AreaDefinition):
        raise TypeError('target_area_def must be of type AreaDefinition')
    if not isinstance(source_area_def, geometry.AreaDefinition):
        raise TypeError('source_area_def must be of type AreaDefinition')
    if not isinstance(source_image_data, (np.ndarray,
                                          np.ma.core.MaskedArray)):
        raise TypeError('source_image must be of type ndarray'
                        ' or a masked array.')

    #Calculate number of segments if needed 
    if segments is None:
        rows = target_area_def.y_size
        cut_off = 500
        if rows > cut_off:
            segments = int(rows / cut_off)
        else:
            segments = 1
    
    
    if segments > 1:
        #Iterate through segments        
        for i, target_slice in enumerate(geometry._get_slice(segments,  
                                                  target_area_def.shape)):
            
            #Select data from segment with slice
            lons, lats = target_area_def.get_lonlats(nprocs=nprocs, data_slice=target_slice)
            
            #Calculate partial result
            next_result = get_image_from_lonlats(lons, lats, source_area_def, 
                                                 source_image_data, 
                                                 fill_value, nprocs)
                
            #Build result iteratively 
            if i == 0:
                #First iteration
                result = next_result
            else:            
                result = np.row_stack((result, next_result))
        
        return result
    else:
        #Get lon lat arrays of target area
        lons, lats = target_area_def.get_lonlats(nprocs)
        #Get target image
        return get_image_from_lonlats(lons, lats, source_area_def, 
                                      source_image_data, fill_value, nprocs)
Example #2
0
def get_neighbour_info(source_geo_def, target_geo_def, radius_of_influence, 
                       neighbours=8, epsilon=0, reduce_data=True, nprocs=1, segments=None):
    """Returns neighbour info
    
    :Parameters:
    source_geo_def : object
        Geometry definition of source
    target_geo_def : object
        Geometry definition of target
    radius_of_influence : float 
        Cut off distance in meters
    neighbours : int, optional 
        The number of neigbours to consider for each grid point
    epsilon : float, optional
        Allowed uncertainty in meters. Increasing uncertainty
        reduces execution time
    fill_value : {int, None}, optional 
            Set undetermined pixels to this value.
            If fill_value is None a masked array is returned 
            with undetermined pixels masked    
    reduce_data : bool, optional
        Perform initial coarse reduction of source dataset in order
        to reduce execution time
    nprocs : int, optional
        Number of processor cores to be used
    segments : {int, None}
        Number of segments to use when resampling.
        If set to None an estimate will be calculated
            
    :Returns:
    (valid_input_index, valid_output_index, 
    index_array, distance_array) : tuple of numpy arrays
        Neighbour resampling info
    """

    if source_geo_def.size < neighbours:
        warnings.warn('Searching for %s neighbours in %s data points' % 
                      (neighbours, source_geo_def.size))

    if segments is None:
        cut_off = 3000000
        if target_geo_def.size > cut_off:
            segments = int(target_geo_def.size / cut_off)
        else:
            segments = 1
    
    #Find reduced input coordinate set
    valid_input_index, source_lons, source_lats = _get_valid_input_index(source_geo_def, target_geo_def, 
                                               reduce_data, 
                                               radius_of_influence, 
                                               nprocs=nprocs)    
    
    #Create kd-tree
    try:
        resample_kdtree = _create_resample_kdtree(source_lons, source_lats, 
                                                  valid_input_index, 
                                                  nprocs=nprocs)
    except EmptyResult:
        #Handle if all input data is reduced away
         valid_output_index, index_array, distance_array = \
             _create_empty_info(source_geo_def, target_geo_def, neighbours)
         return (valid_input_index, valid_output_index, index_array, 
                 distance_array)
     
    if segments > 1:
        #Iterate through segments     
        for i, target_slice in enumerate(geometry._get_slice(segments, 
                                                   target_geo_def.shape)):

            #Query on slice of target coordinates
            next_voi, next_ia, next_da = \
                    _query_resample_kdtree(resample_kdtree, source_geo_def, 
                                           target_geo_def, 
                                           radius_of_influence, target_slice,
                                           neighbours=neighbours, 
                                           epsilon=epsilon, 
                                           reduce_data=reduce_data, 
                                           nprocs=nprocs)

            #Build result iteratively
            if i == 0:
                #First iteration
                valid_output_index = next_voi
                index_array = next_ia
                distance_array = next_da
            else:    
                valid_output_index = np.append(valid_output_index, next_voi)
                if neighbours > 1:
                    index_array = np.row_stack((index_array, next_ia))
                    distance_array = np.row_stack((distance_array, next_da))
                else:
                    index_array = np.append(index_array, next_ia)
                    distance_array = np.append(distance_array, next_da)        
    else:
        #Query kd-tree with full target coordinate set        
        full_slice = slice(None)
        valid_output_index, index_array, distance_array = \
                    _query_resample_kdtree(resample_kdtree, source_geo_def, 
                                           target_geo_def, 
                                           radius_of_influence, full_slice,
                                           neighbours=neighbours, 
                                           epsilon=epsilon, 
                                           reduce_data=reduce_data, 
                                           nprocs=nprocs)
    
    # Check if number of neighbours is potentially too low
    if neighbours > 1:
        if not np.all(np.isinf(distance_array[:, -1])):
            warnings.warn(('Possible more than %s neighbours '
                           'within %s m for some data points') % 
                          (neighbours, radius_of_influence))
         
    return valid_input_index, valid_output_index, index_array, distance_array