|
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