PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ ST_ClusterKMeans()

Datum ST_ClusterKMeans ( PG_FUNCTION_ARGS  )
extern

Definition at line 173 of file lwgeom_window.c.

174{
175 WindowObject winobj = PG_WINDOW_OBJECT();
176 kmeans_context *context;
177 int64 curpos, rowcount;
178
179 rowcount = WinGetPartitionRowCount(winobj);
180 context = (kmeans_context *)
181 WinGetPartitionLocalMemory(winobj,
182 sizeof(kmeans_context) + sizeof(int) * rowcount);
183
184 if (!context->isdone)
185 {
186 int i, k, N;
187 bool isnull, isout;
188 LWGEOM **geoms;
189 int *r;
190
191 /* What is K? If it's NULL or invalid, we can't procede */
192 k = DatumGetInt32(WinGetFuncArgCurrent(winobj, 1, &isnull));
193 if (isnull || k <= 0)
194 {
195 context->isdone = true;
196 context->isnull = true;
197 PG_RETURN_NULL();
198 }
199
200 /* We also need a non-zero N */
201 N = (int) WinGetPartitionRowCount(winobj);
202 if (N <= 0)
203 {
204 context->isdone = true;
205 context->isnull = true;
206 PG_RETURN_NULL();
207 }
208
209 /* Error out if N < K */
210 if (N<k)
211 {
212 lwpgerror("K (%d) must be smaller than the number of rows in the group (%d)", k, N);
213 }
214
215 /* Read all the geometries from the partition window into a list */
216 geoms = palloc(sizeof(LWGEOM*) * N);
217 for (i = 0; i < N; i++)
218 {
219 GSERIALIZED *g;
220 Datum arg = WinGetFuncArgInPartition(winobj, 0, i,
221 WINDOW_SEEK_HEAD, false, &isnull, &isout);
222
223 /* Null geometries are entered as NULL pointers */
224 if (isnull)
225 {
226 geoms[i] = NULL;
227 continue;
228 }
229
230 g = (GSERIALIZED*)PG_DETOAST_DATUM_COPY(arg);
231 geoms[i] = lwgeom_from_gserialized(g);
232 }
233
234 /* Calculate k-means on the list! */
235 r = lwgeom_cluster_2d_kmeans((const LWGEOM **)geoms, N, k);
236
237 /* Clean up */
238 for (i = 0; i < N; i++)
239 if (geoms[i])
240 lwgeom_free(geoms[i]);
241
242 pfree(geoms);
243
244 if (!r)
245 {
246 context->isdone = true;
247 context->isnull = true;
248 PG_RETURN_NULL();
249 }
250
251 /* Safe the result */
252 memcpy(context->result, r, sizeof(int) * N);
253 lwfree(r);
254 context->isdone = true;
255 }
256
257 if (context->isnull)
258 PG_RETURN_NULL();
259
260 curpos = WinGetCurrentPosition(winobj);
261 PG_RETURN_INT32(context->result[curpos]);
262}
char * r
Definition cu_in_wkt.c:24
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void lwgeom_free(LWGEOM *geom)
Definition lwgeom.c:1138
void lwfree(void *mem)
Definition lwutil.c:242
int * lwgeom_cluster_2d_kmeans(const LWGEOM **geoms, uint32_t ngeoms, uint32_t k)
Take a list of LWGEOMs and a number of clusters and return an integer array indicating which cluster ...
Definition lwkmeans.c:244

References kmeans_context::isdone, kmeans_context::isnull, lwfree(), lwgeom_cluster_2d_kmeans(), lwgeom_free(), lwgeom_from_gserialized(), r, and kmeans_context::result.

Here is the call graph for this function: