Browse Source

v.cluster: fix cluster id assignment

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@64487 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 10 years ago
parent
commit
bf156471da
1 changed files with 66 additions and 19 deletions
  1. 66 19
      vector/v.cluster/main.c

+ 66 - 19
vector/v.cluster/main.c

@@ -239,7 +239,8 @@ int main(int argc, char *argv[])
     noutliers = nclusters = 0;
     if (clmethod == CL_DBSCAN) {
 	/* DBSCAN 
-	 * the neighbors of each point with at least minpnts neighbors 
+	 * the neighbors of each point 
+	 * with at least minpnts neighbors within distance (epsilon)
 	 * are added to a cluster */
 
 	/* get epsilon */
@@ -315,17 +316,30 @@ int main(int argc, char *argv[])
 	    G_percent(i++, npoints, 4);
 
 	    /* radius search */
+	    /* TODO: use knn search */
 	    kdfound = kdtree_dnn(kdt, c, &kduid, &kddist, eps, &uid);
-	    
+
 	    /* must have min neighbors within radius */
 	    if (kdfound >= minpnts) {
 
-		cat = idx[cid[uid]];
+		OLD = cid[uid];
+		NEW = idx[OLD];
+		while (OLD != NEW) {
+		    OLD = NEW;
+		    NEW = idx[OLD];
+		}
+		cat = NEW;
 
 		/* find latest cluster */
 		for (j = 0; j < kdfound; j++) {
-		    if (cat < idx[cid[kduid[j]]]) {
-			cat = idx[cid[kduid[j]]];
+		    OLD = cid[kduid[j]];
+		    NEW = idx[OLD];
+		    while (OLD != NEW) {
+			OLD = NEW;
+			NEW = idx[OLD];
+		    }
+		    if (cat < NEW) {
+			cat = NEW;
 		    }
 		}
 
@@ -342,7 +356,13 @@ int main(int argc, char *argv[])
 		/* set or update cluster ids */
 		if (cid[uid] != 0) {
 		    /* relabel */
-		    idx[cid[uid]] = cat;
+		    OLD = cid[uid];
+		    NEW = idx[OLD];
+		    while (OLD != NEW) {
+			OLD = NEW;
+			NEW = idx[OLD];
+		    }
+		    idx[NEW] = cat;
 		}
 		else {
 		    cid[uid] = cat;
@@ -351,7 +371,13 @@ int main(int argc, char *argv[])
 		for (j = 0; j < kdfound; j++) {
 		    if (cid[kduid[j]] != 0) {
 			/* relabel */
-			idx[cid[kduid[j]]] = cat;
+			OLD = cid[kduid[j]];
+			NEW = idx[OLD];
+			while (OLD != NEW) {
+			    OLD = NEW;
+			    NEW = idx[OLD];
+			}
+			idx[NEW] = cat;
 		    }
 		    else {
 		       cid[kduid[j]] = cat;
@@ -486,9 +512,6 @@ int main(int argc, char *argv[])
 
 	/* create clusters */
 	G_message(_("Building clusters ..."));
-	clcnt = G_malloc((nlines + 1) * sizeof(int));
-	for (i = 0; i <= nlines; i++)
-	    clcnt[i] = 0;
 	nclusters = 0;
 	kdtree_init_trav(&trav, kdt);
 	c[2] = 0.0;
@@ -503,12 +526,24 @@ int main(int argc, char *argv[])
 	    /* any neighbor within radius */
 	    if (kdfound > 0) {
 
-		cat = idx[cid[uid]];
+		OLD = cid[uid];
+		NEW = idx[OLD];
+		while (OLD != NEW) {
+		    OLD = NEW;
+		    NEW = idx[OLD];
+		}
+		cat = NEW;
 
 		/* find latest cluster */
 		for (j = 0; j < kdfound; j++) {
-		    if (cat < idx[cid[kduid[j]]]) {
-			cat = idx[cid[kduid[j]]];
+		    OLD = cid[kduid[j]];
+		    NEW = idx[OLD];
+		    while (OLD != NEW) {
+			OLD = NEW;
+			NEW = idx[OLD];
+		    }
+		    if (cat < NEW) {
+			cat = NEW;
 		    }
 		}
 
@@ -520,27 +555,36 @@ int main(int argc, char *argv[])
 			G_fatal_error(_("nlines: %d, nclusters: %d"), nlines, nclusters);
 		    idx[nclusters] = nclusters;
 		    cid[uid] = nclusters;
-		    clcnt[cat] = 1;
 		}
 
 		/* set or update cluster ids */
 		if (cid[uid] != 0) {
 		    /* relabel */
-		    idx[cid[uid]] = cat;
+		    OLD = cid[uid];
+		    NEW = idx[OLD];
+		    while (OLD != NEW) {
+			OLD = NEW;
+			NEW = idx[OLD];
+		    }
+		    idx[NEW] = cat;
 		}
 		else {
 		    cid[uid] = cat;
-		    clcnt[cat]++;
 		}
 
 		for (j = 0; j < kdfound; j++) {
 		    if (cid[kduid[j]] != 0) {
+			OLD = cid[kduid[j]];
+			NEW = idx[OLD];
+			while (OLD != NEW) {
+			    OLD = NEW;
+			    NEW = idx[OLD];
+			}
 			/* relabel */
-			idx[cid[kduid[j]]] = cat;
+			idx[NEW] = cat;
 		    }
 		    else {
 		        cid[kduid[j]] = cat;
-			clcnt[cat]++;
 		    }
 		}
 		G_free(kddist);
@@ -560,6 +604,9 @@ int main(int argc, char *argv[])
 	/* generate a renumbering scheme */
 	G_message(_("Generating renumbering scheme..."));
 	G_debug(1, "%d initial clusters", nclusters);
+	clcnt = G_malloc((nlines + 1) * sizeof(int));
+	for (i = 0; i <= nlines; i++)
+	    clcnt[i] = 0;
 	/* allocate final clump ID */
 	renumber = (int *) G_malloc((nclusters + 1) * sizeof(int));
 	renumber[0] = 0;
@@ -576,7 +623,7 @@ int main(int argc, char *argv[])
 		    NEW = idx[OLD];
 		}
 		idx[i] = NEW;
-		clcnt[NEW] += clcnt[i];
+		clcnt[NEW]++;
 	    }
 	}
 	for (i = 1; i <= nclusters; i++) {