voxcity 0.5.20__py3-none-any.whl → 0.5.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/exporter/__init__.py +0 -1
- voxcity/exporter/envimet.py +16 -1
- voxcity/geoprocessor/utils.py +38 -24
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/METADATA +1 -1
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/RECORD +9 -9
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/WHEEL +0 -0
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/licenses/AUTHORS.rst +0 -0
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/licenses/LICENSE +0 -0
- {voxcity-0.5.20.dist-info → voxcity-0.5.21.dist-info}/top_level.txt +0 -0
voxcity/exporter/__init__.py
CHANGED
voxcity/exporter/envimet.py
CHANGED
|
@@ -334,8 +334,23 @@ def create_xml_content(building_height_grid, building_id_grid, land_cover_veg_gr
|
|
|
334
334
|
"$locationTimeZone_Longitude$": timezone_info[1],
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
+
# Ensure no None values are passed to replace()
|
|
337
338
|
for placeholder, value in placeholders.items():
|
|
338
|
-
|
|
339
|
+
if value is None:
|
|
340
|
+
print(f"Warning: {placeholder} is None, using fallback value")
|
|
341
|
+
if placeholder == "$locationName$":
|
|
342
|
+
value = "Unknown Location/ Unknown Country"
|
|
343
|
+
elif placeholder == "$locationTimeZone_Name$":
|
|
344
|
+
value = "UTC+00:00"
|
|
345
|
+
elif placeholder == "$locationTimeZone_Longitude$":
|
|
346
|
+
value = "0.00000"
|
|
347
|
+
elif placeholder == "$modelDescription$":
|
|
348
|
+
value = "[Enter model description]"
|
|
349
|
+
elif placeholder == "$modelAuthor$":
|
|
350
|
+
value = "[Enter model author name]"
|
|
351
|
+
else:
|
|
352
|
+
value = "Unknown"
|
|
353
|
+
xml_template = xml_template.replace(placeholder, str(value))
|
|
339
354
|
|
|
340
355
|
# Calculate building heights including terrain elevation
|
|
341
356
|
building_on_dem_grid = building_height_grid + dem_grid
|
voxcity/geoprocessor/utils.py
CHANGED
|
@@ -508,7 +508,7 @@ def get_city_country_name_from_rectangle(coordinates):
|
|
|
508
508
|
coordinates (list): List of (longitude, latitude) coordinates defining the rectangle
|
|
509
509
|
|
|
510
510
|
Returns:
|
|
511
|
-
str: String in format "city/ country" or
|
|
511
|
+
str: String in format "city/ country" or fallback value if lookup fails
|
|
512
512
|
|
|
513
513
|
Example:
|
|
514
514
|
>>> coords = [(139.65, 35.67), (139.66, 35.67),
|
|
@@ -524,7 +524,7 @@ def get_city_country_name_from_rectangle(coordinates):
|
|
|
524
524
|
center_coord = (center_lat, center_lon)
|
|
525
525
|
|
|
526
526
|
# Initialize geocoder with rate limiting to avoid hitting API limits
|
|
527
|
-
geolocator = Nominatim(user_agent="
|
|
527
|
+
geolocator = Nominatim(user_agent="VoxCity/1.0 (voxcity@example.com)")
|
|
528
528
|
reverse = RateLimiter(geolocator.reverse, min_delay_seconds=2, error_wait_seconds=5, max_retries=3)
|
|
529
529
|
|
|
530
530
|
try:
|
|
@@ -537,9 +537,12 @@ def get_city_country_name_from_rectangle(coordinates):
|
|
|
537
537
|
country = address.get('country', '')
|
|
538
538
|
return f"{city}/ {country}"
|
|
539
539
|
else:
|
|
540
|
-
print("Location not found")
|
|
540
|
+
print("Location not found, using fallback value")
|
|
541
|
+
return "Unknown Location/ Unknown Country"
|
|
541
542
|
except Exception as e:
|
|
542
543
|
print(f"Error retrieving location for {center_coord}: {e}")
|
|
544
|
+
print("Using fallback value")
|
|
545
|
+
return "Unknown Location/ Unknown Country"
|
|
543
546
|
|
|
544
547
|
def get_timezone_info(rectangle_coords):
|
|
545
548
|
"""
|
|
@@ -558,9 +561,6 @@ def get_timezone_info(rectangle_coords):
|
|
|
558
561
|
Returns:
|
|
559
562
|
tuple: (timezone string with UTC offset, central meridian longitude string)
|
|
560
563
|
|
|
561
|
-
Raises:
|
|
562
|
-
ValueError: If timezone cannot be determined for the given location
|
|
563
|
-
|
|
564
564
|
Example:
|
|
565
565
|
>>> coords = [(139.65, 35.67), (139.66, 35.67),
|
|
566
566
|
... (139.66, 35.68), (139.65, 35.68)]
|
|
@@ -573,25 +573,39 @@ def get_timezone_info(rectangle_coords):
|
|
|
573
573
|
center_lon = sum(longitudes) / len(longitudes)
|
|
574
574
|
center_lat = sum(latitudes) / len(latitudes)
|
|
575
575
|
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
576
|
+
try:
|
|
577
|
+
# Find timezone at center coordinates
|
|
578
|
+
tf = TimezoneFinder()
|
|
579
|
+
timezone_str = tf.timezone_at(lng=center_lon, lat=center_lat)
|
|
580
|
+
|
|
581
|
+
if timezone_str:
|
|
582
|
+
# Get current time in local timezone to calculate offset
|
|
583
|
+
timezone = pytz.timezone(timezone_str)
|
|
584
|
+
now = datetime.now(timezone)
|
|
585
|
+
offset_seconds = now.utcoffset().total_seconds()
|
|
586
|
+
offset_hours = offset_seconds / 3600
|
|
587
|
+
|
|
588
|
+
# Format timezone offset and calculate central meridian
|
|
589
|
+
utc_offset = f"UTC{offset_hours:+.2f}"
|
|
590
|
+
timezone_longitude = offset_hours * 15 # Each hour offset = 15 degrees longitude
|
|
591
|
+
timezone_longitude_str = f"{timezone_longitude:.5f}"
|
|
592
|
+
|
|
593
|
+
return utc_offset, timezone_longitude_str
|
|
594
|
+
else:
|
|
595
|
+
# Fallback: estimate timezone from longitude
|
|
596
|
+
print("Timezone not found, estimating from longitude")
|
|
597
|
+
estimated_offset = center_lon / 15 # Rough estimation: 15 degrees per hour
|
|
598
|
+
utc_offset = f"UTC{estimated_offset:+.2f}"
|
|
599
|
+
timezone_longitude_str = f"{center_lon:.5f}"
|
|
600
|
+
return utc_offset, timezone_longitude_str
|
|
601
|
+
except Exception as e:
|
|
602
|
+
print(f"Error retrieving timezone for {center_lon}, {center_lat}: {e}")
|
|
603
|
+
print("Using fallback timezone values")
|
|
604
|
+
# Fallback values
|
|
605
|
+
estimated_offset = center_lon / 15
|
|
606
|
+
utc_offset = f"UTC{estimated_offset:+.2f}"
|
|
607
|
+
timezone_longitude_str = f"{center_lon:.5f}"
|
|
592
608
|
return utc_offset, timezone_longitude_str
|
|
593
|
-
else:
|
|
594
|
-
raise ValueError("Time zone not found for the given location.")
|
|
595
609
|
|
|
596
610
|
def validate_polygon_coordinates(geometry):
|
|
597
611
|
"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: voxcity
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.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
|
Author-email: Kunihiko Fujiwara <kunihiko@nus.edu.sg>
|
|
6
6
|
Maintainer-email: Kunihiko Fujiwara <kunihiko@nus.edu.sg>
|
|
@@ -9,8 +9,8 @@ voxcity/downloader/oemj.py,sha256=iDacTpiqn7RAXuqyEtHP29m0Cycwta5sMy9-GdvX3Fg,12
|
|
|
9
9
|
voxcity/downloader/osm.py,sha256=kXiUedT7dwPOQ_4nxXptfeqNb5RKTIsQLG5km7Q8kKk,41645
|
|
10
10
|
voxcity/downloader/overture.py,sha256=4YG2DMwUSSyZKUw_o8cGhMmAkPJon82aPqOFBvrre-Y,11987
|
|
11
11
|
voxcity/downloader/utils.py,sha256=tz6wt4B9BhEOyvoF5OYXlr8rUd5cBEDedWL3j__oT70,3099
|
|
12
|
-
voxcity/exporter/__init__.py,sha256=
|
|
13
|
-
voxcity/exporter/envimet.py,sha256=
|
|
12
|
+
voxcity/exporter/__init__.py,sha256=2htEXMrq6knO8JMROtfz-0HFGddsAJkXqNUB2_MhqvM,70
|
|
13
|
+
voxcity/exporter/envimet.py,sha256=Esi7SmidEyaRvSLOUgS-o9lcjJlhbp_D-ZdXa-BMrGU,30746
|
|
14
14
|
voxcity/exporter/magicavoxel.py,sha256=SfGEgTZRlossKx3Xrv9d3iKSX-HmfQJEL9lZHgWMDX4,12782
|
|
15
15
|
voxcity/exporter/obj.py,sha256=h1_aInpemcsu96fSTwjKMqX2VZAFYbZbElWd4M1ogyI,27973
|
|
16
16
|
voxcity/geoprocessor/__init__.py,sha256=JzPVhhttxBWvaZ0IGX2w7OWL5bCo_TIvpHefWeNXruA,133
|
|
@@ -19,7 +19,7 @@ voxcity/geoprocessor/grid.py,sha256=Uy8Oz4iL7vnPMqp_qtp4dQrs00yd2L9CSIPmF5KnbtI,
|
|
|
19
19
|
voxcity/geoprocessor/mesh.py,sha256=MK2rkBfVyLQ_nkhgLMa6R3_SxYFE2-MHaSiRP6bJ7no,28584
|
|
20
20
|
voxcity/geoprocessor/network.py,sha256=YynqR0nq_NUra_cQ3Z_56KxfRia1b6-hIzGCj3QT-wE,25137
|
|
21
21
|
voxcity/geoprocessor/polygon.py,sha256=-LonxtW5du3UP61oygqtDJl6GGsCYnUuN9KYwl1UFdc,53707
|
|
22
|
-
voxcity/geoprocessor/utils.py,sha256=
|
|
22
|
+
voxcity/geoprocessor/utils.py,sha256=yt9mGm3_AefXTlQ5LWqhm5WQTSHr0XbD7GbkvpSMCGs,31077
|
|
23
23
|
voxcity/simulator/__init__.py,sha256=APdkcdaovj0v_RPOaA4SBvFUKT2RM7Hxuuz3Sux4gCo,65
|
|
24
24
|
voxcity/simulator/solar.py,sha256=HUvSm7IHOpU8JyF6rib54LXBijoWaWM87dKYGeC_BxA,82298
|
|
25
25
|
voxcity/simulator/utils.py,sha256=sEYBB2-hLJxTiXQps1_-Fi7t1HN3-1OPOvBCWtgIisA,130
|
|
@@ -29,9 +29,9 @@ voxcity/utils/lc.py,sha256=h2yOWLUIrrummkyMyhRK5VbyrsPtslS0MJov_y0WGIQ,18925
|
|
|
29
29
|
voxcity/utils/material.py,sha256=H8K8Lq4wBL6dQtgj7esUW2U6wLCOTeOtelkTDJoRgMo,10007
|
|
30
30
|
voxcity/utils/visualization.py,sha256=-Hc9XJbAppI0CB_Sfrlv0kLnJGRBdY2u8g0jdCPYT7w,112803
|
|
31
31
|
voxcity/utils/weather.py,sha256=2Jtg-rIVJcsTtiKE-KuDnhIqS1-MSS16_zFRzj6zmu4,36435
|
|
32
|
-
voxcity-0.5.
|
|
33
|
-
voxcity-0.5.
|
|
34
|
-
voxcity-0.5.
|
|
35
|
-
voxcity-0.5.
|
|
36
|
-
voxcity-0.5.
|
|
37
|
-
voxcity-0.5.
|
|
32
|
+
voxcity-0.5.21.dist-info/licenses/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
|
|
33
|
+
voxcity-0.5.21.dist-info/licenses/LICENSE,sha256=s_jE1Df1nTPL4A_5GCGic5Zwex0CVaPKcAmSilxJPPE,1089
|
|
34
|
+
voxcity-0.5.21.dist-info/METADATA,sha256=nhmsreM885ktO6XCBJQoSw60lbvcWK-ywcWbHYovJxg,26328
|
|
35
|
+
voxcity-0.5.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
voxcity-0.5.21.dist-info/top_level.txt,sha256=00b2U-LKfDllt6RL1R33MXie5MvxzUFye0NGD96t_8I,8
|
|
37
|
+
voxcity-0.5.21.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|