voxcity 0.6.19__py3-none-any.whl → 0.6.21__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of voxcity might be problematic. Click here for more details.

voxcity/utils/weather.py CHANGED
@@ -209,7 +209,9 @@ def process_epw(epw_path: Union[str, Path]) -> Tuple[pd.DataFrame, Dict]:
209
209
  # =============================================================================
210
210
 
211
211
  def get_nearest_epw_from_climate_onebuilding(longitude: float, latitude: float, output_dir: str = "./", max_distance: Optional[float] = None,
212
- extract_zip: bool = True, load_data: bool = True, region: Optional[Union[str, List[str]]] = None) -> Tuple[Optional[str], Optional[pd.DataFrame], Optional[Dict]]:
212
+ extract_zip: bool = True, load_data: bool = True, region: Optional[Union[str, List[str]]] = None,
213
+ allow_insecure_ssl: bool = False, allow_http_fallback: bool = False,
214
+ ssl_verify: Union[bool, str] = True) -> Tuple[Optional[str], Optional[pd.DataFrame], Optional[Dict]]:
213
215
  """
214
216
  Download and process EPW weather file from Climate.OneBuilding.Org based on coordinates.
215
217
 
@@ -243,6 +245,9 @@ def get_nearest_epw_from_climate_onebuilding(longitude: float, latitude: float,
243
245
  plus legacy "Canada", "USA", "Caribbean" (Region 4).
244
246
  Use "all" to scan every dataset.
245
247
  If None, will auto-detect region based on coordinates.
248
+ allow_insecure_ssl (bool): If True, on SSL errors retry with certificate verification disabled.
249
+ allow_http_fallback (bool): If True, on SSL/network errors, also try HTTP (insecure) fallback.
250
+ ssl_verify (bool|str): Passed to requests as 'verify' parameter for HTTPS; can be False or CA bundle path.
246
251
 
247
252
  Returns:
248
253
  Tuple containing:
@@ -629,9 +634,36 @@ def get_nearest_epw_from_climate_onebuilding(longitude: float, latitude: float,
629
634
  continue
630
635
  tried.add(u)
631
636
  try:
632
- resp = requests.get(u, timeout=timeout_s)
637
+ resp = requests.get(u, timeout=timeout_s, verify=ssl_verify)
633
638
  resp.raise_for_status()
634
639
  return resp.content
640
+ except requests.exceptions.SSLError:
641
+ # Retry with user-controlled insecure SSL
642
+ if allow_insecure_ssl:
643
+ try:
644
+ resp = requests.get(u, timeout=timeout_s, verify=False)
645
+ resp.raise_for_status()
646
+ return resp.content
647
+ except requests.exceptions.RequestException:
648
+ if allow_http_fallback and u.lower().startswith("https://"):
649
+ insecure_url = "http://" + u.split("://", 1)[1]
650
+ try:
651
+ resp = requests.get(insecure_url, timeout=timeout_s)
652
+ resp.raise_for_status()
653
+ return resp.content
654
+ except requests.exceptions.RequestException:
655
+ pass
656
+ continue
657
+ else:
658
+ if allow_http_fallback and u.lower().startswith("https://"):
659
+ insecure_url = "http://" + u.split("://", 1)[1]
660
+ try:
661
+ resp = requests.get(insecure_url, timeout=timeout_s)
662
+ resp.raise_for_status()
663
+ return resp.content
664
+ except requests.exceptions.RequestException:
665
+ pass
666
+ continue
635
667
  except requests.exceptions.HTTPError as he:
636
668
  # Only continue on 404; raise on other HTTP errors
637
669
  if getattr(he.response, "status_code", None) == 404:
@@ -658,9 +690,32 @@ def get_nearest_epw_from_climate_onebuilding(longitude: float, latitude: float,
658
690
  List of dictionaries containing station metadata
659
691
  """
660
692
  try:
661
- # Download KML file with timeout
662
- response = requests.get(kml_url, timeout=30)
663
- response.raise_for_status()
693
+ # Download KML file with timeout (secure first)
694
+ try:
695
+ response = requests.get(kml_url, timeout=30, verify=ssl_verify)
696
+ response.raise_for_status()
697
+ except requests.exceptions.SSLError:
698
+ if allow_insecure_ssl:
699
+ # Retry with certificate verification disabled (last resort)
700
+ try:
701
+ response = requests.get(kml_url, timeout=30, verify=False)
702
+ response.raise_for_status()
703
+ except requests.exceptions.RequestException:
704
+ # Try HTTP fallback if original was HTTPS and allowed
705
+ if allow_http_fallback and kml_url.lower().startswith("https://"):
706
+ insecure_url = "http://" + kml_url.split("://", 1)[1]
707
+ response = requests.get(insecure_url, timeout=30)
708
+ response.raise_for_status()
709
+ else:
710
+ raise
711
+ else:
712
+ # Try HTTP fallback only if allowed and original was HTTPS
713
+ if allow_http_fallback and kml_url.lower().startswith("https://"):
714
+ insecure_url = "http://" + kml_url.split("://", 1)[1]
715
+ response = requests.get(insecure_url, timeout=30)
716
+ response.raise_for_status()
717
+ else:
718
+ raise
664
719
 
665
720
  # Try to decode content with multiple encodings
666
721
  content = try_decode(response.content)
@@ -917,8 +972,15 @@ def read_epw_for_solar_simulation(epw_file_path):
917
972
  Raises:
918
973
  ValueError: If LOCATION line not found or data parsing fails
919
974
  """
975
+ # Validate input path
976
+ if epw_file_path is None:
977
+ raise TypeError("EPW file path is None. Provide a valid path or ensure download succeeded.")
978
+ epw_path_obj = Path(epw_file_path)
979
+ if not epw_path_obj.exists() or not epw_path_obj.is_file():
980
+ raise FileNotFoundError(f"EPW file not found: {epw_file_path}")
981
+
920
982
  # Read the entire EPW file
921
- with open(epw_file_path, 'r', encoding='utf-8') as f:
983
+ with open(epw_path_obj, 'r', encoding='utf-8') as f:
922
984
  lines = f.readlines()
923
985
 
924
986
  # Find the LOCATION line (first line in EPW format)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voxcity
3
- Version: 0.6.19
3
+ Version: 0.6.21
4
4
  Summary: voxcity is an easy and one-stop tool to output 3d city models for microclimate simulation by integrating multiple geospatial open-data
5
5
  License: MIT
6
6
  License-File: AUTHORS.rst
@@ -129,7 +129,7 @@ Make sure you have Python 3.12 installed. Install voxcity with:
129
129
  ```bash
130
130
  conda create --name voxcity python=3.12
131
131
  conda activate voxcity
132
- conda install -c conda-forge gdal
132
+ conda install -c conda-forge gdal timezonefinder
133
133
  pip install voxcity
134
134
  ```
135
135
 
@@ -1,6 +1,6 @@
1
1
  voxcity/__init__.py,sha256=el9v3gfybHOF_GUYPeSOqN0-vCrTW0eU1mcvi0sEfeU,252
2
2
  voxcity/downloader/__init__.py,sha256=o_T_EU7hZLGyXxX9wVWn1x-OAa3ThGYdnpgB1_2v3AE,151
3
- voxcity/downloader/citygml.py,sha256=vEsMDCjK64UwpCmQi6ELoqC7h5sbIUW8hWAxVf5ViNI,41321
3
+ voxcity/downloader/citygml.py,sha256=I8-wWijqVOA1VeH3nFP9ZlC3l6XvXfli6lB17ZIXHb0,42232
4
4
  voxcity/downloader/eubucco.py,sha256=ln1YNaaOgJfxNfCtVbYaMm775-bUvpAA_LDv60_i22w,17875
5
5
  voxcity/downloader/gee.py,sha256=nvJvYqcSZyyontRtG2cFeb__ZJfeY4rRN1NBPORxLwQ,23557
6
6
  voxcity/downloader/mbfp.py,sha256=UXDVjsO0fnb0fSal9yqrSFEIBThnRmnutnp08kZTmCA,6595
@@ -13,8 +13,8 @@ voxcity/exporter/cityles.py,sha256=Kfl2PAn4WquqCdjOlyPrHysxPLaudh8QfsoC6WAXlvs,1
13
13
  voxcity/exporter/envimet.py,sha256=Sh7s1JdQ6SgT_L2Xd_c4gtEGWK2hTS87bccaoIqik-s,31105
14
14
  voxcity/exporter/magicavoxel.py,sha256=SfGEgTZRlossKx3Xrv9d3iKSX-HmfQJEL9lZHgWMDX4,12782
15
15
  voxcity/exporter/netcdf.py,sha256=48rJ3wDsFhi9ANbElhMjXLxWMJoJzBt1gFbN0ekPp-A,7404
16
- voxcity/exporter/obj.py,sha256=7xmVSQ_y-X8QLjNdASDPsaltGvmyW9-yAacocByYKl4,58160
17
- voxcity/generator.py,sha256=4WSjO09f8z3zt0tpKY0fyAfOMym1JT4VH3Tt1lOg2Bk,66900
16
+ voxcity/exporter/obj.py,sha256=aiaG8hMuggNnyCwsFZVhisnHm3BbUHi8SX4m9CyCYgc,59565
17
+ voxcity/generator.py,sha256=Sw-PN0FNLbUPuawHv_tZZPrEkSnPgIc5DBAh3JUn1aY,68473
18
18
  voxcity/geoprocessor/__init__.py,sha256=WYxcAQrjGucIvGHF0JTC6rONZzL3kCms1S2vpzS6KaU,127
19
19
  voxcity/geoprocessor/draw.py,sha256=AZMWq23wxxDJygNloCbVzWAAr1JO7nC94umf9LSxJ5o,49248
20
20
  voxcity/geoprocessor/grid.py,sha256=NmlQwl1nJpS7MduVtJeJCG-xBfVIwKTOip7pMm3RhsY,76722
@@ -23,16 +23,16 @@ voxcity/geoprocessor/network.py,sha256=YynqR0nq_NUra_cQ3Z_56KxfRia1b6-hIzGCj3QT-
23
23
  voxcity/geoprocessor/polygon.py,sha256=DfzXf6R-qoWXEZv1z1aHCVfr-DCuCFw6lieQT5cNHPA,61188
24
24
  voxcity/geoprocessor/utils.py,sha256=s17XpgkLBelmNCk2wcUwTK1tEiFpguWR2BF_n7K17jg,31378
25
25
  voxcity/simulator/__init__.py,sha256=APdkcdaovj0v_RPOaA4SBvFUKT2RM7Hxuuz3Sux4gCo,65
26
- voxcity/simulator/solar.py,sha256=4WBFgMm25-9rZ5bSGBmIpaxq2mma9X46Fom7UvGEnT8,106361
26
+ voxcity/simulator/solar.py,sha256=4D5t2I79vBW1qXd90BZR0tMiA9WOEXWLG5b-d6E2XbQ,107127
27
27
  voxcity/simulator/utils.py,sha256=sEYBB2-hLJxTiXQps1_-Fi7t1HN3-1OPOvBCWtgIisA,130
28
28
  voxcity/simulator/view.py,sha256=k3FoS6gsibR-eDrTHJivJSQfvN3Tg8R8eSTeMqd9ans,93942
29
29
  voxcity/utils/__init__.py,sha256=Q-NYCqYnAAaF80KuNwpqIjbE7Ec3Gr4y_khMLIMhJrg,68
30
30
  voxcity/utils/lc.py,sha256=722Gz3lPbgAp0mmTZ-g-QKBbAnbxrcgaYwb1sa7q8Sk,16189
31
31
  voxcity/utils/material.py,sha256=H8K8Lq4wBL6dQtgj7esUW2U6wLCOTeOtelkTDJoRgMo,10007
32
- voxcity/utils/visualization.py,sha256=_c5WnhA0fawkseUviKEIpUUsF-M-OOLOT9FrpgQIh1A,118556
33
- voxcity/utils/weather.py,sha256=WcmohW0yx2-uNMO5ffgxCtKUt32q6PQsAT43P5DwJx4,44760
34
- voxcity-0.6.19.dist-info/licenses/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
35
- voxcity-0.6.19.dist-info/licenses/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
36
- voxcity-0.6.19.dist-info/METADATA,sha256=AUmkbdSOZM7RywhizzSM_xzphJ-QLbQEuHx9IjvGSKQ,26212
37
- voxcity-0.6.19.dist-info/WHEEL,sha256=M5asmiAlL6HEcOq52Yi5mmk9KmTVjY2RDPtO4p9DMrc,88
38
- voxcity-0.6.19.dist-info/RECORD,,
32
+ voxcity/utils/visualization.py,sha256=rPPxZeoMvzDblZe6A2vgRkX1PHXVdft6l36nLOuSRkU,114774
33
+ voxcity/utils/weather.py,sha256=cb6ZooL42Hc4214OtFiJ78cCgWYM6VE-DU8S3e-urRg,48449
34
+ voxcity-0.6.21.dist-info/licenses/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
35
+ voxcity-0.6.21.dist-info/licenses/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
36
+ voxcity-0.6.21.dist-info/METADATA,sha256=mt2V_ZeRFL7UUBuEeUUUc_Br_fhvB9pPtbXVTaTvobY,26227
37
+ voxcity-0.6.21.dist-info/WHEEL,sha256=M5asmiAlL6HEcOq52Yi5mmk9KmTVjY2RDPtO4p9DMrc,88
38
+ voxcity-0.6.21.dist-info/RECORD,,