Skip to content

Commit

Permalink
Merge pull request #39 from wri/feature/open_buildings
Browse files Browse the repository at this point in the history
[CIF-168] add open buildings layer
  • Loading branch information
chrowe authored May 29, 2024
2 parents 4e762a3 + 9831b26 commit 2f4fdb1
Showing 7 changed files with 394 additions and 85 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,17 @@ The Cities Indicator Framework (CIF) is a set of Python tools to make it easier
## Quick start
If all you want to do is use the CIF, the quickest way to get started is to use our [WRI Cities Indicator Framework Colab Notebook](https://colab.research.google.com/drive/1PV1H-godxJ6h42p74Ij9sdFh3T0RN-7j#scrollTo=eM14UgpmpZL-)

## PR Review
0. Prerequisites
1. Git
* On Windows I recommend WSL https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-git
3. https://cli.github.com/
* On MacOS I recommend the Homebrew option
* If you don't have an ssh key, it will install one for you
4. Conda (or Mamba) to install dependencies
* If you have Homebrew `brew install --cask miniconda`


## Dependencies
### Conda
`conda env create -f environment.yml`
1 change: 1 addition & 0 deletions city_metrix/layers/__init__.py
Original file line number Diff line number Diff line change
@@ -13,3 +13,4 @@
from .world_pop import WorldPop
from .built_up_height import BuiltUpHeight
from .average_net_building_height import AverageNetBuildingHeight
from .open_buildings import OpenBuildings
44 changes: 44 additions & 0 deletions city_metrix/layers/open_buildings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import ee
import geemap
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon, MultiPolygon

from .layer import Layer


class OpenBuildings(Layer):
def __init__(self, country='USA', **kwargs):
super().__init__(**kwargs)
self.country = country

def get_data(self, bbox):
dataset = ee.FeatureCollection(f"projects/sat-io/open-datasets/VIDA_COMBINED/{self.country}")
open_buildings = dataset.filterBounds(ee.Geometry.BBox(*bbox))
openbuilds = geemap.ee_to_gdf(open_buildings).reset_index()

# filter out geom_type GeometryCollection
gc_openbuilds = openbuilds[openbuilds.geom_type == 'GeometryCollection']
if len(gc_openbuilds) > 0:
# select Polygons and Multipolygons from GeometryCollection
gc_openbuilds['geometries'] = gc_openbuilds.apply(lambda x: [g for g in x.geometry.geoms], axis=1)
gc_openbuilds_polygon = []
# iterate over each row in gc_openbuilds
for index, row in gc_openbuilds.iterrows():
for geom in row['geometries']:
# Check if the geometry is a Polygon or MultiPolygon
if isinstance(geom, Polygon) or isinstance(geom, MultiPolygon):
# Create a new row with the same attributes as the original row, but with the Polygon geometry
new_row = row.drop(['geometry', 'geometries'])
new_row['geometry'] = geom
gc_openbuilds_polygon.append(new_row)
if len(gc_openbuilds_polygon) > 0:
# convert list to geodataframe
gc_openbuilds_polygon = gpd.GeoDataFrame(gc_openbuilds_polygon, geometry='geometry')
# replace GeometryCollection with Polygon, merge back to openbuilds
openbuilds = openbuilds[openbuilds.geom_type != 'GeometryCollection']
openbuilds = pd.concat([openbuilds, gc_openbuilds_polygon], ignore_index=True).reset_index()
else:
openbuilds = openbuilds[openbuilds.geom_type != 'GeometryCollection'].reset_index()

return openbuilds
10 changes: 10 additions & 0 deletions docs/developer.md
Original file line number Diff line number Diff line change
@@ -79,6 +79,16 @@ Hopefully we already have the layers you need in `city_metrix/layers/` and you c

4. Import the new layer class to [city_metrix/layers/\_\_init\_\_.py](../city_metrix/layers/__init__.py)

5. Add a test to [tests/layers.py](../tests/layers.py) to ensure the new layer is working as expected.

6. Add a section to the get layers.ipynb notebook to demonstrate how to use the new layer.

7. Create a PR to merge the new layer into the main branch with these in the PR description:
- Link to Jira ticket (if any)
- A brief description of the new layer
- A link to the Airtable record for the new layer
- Explain how to test the new layer


## Adding an Indicator
Once you have all the data layers you need as inputs, here is the process to create an indicator using them.
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ dependencies:
- dask[complete]=2023.11.0
- matplotlib=3.8.2
- jupyterlab=4.0.10
- geemap=0.32.0
- pip=23.3.1
- pip:
- cartoframes==1.2.5
Loading

0 comments on commit 2f4fdb1

Please sign in to comment.