[GRASS-SVN] r57812 - grass-addons/grass7/vector/v.centerpoint

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Sep 22 07:40:30 PDT 2013


Author: mmetz
Date: 2013-09-22 07:40:29 -0700 (Sun, 22 Sep 2013)
New Revision: 57812

Added:
   grass-addons/grass7/vector/v.centerpoint/Makefile
   grass-addons/grass7/vector/v.centerpoint/areas.c
   grass-addons/grass7/vector/v.centerpoint/lines.c
   grass-addons/grass7/vector/v.centerpoint/local_proto.h
   grass-addons/grass7/vector/v.centerpoint/main.c
   grass-addons/grass7/vector/v.centerpoint/points.c
   grass-addons/grass7/vector/v.centerpoint/v.centerpoint.html
Modified:
   grass-addons/grass7/vector/v.centerpoint/
Log:
add v.centerpoint


Property changes on: grass-addons/grass7/vector/v.centerpoint
___________________________________________________________________
Added: svn:ignore
   + OBJ.* *.tmp.html


Added: grass-addons/grass7/vector/v.centerpoint/Makefile
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/Makefile	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/Makefile	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,13 @@
+
+MODULE_TOPDIR = ../..
+
+PGM = v.centerpoint
+
+LIBES = $(VECTORLIB) $(GISLIB)
+DEPENDENCIES = $(VECTORDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd


Property changes on: grass-addons/grass7/vector/v.centerpoint/Makefile
___________________________________________________________________
Added: svn:mime-type
   + text/x-makefile
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/areas.c
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/areas.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/areas.c	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,574 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+static double d_ulp(double d)
+{
+    int exp;
+
+    if (d == 0)
+	return GRASS_EPSILON;
+
+    d = frexp(d, &exp);
+    exp -= 51;
+    d = ldexp(d, exp);
+
+    return d;
+}
+
+int areas_center(struct Map_info *In, struct Map_info *Out, int layer, 
+                 struct cat_list *cat_list, int mode)
+{
+    int area, nareas, isle, nisles, nisles_alloc;
+    struct line_pnts *Points, **IPoints, *OPoints;
+    struct line_cats *Cats;
+    struct bound_box box;
+    double x, y, z, meanx, meany, meanz;
+    double *xp, *yp;
+    double w, tot_w;
+    int i;
+    
+    Points = Vect_new_line_struct();
+    OPoints = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    
+    nisles_alloc = 10;
+    IPoints = G_malloc(nisles_alloc * sizeof (struct line_pnts *));
+    
+    nisles = nisles_alloc;
+    for (isle = 0; isle < nisles_alloc; isle++) {
+	IPoints[isle] = Vect_new_line_struct();
+    } 
+
+    nareas = Vect_get_num_areas(In);
+    
+    /* geometric mean = center of gravity */
+    if (mode & A_MEAN) {
+
+	G_message(_("Calculating centers of gravity for areas..."));
+
+	G_percent(0, nareas, 4);
+
+	for (area = 1; area <= nareas; area++) {
+
+	    Vect_reset_cats(Cats);
+	    if (layer > 1) {
+		Vect_get_area_cats(In, area, Cats);
+	        if (!Vect_cats_in_constraint(Cats, layer, cat_list))
+		    continue;
+	    }
+	    
+	    Vect_get_area_points(In, area, Points);
+	    Vect_line_prune(Points);
+	    
+	    nisles = Vect_get_area_num_isles(In, area);
+	    if (nisles > nisles_alloc) {
+		IPoints = G_realloc(IPoints, nisles * sizeof (struct line_pnts *));
+		for (isle = nisles_alloc; isle < nisles; isle++) {
+		    IPoints[isle] = Vect_new_line_struct();
+		}
+		nisles_alloc = nisles;
+	    }
+	    for (isle = 1; isle < nisles; isle++) {
+		Vect_get_isle_points(In, isle, IPoints[isle - 1]);
+		Vect_line_prune(IPoints[isle - 1]);
+	    }
+
+	    /* surveyor's / shoelace formula */
+	    /* the surveyor should not be too far away (fp precision limit) */
+	    /* surveyor's position: */
+	    Vect_line_box(Points, &box);
+	    x = (box.W + box.E) / 2.;
+	    y = (box.S + box.N) / 2.;
+	    z = 0;
+	    meanx = meany = meanz = 0.;
+	    tot_w = 0.;
+
+	    xp = Points->x;
+	    yp = Points->y;
+	    for (i = 1; i < Points->n_points; i++) {
+		w = (x - xp[i - 1]) * (yp[i] - y) - 
+		    (x - xp[i]) * (yp[i - 1] - y);
+
+		meanx += (xp[i - 1] + xp[i] + x) * w;
+		meany += (yp[i - 1] + yp[i] + y) * w;
+		tot_w += w;
+	    }
+
+	    for (isle = 0; isle < nisles; isle++) {
+		xp = IPoints[isle]->x;
+		yp = IPoints[isle]->y;
+		for (i = 1; i < IPoints[isle]->n_points; i++) {
+		    w = (x - xp[i - 1]) * (yp[i] - y) - 
+			(x - xp[i]) * (yp[i - 1] - y);
+
+		    meanx += (xp[i - 1] + xp[i] + x) * w;
+		    meany += (yp[i - 1] + yp[i] + y) * w;
+		    tot_w += w;
+		}
+	    }
+	    if (tot_w != 0) {
+		x = meanx / (tot_w * 3);
+		y = meany / (tot_w * 3);
+	    }
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, z);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "7|%.15g|%.15g|%.15g\n", x, y, z);
+
+	    G_percent(area, nareas, 4);
+	}
+    }
+
+    /* approximate geometric median with Weiszfeld's algorithm:
+     * iterative least squares reduction */
+    if (mode & A_MEDIAN) {
+	struct line_pnts *CPoints;
+	double sx, sy, cx, cy, dx, dy;
+	double medx, medy;
+	double *wc;
+	int nwc, nwc_alloc, wci;
+	double dist, distsum, dist2all, lastdist2all;
+	int j, iter, maxiter = 1000;
+
+	G_message(_("Calculating geometric medians for areas..."));
+	
+	CPoints = Vect_new_line_struct();
+	
+	nwc_alloc = 100;
+	wc = G_malloc(nwc_alloc * sizeof(double));
+	
+	G_percent(0, nareas, 4);
+
+	for (area = 1; area <= nareas; area++) {
+
+	    Vect_reset_cats(Cats);
+	    if (layer > 1) {
+		Vect_get_area_cats(In, area, Cats);
+	        if (!Vect_cats_in_constraint(Cats, layer, cat_list))
+		    continue;
+	    }
+
+	    Vect_get_area_points(In, area, Points);
+	    Vect_line_prune(Points);
+	    nwc = Points->n_points - 1;
+	    
+	    nisles = Vect_get_area_num_isles(In, area);
+	    if (nisles > nisles_alloc) {
+		IPoints = G_realloc(IPoints, nisles * sizeof (struct line_pnts *));
+		for (isle = nisles_alloc; isle < nisles; isle++) {
+		    IPoints[isle] = Vect_new_line_struct();
+		}
+		nisles_alloc = nisles;
+	    }
+	    for (isle = 1; isle < nisles; isle++) {
+		Vect_get_isle_points(In, isle, IPoints[isle - 1]);
+		Vect_line_prune(IPoints[isle - 1]);
+		nwc += IPoints[isle - 1]->n_points - 1;
+	    }
+
+	    if (nwc_alloc < nwc) {
+		nwc_alloc = nwc;
+		wc = G_realloc(wc, nwc_alloc * sizeof(double));
+	    }
+		
+	    /* surveyor's / shoelace formula */
+	    /* the surveyor should not be too far away (fp precision limit) */
+	    /* surveyor's position: */
+	    Vect_line_box(Points, &box);
+	    sx = (box.W + box.E) / 2.;
+	    sy = (box.S + box.N) / 2.;
+	    x = y = z = 0;
+	    meanx = meany = meanz = 0.;
+	    tot_w = 0.;
+
+	    wci = 0;
+	    Vect_reset_line(CPoints);
+	    xp = Points->x;
+	    yp = Points->y;
+	    for (i = 1; i < Points->n_points; i++) {
+		w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+		    (sx - xp[i]) * (yp[i - 1] - sy);
+		
+		tot_w += w;
+
+		cx = xp[i - 1] + xp[i] + sx;
+		cy = yp[i - 1] + yp[i] + sy;
+		meanx += cx * w;
+		meany += cy * w;
+
+		wc[wci++] = w;
+		Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+	    }
+
+	    for (isle = 0; isle < nisles; isle++) {
+		xp = IPoints[isle]->x;
+		yp = IPoints[isle]->y;
+		for (i = 1; i < IPoints[isle]->n_points; i++) {
+		    w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+			(sx - xp[i]) * (yp[i - 1] - sy);
+
+		    tot_w += w;
+
+		    cx = xp[i - 1] + xp[i] + sx;
+		    cy = yp[i - 1] + yp[i] + sy;
+		    meanx += cx * w;
+		    meany += cy * w;
+
+		    wc[wci++] = w;
+		    Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+		}
+	    }
+	    if (tot_w != 0) {
+		x = meanx / (tot_w * 3);
+		y = meany / (tot_w * 3);
+	    }
+
+	    medx = x;
+	    medy = y;
+
+	    /* update surveyor's point */
+	    sx = x;
+	    sy = y;
+
+	    x = y = z = 0;
+	    meanx = meany = meanz = 0.;
+	    tot_w = 0.;
+
+	    wci = 0;
+	    Vect_reset_line(CPoints);
+	    xp = Points->x;
+	    yp = Points->y;
+	    for (i = 1; i < Points->n_points; i++) {
+		w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+		    (sx - xp[i]) * (yp[i - 1] - sy);
+		
+		tot_w += w;
+
+		cx = xp[i - 1] + xp[i] + sx;
+		cy = yp[i - 1] + yp[i] + sy;
+		meanx += cx * w;
+		meany += cy * w;
+
+		wc[wci++] = w;
+		Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+	    }
+
+	    for (isle = 0; isle < nisles; isle++) {
+		xp = IPoints[isle]->x;
+		yp = IPoints[isle]->y;
+		for (i = 1; i < IPoints[isle]->n_points; i++) {
+		    w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+			(sx - xp[i]) * (yp[i - 1] - sy);
+
+		    tot_w += w;
+
+		    cx = xp[i - 1] + xp[i] + sx;
+		    cy = yp[i - 1] + yp[i] + sy;
+		    meanx += cx * w;
+		    meany += cy * w;
+
+		    wc[wci++] = w;
+		    Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+		}
+	    }
+	    if (tot_w != 0) {
+		x = meanx / (tot_w * 3);
+		y = meany / (tot_w * 3);
+	    }
+
+	    lastdist2all = -1;
+
+	    G_debug(3, "Approximating geometric median...");
+	    /* depends on the location of the surveyor
+	     * why? */
+
+	    for (iter = 0; iter < maxiter; iter++) {
+
+		distsum = dist2all = 0.;
+		x = y = z = 0.;
+
+		for (j = 0; j < CPoints->n_points; j++) {
+
+		    dx = CPoints->x[j] - medx;
+		    dy = CPoints->y[j] - medy;
+		    dist = sqrt(dx * dx + dy * dy);
+
+		    if (dist) {
+			w = wc[j] / dist;
+			x += CPoints->x[j] * w;
+			y += CPoints->y[j] * w;
+
+			distsum += w;
+		    }
+		    if (wc[j])
+			dist2all += dist / fabs(wc[j]);
+		}
+		
+		if (distsum) {
+		    x /= distsum;
+		    y /= distsum;
+		}
+
+		G_debug(3, "dist2all: %.15g", dist2all);
+		G_debug(3, "lastdist2all: %.15g", lastdist2all);
+		if (lastdist2all > 0) {
+		    double d = d_ulp(lastdist2all);
+		    
+		    if (lastdist2all - dist2all < d)
+			break;
+		}
+		if (dist2all == 0.)
+		    break;
+
+		lastdist2all = dist2all;
+
+		medx = x;
+		medy = y;
+
+		/* update surveyor's point */
+		sx = x;
+		sy = y;
+
+		x = y = z = 0;
+		meanx = meany = meanz = 0.;
+		tot_w = 0.;
+
+		wci = 0;
+		Vect_reset_line(CPoints);
+		xp = Points->x;
+		yp = Points->y;
+		for (i = 1; i < Points->n_points; i++) {
+		    w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+			(sx - xp[i]) * (yp[i - 1] - sy);
+		    
+		    tot_w += w;
+
+		    cx = xp[i - 1] + xp[i] + sx;
+		    cy = yp[i - 1] + yp[i] + sy;
+		    meanx += cx * w;
+		    meany += cy * w;
+
+		    wc[wci++] = w;
+		    Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+		}
+
+		for (isle = 0; isle < nisles; isle++) {
+		    xp = IPoints[isle]->x;
+		    yp = IPoints[isle]->y;
+		    for (i = 1; i < IPoints[isle]->n_points; i++) {
+			w = (sx - xp[i - 1]) * (yp[i] - sy) - 
+			    (sx - xp[i]) * (yp[i - 1] - sy);
+
+			tot_w += w;
+
+			cx = xp[i - 1] + xp[i] + sx;
+			cy = yp[i - 1] + yp[i] + sy;
+			meanx += cx * w;
+			meany += cy * w;
+
+			wc[wci++] = w;
+			Vect_append_point(CPoints, cx / 3., cy / 3., 0);
+		    }
+		}
+		if (tot_w != 0) {
+		    x = meanx / (tot_w * 3);
+		    y = meany / (tot_w * 3);
+		}
+	    }
+	    G_debug(3, "Iteration converged after %d passes, dist = %.15g",
+		    iter, lastdist2all);
+
+	    x = medx;
+	    y = medy;
+
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, 0);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "8|%.15g|%.15g|%.15g\n", x, y, 0.);
+
+	    G_percent(area, nareas, 4);
+	}
+    }
+
+    /* approximate geometric median with Weiszfeld's algorithm:
+     * iterative least squares reduction */
+    if (mode & A_MEDIAN_B) {
+	struct line_pnts *CPoints;
+	double cx, cy, dx, dy;
+	double medx, medy;
+	double *wb, tot_w;
+	int nw, nw_alloc, wi;
+	double dist, distsum, dist2all, lastdist2all;
+	int j, iter, maxiter = 1000;
+
+	G_message(_("Calculating geometric medians for areas..."));
+	
+	CPoints = Vect_new_line_struct();
+	
+	nw_alloc = 100;
+	wb = G_malloc(nw_alloc * sizeof(double));
+	
+	G_percent(0, nareas, 4);
+
+	for (area = 1; area <= nareas; area++) {
+
+	    Vect_reset_cats(Cats);
+	    if (layer > 1) {
+		Vect_get_area_cats(In, area, Cats);
+	        if (!Vect_cats_in_constraint(Cats, layer, cat_list))
+		    continue;
+	    }
+
+	    Vect_get_area_points(In, area, Points);
+	    Vect_line_prune(Points);
+	    nw = Points->n_points - 1;
+	    
+	    nisles = Vect_get_area_num_isles(In, area);
+	    if (nisles > nisles_alloc) {
+		IPoints = G_realloc(IPoints, nisles * sizeof (struct line_pnts *));
+		for (isle = nisles_alloc; isle < nisles; isle++) {
+		    IPoints[isle] = Vect_new_line_struct();
+		}
+		nisles_alloc = nisles;
+	    }
+	    for (isle = 1; isle < nisles; isle++) {
+		Vect_get_isle_points(In, isle, IPoints[isle - 1]);
+		Vect_line_prune(IPoints[isle - 1]);
+		nw += IPoints[isle - 1]->n_points - 1;
+	    }
+
+	    if (nw_alloc < nw) {
+		nw_alloc = nw;
+		wb = G_realloc(wb, nw_alloc * sizeof(double));
+	    }
+
+	    /* segment lengths */
+	    meanx = meany = 0.;
+	    tot_w = 0.;
+	    wi = 0;
+	    Vect_reset_line(CPoints);
+	    xp = Points->x;
+	    yp = Points->y;
+	    for (i = 1; i < Points->n_points; i++) {
+		dx = xp[i] - xp[i - 1];
+		dy = yp[i] - yp[i - 1];
+		w = sqrt(dx * dx + dy * dy);
+
+		cx = xp[i - 1] + xp[i];
+		meanx += cx * w;
+		cy = yp[i - 1] + yp[i];
+		meany += cy * w;
+
+		wb[wi++] = w;
+		tot_w += w;
+
+		Vect_append_point(CPoints, cx / 2., cy / 2., 0);
+	    }
+
+	    for (isle = 0; isle < nisles; isle++) {
+		xp = IPoints[isle]->x;
+		yp = IPoints[isle]->y;
+		for (i = 1; i < IPoints[isle]->n_points; i++) {
+		    dx = xp[i] - xp[i - 1];
+		    dy = yp[i] - yp[i - 1];
+		    w = sqrt(dx * dx + dy * dy);
+
+		    cx = xp[i - 1] + xp[i];
+		    meanx += cx * w;
+		    cy = yp[i - 1] + yp[i];
+		    meany += cy * w;
+
+		    wb[wi++] = w;
+		    tot_w += w;
+
+		    Vect_append_point(CPoints, cx / 2., cy / 2., 0);
+		}
+	    }
+	    if (tot_w != 0) {
+		meanx /= (tot_w * 2);
+		meany /= (tot_w * 2);
+	    }
+
+	    medx = meanx;
+	    medy = meany;
+
+	    G_debug(3, "Approximating geometric median...");
+
+	    lastdist2all = -1;
+	    for (iter = 0; iter < maxiter; iter++) {
+
+		distsum = dist2all = 0.;
+		x = y = z = 0.;
+
+		for (j = 0; j < CPoints->n_points; j++) {
+
+		    dx = CPoints->x[j] - medx;
+		    dy = CPoints->y[j] - medy;
+		    dist = sqrt(dx * dx + dy * dy);
+
+		    if (dist) {
+			w = wb[j] / dist;
+			x += CPoints->x[j] * w;
+			y += CPoints->y[j] * w;
+
+			distsum += w;
+		    }
+		    if (wb[j])
+			dist2all += dist / wb[j];
+		}
+		
+		if (distsum) {
+		    x /= distsum;
+		    y /= distsum;
+		}
+
+		G_debug(3, "dist2all: %.15g", dist2all);
+		G_debug(3, "lastdist2all: %.15g", lastdist2all);
+		if (lastdist2all > 0) {
+		    double d = d_ulp(lastdist2all);
+		    
+		    if (lastdist2all - dist2all < d)
+			break;
+		}
+		if (dist2all == 0.)
+		    break;
+
+		lastdist2all = dist2all;
+
+		medx = x;
+		medy = y;
+	    }
+	    G_debug(3, "Iteration converged after %d passes, dist = %.15g",
+		    iter, lastdist2all);
+
+	    x = meanx;
+	    y = meany;
+
+	    x = medx;
+	    y = medy;
+
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, 0);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "9|%.15g|%.15g|%.15g\n", x, y, 0.);
+
+	    G_percent(area, nareas, 4);
+	}
+    }
+
+    return 1;
+}


Property changes on: grass-addons/grass7/vector/v.centerpoint/areas.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/lines.c
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/lines.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/lines.c	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,258 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+static double d_ulp(double d)
+{
+    int exp;
+
+    if (d == 0)
+	return GRASS_EPSILON;
+
+    d = frexp(d, &exp);
+    exp -= 51;
+    d = ldexp(d, exp);
+
+    return d;
+}
+
+int lines_center(struct Map_info *In, struct Map_info *Out, int layer, 
+                 struct cat_list *cat_list, int n_primitives, int mode)
+{
+    struct line_pnts *Points, *OPoints;
+    struct line_cats *Cats;
+    double x, y, z;
+    int type;
+    int counter;
+
+    Points = Vect_new_line_struct();
+    OPoints = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    /* mid point */
+    if (mode & L_MID) {
+	double len;
+
+	counter = 0;
+
+	Vect_rewind(In);
+	while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+	    G_percent(counter, n_primitives, 4);
+	    counter++;
+
+	    if (!(type & GV_LINE))
+		continue;
+	    if (layer > 0 &&
+	        !Vect_cats_in_constraint(Cats, layer, cat_list))
+		continue;
+
+	    Vect_line_prune(Points);
+
+	    len = Vect_line_length(Points) / 2.;
+	    
+	    Vect_point_on_line(Points, len, &x, &y, &z, NULL, NULL);
+	    
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, z);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "4|%.15g|%.15g|%.15g\n", x, y, z);
+	}
+	G_percent(1, 1, 1);
+    }
+    
+    /* center of gravity */
+    if (mode & L_MEAN) {
+	double len, slen;
+	double dx, dy, dz;
+	int i;
+
+	counter = 0;
+
+	Vect_rewind(In);
+	while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+	    G_percent(counter, n_primitives, 4);
+	    counter++;
+	    if (!(type & GV_LINE))
+		continue;
+	    if (layer > 0 &&
+	        !Vect_cats_in_constraint(Cats, layer, cat_list))
+		continue;
+
+	    Vect_line_prune(Points);
+
+	    len = 0.;
+	    
+	    x = y = z = 0.;
+
+	    for (i = 1; i < Points->n_points; i++) {
+		dx = Points->x[i - 1] - Points->x[i];
+		dy = Points->y[i - 1] - Points->y[i];
+		dz = Points->z[i - 1] - Points->z[i];
+		
+		slen = sqrt(dx * dx + dy * dy + dz * dz);
+		
+		x += (Points->x[i - 1] + Points->x[i]) * slen;
+		y += (Points->y[i - 1] + Points->y[i]) * slen;
+		z += (Points->z[i - 1] + Points->z[i]) * slen;
+		
+		len += slen;
+	    }
+	    
+	    x /= (len * 2);
+	    y /= (len * 2);
+	    z /= (len * 2);
+
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, z);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "5|%.15g|%.15g|%.15g\n", x, y, z);
+	}
+	G_percent(1, 1, 1);
+    }
+
+    /* approximate geometric median with Weiszfeld's algorithm:
+     * iterative least squares reduction */
+    if (mode & L_MEDIAN) {
+	struct line_pnts *SPoints;
+	double *len;
+	double dx, dy, dz;
+	double xmean, ymean, zmean;
+	double medx, medy, medz;
+	double dist, distsum, dist2all, lastdist2all;
+	int i, j, iter, maxiter = 100;
+	
+	SPoints = Vect_new_line_struct();
+
+	counter = 0;
+
+	Vect_rewind(In);
+	while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+	    G_percent(counter, n_primitives, 4);
+	    counter++;
+	    if (!(type & GV_LINE))
+		continue;
+	    if (layer > 0 &&
+	        !Vect_cats_in_constraint(Cats, layer, cat_list))
+		continue;
+
+	    Vect_line_prune(Points);
+	    
+	    len = G_malloc((Points->n_points - 1) * sizeof(double));
+	    Vect_reset_line(SPoints);
+	    
+	    xmean = ymean = zmean = 0.;
+	    
+	    for (i = 0; i < Points->n_points - 1; i++) {
+		dx = Points->x[i + 1] - Points->x[i];
+		dy = Points->y[i + 1] - Points->y[i];
+		dz = Points->z[i + 1] - Points->z[i];
+		
+		len[i] = sqrt(dx * dx + dy * dy + dz * dz);
+
+		x = (Points->x[i + 1] + Points->x[i]) / 2.;
+		y = (Points->y[i + 1] + Points->y[i]) / 2.;
+		z = (Points->z[i + 1] + Points->z[i]) / 2.;
+		
+		Vect_append_point(SPoints, x, y, z);
+		
+		xmean += Points->x[i];
+		ymean += Points->y[i];
+		zmean += Points->z[i];
+	    }
+	    
+	    i = Points->n_points - 1;
+	    xmean += Points->x[i];
+	    ymean += Points->y[i];
+	    zmean += Points->z[i];
+	    
+	    xmean /= Points->n_points;
+	    ymean /= Points->n_points;
+	    zmean /= Points->n_points;
+
+	    medx = xmean;
+	    medy = ymean;
+	    medz = zmean;
+
+	    lastdist2all = -1;
+
+	    G_debug(3, "Approximating geometric median...");
+
+	    for (iter = 0; iter < maxiter; iter++) {
+
+		distsum = dist2all = 0.;
+		x = y = z = 0.;
+
+		for (j = 0; j < SPoints->n_points; j++) {
+
+		    dx = SPoints->x[j] - medx;
+		    dy = SPoints->y[j] - medy;
+		    dz = SPoints->z[j] - medz;
+		    dist = sqrt(dx * dx + dy * dy + dz * dz);
+		    
+		    if (dist) {
+			x += SPoints->x[j] * len[j] / dist;
+			y += SPoints->y[j] * len[j] / dist;
+			z += SPoints->z[j] * len[j] / dist;
+
+			distsum += len[j] / dist;
+			dist2all += dist;
+		    }
+		    if (len[j])
+			dist2all += dist / len[j];
+		}
+		
+		if (distsum) {
+		    x /= distsum;
+		    y /= distsum;
+		    z /= distsum;
+		}
+
+		G_debug(3, "dist2all: %.15g", dist2all);
+		G_debug(3, "lastdist2all: %.15g", lastdist2all);
+		if (lastdist2all > 0) {
+		    double d = d_ulp(lastdist2all);
+		    
+		    if (lastdist2all - dist2all < d)
+			break;
+		}
+		if (dist2all == 0.)
+		    break;
+
+		lastdist2all = dist2all;
+
+		medx = x;
+		medy = y;
+		medz = z;
+	    }
+	    G_debug(3, "Iteration converged after %d passes, dist = %.15g",
+		    iter, lastdist2all);
+
+	    G_free(len);
+
+	    x = medx;
+	    y = medy;
+	    z = medz;
+
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, z);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "6|%.15g|%.15g|%.15g\n", x, y, z);
+	}
+	G_percent(1, 1, 1);
+    }
+
+    return 1;
+}


Property changes on: grass-addons/grass7/vector/v.centerpoint/lines.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/local_proto.h
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/local_proto.h	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/local_proto.h	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,18 @@
+#define P_MEAN		0x001
+#define P_MEDIAN	0x002
+#define P_MEDIAN_P	0x004
+#define L_MID		0x008
+#define L_MEAN		0x010
+#define L_MEDIAN	0x020
+#define A_MEAN		0x040
+#define A_MEDIAN	0x080
+#define A_MEDIAN_B	0x100
+
+int points_center(struct Map_info *, struct Map_info *, int, 
+                  struct cat_list *, int, int);
+
+int lines_center(struct Map_info *, struct Map_info *, int, 
+                 struct cat_list *, int, int);
+
+int areas_center(struct Map_info *, struct Map_info *, int, 
+                 struct cat_list *, int);


Property changes on: grass-addons/grass7/vector/v.centerpoint/local_proto.h
___________________________________________________________________
Added: svn:mime-type
   + text/x-chdr
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/main.c
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/main.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/main.c	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,260 @@
+
+/****************************************************************
+ *
+ * MODULE:     v.centerpoint
+ *
+ * AUTHOR(S):  GRASS Development Team, Radim Blazek, Maris Nartiss
+ *
+ * PURPOSE:    copies vector data from source map to destination map
+ *             prints out all point coordinates and atributes
+ *
+ * COPYRIGHT:  (C) 2002-2009 by the GRASS Development Team
+ *
+ *             This program is free software under the
+ *             GNU General Public License (>=v2).
+ *             Read the file COPYING that comes with GRASS
+ *             for details.
+ *
+ ****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+int main(int argc, char *argv[])
+{
+    struct Map_info In, Out, *Outp;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    int i, type, out3d;
+    char *mapset;
+    struct GModule *module;	/* GRASS module for parsing arguments */
+    struct Option *old, *new, *type_opt, *lyr_opt, *cats_opt, *where_opt;
+    struct Option *pmode, *lmode, *amode;
+    struct Flag *topo_flag;
+    char *pdesc, *ldesc, *adesc;
+    struct cat_list *cat_list = NULL;
+    int layer, itype;
+    int nprimitives, npoints, nlines;
+    int mode;
+
+    /* initialize GIS environment */
+    /* reads grass env, stores program name to G_program_name() */
+    G_gisinit(argv[0]);
+
+    /* initialize module */
+    module = G_define_module();
+    G_add_keyword(_("vector"));
+    G_add_keyword(_("geometry"));
+    G_add_keyword(_("center"));
+    module->description = _("Calculate center points");
+
+    /* Define the different options as defined in gis.h */
+    old = G_define_standard_option(G_OPT_V_INPUT);
+
+    new = G_define_standard_option(G_OPT_V_OUTPUT);
+    new->required = NO;
+
+    type_opt = G_define_standard_option(G_OPT_V_TYPE);
+    type_opt->options = "point,line,area";
+    type_opt->answer = "point,line,area";
+    type_opt->guisection = _("Selection");
+
+    lyr_opt = G_define_standard_option(G_OPT_V_FIELD_ALL);
+    lyr_opt->guisection = _("Selection");
+
+    cats_opt = G_define_standard_option(G_OPT_V_CATS);
+    cats_opt->guisection = _("Selection");
+
+    where_opt = G_define_standard_option(G_OPT_DB_WHERE);
+    where_opt->guisection = _("Selection");
+
+    pmode = G_define_option();
+    pmode->type = TYPE_STRING;
+    pmode->key = "pcenter";
+    pmode->label = _("point center");
+    pmode->multiple = YES;
+    pmode->options = "mean,median,pmedian";
+    pmode->answer = "mean";
+    pdesc = NULL;
+    G_asprintf(&pdesc,
+	       "mean;%s;"
+	       "median;%s;"
+	       "pmedian;%s;",
+	       _("Geometric mean (center of gravity)"),
+	       _("Geometric median"),
+	       _("Point closest to geometric median"));
+    pmode->descriptions = pdesc;
+
+    lmode = G_define_option();
+    lmode->type = TYPE_STRING;
+    lmode->key = "lcenter";
+    lmode->label = _("line center");
+    lmode->multiple = YES;
+    lmode->options = "mid,mean,median";
+    lmode->answer = "mid";
+    ldesc = NULL;
+    G_asprintf(&ldesc,
+	       "mid;%s;"
+	       "mean;%s;"
+	       "median;%s;",
+	       _("Line mid point"),
+	       _("Geometric mean (center of gravity)"),
+	       _("Geometric median using line segments"));
+    lmode->descriptions = ldesc;
+
+    amode = G_define_option();
+    amode->type = TYPE_STRING;
+    amode->key = "acenter";
+    amode->label = _("area center");
+    amode->multiple = YES;
+    amode->options = "mean,median,bmedian";
+    amode->answer = "mean";
+    adesc = NULL;
+    G_asprintf(&adesc,
+	       "mean;%s;"
+	       "median;%s;"
+	       "bmedian;%s;",
+	       _("Geometric mean (center of gravity)"),
+	       _("Geometric median using area sizes"),
+	       _("Geometric median using boundary segments"));
+    amode->descriptions = adesc;
+
+    topo_flag = G_define_standard_flag(G_FLG_V_TOPO);
+
+    /* parse options and flags */
+    if (G_parser(argc, argv))
+	exit(EXIT_FAILURE);
+
+    if (!(itype = Vect_option_to_types(type_opt)))
+	G_fatal_error(_("No feature types selected"));
+    
+    mode = 0;
+    for (i = 0; pmode->answers[i]; i++) {
+	if (!strcmp(pmode->answers[i], "mean"))
+	    mode |= P_MEAN;
+	else if (!strcmp(pmode->answers[i], "median"))
+	    mode |= P_MEDIAN;
+	else if (!strcmp(pmode->answers[i], "pmedian"))
+	    mode |= P_MEDIAN_P;
+	else
+	    G_fatal_error(_("Invalid answer '%s' for option '%s'"),
+	                  pmode->answers[i], pmode->key);
+    }
+    for (i = 0; lmode->answers[i]; i++) {
+	if (!strcmp(lmode->answers[i], "mid"))
+	    mode |= L_MID;
+	else if (!strcmp(lmode->answers[i], "mean"))
+	    mode |= L_MEAN;
+	else if (!strcmp(lmode->answers[i], "median"))
+	    mode |= L_MEDIAN;
+	else
+	    G_fatal_error(_("Invalid answer '%s' for option '%s'"),
+	                  lmode->answers[i], lmode->key);
+    }
+    for (i = 0; amode->answers[i]; i++) {
+	if (!strcmp(amode->answers[i], "mean"))
+	    mode |= A_MEAN;
+	else if (!strcmp(amode->answers[i], "median"))
+	    mode |= A_MEDIAN;
+	else if (!strcmp(amode->answers[i], "bmedian"))
+	    mode |= A_MEDIAN_B;
+	else
+	    G_fatal_error(_("Invalid answer '%s' for option '%s'"),
+	                  amode->answers[i], amode->key);
+    }
+
+    if ((mapset = (char *)G_find_vector2(old->answer, "")) == NULL)
+	G_fatal_error(_("Vector map <%s> not found"), old->answer);
+
+    Vect_set_open_level(1);
+
+    if (1 > Vect_open_old(&In, old->answer, mapset))
+	G_fatal_error(_("Unable to open vector map <%s>"), old->answer);
+
+    layer = -1;
+    if (lyr_opt->answer)
+	layer = Vect_get_field_number(&In, lyr_opt->answer);
+
+    if (layer > 0)
+	cat_list = Vect_cats_set_constraint(&In, layer, where_opt->answer,
+                                            cats_opt->answer);
+
+    out3d = Vect_is_3d(&In);
+
+    Outp = NULL;
+    if (new->answer) {
+	Vect_check_input_output_name(old->answer, new->answer, G_FATAL_EXIT);
+	Vect_open_new(&Out, new->answer, out3d);
+
+	/* Copy header and history data from old to new map */
+	Vect_copy_head_data(&In, &Out);
+	Vect_hist_copy(&In, &Out);
+	Vect_hist_command(&Out);
+
+	Outp = &Out;
+    }
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    i = 1;
+    nprimitives = npoints = nlines = 0;
+
+    /* count features */
+    while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) {
+
+	nprimitives++;
+
+	if (type == GV_LINE) {
+	    nlines++;
+	}
+	if (type == GV_POINT) {
+	    npoints++;
+	}
+    }
+
+    /* filter feature count */
+    if (!((mode & P_MEAN) | (mode & P_MEDIAN) | (mode & P_MEDIAN_P)))
+	npoints = 0;
+    if (!((mode & L_MID) | (mode & L_MEAN) | (mode & L_MEDIAN)))
+	nlines = 0;
+
+    /* do the work */
+    if (npoints) {
+	points_center(&In, Outp, layer, cat_list, nprimitives, mode);
+    }
+    if (nlines) {
+	lines_center(&In, Outp, layer, cat_list, nprimitives, mode);
+	Vect_copy_tables(&In, &Out, layer);
+    }
+    
+    Vect_close(&In);
+
+    /* areas */
+    if (itype & GV_AREA) {
+	Vect_set_open_level(2);
+
+	if (1 > Vect_open_old(&In, old->answer, mapset))
+	    G_warning(_("Unable to open vector map <%s> with topology"), old->answer);
+	else {
+	    int nareas = Vect_get_num_areas(&In);
+	    
+	    if (nareas)
+		areas_center(&In, Outp, layer, cat_list, mode);
+
+	    Vect_close(&In);
+	}
+    }
+
+    if (Outp) {
+	if (!topo_flag->answer)
+	    Vect_build(&Out);
+	Vect_close(&Out);
+    }
+
+    exit(EXIT_SUCCESS);
+}


Property changes on: grass-addons/grass7/vector/v.centerpoint/main.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/points.c
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/points.c	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/points.c	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,227 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+#include "local_proto.h"
+
+static double d_ulp(double d)
+{
+    int exp;
+
+    if (d == 0)
+	return GRASS_EPSILON;
+
+    d = frexp(d, &exp);
+    exp -= 51;
+    d = ldexp(d, exp);
+
+    return d;
+}
+
+int points_center(struct Map_info *In, struct Map_info *Out, int layer, 
+                  struct cat_list *cat_list, int n_primitives, int mode)
+{
+    struct line_pnts *Points, *OPoints;
+    struct line_cats *Cats, *OCats;
+    double xsum, xmean, ysum, ymean, zsum, zmean;
+    double x, y, z;
+    double medx, medy, medz;
+    int type, counter, n;
+    int iter, maxiter = 100;
+
+    Points = Vect_new_line_struct();
+    OPoints = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    OCats = Vect_new_cats_struct();
+
+    Vect_rewind(In);
+
+    /* coordinates' mean */
+    counter = n = 0;
+    xsum = ysum = zsum = 0.;
+    G_message(_("Calculating mean point coordinates (center of gravity)..."));
+    while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+	G_percent(counter, n_primitives, 4);
+	counter++;
+	if (!(type & GV_POINT))
+	    continue;
+	
+	if (layer > 0 && !Vect_cats_in_constraint(Cats, layer, cat_list))
+	    continue;
+
+	xsum += Points->x[0];
+	ysum += Points->y[0];
+	zsum += Points->z[0];
+	n++;
+    }
+    G_percent(1, 1, 1);
+
+    xmean = xsum / n;
+    ymean = ysum / n;
+    zmean = zsum / n;
+
+    if (mode & P_MEAN) {
+	x = xmean;
+	y = ymean;
+	z = zmean;
+
+	if (Out) {
+	    Vect_reset_line(OPoints);
+	    Vect_append_point(OPoints, x, y, z);
+	    Vect_reset_cats(OCats);
+	    Vect_cat_set(OCats, 1, 1);
+	    Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	}
+	else
+	    fprintf(stdout, "1|%.15g|%.15g|%.15g\n", x, y, z);
+    }
+    
+    medx = xmean;
+    medy = ymean;
+    medz = zmean;
+
+    /* approximate geometric median with Weiszfeld's algorithm:
+     * iterative least squares reduction */
+    if ((mode & P_MEDIAN) || (mode & P_MEDIAN_P)) {
+	double dist, distsum, dist2all, lastdist2all;
+	double dx, dy, dz;
+	
+	medx = xmean;
+	medy = ymean;
+	medz = zmean;
+	lastdist2all = -1;
+
+	G_message(_("Approximating geometric median..."));
+
+	for (iter = 0; iter < maxiter; iter++) {
+
+	    G_percent(iter, maxiter, 4);
+
+	    distsum = dist2all = 0.;
+	    x = y = z = 0.;
+
+	    Vect_rewind(In);
+	    while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+		if (!(type & GV_POINT))
+		    continue;
+		if (layer > 0 && 
+		    !Vect_cats_in_constraint(Cats, layer, cat_list))
+		    continue;
+
+		dx = Points->x[0] - medx;
+		dy = Points->y[0] - medy;
+		dz = Points->z[0] - medz;
+		dist = sqrt(dx * dx + dy * dy + dz * dz);
+		
+		if (dist) {
+		    x += Points->x[0] / dist;
+		    y += Points->y[0] / dist;
+		    z += Points->z[0] / dist;
+
+		    distsum += 1 / dist;
+		    dist2all += dist;
+		}
+	    }
+	    
+	    if (distsum) {
+		x /= distsum;
+		y /= distsum;
+		z /= distsum;
+	    }
+
+	    G_debug(3, "dist2all: %.15g", dist2all);
+	    G_debug(3, "lastdist2all: %.15g", lastdist2all);
+	    if (lastdist2all > 0) {
+		double d = d_ulp(lastdist2all);
+		
+		if (lastdist2all - dist2all < d)
+		    break;
+	    }
+	    if (dist2all == 0.)
+		break;
+
+	    lastdist2all = dist2all;
+
+	    medx = x;
+	    medy = y;
+	    medz = z;
+	}
+	G_percent(1, 1, 1);
+	G_message(_("Iteration converged after %d passes, dist = %.15g"),
+	          iter, lastdist2all);
+
+	if (mode & P_MEDIAN) {
+	    x = medx;
+	    y = medy;
+	    z = medz;
+
+	    if (Out) {
+		Vect_reset_line(OPoints);
+		Vect_append_point(OPoints, x, y, z);
+		Vect_reset_cats(OCats);
+		Vect_cat_set(OCats, 1, 2);
+		Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	    }
+	    else
+		fprintf(stdout, "2|%.15g|%.15g|%.15g\n", x, y, z);
+	}
+    }
+
+    /* find point closest to approximated median */
+    if (mode & P_MEDIAN_P) {
+	double dx, dy, dz;
+	double dist, mindist;
+	double xmin, ymin, zmin;
+
+	counter = 0;
+	
+	xmin = medx;
+	ymin = medy;
+	zmin = medz;
+	
+	mindist = -1;
+
+	G_message(_("Searching point closest to approximated median..."));
+
+	Vect_rewind(In);
+	while ((type = Vect_read_next_line(In, Points, Cats)) > 0) {
+	    G_percent(counter, n_primitives, 4);
+	    counter++;
+	    if (!(type & GV_POINT))
+		continue;
+	    if (layer > 0 &&
+	        !Vect_cats_in_constraint(Cats, layer, cat_list))
+		continue;
+
+	    dx = Points->x[0] - medx;
+	    dy = Points->y[0] - medy;
+	    dz = Points->z[0] - medz;
+	    dist = sqrt(dx * dx + dy * dy + dz * dz);
+	    
+	    if (dist < mindist || mindist < 0) {
+		xmin = Points->x[0];
+		ymin = Points->y[0];
+		zmin = Points->z[0];
+		mindist = dist;
+	    }
+	}
+	G_percent(1, 1, 1);
+
+	x = xmin;
+	y = ymin;
+	z = zmin;
+	if (Out) {
+	    Vect_reset_line(OPoints);
+	    Vect_append_point(OPoints, x, y, z);
+	    Vect_reset_cats(OCats);
+	    Vect_cat_set(OCats, 1, 3);
+	    Vect_write_line(Out, GV_POINT, OPoints, Cats);
+	}
+	else
+	    fprintf(stdout, "3|%.15g|%.15g|%.15g\n", x, y, z);
+    }
+
+    return 1;
+}


Property changes on: grass-addons/grass7/vector/v.centerpoint/points.c
___________________________________________________________________
Added: svn:mime-type
   + text/x-csrc
Added: svn:eol-style
   + native

Added: grass-addons/grass7/vector/v.centerpoint/v.centerpoint.html
===================================================================
--- grass-addons/grass7/vector/v.centerpoint/v.centerpoint.html	                        (rev 0)
+++ grass-addons/grass7/vector/v.centerpoint/v.centerpoint.html	2013-09-22 14:40:29 UTC (rev 57812)
@@ -0,0 +1,78 @@
+<h2>DESCRIPTION</h2>
+
+<em>v.centerpoint</em> calculates center points for point clouds, lines 
+and areas. Center points can be geometric means (centers of gravity) or 
+geometric medians, which is more robust in case of outliers.
+<p>
+For points, center points are calculated considering all points. For 
+lines and areas, center points are calculated for each line or area 
+separately.
+<p>
+If no output vector is given, center points are printed to stdout in 
+ASCII point format:
+<div class="code"><pre>
+<cat>|<easting>|<northing>
+</pre></div>
+The category values are
+<ul>
+  <li><b>1</b> - mean of points</li>
+  <li><b>2</b> - median of points</li>
+  <li><b>3</b> - point closest to median of points</li>
+  <li><b>4</b> - mid point of each line</li>
+  <li><b>5</b> - mean of each line</li>
+  <li><b>6</b> - median of each line</li>
+  <li><b>7</b> - mean of each area</li>
+  <li><b>8</b> - median of each area using area triangulation</li>
+  <li><b>9</b> - median of each area using boundaries</li>
+</ul>
+If an output vector is given, center points inherit the categories of 
+the respective lines and areas. For points, the category is set to 1
+
+<h4>Point centers</h4>
+<ul>
+  <li><b>mean</b> - center of gravity, mean of all point coordinates</li>
+  <li><b>median</b> - geometric median, minimum distance to all points</li>
+  <li><b>pmedian</b> - point closest to the geometric median</li>
+</ul>
+
+<h4>Line centers</h4>
+<ul>
+  <li><b>mid</b> - the mid point of each line, lies exactly on the line</li>
+  <li><b>mean</b> - center of gravity, mean of all line segments, might 
+  not lie on the line</li>
+  <li><b>median</b> - geometric median, minimum distance to all line 
+  segments, might not lie on the line</li>
+</ul>
+
+<h4>Area centers</h4>
+<ul>
+  <li><b>mean</b> - center of gravity, calculated using area triangulation</li>
+  <li><b>median</b> - geometric median, minimum distance to area 
+  triangulation, might not lie inside the area</li>
+  <li><b>bmedian</b> - geometric median, minimum distance to boundary 
+  segments, might not lie inside the area</li>
+</ul>
+
+<h2>EXAMPLE</h2>
+
+Calculate center of gravity for the LiDAR point cloud 'elev_lid_bepts' 
+in the North Carolina sample dataset:
+<div class="code"><pre>
+v.centerpoint input=elev_lid_bepts output=elev_lid_bepts_mean
+</pre></div>
+
+<div class="code"><pre>
+v.centerpoint in=urbanarea out=urbanarea_median acenter=median
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="v.centroid.html">v.centroid</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Markus Metz
+
+<p><i>Last changed: $Date$</i>


Property changes on: grass-addons/grass7/vector/v.centerpoint/v.centerpoint.html
___________________________________________________________________
Added: svn:mime-type
   + text/html
Added: svn:keywords
   + Author Date Id
Added: svn:eol-style
   + native



More information about the grass-commit mailing list