Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
fmcclean committed Jun 1, 2020
0 parents commit 1bc9ac0
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "citycatio"]
path = citycatio
branch = citycatio
url = https://github.com/nclwater/citycat-output
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Citycatpg

Citycatpg is a Python package that runs CityCAT models from a PostgreSQL database.

## Tests
`python -m unittests`
1 change: 1 addition & 0 deletions citycatpg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .main import read_postgis
15 changes: 15 additions & 0 deletions citycatpg/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from citycatio import Model
import rasterio as rio
import pandas as pd


def read_postgis(con, domain_table='domain', domain_id=1, rainfall_table='rainfall', dem_table='dem'):
with con.cursor() as cursor:
cursor.execute("""
SELECT ST_AsGDALRaster(ST_Union(ST_Clip(rast, geom)), 'GTiff')
FROM {}, {} WHERE ST_Intersects(rast, geom) and gid={}
""".format(dem_table, domain_table, domain_id))

dem = rio.MemoryFile(cursor.fetchone()[0].tobytes())

return Model(dem=dem, rainfall=pd.DataFrame([0]))
9 changes: 9 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
channels:
- conda-forge

dependencies:
- geopandas
- rasterio
- netCDF4
- psycopg2
- sqlalchemy
Empty file added tests/__init__.py
Empty file.
52 changes: 52 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import unittest
from shapely.geometry import Polygon
from citycatpg import read_postgis
import rasterio as rio
from rasterio.transform import Affine
import numpy as np
import psycopg2

dem_file = rio.MemoryFile()
x_min, y_max = 100, 500
res = 5
height, width = 100, 200
x_max = x_min + width * res
y_min = y_max - height * res
array = np.round(np.random.random((height, width)), 3)
transform = Affine.translation(x_min, y_max) * Affine.scale(res, -res)

with rio.open(
dem_file,
'w',
driver='GTiff',
height=height,
width=width,
count=1,
dtype=array.dtype,
transform=transform,
nodata=-9999
) as dst:
dst.write(array, 1)


class TestReadPostgis(unittest.TestCase):
def test_read_postgis(self):
con = psycopg2.connect(database='postgres', user='postgres', password='password', host='localhost')
dem_file.seek(0)
with con.cursor() as cursor:
cursor.execute("CREATE EXTENSION IF NOT EXISTS postgis_raster")
cursor.execute("SET postgis.gdal_enabled_drivers TO 'GTiff'")

cursor.execute("DROP TABLE IF EXISTS domain")
cursor.execute("CREATE TABLE domain (gid serial PRIMARY KEY, geom geometry)")
cursor.execute("INSERT INTO domain(geom) VALUES (ST_GeomFromText('{}'))".format(
Polygon([[x_min, y_min], [x_min, y_max], [x_max/2, y_max/2], [x_max, y_min], [x_min, y_min]])))

cursor.execute("DROP TABLE IF EXISTS dem")
cursor.execute("CREATE TABLE dem (rast raster)")
cursor.execute("INSERT INTO dem(rast) VALUES (ST_FromGDALRaster({}))".format(psycopg2.Binary(dem_file.read())))

cursor.execute("DROP TABLE IF EXISTS rainfall")

model = read_postgis(con)
model.write('tests/test_model')

0 comments on commit 1bc9ac0

Please sign in to comment.