13 double dx = (pa->
x - pb->
x);
14 double dy = (pa->
y - pb->
y);
23 double d_closest = FLT_MAX;
28 for (i = 0; i < num_objs; i++)
55 if (num_objs <= 0)
return;
57 for (i = 0; i < num_objs; i++)
60 if (clusters[i] != cluster)
continue;
80 int num_centroids = 0;
84 POINT2D min = { DBL_MAX, DBL_MAX };
85 POINT2D max = { -DBL_MAX, -DBL_MAX };
102 lwerror(
"%s: number of geometries is less than the number of clusters requested", __func__);
107 memset(centroids, 0,
sizeof(
LWGEOM*) * ngeoms);
113 memset(centers_raw, 0,
sizeof(
POINT2D) * k);
127 memset(config.
clusters, 0,
sizeof(
int) * ngeoms);
131 for (i = 0; i < ngeoms; i++)
133 const LWGEOM *geom = geoms[i];
139 config.
objs[i] = NULL;
150 config.
objs[i] = NULL;
153 centroids[num_centroids++] =
centroid;
166 if (cp->
x < min.
x) min.
x = cp->
x;
167 if (cp->
y < min.
y) min.
y = cp->
y;
168 if (cp->
x > max.
x) max.
x = cp->
x;
169 if (cp->
y > max.
y) max.
y = cp->
y;
176 dx = (max.
x - min.
x)/k;
177 dy = (max.
y - min.
y)/k;
178 seen =
lwalloc(
sizeof(
int)*config.
k);
179 memset(seen, 0,
sizeof(
int)*config.
k);
180 for (i = 0; i < k; i++)
187 p.
x = min.
x + dx * (i + 0.5);
188 p.
y = min.
y + dy * (i + 0.5);
195 lwerror(
"unable to calculate cluster seed points, too many NULLs or empties?");
201 if (seen[j] == closest)
204 for (k = 1; k < config.
num_objs; k++)
206 t = (closest + k) % config.
num_objs;
220 seen[sidx++] = closest;
225 centers_raw[i] = *((
POINT2D*)config.
objs[closest]);
226 config.
centers[i] = &(centers_raw[i]);
uint32_t lwgeom_get_type(const LWGEOM *geom)
Return LWTYPE number.
kmeans_result kmeans(kmeans_config *config)
Datum centroid(PG_FUNCTION_ARGS)
LWGEOM * lwgeom_centroid(const LWGEOM *geom)
LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
static double lwkmeans_pt_distance(const Pointer a, const Pointer b)
int * lwgeom_cluster_2d_kmeans(const LWGEOM **geoms, int ngeoms, int k)
Take a list of LWGEOMs and a number of clusters and return an integer array indicating which cluster ...
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, int n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
static void lwkmeans_pt_centroid(const Pointer *objs, const int *clusters, size_t num_objs, int cluster, Pointer centroid)
unsigned int max_iterations
static int lwkmeans_pt_closest(const Pointer *objs, size_t num_objs, const Pointer a)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
void * lwalloc(size_t size)
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
kmeans_distance_method distance_method
kmeans_centroid_method centroid_method
void lwerror(const char *fmt,...)
Write a notice out to the error handler.