예제 #1
0
def save_planet_images_to_shapefile(geojson_list, save_shp_path, wkt_string, extent_polygon=None, b_group_date=False):
    '''
    get the meta data and extent of download
    :param geojson_list: geojson_list
    :param save_shp_path:
    :param extent_polygon: a extent polygon
    :param b_group_date:
    :return:
    '''

    # remove incomplete scenes
    geojson_list = [ item for item in geojson_list if 'incomplete_scenes' not in item ]
    if len(geojson_list) < 1:
        raise ValueError('No geojson files (exclude incomplete_scenes) the given folder')

    if extent_polygon is not None and len(extent_polygon) > 1:
        raise ValueError('Only support one extent polygon')

    extent = extent_polygon[0]

    if b_group_date is False:
        geojson_group = {'all': geojson_list}
    else:
        geojson_group = group_geojson_by_date(geojson_list)

    for key in geojson_group.keys():
        sub_geojsons = geojson_group[key]
        if len(sub_geojsons) < 1:
            continue

        sel_geojson_list, sel_polygons = get_geojson_list_overlap_a_polygon(extent,sub_geojsons)
        if len(sel_geojson_list) < 1:
            continue
        scene_table, scene_without_asset = get_meta_dict(sel_geojson_list)


        if len(scene_table['scene_id']) != len(sel_polygons):
            raise ValueError('The count of scence ID and polygon are different, could due to some duplicated scenes ')

        # to strings, ESRI Shapefile does not support datetime fields
        scene_table['acquisitionDate'] = [ timeTools.datetime2str(item) for item in  scene_table['acquisitionDate']]
        scene_table['downloadTime'] = [ timeTools.datetime2str(item) for item in  scene_table['downloadTime']]

        scene_table['Polygons'] = sel_polygons
        df = pd.DataFrame(scene_table)

        if key=="all":
            save_path = save_shp_path
        else:
            date_str = timeTools.date2str(key)
            save_path = io_function.get_name_by_adding_tail(save_shp_path,date_str)
        vector_gpd.save_polygons_to_files(df,'Polygons', wkt_string, save_path)

    return True
예제 #2
0
def main():

    file_list = io_function.get_file_list_by_pattern(arcticDEM_reg_tif_dir,
                                                     '*_dem_reg.tif')
    print('Get %d dem_reg.tif from %s' %
          (len(file_list), arcticDEM_reg_tif_dir))

    year_dates = [
        timeTools.get_yeardate_yyyymmdd(os.path.basename(item),
                                        pattern='[0-9]{8}_')
        for item in file_list
    ]
    month_list = [item.month for item in year_dates]
    value_list = month_list

    # save unique date to txt file
    dates_unique = set(year_dates)
    dates_unique = sorted(dates_unique)
    dates_unique_str = [
        timeTools.date2str(item, '%Y-%m-%d') for item in dates_unique
    ]
    io_function.save_list_to_txt('dates_unique.txt', dates_unique_str)

    # plot a histogram
    # bin_count = 12
    bins = np.arange(0, 12, 1)
    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8, 8))
    n, bins, patches = ax.hist(value_list,
                               bins=bins,
                               alpha=0.75,
                               ec="black",
                               linewidth='1.5',
                               color='grey',
                               hatch='',
                               rwidth=1)  # density = True, # label=labels,

    # ax.legend(prop={'size': 12})
    plt.xticks(bins)
    ax.tick_params(axis='both',
                   which='both',
                   direction='out',
                   length=7,
                   labelsize=20)  # ,width=50 #,
    # if xlabelrotation is not None:
    #     ax.tick_params(axis='x', labelrotation=90)

    # if ylim is not None:
    #     ax.set_ylim(ylim)

    plt.gcf().subplots_adjust(bottom=0.15)
    # plt.grid(True)
    plt.savefig('ArcticDEM_strip_date_hist.jpg')  #
def merge_multi_headwall_shp_to_one(shp_list, save_path):
    '''
    merge multiple shapefile of headwall on different dates to one file
    :param shp_dir:
    :param save_path:
    :return:
    '''
    # shp_list = io_function.get_file_list_by_ext('.shp',shp_dir,bsub_folder=False)
    if len(shp_list) < 1:
        print('Warning, no input shapefile, skip merging multiple shapefiles')
        return False

    if os.path.isfile(save_path):
        print('warning, %s already exists, skip' % save_path)
        return True

    # merge shapefile, one by one, and add the year and date from filename
    line_list = []
    id_list = []
    year_list = []
    date_list = []
    length_m_list = []  # length in meters
    for shp in shp_list:
        # these are line vector, we still can use the following function to read them
        lines, lengths = vector_gpd.read_polygons_attributes_list(
            shp, 'length_m')
        curr_count = len(id_list)
        acuiqsition_date = timeTools.get_yeardate_yyyymmdd(
            os.path.basename(shp))
        year = acuiqsition_date.year
        for idx, (line, length) in enumerate(zip(lines, lengths)):
            id_list.append(idx + curr_count)
            line_list.append(line)
            length_m_list.append(length)
            year_list.append(year)
            date_list.append(timeTools.date2str(acuiqsition_date))

    save_pd = pd.DataFrame({
        'id': id_list,
        'length_m': length_m_list,
        'dem_year': year_list,
        'dem_date': date_list,
        'Line': line_list
    })
    ref_prj = map_projection.get_raster_or_vector_srs_info_proj4(shp_list[0])
    return vector_gpd.save_polygons_to_files(save_pd, 'Line', ref_prj,
                                             save_path)
예제 #4
0
def dem_diff_newest_oldest(dem_tif_list, out_dem_diff, out_date_diff):
    '''
    get DEM difference, for each pixel, newest vaild value - oldest valid value
    :param dem_list:
    :param output:
    :return:
    '''
    if len(dem_tif_list) < 2:
        basic.outputlogMessage('error, the count of DEM is smaller than 2')
        return False

    # groups DEM with original images acquired at the same year months
    dem_groups_date = group_demTif_yearmonthDay(dem_tif_list, diff_days=0)
    # sort based on yeardate in accending order : operator.itemgetter(0)
    dem_groups_date = dict(
        sorted(dem_groups_date.items(), key=operator.itemgetter(0)))
    txt_save_path = os.path.splitext(out_date_diff)[0] + '.txt'
    io_function.save_dict_to_txt_json(txt_save_path, dem_groups_date)

    date_list = list(dem_groups_date.keys())
    dem_tif_list = [dem_groups_date[key][0] for key in dem_groups_date.keys()
                    ]  # each date, only have one tif
    tif_obj_list = [raster_io.open_raster_read(tif) for tif in dem_tif_list]

    height, width, _ = raster_io.get_width_heigth_bandnum(tif_obj_list[0])

    # check them have the width and height
    for tif, obj in zip(dem_tif_list[1:], tif_obj_list[1:]):
        h, w, _ = raster_io.get_width_heigth_bandnum(obj)
        if h != height or w != width:
            raise ValueError(
                'the height and width of %s is different from others' % tif)

    # divide the image the many small patches, then calcuate one by one, solving memory issues.
    image_patches = split_image.sliding_window(width,
                                               height,
                                               1024,
                                               1024,
                                               adj_overlay_x=0,
                                               adj_overlay_y=0)
    patch_count = len(image_patches)
    tif_obj_list = None

    # read all and their date
    date_pair_list = list(combinations(date_list, 2))
    date_diff_list = [(item[1] - item[0]).days for item in date_pair_list]
    # sort based on day difference (from max to min)
    date_pair_list_sorted = [
        x for _, x in sorted(zip(date_diff_list, date_pair_list), reverse=True)
    ]  # descending

    # get the difference
    date_diff_np = np.zeros((height, width), dtype=np.uint16)
    dem_diff_np = np.empty((height, width), dtype=np.float32)
    dem_diff_np[:] = np.nan

    for idx, patch in enumerate(image_patches):
        print('tile: %d / %d' % (idx + 1, patch_count))

        patch_w = patch[2]
        patch_h = patch[3]
        patch_date_diff = np.zeros((patch_h, patch_w), dtype=np.uint16)
        patch_dem_diff = np.empty((patch_h, patch_w), dtype=np.float32)
        patch_dem_diff[:] = np.nan

        # use dict to read data from disk (only need)
        dem_data_dict = {}
        for p_idx, pair in enumerate(date_pair_list_sorted):
            diff_days = (pair[1] - pair[0]).days
            basic.outputlogMessage(
                'Getting DEM difference using the one on %s and %s, total day diff: %d'
                % (timeTools.date2str(pair[1]), timeTools.date2str(
                    pair[0]), diff_days))
            # print(pair,':',(pair[1] - pair[0]).days)

            data_old, data_new = read_date_dem_to_memory(p_idx,
                                                         pair,
                                                         date_pair_list_sorted,
                                                         dem_data_dict,
                                                         dem_groups_date,
                                                         boundary=patch)

            # print('data_old shape:',data_old.shape)
            # print('data_new shape:',data_new.shape)

            diff_two = data_new - data_old
            # print(diff_two)

            # fill the element
            new_ele = np.where(
                np.logical_and(np.isnan(patch_dem_diff), ~np.isnan(diff_two)))

            patch_dem_diff[new_ele] = diff_two[new_ele]
            patch_date_diff[new_ele] = diff_days

            # check if all have been filled ( nan pixels)
            diff_remain_hole = np.where(np.isnan(patch_dem_diff))
            # basic.outputlogMessage(' remain %.4f percent pixels need to be filled'% (100.0*diff_remain_hole[0].size/patch_dem_diff.size) )
            if diff_remain_hole[0].size < 1:
                break

        # copy to the entire image
        row_s = patch[1]
        row_e = patch[1] + patch[3]
        col_s = patch[0]
        col_e = patch[0] + patch[2]
        dem_diff_np[row_s:row_e, col_s:col_e] = patch_dem_diff
        date_diff_np[row_s:row_e, col_s:col_e] = patch_date_diff

    # save date diff to tif (16 bit)
    raster_io.save_numpy_array_to_rasterfile(date_diff_np,
                                             out_date_diff,
                                             dem_tif_list[0],
                                             nodata=0,
                                             compress='lzw',
                                             tiled='yes',
                                             bigtiff='if_safer')

    # # stretch the DEM difference, save to 8 bit.
    # dem_diff_np_8bit = raster_io.image_numpy_to_8bit(dem_diff_np,10,-10,dst_nodata=0)
    # out_dem_diff_8bit = io_function.get_name_by_adding_tail(out_dem_diff, '8bit')
    # raster_io.save_numpy_array_to_rasterfile(dem_diff_np_8bit, out_dem_diff_8bit, dem_tif_list[0], nodata=0)

    # if possible, save to 16 bit, to save the disk storage.
    # dem_diff_np[0:5,0] = -500
    # dem_diff_np[0,0:5] = 500
    # print(np.nanmin(dem_diff_np))
    # print(np.nanmax(dem_diff_np))
    range = np.iinfo(np.int16)
    # dem_diff_np_cm = dem_diff_np*100
    # if np.nanmin(dem_diff_np_cm) < range.min or np.nanmax(dem_diff_np_cm) > range.max:
    # save dem diff to files (float), meter
    raster_io.save_numpy_array_to_rasterfile(dem_diff_np,
                                             out_dem_diff,
                                             dem_tif_list[0],
                                             nodata=-9999,
                                             compress='lzw',
                                             tiled='yes',
                                             bigtiff='if_safer')
    # else:
    #     # save dem diff to 16bit, centimeter, only handle diff from -327.67 to 327.67 meters
    #     dem_diff_np_cm = dem_diff_np_cm.astype(np.int16)        # save to int16
    #     raster_io.save_numpy_array_to_rasterfile(dem_diff_np_cm, out_dem_diff_cm, dem_tif_list[0],nodata=32767,compress='lzw',tiled='yes',bigtiff='if_safer')

    return True
예제 #5
0
def main(options, args):

    # https://www.earthdatascience.org/tutorials/intro-google-earth-engine-python-api/
    # for each computer, need to run "earthengine authenticate" first.
    ee.Initialize()

    # all images will save to Google Drive first
    # currently, manually download them from Google Drive
    save_folder = args[0]

    extent_shp = options.extent_shp
    if extent_shp is None:
        raise ValueError('must provide a exent shp')

    region_name = options.region_name
    if region_name is None:
        region_name = os.path.splitext(os.path.basename(extent_shp))[0]

    # checking input shapefile
    # if extent_shp is not None:
    assert io_function.is_file_exist(extent_shp)
    shp_polygon_projection = get_projection_proj4(extent_shp).strip()
    if shp_polygon_projection != '+proj=longlat +datum=WGS84 +no_defs':
        raise ValueError('Only accept %s, please check projection of %s' %
                         (shp_polygon_projection, extent_shp))

    resolution = options.resolution
    global out_res
    out_res = resolution

    projection = options.projection_epsg
    global out_projection
    out_projection = projection

    extent_4points = get_extent_xy_from_shp(extent_shp)

    if os.path.isdir(save_folder) is False:
        io_function.mkdir(save_folder)

    # Sentinel-1 SAR GRD
    # https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S1_GRD

    # product_list = ['COPERNICUS/S1_GRD']

    # https://developers.google.com/earth-engine/tutorials/community/sar-basics

    # The Level-1 GRD processing assumes an ellipsoid Earth surface model, thus Level-1 GRD needs to be processed to create the Level-2 geocoded,
    # calibrated backscattering coefficients which end up in the GEE COPERNICUS/S1_GRD_FLOAT collection.

    # The S1_GRD_FLOAT collection, and its log-scaled COPERNICUS/S1_GRD computed equivalent,
    # contains "analysis-ready" images, as they have square pixel spacing, with pixel values as FLOAT32,
    # and a UTM projection in the auto-determined zone. Thus, they can be combined with other images, used in feature extractions and reductions, etc.

    product_list = ['COPERNICUS/S1_GRD_FLOAT']
    Polarisation_list = ['VV', 'HH', 'HV', 'VH']
    instrumentMode_list = ['IW']
    orbit_pass_list = ['DESCENDING', 'ASCENDING']

    b_crop = False  # crop images to input extent

    dates_list = options.dates_list_txt
    if dates_list is None:
        start_date, end_date = options.start_date, options.end_date
        for product in product_list:
            for polarization in Polarisation_list:
                for mode in instrumentMode_list:
                    for orbit_pass in orbit_pass_list:
                        gee_download_sentinel1_sar_grd(region_name,
                                                       product,
                                                       polarization,
                                                       mode,
                                                       orbit_pass,
                                                       start_date,
                                                       end_date,
                                                       extent_4points,
                                                       save_folder,
                                                       resolution,
                                                       projection,
                                                       crop=b_crop,
                                                       wait_all_finished=True)
    else:
        all_task_list = []
        dates_list = io_function.read_list_from_txt(dates_list)
        for idx, date_str in enumerate(dates_list):

            active_tasks = active_task_count(all_task_list)
            while active_tasks > maximum_submit_tasks:
                print(
                    '%s : %d (>%d) tasks already in the queue, wait 60 seconds'
                    % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                       active_tasks, maximum_submit_tasks))
                time.sleep(60)
                active_tasks = active_task_count(all_task_list)

            print('%d/%d Get snow cover for %s' %
                  (idx, len(dates_list), date_str))
            start_date = date_str
            end_date = timeTools.str2date(
                start_date, format='%Y-%m-%d') + timedelta(days=1)
            end_date = timeTools.date2str(end_date, format='%Y-%m-%d')

            for product in product_list:
                for polarization in Polarisation_list:
                    for mode in instrumentMode_list:
                        for orbit_pass in orbit_pass_list:
                            tasks = gee_download_sentinel1_sar_grd(
                                region_name,
                                product,
                                polarization,
                                mode,
                                orbit_pass,
                                start_date,
                                end_date,
                                extent_4points,
                                save_folder,
                                resolution,
                                projection,
                                crop=b_crop,
                                wait_all_finished=False)
                            if tasks is False:
                                continue
                            all_task_list.extend(tasks)

        # wait until all finished
        wait_all_task_finished(all_task_list)
예제 #6
0
def main(options, args):
    # https://www.earthdatascience.org/tutorials/intro-google-earth-engine-python-api/
    # for each computer, need to run "earthengine authenticate" first.
    ee.Initialize()

    # all images will save to Google Drive first, then move them to the below folder
    # not yet implemented, currently, manually download them from Google Drive
    save_folder = args[0]

    extent_shp = options.extent_shp
    if extent_shp is None:
        raise ValueError('must provide a exent shp')

    region_name = options.region_name
    if region_name is None:
        region_name = os.path.splitext(os.path.basename(extent_shp))[0]

    # checking input shapefile
    # if extent_shp is not None:
    assert io_function.is_file_exist(extent_shp)
    shp_polygon_projection = get_projection_proj4(extent_shp).strip()
    if shp_polygon_projection != '+proj=longlat +datum=WGS84 +no_defs':
        raise ValueError('Only accept %s, please check projection of %s' %
                         (shp_polygon_projection, extent_shp))

    extent_4points = get_extent_xy_from_shp(extent_shp)

    if os.path.isdir(save_folder) is False:
        io_function.mkdir(save_folder)

    snow_products = ['MODIS/006/MYD10A1', 'MODIS/006/MOD10A1']
    # snow_products = ['MODIS/006/MYD10A1']   # , 'MODIS/006/MOD10A1'

    # band_names = ['NDSI']
    band_names = ['NDSI_Snow_Cover', 'NDSI_Snow_Cover_Class']
    # there are nine bands.
    #       "id": "NDSI_Snow_Cover",
    #       "id": "NDSI_Snow_Cover_Basic_QA",
    #       "id": "NDSI_Snow_Cover_Algorithm_Flags_QA",
    #       "id": "NDSI",
    #       "id": "Snow_Albedo_Daily_Tile",
    #       "id": "orbit_pnt",
    #       "id": "granule_pnt",
    #       "id": "NDSI_Snow_Cover_Class",
    #       "id": "Snow_Albedo_Daily_Tile_Class",

    dates_list = options.dates_list_txt
    if dates_list is None:
        start_date, end_date = options.start_date, options.end_date
        for product in snow_products:
            for band_name in band_names:
                gee_download_modis_snow(region_name, product, band_name,
                                        start_date, end_date, extent_4points,
                                        save_folder)
    else:
        all_task_list = []
        dates_list = io_function.read_list_from_txt(dates_list)
        for idx, date_str in enumerate(dates_list):

            active_tasks = active_task_count(all_task_list)
            while active_tasks > maximum_submit_tasks:
                print(
                    '%s : %d (>%d) tasks already in the queue, wait 60 seconds'
                    % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                       active_tasks, maximum_submit_tasks))
                time.sleep(60)
                active_tasks = active_task_count(all_task_list)

            print('%d/%d Get snow cover for %s' %
                  (idx, len(dates_list), date_str))
            start_date = date_str
            end_date = timeTools.str2date(
                start_date, format='%Y-%m-%d') + timedelta(days=1)
            end_date = timeTools.date2str(end_date, format='%Y-%m-%d')

            for product in snow_products:
                for band_name in band_names:
                    tasks = gee_download_modis_snow(region_name,
                                                    product,
                                                    band_name,
                                                    start_date,
                                                    end_date,
                                                    extent_4points,
                                                    save_folder,
                                                    wait_all_finished=False)
                    if tasks is False:
                        continue
                    all_task_list.extend(tasks)

        # wait until all finished
        wait_all_task_finished(all_task_list)

    pass