Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saving additional info zone helper #3388

Merged
merged 5 commits into from
Sep 19, 2023
Merged
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
52 changes: 45 additions & 7 deletions cea/datamanagement/zone_helper.py
Copy link
Collaborator

@MatNif MatNif Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the changes look good to be. The only question I have is about the removal of the string-to-float conversion for some of the parameters (lines 75-80): What's the reasoning behind removing that section?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this.
Please see my comments below.

Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,6 @@ def assign_attributes(shapefile, buildings_height, buildings_floors, buildings_h
'if we do not find data in OSM for a particular building, we estimate it based on the number of floors, '
'multiplied by a pre-defined floor-to-floor height (set to 3m by default)')

# Make sure relevant OSM parameters (if available) are passed as floats, not strings
OSM_COLUMNS = ['building:min_level', 'min_height', 'building:levels', 'height']
selected_columns = list(set(list_of_columns).intersection(set(OSM_COLUMNS)))
shapefile[selected_columns] = shapefile[selected_columns] \
.fillna(1).apply(lambda x: pd.to_numeric(x, errors='coerce'))

Copy link
Collaborator Author

@ShiZhongming ShiZhongming Sep 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MatNif
Correct me if I am wrong. The original Line 75-80 and Line 81-85 are duplicated. Hence, I removed the Line75-80

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I think you're right. I missed that.

In that case, I think this PR is good to go.

# Make sure relevant OSM parameters (if available) are passed as floats, not strings
OSM_COLUMNS = ['building:min_level', 'min_height', 'building:levels', 'height']
shapefile[[c for c in OSM_COLUMNS if c in list_of_columns]] = \
Expand Down Expand Up @@ -191,6 +185,46 @@ def assign_attributes(shapefile, buildings_height, buildings_floors, buildings_h

return shapefile

def assign_attributes_additional(shapefile):
"""
This script fills the zone.shp file with additional information from OSM,
including house number, street name, postcode, if HDB (for Singapore), city, country
"""
# TODO: include different terms used by OSM in different countries
# As of 19 Sept 2023, this function works fine in Switzerland and Singapore

# local variables
no_buildings = shapefile.shape[0]
list_of_columns = shapefile.columns

# Check which attributes OSM has (sometimes it does not have any) and create the column if missing
if 'addr:city' not in list_of_columns:
shapefile['addr:city'] = [''] * no_buildings
if 'addr:country' not in list_of_columns:
shapefile['addr:country'] = [''] * no_buildings
if 'addr:postcode' not in list_of_columns:
shapefile['addr:postcode'] = [''] * no_buildings
if 'addr:street' not in list_of_columns:
shapefile['addr:street'] = [''] * no_buildings
if 'addr:housename' not in list_of_columns:
shapefile['addr:housename'] = [''] * no_buildings
if 'addr:housenumber' not in list_of_columns:
shapefile['addr:country'] = [''] * no_buildings
if 'residential' not in list_of_columns:
shapefile['residential'] = [''] * no_buildings #not HDB

# Assign the cea-formatted columns with attributes
shapefile['house_no'] = shapefile['addr:housenumber']
shapefile['street'] = shapefile['addr:street']
shapefile['postcode'] = shapefile['addr:postcode']
shapefile['house_name'] = shapefile['addr:housename']
shapefile['resi_type'] = shapefile['residential']
shapefile['city'] = shapefile['addr:city']
shapefile['country'] = shapefile['addr:country']

return shapefile



def fix_overlapping_geoms(buildings, zone):
"""
Expand Down Expand Up @@ -482,6 +516,10 @@ def polygon_to_zone(buildings_floors, buildings_floors_below_ground, buildings_h
shapefile = assign_attributes(shapefile, buildings_height, buildings_floors,
buildings_height_below_ground, buildings_floors_below_ground, key="B")

# adding additional information from OSM
# (e.g. house number, street number, postcode, if HDB for Singapore buildings)
shapefile = assign_attributes_additional(shapefile)

# fix geometries of buildings with overlapping polygons
if fix_overlapping is True:
print("Fixing overlapping geometries.")
Expand All @@ -498,7 +536,7 @@ def polygon_to_zone(buildings_floors, buildings_floors_below_ground, buildings_h
# clean up attributes
cleaned_shapefile = shapefile[
["Name", "height_ag", "floors_ag", "height_bg", "floors_bg", "description", "category", "geometry",
"REFERENCE"]]
"REFERENCE", 'house_no', 'street', 'postcode', 'house_name', 'resi_type', 'city', 'country']]
cleaned_shapefile = cleaned_shapefile.to_crs(get_projected_coordinate_system(float(lat), float(lon)))

# save shapefile to zone.shp
Expand Down
42 changes: 42 additions & 0 deletions cea/schemas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17933,6 +17933,48 @@ get_zone_geometry:
unit: 'NA'
values: alphanumeric
nullable: true
house_no:
description: House number in the address(if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
street:
description: Street name in the address (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
postcode:
description: Postal code in the address (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
house_name:
description: House number (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
resi_type:
description: Residential type, e.g. HDB for Singapore (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
city:
description: City name in the address (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
country:
description: Country 2-digit code in the address (if any)
type: string
unit: 'NA'
values: alphanumeric
nullable: true
used_by:
- archetypes_mapper
- decentralized
Expand Down
4 changes: 2 additions & 2 deletions cea/utilities/standardize_coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

def shapefile_to_WSG_and_UTM(shapefile_path):

# read the CPG and replace whateever is there with ISO, and save
# read the CPG and replace whatever is there with ISO, and save
ensure_cpg_file(shapefile_path)

# get coordinate system and project to WSG 84
Expand Down Expand Up @@ -65,4 +65,4 @@ def get_lat_lon_projected_shapefile(data):
data = data.to_crs(get_geographic_coordinate_system())
lon = data.geometry[0].centroid.coords.xy[0][0]
lat = data.geometry[0].centroid.coords.xy[1][0]
return lat, lon
return lat, lon