356{
357 WindowObject winobj = PG_WINDOW_OBJECT();
359 int64 curpos, rowcount;
360
361 rowcount = WinGetPartitionRowCount(winobj);
363 WinGetPartitionLocalMemory(winobj,
365
367 {
368 int i, k, N;
369 bool isnull, isout;
370 double max_radius = 0.0;
373 Datum argdatum;
374
375
376 argdatum = WinGetFuncArgCurrent(winobj, 1, &isnull);
377 k = DatumGetInt32(argdatum);
378 if (isnull || k <= 0)
379 {
382 PG_RETURN_NULL();
383 }
384
385
386 N = (int) WinGetPartitionRowCount(winobj);
387 if (N <= 0)
388 {
391 PG_RETURN_NULL();
392 }
393
394
395 argdatum = WinGetFuncArgCurrent(winobj, 2, &isnull);
396 if (!isnull)
397 {
398 max_radius = DatumGetFloat8(argdatum);
399 if (max_radius < 0)
400 max_radius = 0.0;
401 }
402
403
404 if (N<k)
405 lwpgerror("K (%d) must be smaller than the number of rows in the group (%d)", k, N);
406
407
408 geoms = palloc(
sizeof(
LWGEOM*) * N);
409 for (i = 0; i < N; i++)
410 {
412 Datum arg = WinGetFuncArgInPartition(winobj, 0, i,
413 WINDOW_SEEK_HEAD, false, &isnull, &isout);
414
415
416 if (isnull)
417 {
418 geoms[i] = NULL;
419 continue;
420 }
421
424 }
425
426
428
429
430 for (i = 0; i < N; i++)
431 if (geoms[i])
433
434 pfree(geoms);
435
437 {
440 PG_RETURN_NULL();
441 }
442
443
444 memcpy(context->
result,
r,
sizeof(
int) * N);
447 }
448
450 PG_RETURN_NULL();
451
452 curpos = WinGetCurrentPosition(winobj);
453 PG_RETURN_INT32(context->
result[curpos]);
454}
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
int * lwgeom_cluster_kmeans(const LWGEOM **geoms, uint32_t n, uint32_t k, double max_radius)
Take a list of LWGEOMs and a number of clusters and return an integer array indicating which cluster ...