def test_get_position_pandas_datetime_series(): df = pd.DataFrame({'date': [date] * 3, 'lat': [lat] * 3, 'lng': [lng] * 3}) pos = pd.DataFrame(get_position(df['date'], df['lng'], df['lat'])) assert pos.shape == (3, 2) assert all(x in pos.columns for x in ['azimuth', 'altitude']) assert pos.dtypes['azimuth'] == np.dtype('float64') assert pos.dtypes['altitude'] == np.dtype('float64') assert np.isclose(pos['azimuth'].iloc[0], -2.5003175907168385) assert np.isclose(pos['altitude'].iloc[0], -0.7000406838781611)
def create_stac_items(scenes_list: str, grid_geom: str, collection: int = 1, level: int = 1): """Create STAC Items from scene_list and WRS2 grid.""" # Read WRS2 Grid geometries with open(grid_geom, "r") as f: wrs_grid_list = [json.loads(line) for line in f.readlines()] pr = [x["properties"]["PR"] for x in wrs_grid_list] wrs_grid = dict(zip(pr, wrs_grid_list)) for pr in wrs_grid.keys(): wrs_grid[pr]["geometry"] = _reduce_precision( wrs_grid[pr]["geometry"]) # Open list of scenes with open(scenes_list, "r") as f: reader = csv.DictReader(f) for value in reader: # LC08_L1GT_070235_20180607_20180608_01_RT product_id = value["productId"] productid_info = product_id.split("_") path_row = productid_info[2] collection_number = productid_info[-2] collection_category = productid_info[-1] sat_number = int(productid_info[0][2:4]) sensor = productid_info[0][1] _level = int(value["processingLevel"][1]) if _level != level: continue if int(collection_number) != collection: continue grid_cell = wrs_grid[path_row] scene_time = grid_cell["properties"]["PERIOD"] geom = grid_cell["geometry"] if sensor == "C": instruments = ["oli", "tirs"] elif sensor == "O": instruments = ["oli"] elif sensor == "T" and sat_number >= 8: instruments = ["tirs"] elif sensor == "E": instruments = ["etm"] elif sensor == "T" and sat_number <= 8: instruments = ["tm"] elif sensor == "M": instruments = ["mss"] path = int(value["path"]) row = int(value["row"]) # we remove the milliseconds because it's missing for some entry d = value["acquisitionDate"].split(".") if len(d) == 1: date_info = datetime.strptime( value["acquisitionDate"], "%Y-%m-%d %H:%M:%S").replace(tzinfo=timezone.utc) else: date_info = datetime.strptime( value["acquisitionDate"], "%Y-%m-%d %H:%M:%S.%f").replace(tzinfo=timezone.utc) center_lat = (float(value["min_lat"]) + float(value["max_lat"])) / 2 center_lon = (float(value["min_lon"]) + float(value["max_lon"])) / 2 pos = get_position(date_info, center_lon, center_lat) sun_azimuth = math.degrees(pos["azimuth"] + math.pi) % 360 sun_elevation = math.degrees(pos["altitude"]) collection_name = f"aws-landsat-c{collection}l{level}" stac_item = { "type": "Feature", "stac_extensions": [eo_extension, landsat_extension, view_extension], "id": product_id, "collection": collection_name, "bbox": feature_bounds(geom), "geometry": geom, "properties": { "datetime": date_info.strftime("%Y-%m-%dT%H:%M:%S.%fZ"), "platform": f"LANDSAT_{sat_number}", "instruments": instruments, "gsd": 30, "view:sun_azimuth": round(sun_azimuth, 6), "view:sun_elevation": round(sun_elevation, 6), "landsat:wrs_type": 2, "landsat:wrs_row": row, "landsat:wrs_path": path, "landsat:scene_id": value["entityId"], "landsat:day_or_night": scene_time.lower(), "landsat:processing_level": value["processingLevel"], "landsat:collection_category": collection_category, "landsat:collection_number": collection_number, "landsat:cloud_cover_land": float(value["cloudCover"]), "eo:cloud_cover": float(value["cloudCover"]), }, "links": [{ "title": "AWS Public Dataset page for Landsat-8", "rel": "about", "type": "text/html", "href": "https://registry.opendata.aws/landsat-8", }], } prefix = f"https://landsat-pds.s3.us-west-2.amazonaws.com/c{int(collection_number)}/L{sat_number}/{path:03}/{row:03}/{product_id}/{product_id}" stac_item["assets"] = create_assets(prefix) yield stac_item
def sun_positions(arr_utc: np.ndarray, lon: float, lat: float) -> Tuple[np.ndarray, np.ndarray]: sc = suncalc.get_position(arr_utc, lon, lat) return sc['azimuth'], sc['altitude']
def test_get_position_pandas_single_timestamp(): ts_date = pd.Timestamp(date) pos = get_position(ts_date, lng, lat) assert np.isclose(pos['azimuth'], -2.5003175907168385) assert np.isclose(pos['altitude'], -0.7000406838781611)
def test_get_position(): """getPosition returns azimuth and altitude for the given time and location """ pos = get_position(date, lng, lat) assert np.isclose(pos['azimuth'], -2.5003175907168385) assert np.isclose(pos['altitude'], -0.7000406838781611)