|
1 | 1 |
|
2 | 2 | from typing import Union |
3 | 3 | from datetime import datetime, timedelta |
| 4 | + |
| 5 | +from geopandas import GeoSeries |
4 | 6 | import numpy as np |
5 | 7 | import pandas as pd |
6 | 8 | import rasters as rt |
@@ -146,17 +148,27 @@ def calculate_solar_day_of_year( |
146 | 148 | """ |
147 | 149 | times = _parse_time(time_UTC) |
148 | 150 |
|
149 | | - if geometry is not None: |
| 151 | + # If latitude is not provided, try to extract from geometry |
| 152 | + if lat is None and isinstance(geometry, SpatialGeometry): |
| 153 | + lat = geometry.lat |
| 154 | + elif lat is None and isinstance(geometry, GeoSeries): |
| 155 | + lat = geometry.y |
| 156 | + elif lat is None: |
| 157 | + raise ValueError("no latitude provided") |
| 158 | + |
| 159 | + if lon is None and isinstance(geometry, SpatialGeometry): |
150 | 160 | lon = geometry.lon |
151 | | - elif lon is not None: |
152 | | - lon = np.asarray(lon) |
153 | | - else: |
154 | | - raise ValueError('Must provide either spatial or lon.') |
155 | | - |
| 161 | + elif lon is None and isinstance(geometry, GeoSeries): |
| 162 | + lon = geometry.x |
| 163 | + elif lon is None: |
| 164 | + raise ValueError("no longitude provided") |
| 165 | + |
156 | 166 | # Broadcast times and lons |
157 | 167 | times_b, lons_b = _broadcast_time_and_space(times, lon) |
158 | | - # Calculate DOY_UTC |
159 | | - doy_UTC = np.array([t.timetuple().tm_yday for t in times_b.flat]).reshape(times_b.shape) |
| 168 | + # Vectorized conversion to pandas datetime and dayofyear extraction |
| 169 | + times_b_flat = times_b.flatten() |
| 170 | + times_b_dt = pd.to_datetime(times_b_flat) |
| 171 | + doy_UTC = times_b_dt.dayofyear.values.reshape(times_b.shape) |
160 | 172 |
|
161 | 173 | hour_UTC = ( |
162 | 174 | times_b.astype('datetime64[h]').astype(int) % 24 |
|
0 commit comments