Skip to content

Instantly share code, notes, and snippets.

@dbaston
Last active December 19, 2015 20:40
Show Gist options
  • Save dbaston/6f76c3462e40a69518cd to your computer and use it in GitHub Desktop.
Save dbaston/6f76c3462e40a69518cd to your computer and use it in GitHub Desktop.
ST_ClusterIntersecting as a window function
PG_FUNCTION_INFO_V1(cluster_intersecting_window);
Datum cluster_intersecting_window(PG_FUNCTION_ARGS)
{
WindowObject win_obj = PG_WINDOW_OBJECT();
uint32_t row = WinGetCurrentPosition(win_obj);
uint32_t ngeoms = WinGetPartitionRowCount(win_obj);
uint32_t* cluster_assignments = WinGetPartitionLocalMemory(win_obj, ngeoms * sizeof(uint32_t));
if (row == 0) /* beginning of the partition; do all of the work now */
{
uint32_t i;
GEOSGeometry** geos_geoms = lwalloc(ngeoms * sizeof(GEOSGeometry*));
UNIONFIND* uf = UF_create(ngeoms);
initGEOS(lwnotice, lwgeom_geos_error);
for (i = 0; i < ngeoms; i++)
{
GSERIALIZED* g;
bool is_null;
Datum arg = WinGetFuncArgInPartition(win_obj, 0, i, WINDOW_SEEK_HEAD, false, &is_null, NULL);
if (is_null) {
/* TODO */
continue;
}
g = (GSERIALIZED*) PG_DETOAST_DATUM(arg);// DatumGetPointer(arg);
geos_geoms[i] = POSTGIS2GEOS(g);
if (!geos_geoms[i]) {
/* TODO */
}
}
union_intersecting_pairs(geos_geoms, ngeoms, uf);
/* TODO check for error */
for (i = 0; i < ngeoms; i++)
{
cluster_assignments[i] = uf->clusters[i];
GEOSGeom_destroy(geos_geoms[i]);
}
UF_destroy(uf);
}
PG_RETURN_INT32(cluster_assignments[row]);
}
CREATE OR REPLACE FUNCTION ST_ClusterIntersectingW(geometry)
RETURNS int
AS 'MODULE_PATHNAME', 'cluster_intersecting_window'
LANGUAGE 'c' IMMUTABLE STRICT WINDOW;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment