From 01eef5ee9e35b6fd9a3d0bb993a5a3dd5d9e1417 Mon Sep 17 00:00:00 2001 From: Stuart Lynn Date: Tue, 15 Mar 2016 17:01:03 -0400 Subject: [PATCH] inital attempt at contours --- pg/sql/0.0.1/07_contours.sql | 12 +++++ python/crankshaft/crankshaft/__init__.py | 1 + .../crankshaft/contours/__init__.py | 1 + .../crankshaft/contours/contours.py | 47 +++++++++++++++++++ python/crankshaft/setup.py | 4 +- 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 pg/sql/0.0.1/07_contours.sql create mode 100644 python/crankshaft/crankshaft/contours/__init__.py create mode 100644 python/crankshaft/crankshaft/contours/contours.py diff --git a/pg/sql/0.0.1/07_contours.sql b/pg/sql/0.0.1/07_contours.sql new file mode 100644 index 0000000..0ff2e70 --- /dev/null +++ b/pg/sql/0.0.1/07_contours.sql @@ -0,0 +1,12 @@ + + +CREATE OR REPLACE FUNCTION + cdb_contours_count ( + query TEXT, + levels NUMERIC[] + ) +RETURNS TABLE (the_geom geometry , level Numeric) +AS $$ + from crankshaft.contours import create_countours_count + return create_countours_count(query,levels) +$$ LANGUAGE plpythonu; diff --git a/python/crankshaft/crankshaft/__init__.py b/python/crankshaft/crankshaft/__init__.py index d07e330..ac0e870 100644 --- a/python/crankshaft/crankshaft/__init__.py +++ b/python/crankshaft/crankshaft/__init__.py @@ -1,2 +1,3 @@ import random_seeds import clustering +import contours diff --git a/python/crankshaft/crankshaft/contours/__init__.py b/python/crankshaft/crankshaft/contours/__init__.py new file mode 100644 index 0000000..b0343a5 --- /dev/null +++ b/python/crankshaft/crankshaft/contours/__init__.py @@ -0,0 +1 @@ +from contours import * diff --git a/python/crankshaft/crankshaft/contours/contours.py b/python/crankshaft/crankshaft/contours/contours.py new file mode 100644 index 0000000..7f305ff --- /dev/null +++ b/python/crankshaft/crankshaft/contours/contours.py @@ -0,0 +1,47 @@ + +import matplotlib.pyplot as plt +import numpy as np +import plpy + +def contour_to_polygon(contour): + plpy.notice('appending contour ') + c = np.append(contour, [contour[0]], axis=0) + points =','.join( [ " ".join(str(a) for a in b) for b in c]) + + return "POLYGON(({points}))::geometry".format(points=points) + +def create_countours_count(query,levels,mesh_size=20): + qresult = plpy.execute( "select ST_X(the_geom)::Numeric as x, ST_Y(the_geom)::Numeric as y from ({query}) a ".format(query=query)) + x =[] + y =[] + for a in qresult: + if a['x'] and a['y']: + x.append(float(a['x'])) + y.append(float(a['y'])) + + plpy.notice(np.shape(x)) + plpy.notice(np.shape(y)) + + if None in x: + plpy.notice("NULL IN LIST X ") + if None in y: + plpy.notice("NULL IN LIST Y ") + + x_min,x_max = np.min(x), np.max(x) + y_min,y_max = np.min(y), np.max(y) + plpy.notice(x_min) + plpy.notice(x_max) + plpy.notice(y_min) + plpy.notice(y_max) + plpy.notice(mesh_size) + + x_grid = np.linspace(x_min,x_max, mesh_size) + y_grid = np.linspace(y_min,y_max, mesh_size) + range = [[x_min,x_max],[y_min,y_max]] + a, xedges, yedges= np.histogram2d(x,y,bins=(mesh_size,mesh_size), range=range) + a = np.swapaxes(a,0,1) + plpy.notice("here about to create the contours") + + CS = plt.contour(xedges[1:],yedges[1:] ,a,4,linewidths=0.5, colors='b') + plpy.notice(levels) + return[(contour_to_polygon(CS.Cntr.trace((level))[0]), float(level)) for level in levels] diff --git a/python/crankshaft/setup.py b/python/crankshaft/setup.py index c0f8c50..e7693ca 100644 --- a/python/crankshaft/setup.py +++ b/python/crankshaft/setup.py @@ -40,9 +40,9 @@ setup( # The choice of component versions is dictated by what's # provisioned in the production servers. - install_requires=['pysal==1.11.0','numpy==1.6.1','scipy==0.17.0'], + install_requires=['pysal==1.11.0','numpy==1.10.1','scipy==0.17.0', 'matplotlib==1.4.3'], - requires=['pysal', 'numpy'], + requires=['pysal', 'numpy', 'matplotlib'], test_suite='test' )