Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 0 additions & 11 deletions hera/datalayer/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,17 +168,6 @@ def addDocument(self,projectName,resource="",dataFormat="string",type="",desc={}
"or one of the fields type is not proper. %s " % str(e))
return obj

def addDocumentFromJSON(self, json_data):
"""
Adds a document from a JSON string representation.

Parameters
----------
json_data : str
A JSON string representing the document.
"""
self._metadataCol.from_json(json_data).save()

def deleteDocuments(self, projectName, **query):
"""
Deletes documents that satisfy the given query.
Expand Down
66 changes: 0 additions & 66 deletions hera/measurements/GIS/raster/landcover.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,43 +485,6 @@ def getRoughness(self, minx, miny, maxx, maxy, dxdy=30, inputCRS=WSG84, dataSour
)
return landcover

def _handleType1(self, landcover):
"""
Converting land type of Type-1 to roughness.
Based on the paper:
* https://wes.copernicus.org/articles/6/1379/2021/ table a2
* https://doi.org/10.5194/wes-6-1379-2021 Satellite-based estimation of roughness lengths and displacement heights for wind resource modelling, Rogier Floors, Merete Badger, Ib Troen, Kenneth Grogan, and Finn-Hendrik Permien

Parameters
----------
landcover : int
Landcover type value.

Returns
-------
float
"""
roughnessDict = {
0: 0.0001, # Water
1: 1, # Evergreen needleleaf forest
2: 1, # Evergreen broadleaf forest
3: 1, # Deciduous needleleaf forest
4: 1, # Deciduous broadleaf forest
5: 1, # Mixed forests
6: 0.05, # Closed shrubland
7: 0.06, # Open shrublands
8: 0.05, # Woody savannas
9: 0.15, # Savannas
10: 0.12, # Grasslands
11: 0.3, # Permanent wetlands
12: 0.15, # Croplands
13: 0.8, # Urban and built-up
14: 0.14, # Cropland/natural vegetation mosaic
15: 0.001, # Snow and ice
16: 0.01 # Barren or sparsely vegetated
}
return roughnessDict.get(landcover, 0.05)

def getCodingMap(self, datasourceName):
"""
Returns dictionary that maps landcover int value to string of landcover.
Expand Down Expand Up @@ -557,35 +520,6 @@ def getCodingMap(self, datasourceName):
}
return {}

@staticmethod
def roughnesslength2sandgrainroughness(rl):
"""
Converts roughness length to equivalent sand grain roughness.

Based on:
Desmond, C. J., Watson, S. J., & Hancock, P. E. (2017).
Modelling the wind energy resource in complex terrain and atmospheres.
Numerical simulation and wind tunnel investigation of non-neutral forest canopy flow.
Journal of wind engineering and industrial aerodynamics, 166, 48-60.
https://www.sciencedirect.com/science/article/pii/S0167610516300083#bib12

Equation 5: Equivalent sand grain roughness (m) is z0 * 30

We can use it for "nutkRoughWallFunction" boundary condition for Ks (sand grain roughness) parameter.
Cs value can be set as 0.5.

Parameters
----------
rl : float
Roughness length.

Returns
-------
float
Equivalent sand grain roughness (Ks).
"""
return rl * 30.0 # return Ks value

def _getUrbanRoughnessFromLandCover(self, landcover, windMeteorologicalDirection, resolution, dataSourceName, GIS_BUILDINGS_dataSourceName):
"""
Add Roughness for Urban areas to landcover Xarray.
Expand Down
35 changes: 0 additions & 35 deletions hera/measurements/GIS/raster/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,6 @@ def __init__(self, projectName, filesDirectory=None,connectionName=None):

self._presentation = presentation(dataLayer=self)

def tileScaleAtLatLonZoom(self,latitude,longitude,zoomlevel):
"""
Returns the scale of a tile im meters at the location and zoom level

Parameters
----------
latitude : float
The latitude in WGS84

longitude : float
The longitude in WGS

zoomlevel : int
The zoom to retrieve. usually up to ~19. (highest).

Returns
-------
float
"""
return self.Z0RES / (2 ** zoomlevel) * numpy.cos(numpy.deg2rad(latitude))

def getImageFromCorners(self, minx, miny, maxx, maxy, zoomlevel, tileServer=None, inputCRS=WSG84, outputCRS=WSG84):
"""
Gets the image from the lower left corner and upper right cornet - [left,right,bottom,top] in the coordinate system of the outputCRS.
Expand Down Expand Up @@ -258,20 +237,6 @@ def deg2tile(self, lat_deg, lon_deg, zoom):
ytile = int((1.0 - math.asinh(math.tan(lat_rad)) / math.pi) / 2.0 * n)
return (xtile, ytile)

def listImages(self,**filters):
"""Return stored tile image documents matching the given filters."""
return self.getMeasurementsDocuments(type=self.doctype, **filters)

def setDefaultTileServer(self,server):
"""Set the default tile server URL in the project config.

Parameters
----------
server : str
URL template for the tile server.
"""
self.setConfig(**{"defaultTileServer": server})


class presentation:
"""
Expand Down
95 changes: 1 addition & 94 deletions hera/measurements/GIS/vector/buildings/toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,97 +197,4 @@ def getBuildingsFromRectangle(self, minx, miny, maxx, maxy, dataSourceName=None,
if withElevation:
buildings = self.getBuildingHeightFromRasterTopographyToolkit(buildings)

return buildings
@staticmethod
def get_buildings_height(gdf):
"""
Extract building names, geometries(coordination), and height information from a GeoDataFrame.
if there is no height available - it will calculate the number of levels in the building * 3/
else: none

Parameters:
gdf (GeoDataFrame): A GeoPandas DataFrame containing building geometries
and associated properties.

Returns:
geopandas.DataFrame

"""
building_info = []

for index, row in gdf.iterrows():
name = row.get('name', 'Unnamed') # Extract the building name

# Retain the original geometry
geometry = row.geometry

# Try to get the height or number of levels
height = row.get('height')
levels = row.get('building:levels')

# Determine the height value
if height is None and levels is not None:
height = levels * 3 # Estimate height based on number of levels

# Append the building information
building_info.append({
'name': name,
'geometry': geometry, # Keep the original geometry
'height': height
})

return gpd.GeoDataFrame(building_info)
@staticmethod
def filter_buildings_in_area(buildings_data, min_longitude, min_latitude, max_longitude, max_latitude):
"""
Filter building features by a specified geographic area using a bounding box.

Parameters:
----------
buildings_data : dict
A GeoJSON-like dictionary containing building features to filter.

min_longitude : float
Minimum longitude defining the bounding box.

min_latitude : float
Minimum latitude defining the bounding box.

max_longitude : float
Maximum longitude defining the bounding box.

max_latitude : float
Maximum latitude defining the bounding box.

Returns:
-------
gpd.GeoDataFrame
A GeoDataFrame containing buildings that are located within the specified area.
"""
# Create a polygon from the bounding box
bbox_polygon = Polygon([(min_longitude, min_latitude),
(max_longitude, min_latitude),
(max_longitude, max_latitude),
(min_longitude, max_latitude),
(min_longitude, min_latitude)]) # Close the polygon

# List to hold filtered building data
filtered_buildings = []

for feature in buildings_data['features']:
geometry = feature['geometry']
properties = feature['properties']

# Create a geometry shape from the geometry data
geom = shape(geometry) # Handles Point, Polygon, MultiPolygon, etc.

# Check if the geometry intersects with the bounding box polygon
if geom.intersects(bbox_polygon):
# Add all properties and the geometry
properties['geometry'] = geom
filtered_buildings.append(properties)

# Create a GeoDataFrame
gdf = gpd.GeoDataFrame(filtered_buildings)

return gdf
return buildings
26 changes: 0 additions & 26 deletions hera/measurements/GIS/vector/toolkit.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import io
from hera import toolkit
import geopandas
from shapely.geometry import Polygon, box
from ..utils import ITM,ED50_ZONE36N,WGS84
from ....utils.logging import get_classMethod_logger


TOOLKIT_VECTOR_REGIONNAME = "regionName"


class VectorToolkit(toolkit.abstractToolkit):
"""Base toolkit for vector GIS data operations."""

Expand All @@ -34,28 +30,6 @@ def __init__(self, projectName, toolkitName = 'VectorToolkit', filesDirectory=No
"""
super().__init__(projectName=projectName,toolkitName=toolkitName,filesDirectory=filesDirectory,connectionName=connectionName)

@staticmethod
def geopandasToGeoJson(geoData):
"""Convert a GeoDataFrame to a GeoJSON string.

Parameters
----------
geoData : geopandas.GeoDataFrame
The GeoDataFrame to convert.

Returns
-------
str
GeoJSON string representation.
"""
if isinstance(geoData,geopandas.GeoDataFrame):
dataHandler = io.BytesIO()
geoData.to_file(dataHandler,driver='GeoJSON')
return dataHandler.getvalue().decode('ascii')

else:
raise ValueError("Function receives only GeoDataFrame")

def _RegionToGeopandas(self, regionData, crs = None):
"""
Converts a shape to geopandas.
Expand Down
16 changes: 0 additions & 16 deletions hera/measurements/GIS/vector/topography.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,22 +97,6 @@ def cutRegionFromSource(self, shapeDataOrName, datasourceName, isBounds = False,



def geoPandasToSTL(self,gpandas, dxdy=50, solidName="Topography"):
"""
Transforsm the gpandas to STL.

Parameters
----------
gpandas
dxdy
solidName

Returns
-------

"""
return self.stlFactory.vectorToSTL(gpandas, dxdy=dxdy, solidName="Topography")

def regionToSTL(self, shapeDataOrName, dxdy, datasourceName, crs=None):
"""
Converts a region in a vector height map (contours) to STL at requested resolution
Expand Down
Loading
Loading