diff --git a/src/pg/sql/21_spatial_lag.sql b/src/pg/sql/21_spatial_lag.sql new file mode 100644 index 0000000..1df69cb --- /dev/null +++ b/src/pg/sql/21_spatial_lag.sql @@ -0,0 +1,17 @@ +-- Spatial Lag with kNN neighbors (internal function) +CREATE OR REPLACE FUNCTION + CDB_SpatialLag( + subquery TEXT, + column_name TEXT, + w_type TEXT, + num_ngbrs INT, + geom_col TEXT, + id_col TEXT) +RETURNS TABLE (lag NUMERIC, rowid INT) +AS $$ + from crankshaft.spatial_lag import Spatial + spatial = Spatial() + # TODO: use named parameters or a dictionary + return spatial.spatial_lag(subquery, column_name, w_type, + num_ngbrs, geom_col, id_col) +$$ LANGUAGE plpythonu; diff --git a/src/py/crankshaft/crankshaft/analysis_data_provider.py b/src/py/crankshaft/crankshaft/analysis_data_provider.py index cbc27bc..36f38c0 100644 --- a/src/py/crankshaft/crankshaft/analysis_data_provider.py +++ b/src/py/crankshaft/crankshaft/analysis_data_provider.py @@ -30,7 +30,7 @@ class AnalysisDataProvider: except plpy.SPIError, err: plpy.error('Analysis failed: %s' % err) - def get_moran(self, w_type, params): + def get_neighbor(self, w_type, params): """fetch data for moran's i analyses""" try: query = pu.construct_neighbor_query(w_type, params) diff --git a/src/py/crankshaft/crankshaft/clustering/moran.py b/src/py/crankshaft/crankshaft/clustering/moran.py index 0e12e3f..3b74963 100644 --- a/src/py/crankshaft/crankshaft/clustering/moran.py +++ b/src/py/crankshaft/crankshaft/clustering/moran.py @@ -36,7 +36,7 @@ class Moran: ("subquery", subquery), ("num_ngbrs", num_ngbrs)]) - result = self.data_provider.get_moran(w_type, params) + result = self.data_provider.get_neighbor(w_type, params) # collect attributes attr_vals = pu.get_attributes(result) @@ -66,7 +66,7 @@ class Moran: ("subquery", subquery), ("num_ngbrs", num_ngbrs)]) - result = self.data_provider.get_moran(w_type, params) + result = self.data_provider.get_neighbor(w_type, params) attr_vals = pu.get_attributes(result) weight = pu.get_weight(result, w_type, num_ngbrs) @@ -93,7 +93,7 @@ class Moran: ("subquery", subquery), ("num_ngbrs", num_ngbrs)]) - result = self.data_provider.get_moran(w_type, params) + result = self.data_provider.get_neighbor(w_type, params) # collect attributes numer = pu.get_attributes(result, 1) @@ -123,7 +123,7 @@ class Moran: ("subquery", subquery), ("num_ngbrs", num_ngbrs)]) - result = self.data_provider.get_moran(w_type, params) + result = self.data_provider.get_neighbor(w_type, params) # collect attributes numer = pu.get_attributes(result, 1) @@ -154,7 +154,7 @@ class Moran: ("subquery", subquery), ("num_ngbrs", num_ngbrs)]) - result = self.data_provider.get_moran(w_type, params) + result = self.data_provider.get_neighbor(w_type, params) # collect attributes attr1_vals = pu.get_attributes(result, 1) diff --git a/src/py/crankshaft/crankshaft/spatial_lag/__init__.py b/src/py/crankshaft/crankshaft/spatial_lag/__init__.py new file mode 100644 index 0000000..1442ad5 --- /dev/null +++ b/src/py/crankshaft/crankshaft/spatial_lag/__init__.py @@ -0,0 +1,2 @@ +"""Import all functions from for clustering""" +from spatial_lag import * diff --git a/src/py/crankshaft/crankshaft/spatial_lag/spatial_lag.py b/src/py/crankshaft/crankshaft/spatial_lag/spatial_lag.py new file mode 100644 index 0000000..947e009 --- /dev/null +++ b/src/py/crankshaft/crankshaft/spatial_lag/spatial_lag.py @@ -0,0 +1,46 @@ +""" +Spatial Lag (using local kNN neighbors identifying spatial lag for a feature) +""" + +import pysal as ps +from collections import OrderedDict +from crankshaft.analysis_data_provider import AnalysisDataProvider + +# crankshaft module +import crankshaft.pysal_utils as pu + +# High level interface --------------------------------------- + + +class Spatial: + def __init__(self, data_provider=None): + if data_provider is None: + self.data_provider = AnalysisDataProvider() + else: + self.data_provider = data_provider + + def spatial_lag(self, subquery, attr, + w_type, num_ngbrs, geom_col, id_col): + """ + Querying spatial lags for kNN neighbors + """ + + # geometries with attributes that are null are ignored + # resulting in a collection of not as near neighbors + + params = OrderedDict([("id_col", id_col), + ("attr1", attr), + ("geom_col", geom_col), + ("subquery", subquery), + ("num_ngbrs", num_ngbrs)]) + + result = self.data_provider.get_neighbor(w_type, params) + + attr_vals = pu.get_attributes(result) + weight = pu.get_weight(result, w_type, num_ngbrs) + + # calculate spatial_lag values + + lag = ps.weights.spatial_lag.lag_spatial(weight, attr_vals) + + return zip(lag, weight.id_order)