Esempio n. 1
0
    def __call__(self, coord):
        """
        Extracts the 21x21 sub-array from the the full VIIRS tile set
        corresponding to the provided coordinates,
        and returns a normalized 3D tensor.

        Normalization:
            output = ln(input + 1)/ln(max)
            Where max = 92,000 radiance in our dataset.
            Maps to [0,1] and reduces outsize influence of outliers.
        Input:
            coord (tuple of 2 floats)
        Returns a 3D tensor.
        """
        lon, lat = coord

        min_lat, min_lon, max_lat, max_lon = create_space(lat, lon)

        row, col = self.tif.index(min_lon, max_lat)
        row -= self.row_offset
        col -= self.col_offset
        array = self.tif_data[:, row:row + 21, col:col + 21]
        viirs_tensor = torch.tensor(array.reshape(
            (-1, 21, 21))).type(torch.FloatTensor)

        return torch.clamp(torch.log(viirs_tensor + 1) / 11.43, min=0, max=1)
Esempio n. 2
0
def create_poly(r):
    lat = r.cluster_lat
    lon = r.cluster_lon
    min_lat, min_lon, max_lat, max_lon = create_space(lat, lon)
    points = [(min_lon, min_lat), (min_lon, max_lat), (max_lon, max_lat),
              (max_lon, max_lat)]
    return Polygon(points)
Esempio n. 3
0
    def __call__(self, coord, pathrow, img_urls):
        """
        Extracts the 21x21 sub-array from the Landsat scene corresponding
        to the provided coordinates, and returns a normalized 3D tensor.

        Input:
            coord (tuple of 2 floats)
            pathrow (str)
            img_urls: tuple of urls to R, G, and B TIF bands to a single scene

        Returns a 3D tensor.
        """
        r_url, b_url, g_url = img_urls
        lon, lat = coord

        # If we already have the 3d tensor, just return it
        if coord in self.coord_imgs:
            return self.coord_imgs[coord].new_tensor()
        else:
            # Get TIF with 3 bands
            tif = rasterio.open(self._get_tif(img_urls, pathrow), 'r')

        # Extract 224x224 subarray from landsat scene
        min_lat, min_lon, max_lat, max_lon = create_space(lat, lon)
        utm = pyproj.Proj(tif.crs)
        lonlat = pyproj.Proj(init='epsg:4326')
        east, north = pyproj.transform(lonlat, utm, max_lon, max_lat)
        west, south = pyproj.transform(lonlat, utm, min_lon, min_lat)

        north_idx, west_idx = tif.index(west, north)
        south_idx, east_idx = tif.index(east, south)

        raw_array = tif.read(window=Window(
            west_idx, north_idx, abs(west_idx -
                                     east_idx), abs(north_idx - south_idx)))

        tif.close()

        # Convert array to tensor
        landsat_tensor = torch.tensor(raw_array).type(torch.FloatTensor)

        # resize tensor
        landsat_tensor = TF.resize(landsat_tensor, size=(self.ydim, self.xdim))

        # Add tensor to dict
        self.coord_imgs[coord] = landsat_tensor

        return landsat_tensor.new_tensor()
def generate_download_locations(df, ipc=50):
    '''
    Takes a dataframe with columns cluster_lat, cluster_lon
    Generates a 10km x 10km bounding box around the cluster and samples 
    ipc images per cluster. First samples in a grid fashion, then any 
    remaining points are randomly (uniformly) chosen
    '''
    np.random.seed(RANDOM_SEED) # for reproducability
    df_download = {'image_name': [], 'image_lat': [], 'image_lon': []}
    for c in df.columns:
        df_download[c] = []
    # side length of square for uniform distribution
    edge_num = math.floor(math.sqrt(ipc))
    for _, r in df.iterrows():
        min_lat, min_lon, max_lat, max_lon = create_space(r.cluster_lat, r.cluster_lon)
        lats = np.linspace(min_lat, max_lat, edge_num).tolist()
        lons = np.linspace(min_lon, max_lon, edge_num).tolist()

        # performs cartesian product
        uniform_points = np.transpose([np.tile(lats, len(lons)), np.repeat(lons, len(lats))])
        
        lats = uniform_points[:,0].tolist()
        lons = uniform_points[:,1].tolist()
        
        # fills the remainder with random points
        for _ in range(ipc - edge_num * edge_num):
            lat = np.random.uniform(min_lat, max_lat)
            lon = np.random.uniform(min_lon, max_lon)
            lats.append(lat)
            lons.append(lon)
        
        # add to dict
        for lat, lon in zip(lats, lons):
            # image name is going to be image_lat_image_lon_cluster_lat_cluster_lon.png
            image_name = str(lat) + '_' + str(lon) + '_' + str(r.cluster_lat) + '_' + str(r.cluster_lon) + '.png'
            df_download['image_name'].append(image_name)
            df_download['image_lat'].append(lat)
            df_download['image_lon'].append(lon)
            for c in df.columns:
                df_download[c].append(r[c])
        
    return pd.DataFrame.from_dict(df_download)
Esempio n. 5
0
def add_nightlights(df):
    ''' 
    This takes a dataframe with columns cluster_lat, cluster_lon and finds the average 
    nightlights in 2015 using a 10km x 10km box around the point
    '''
    return
    tif_array = None
    print('loading tif...')
    if COUNTRY == 'malawi_2016':
        print('loading tif...')
        tif_array = np.squeeze(tifs[0].get_data())
        add_nightlights(df_c, TIFS[0], tif_array)
    elif COUNTRY == 'ethiopia_2015':
        print('loading tif...')
        tif_array = np.squeeze(tifs[1].get_data())
        add_nightlights(df_c, TIFS[1], tif_array)
    else:
        raise ValueError('Unrecognized country')

    cluster_nightlights = []
    for i, r in df.iterrows():
        min_lat, min_lon, max_lat, max_lon = create_space(
            r.cluster_lat, r.cluster_lon)

        xminPixel, ymaxPixel = tif.proj_to_raster(min_lon, min_lat)
        xmaxPixel, yminPixel = tif.proj_to_raster(max_lon, max_lat)
        assert xminPixel < xmaxPixel, print(r.cluster_lat, r.cluster_lon)
        assert yminPixel < ymaxPixel, print(r.cluster_lat, r.cluster_lon)
        if xminPixel < 0 or xmaxPixel >= tif_array.shape[1]:
            print(f"no match for {r.cluster_lat}, {r.cluster_lon}")
            raise ValueError()
        elif yminPixel < 0 or ymaxPixel >= tif_array.shape[0]:
            print(f"no match for {r.cluster_lat}, {r.cluster_lon}")
            raise ValueError()
        xminPixel, yminPixel, xmaxPixel, ymaxPixel = int(xminPixel), int(
            yminPixel), int(xmaxPixel), int(ymaxPixel)
        cluster_nightlights.append(tif_array[yminPixel:ymaxPixel,
                                             xminPixel:xmaxPixel].mean())

    df['nightlights'] = cluster_nightlights
    return
Esempio n. 6
0
 def __call__(self, coord, country):
     """
     Extracts the 21x21 sub-array from the the full VIIRS tile set
     corresponding to the provided coordinates,
     and returns a normalized 3D tensor.
     
     Normalization:
         output = ln(input + 1)/ln(max)
         Where max = 92,000 radiance in our dataset.
         Maps to [0,1] and reduces outsize influence of outliers.
     Input:
         coord (tuple of 2 floats)
         country (str): One of ['eth', 'mw', 'ng']
     Returns a 3D tensor.
     """
     min_lat, min_lon, max_lat, max_lon = create_space(
         coord[0], coord[1])
     xminPixel, ymaxPixel = self.tifs[country].proj_to_raster(min_lon, min_lat)
     xminPixel, ymaxPixel = int(xminPixel), int(ymaxPixel)
     array = self.arrays[country][:, ymaxPixel-21:ymaxPixel, xminPixel:xminPixel+21]
     viirs_tensor = torch.tensor(array.reshape((-1,21,21))).type(torch.FloatTensor)
     return torch.log(viirs_tensor + 1) / 11.43