voxcity 0.3.14__py3-none-any.whl → 0.3.16__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.
voxcity/generator.py CHANGED
@@ -185,11 +185,12 @@ def get_building_height_grid(rectangle_vertices, meshsize, source, output_dir, *
185
185
 
186
186
  # Check for complementary building data source
187
187
  building_complementary_source = kwargs.get("building_complementary_source")
188
+ building_complement_height = kwargs.get("building_complement_height")
188
189
 
189
190
  if (building_complementary_source is None) or (building_complementary_source=='None'):
190
191
  # Use only primary source
191
192
  if source != "Open Building 2.5D Temporal":
192
- building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices)
193
+ building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices, complement_height=building_complement_height)
193
194
  else:
194
195
  # Handle complementary source
195
196
  if building_complementary_source == "Open Building 2.5D Temporal":
@@ -198,7 +199,7 @@ def get_building_height_grid(rectangle_vertices, meshsize, source, output_dir, *
198
199
  os.makedirs(output_dir, exist_ok=True)
199
200
  geotiff_path_comp = os.path.join(output_dir, "building_height.tif")
200
201
  save_geotiff_open_buildings_temporal(roi, geotiff_path_comp)
201
- building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices, geotiff_path_comp=geotiff_path_comp)
202
+ building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices, geotiff_path_comp=geotiff_path_comp, complement_height=building_complement_height)
202
203
  else:
203
204
  # Get complementary data from other sources
204
205
  if building_complementary_source == 'Microsoft Building Footprints':
@@ -220,7 +221,7 @@ def get_building_height_grid(rectangle_vertices, meshsize, source, output_dir, *
220
221
 
221
222
  # Option to complement footprints only or both footprints and heights
222
223
  complement_building_footprints = kwargs.get("complement_building_footprints")
223
- building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices, gdf_comp=gdf_comp, complement_building_footprints=complement_building_footprints)
224
+ building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings = create_building_height_grid_from_gdf_polygon(gdf, meshsize, rectangle_vertices, gdf_comp=gdf_comp, complement_building_footprints=complement_building_footprints, complement_height=building_complement_height)
224
225
 
225
226
  # Visualize grid if requested
226
227
  grid_vis = kwargs.get("gridvis", True)
@@ -223,15 +223,16 @@ def center_location_map_cityname(cityname, east_west_length, north_south_length,
223
223
 
224
224
  return m, rectangle_vertices
225
225
 
226
- def display_buildings_and_draw_polygon(building_gdf, zoom=17):
226
+ def display_buildings_and_draw_polygon(building_gdf=None, rectangle_vertices=None, zoom=17):
227
227
  """
228
228
  Displays building footprints (in Lon-Lat order) on an ipyleaflet map,
229
229
  and allows the user to draw a polygon whose vertices are returned
230
230
  in a Python list (also in Lon-Lat).
231
231
 
232
232
  Args:
233
- building_gdf (GeoDataFrame): A GeoDataFrame containing building footprints,
234
- with geometry in [lon, lat] order.
233
+ building_gdf (GeoDataFrame, optional): A GeoDataFrame containing building footprints,
234
+ with geometry in [lon, lat] order.
235
+ rectangle_vertices (list, optional): List of [lon, lat] coordinates defining rectangle corners.
235
236
  zoom (int): Initial zoom level for the map. Default=17.
236
237
 
237
238
  Returns:
@@ -243,39 +244,48 @@ def display_buildings_and_draw_polygon(building_gdf, zoom=17):
243
244
  # ---------------------------------------------------------
244
245
  # 1. Determine a suitable map center via bounding box logic
245
246
  # ---------------------------------------------------------
246
- if len(building_gdf) == 0:
247
- # Fallback: If no footprints or invalid data, pick a default
248
- center_lon, center_lat = -100.0, 40.0
249
- else:
247
+ if rectangle_vertices is not None:
248
+ # Get bounds from rectangle vertices
249
+ lons = [v[0] for v in rectangle_vertices]
250
+ lats = [v[1] for v in rectangle_vertices]
251
+ min_lon, max_lon = min(lons), max(lons)
252
+ min_lat, max_lat = min(lats), max(lats)
253
+ center_lon = (min_lon + max_lon) / 2
254
+ center_lat = (min_lat + max_lat) / 2
255
+ elif building_gdf is not None and len(building_gdf) > 0:
250
256
  # Get bounds from GeoDataFrame
251
257
  bounds = building_gdf.total_bounds # Returns [minx, miny, maxx, maxy]
252
258
  min_lon, min_lat, max_lon, max_lat = bounds
253
259
  center_lon = (min_lon + max_lon) / 2
254
260
  center_lat = (min_lat + max_lat) / 2
261
+ else:
262
+ # Fallback: If no inputs or invalid data, pick a default
263
+ center_lon, center_lat = -100.0, 40.0
255
264
 
256
265
  # Create the ipyleaflet map (needs lat,lon)
257
266
  m = Map(center=(center_lat, center_lon), zoom=zoom, scroll_wheel_zoom=True)
258
267
 
259
268
  # -----------------------------------------
260
- # 2. Add each building footprint to the map
269
+ # 2. Add building footprints to the map if provided
261
270
  # -----------------------------------------
262
- for idx, row in building_gdf.iterrows():
263
- # Only handle simple Polygons
264
- if isinstance(row.geometry, geom.Polygon):
265
- # Get coordinates from geometry
266
- coords = list(row.geometry.exterior.coords)
267
- # Convert to (lat,lon) for ipyleaflet, skip last repeated coordinate
268
- lat_lon_coords = [(c[1], c[0]) for c in coords[:-1]]
269
-
270
- # Create the polygon layer
271
- bldg_layer = LeafletPolygon(
272
- locations=lat_lon_coords,
273
- color="blue",
274
- fill_color="blue",
275
- fill_opacity=0.2,
276
- weight=2
277
- )
278
- m.add_layer(bldg_layer)
271
+ if building_gdf is not None:
272
+ for idx, row in building_gdf.iterrows():
273
+ # Only handle simple Polygons
274
+ if isinstance(row.geometry, geom.Polygon):
275
+ # Get coordinates from geometry
276
+ coords = list(row.geometry.exterior.coords)
277
+ # Convert to (lat,lon) for ipyleaflet, skip last repeated coordinate
278
+ lat_lon_coords = [(c[1], c[0]) for c in coords[:-1]]
279
+
280
+ # Create the polygon layer
281
+ bldg_layer = LeafletPolygon(
282
+ locations=lat_lon_coords,
283
+ color="blue",
284
+ fill_color="blue",
285
+ fill_opacity=0.2,
286
+ weight=2
287
+ )
288
+ m.add_layer(bldg_layer)
279
289
 
280
290
  # -----------------------------------------------------------------
281
291
  # 3. Enable drawing of polygons, capturing the vertices in Lon-Lat
@@ -480,7 +480,8 @@ def create_building_height_grid_from_gdf_polygon(
480
480
  rectangle_vertices,
481
481
  gdf_comp=None,
482
482
  geotiff_path_comp=None,
483
- complement_building_footprints=None
483
+ complement_building_footprints=None,
484
+ complement_height=None
484
485
  ):
485
486
  """
486
487
  Create a building height grid from GeoDataFrame data within a polygon boundary.
@@ -492,6 +493,7 @@ def create_building_height_grid_from_gdf_polygon(
492
493
  gdf_comp (geopandas.GeoDataFrame, optional): Complementary GeoDataFrame
493
494
  geotiff_path_comp (str, optional): Path to complementary GeoTIFF file
494
495
  complement_building_footprints (bool, optional): Whether to complement footprints
496
+ complement_height (float, optional): Height value to use for buildings with height=0
495
497
 
496
498
  Returns:
497
499
  tuple: (building_height_grid, building_min_height_grid, building_id_grid, filtered_buildings)
@@ -558,6 +560,11 @@ def create_building_height_grid_from_gdf_polygon(
558
560
  for idx_b, row in filtered_gdf.iterrows():
559
561
  polygon = row.geometry
560
562
  height = row.get('height', None)
563
+
564
+ # Replace height=0 with complement_height if specified
565
+ if complement_height is not None and (height == 0 or height is None):
566
+ height = complement_height
567
+
561
568
  min_height = row.get('min_height', 0)
562
569
  is_inner = row.get('is_inner', False)
563
570
  feature_id = row.get('id', idx_b)
@@ -883,10 +890,19 @@ def grid_to_geodataframe(grid_ori, rectangle_vertices, meshsize):
883
890
 
884
891
  rows, cols = grid.shape
885
892
 
886
- # Calculate cell sizes in degrees (approximate)
887
- # 111,111 meters = 1 degree at equator
888
- cell_size_lon = meshsize / (111111 * np.cos(np.mean([min_lat, max_lat]) * np.pi / 180))
889
- cell_size_lat = meshsize / 111111
893
+ # Set up transformers for accurate coordinate calculations
894
+ wgs84 = CRS.from_epsg(4326)
895
+ web_mercator = CRS.from_epsg(3857)
896
+ transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
897
+ transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
898
+
899
+ # Convert bounds to Web Mercator for accurate distance calculations
900
+ min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
901
+ max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
902
+
903
+ # Calculate cell sizes in Web Mercator coordinates
904
+ cell_size_x = (max_x - min_x) / cols
905
+ cell_size_y = (max_y - min_y) / rows
890
906
 
891
907
  # Create lists to store data
892
908
  polygons = []
@@ -895,12 +911,16 @@ def grid_to_geodataframe(grid_ori, rectangle_vertices, meshsize):
895
911
  # Create grid cells
896
912
  for i in range(rows):
897
913
  for j in range(cols):
898
- # Calculate cell bounds
899
- cell_min_lon = min_lon + j * cell_size_lon
900
- cell_max_lon = min_lon + (j + 1) * cell_size_lon
914
+ # Calculate cell bounds in Web Mercator
915
+ cell_min_x = min_x + j * cell_size_x
916
+ cell_max_x = min_x + (j + 1) * cell_size_x
901
917
  # Flip vertical axis since grid is stored with origin at top-left
902
- cell_min_lat = max_lat - (i + 1) * cell_size_lat
903
- cell_max_lat = max_lat - i * cell_size_lat
918
+ cell_min_y = max_y - (i + 1) * cell_size_y
919
+ cell_max_y = max_y - i * cell_size_y
920
+
921
+ # Convert cell corners back to WGS84
922
+ cell_min_lon, cell_min_lat = transformer_to_wgs84.transform(cell_min_x, cell_min_y)
923
+ cell_max_lon, cell_max_lat = transformer_to_wgs84.transform(cell_max_x, cell_max_y)
904
924
 
905
925
  # Create polygon for cell
906
926
  cell_poly = box(cell_min_lon, cell_min_lat, cell_max_lon, cell_max_lat)
@@ -914,4 +934,71 @@ def grid_to_geodataframe(grid_ori, rectangle_vertices, meshsize):
914
934
  'value': values
915
935
  }, crs=CRS.from_epsg(4326))
916
936
 
937
+ return gdf
938
+
939
+ def grid_to_point_geodataframe(grid_ori, rectangle_vertices, meshsize):
940
+ """Converts a 2D grid to a GeoDataFrame with point geometries at cell centers and values.
941
+
942
+ Args:
943
+ grid: 2D numpy array containing grid values
944
+ rectangle_vertices: List of [lon, lat] coordinates defining area corners
945
+ meshsize: Size of each grid cell in meters
946
+
947
+ Returns:
948
+ GeoDataFrame with columns:
949
+ - geometry: Point geometry at center of each grid cell
950
+ - value: Value from the grid
951
+ """
952
+ grid = np.flipud(grid_ori.copy())
953
+
954
+ # Extract bounds from rectangle vertices
955
+ min_lon = min(v[0] for v in rectangle_vertices)
956
+ max_lon = max(v[0] for v in rectangle_vertices)
957
+ min_lat = min(v[1] for v in rectangle_vertices)
958
+ max_lat = max(v[1] for v in rectangle_vertices)
959
+
960
+ rows, cols = grid.shape
961
+
962
+ # Set up transformers for accurate coordinate calculations
963
+ wgs84 = CRS.from_epsg(4326)
964
+ web_mercator = CRS.from_epsg(3857)
965
+ transformer_to_mercator = Transformer.from_crs(wgs84, web_mercator, always_xy=True)
966
+ transformer_to_wgs84 = Transformer.from_crs(web_mercator, wgs84, always_xy=True)
967
+
968
+ # Convert bounds to Web Mercator for accurate distance calculations
969
+ min_x, min_y = transformer_to_mercator.transform(min_lon, min_lat)
970
+ max_x, max_y = transformer_to_mercator.transform(max_lon, max_lat)
971
+
972
+ # Calculate cell sizes in Web Mercator coordinates
973
+ cell_size_x = (max_x - min_x) / cols
974
+ cell_size_y = (max_y - min_y) / rows
975
+
976
+ # Create lists to store data
977
+ points = []
978
+ values = []
979
+
980
+ # Create grid points at cell centers
981
+ for i in range(rows):
982
+ for j in range(cols):
983
+ # Calculate cell center in Web Mercator
984
+ cell_center_x = min_x + (j + 0.5) * cell_size_x
985
+ # Flip vertical axis since grid is stored with origin at top-left
986
+ cell_center_y = max_y - (i + 0.5) * cell_size_y
987
+
988
+ # Convert cell center back to WGS84
989
+ center_lon, center_lat = transformer_to_wgs84.transform(cell_center_x, cell_center_y)
990
+
991
+ # Create point for cell center
992
+ from shapely.geometry import Point
993
+ cell_point = Point(center_lon, center_lat)
994
+
995
+ points.append(cell_point)
996
+ values.append(grid[i, j])
997
+
998
+ # Create GeoDataFrame
999
+ gdf = gpd.GeoDataFrame({
1000
+ 'geometry': points,
1001
+ 'value': values
1002
+ }, crs=CRS.from_epsg(4326))
1003
+
917
1004
  return gdf
@@ -775,5 +775,140 @@ def visualize_numerical_grid_on_basemap(grid, rectangle_vertices, meshsize, valu
775
775
  # Set title and remove axes
776
776
  ax.set_axis_off()
777
777
 
778
+ plt.tight_layout()
779
+ plt.show()
780
+
781
+ def visualize_numerical_grid_gdf_on_basemap(gdf, value_name="value", cmap='viridis', vmin=None, vmax=None,
782
+ alpha=0.6, figsize=(12, 8), basemap='CartoDB light',
783
+ show_edge=False, edge_color='black', edge_width=0.5):
784
+ """Visualizes a GeoDataFrame with numerical values on a basemap.
785
+
786
+ Args:
787
+ gdf: GeoDataFrame containing grid cells with 'geometry' and 'value' columns
788
+ value_name: Name of the value column and legend label (default: "value")
789
+ cmap: Colormap to use (default: 'viridis')
790
+ vmin: Minimum value for colormap scaling (default: None)
791
+ vmax: Maximum value for colormap scaling (default: None)
792
+ alpha: Transparency of the grid overlay (default: 0.6)
793
+ figsize: Figure size in inches (default: (12, 8))
794
+ basemap: Basemap style (default: 'CartoDB light')
795
+ show_edge: Whether to show cell edges (default: False)
796
+ edge_color: Color of cell edges (default: 'black')
797
+ edge_width: Width of cell edges (default: 0.5)
798
+ """
799
+ # Convert to Web Mercator if not already in that CRS
800
+ if gdf.crs != 'EPSG:3857':
801
+ gdf_web = gdf.to_crs(epsg=3857)
802
+ else:
803
+ gdf_web = gdf
804
+
805
+ # Create figure and axis
806
+ fig, ax = plt.subplots(figsize=figsize)
807
+
808
+ # Plot the GeoDataFrame
809
+ gdf_web.plot(column='value',
810
+ ax=ax,
811
+ alpha=alpha,
812
+ cmap=cmap,
813
+ vmin=vmin,
814
+ vmax=vmax,
815
+ legend=True,
816
+ legend_kwds={'label': value_name},
817
+ edgecolor=edge_color if show_edge else 'none',
818
+ linewidth=edge_width if show_edge else 0)
819
+
820
+ # Add basemap
821
+ basemaps = {
822
+ 'CartoDB dark': ctx.providers.CartoDB.DarkMatter,
823
+ 'CartoDB light': ctx.providers.CartoDB.Positron,
824
+ 'CartoDB voyager': ctx.providers.CartoDB.Voyager,
825
+ 'CartoDB light no labels': ctx.providers.CartoDB.PositronNoLabels,
826
+ 'CartoDB dark no labels': ctx.providers.CartoDB.DarkMatterNoLabels,
827
+ }
828
+ ctx.add_basemap(ax, source=basemaps[basemap])
829
+
830
+ # Set title and remove axes
831
+ ax.set_axis_off()
832
+
833
+ plt.tight_layout()
834
+ plt.show()
835
+
836
+ def visualize_point_grid_on_basemap(point_gdf, value_name='value', **kwargs):
837
+ """Visualizes a point GeoDataFrame on a basemap with colors based on values.
838
+
839
+ Args:
840
+ point_gdf: GeoDataFrame with point geometries and values
841
+ value_name: Name of the column containing values to visualize (default: 'value')
842
+ **kwargs: Optional visualization parameters including:
843
+ - figsize: Tuple for figure size (default: (12, 8))
844
+ - colormap: Matplotlib colormap name (default: 'viridis')
845
+ - markersize: Size of points (default: 20)
846
+ - alpha: Transparency of points (default: 0.7)
847
+ - vmin: Minimum value for colormap scaling (default: None)
848
+ - vmax: Maximum value for colormap scaling (default: None)
849
+ - title: Plot title (default: None)
850
+ - basemap_style: Contextily basemap style (default: CartoDB.Positron)
851
+ - zoom: Basemap zoom level (default: 15)
852
+
853
+ Returns:
854
+ matplotlib figure and axis objects
855
+ """
856
+ import matplotlib.pyplot as plt
857
+ import contextily as ctx
858
+
859
+ # Set default parameters
860
+ defaults = {
861
+ 'figsize': (12, 8),
862
+ 'colormap': 'viridis',
863
+ 'markersize': 20,
864
+ 'alpha': 0.7,
865
+ 'vmin': None,
866
+ 'vmax': None,
867
+ 'title': None,
868
+ 'basemap_style': ctx.providers.CartoDB.Positron,
869
+ 'zoom': 15
870
+ }
871
+
872
+ # Update defaults with provided kwargs
873
+ settings = {**defaults, **kwargs}
874
+
875
+ # Create figure and axis
876
+ fig, ax = plt.subplots(figsize=settings['figsize'])
877
+
878
+ # Convert to Web Mercator for basemap compatibility
879
+ point_gdf_web = point_gdf.to_crs(epsg=3857)
880
+
881
+ # Plot points
882
+ scatter = point_gdf_web.plot(
883
+ column=value_name,
884
+ ax=ax,
885
+ cmap=settings['colormap'],
886
+ markersize=settings['markersize'],
887
+ alpha=settings['alpha'],
888
+ vmin=settings['vmin'],
889
+ vmax=settings['vmax'],
890
+ legend=True,
891
+ legend_kwds={
892
+ 'label': value_name,
893
+ 'orientation': 'vertical',
894
+ 'shrink': 0.8
895
+ }
896
+ )
897
+
898
+ # Add basemap
899
+ ctx.add_basemap(
900
+ ax,
901
+ source=settings['basemap_style'],
902
+ zoom=settings['zoom']
903
+ )
904
+
905
+ # Set title if provided
906
+ if settings['title']:
907
+ plt.title(settings['title'])
908
+
909
+ # Remove axes
910
+ ax.set_axis_off()
911
+
912
+ # Adjust layout to prevent colorbar cutoff
778
913
  plt.tight_layout()
779
914
  plt.show()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voxcity
3
- Version: 0.3.14
3
+ Version: 0.3.16
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>
@@ -225,7 +225,7 @@ from voxcity import get_voxcity
225
225
 
226
226
  voxcity_grid, building_height_grid, building_min_height_grid, \
227
227
  building_id_grid, canopy_height_grid, land_cover_grid, dem_grid, \
228
- building_geojson = get_voxcity(
228
+ building_gdf = get_voxcity(
229
229
  rectangle_vertices,
230
230
  building_source,
231
231
  land_cover_source,
@@ -410,7 +410,7 @@ landmark_kwargs = {
410
410
  "output_directory": "output", # Directory to save output files
411
411
  "output_file_name": "landmark_visibility" # Base filename for outputs
412
412
  }
413
- landmark_vis_map = get_landmark_visibility_map(voxcity_grid, building_id_grid, building_geojson, meshsize, **landmark_kwargs)
413
+ landmark_vis_map = get_landmark_visibility_map(voxcity_grid, building_id_grid, building_gdf, meshsize, **landmark_kwargs)
414
414
  ```
415
415
  <p align="center">
416
416
  <img src="https://raw.githubusercontent.com/kunifujiwara/VoxCity/main/images/landmark.png" alt="Landmark Visibility Map Rendered in Rhino" width="500">
@@ -1,5 +1,5 @@
1
1
  voxcity/__init__.py,sha256=el9v3gfybHOF_GUYPeSOqN0-vCrTW0eU1mcvi0sEfeU,252
2
- voxcity/generator.py,sha256=SDaX1gLAq8NEPVZD8h_bFzUQcm8FjcAJzAy6yMXVsxg,33441
2
+ voxcity/generator.py,sha256=3cr520doEAdoXasvdywiK0FOvIfh1YdALv4tlhFvbAk,33654
3
3
  voxcity/downloader/__init__.py,sha256=OgGcGxOXF4tjcEL6DhOnt13DYPTvOigUelp5xIpTqM0,171
4
4
  voxcity/downloader/eubucco.py,sha256=XCkkdEPNuWdrnuxzL80Ext37WsgiCiZGueb-aQV5rvI,14476
5
5
  voxcity/downloader/gee.py,sha256=j7jmzp44T3M6j_4DwhU9Y8Y6gqbZo1zFIlduQPc0jvk,14339
@@ -14,8 +14,8 @@ voxcity/exporter/envimet.py,sha256=m-y2IYw-yp45AT2wN9UIlxvMjvDvupTKzyfRJl057fE,2
14
14
  voxcity/exporter/magicavoxel.py,sha256=Fsv7yGRXeKmp82xcG3rOb0t_HtoqltNq2tHl08xVlqY,7500
15
15
  voxcity/exporter/obj.py,sha256=oW-kPoZj53nfmO9tXP3Wvizq6Kkjh-QQR8UBexRuMiI,21609
16
16
  voxcity/geoprocessor/__init_.py,sha256=FFJFf6idmAtmNkwfKPt3ERGSIzjb8tt35D1n9QQbCA8,112
17
- voxcity/geoprocessor/draw.py,sha256=7T99AUr2qdt1OTfn4W61_Lph7HGz0_WcgoY6Ezo7sB4,13246
18
- voxcity/geoprocessor/grid.py,sha256=9i0LRa0Ko53a8V5QlnMwy_Qe2pNqq9C4M-ZaAQyjRUs,40129
17
+ voxcity/geoprocessor/draw.py,sha256=8Em2NvazFpYfFJUqG9LofNXaxdghKLL_rNuztmPwn8Q,13911
18
+ voxcity/geoprocessor/grid.py,sha256=aLb_iInDrhh5cacQOOtHPZ9IWFTWsQtF6hEgsA6TB2Y,43761
19
19
  voxcity/geoprocessor/network.py,sha256=opb_kpUCAxDd1qtrWPStqR5reYZtVe96XxazNSen7Lk,18851
20
20
  voxcity/geoprocessor/polygon.py,sha256=8fU2Ayu2Y_G1z7Mbj8KoSKVurdPuAVbASjGMVS36ftM,32249
21
21
  voxcity/geoprocessor/utils.py,sha256=1BRHp-DDeOA8HG8jplY7Eo75G3oXkVGL6DGONL4BA8A,19815
@@ -26,11 +26,11 @@ voxcity/simulator/view.py,sha256=zNbfTLQ2Jo0V5-rFA3-xamRjOuw3H3MBrLKpQp8x3hY,367
26
26
  voxcity/utils/__init_.py,sha256=nLYrj2huBbDBNMqfchCwexGP8Tlt9O_XluVDG7MoFkw,98
27
27
  voxcity/utils/lc.py,sha256=RwPd-VY3POV3gTrBhM7TubgGb9MCd3nVah_G8iUEF7k,11562
28
28
  voxcity/utils/material.py,sha256=Vt3IID5Ft54HNJcEC4zi31BCPqi_687X3CSp7rXaRVY,5907
29
- voxcity/utils/visualization.py,sha256=3cNjJdwIaOlzwgK08S39F1VYNf7vu-x9d4UUiKwXRVo,31943
29
+ voxcity/utils/visualization.py,sha256=2bv3y-1zkUX0cm_YbMHwe_Vt9J2R3QhouaVAGNifQXg,36805
30
30
  voxcity/utils/weather.py,sha256=P6s1y_EstBL1OGP_MR_6u3vr-t6Uawg8uDckJnoI7FI,21482
31
- voxcity-0.3.14.dist-info/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
32
- voxcity-0.3.14.dist-info/LICENSE,sha256=-hGliOFiwUrUSoZiB5WF90xXGqinKyqiDI2t6hrnam8,1087
33
- voxcity-0.3.14.dist-info/METADATA,sha256=qtO4S1XoVHN8Rd9dq2aKKo71tk2U7ap9WDH6koxMKWk,25122
34
- voxcity-0.3.14.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
35
- voxcity-0.3.14.dist-info/top_level.txt,sha256=00b2U-LKfDllt6RL1R33MXie5MvxzUFye0NGD96t_8I,8
36
- voxcity-0.3.14.dist-info/RECORD,,
31
+ voxcity-0.3.16.dist-info/AUTHORS.rst,sha256=m82vkI5QokEGdcHof2OxK39lf81w1P58kG9ZNNAKS9U,175
32
+ voxcity-0.3.16.dist-info/LICENSE,sha256=-hGliOFiwUrUSoZiB5WF90xXGqinKyqiDI2t6hrnam8,1087
33
+ voxcity-0.3.16.dist-info/METADATA,sha256=d67Drf-UV5hy7212m7y3rPmqC-cZ8LwloyVYgwq3EsA,25114
34
+ voxcity-0.3.16.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
35
+ voxcity-0.3.16.dist-info/top_level.txt,sha256=00b2U-LKfDllt6RL1R33MXie5MvxzUFye0NGD96t_8I,8
36
+ voxcity-0.3.16.dist-info/RECORD,,