23 #include <grass/gis.h>
24 #include <grass/Vect.h>
25 #include <grass/glocale.h>
28 static int sort_new(
const void *pa,
const void *pb);
54 double x,
y,
z, along;
58 static int sort_new2(
const void *pa,
const void *pb)
67 static int add_item(
int id,
struct ilist *list)
74 static int find_item(
int id,
struct ilist *list)
111 double thresh,
struct Map_info *Err)
113 struct line_pnts *Points, *NPoints;
114 struct line_cats *Cats;
115 int line, ltype, line_idx;
120 int nanchors, ntosnap;
121 int nsnapped, ncreated;
122 int apoints, npoints, nvertices;
131 if (List_lines->n_values < 1)
140 thresh2 = thresh * thresh;
149 for (line_idx = 0; line_idx < List_lines->n_values; line_idx++) {
152 G_percent(line_idx, List_lines->n_values, 2);
154 line = List_lines->value[line_idx];
162 for (v = 0; v < Points->n_points; v++) {
163 G_debug(3,
" vertex v = %d", v);
177 G_debug(3,
"List : nvalues = %d", List->n_values);
179 if (List->n_values == 0) {
182 if ((point - 1) == apoints) {
185 (
XPNT *) G_realloc(XPnts,
186 (apoints + 1) *
sizeof(
XPNT));
188 XPnts[
point].
x = Points->x[v];
189 XPnts[
point].
y = Points->y[v];
195 G_percent(line_idx, List_lines->n_values, 2);
204 nanchors = ntosnap = 0;
205 for (point = 1; point <= npoints; point++) {
210 G_debug(3,
" point = %d", point);
212 if (XPnts[point].anchor >= 0)
228 G_debug(4,
" %d points in threshold box", List->n_values);
230 for (i = 0; i < List->n_values; i++) {
232 double dx, dy, dist2;
234 pointb = List->value[i];
238 dx = XPnts[pointb].
x - XPnts[
point].
x;
239 dy = XPnts[pointb].
y - XPnts[
point].
y;
240 dist2 = dx * dx + dy * dy;
246 if (XPnts[pointb].anchor == -1) {
250 else if (XPnts[pointb].anchor > 0) {
253 dx = XPnts[XPnts[pointb].
anchor].
x - XPnts[pointb].
x;
254 dy = XPnts[XPnts[pointb].
anchor].
y - XPnts[pointb].
y;
255 dist2_a = dx * dx + dy * dy;
258 if (dist2 < dist2_a) {
269 nsnapped = ncreated = 0;
273 for (line_idx = 0; line_idx < List_lines->n_values; line_idx++) {
274 int v, spoint, anchor;
277 G_percent(line_idx, List_lines->n_values, 2);
279 line = List_lines->value[line_idx];
287 if (Points->n_points >= aindex) {
288 aindex = Points->n_points;
289 Index = (
int *)G_realloc(Index, aindex *
sizeof(
int));
293 for (v = 0; v < Points->n_points; v++) {
307 spoint = List->value[0];
308 anchor = XPnts[spoint].
anchor;
311 Points->x[v] = XPnts[anchor].
x;
312 Points->y[v] = XPnts[anchor].
y;
326 for (v = 0; v < Points->n_points - 1; v++) {
330 G_debug(3,
" segment = %d end anchors : %d %d", v, Index[v],
334 x2 = Points->x[v + 1];
336 y2 = Points->y[v + 1];
370 G_debug(3,
" %d points in box", List->n_values);
374 for (i = 0; i < List->n_values; i++) {
377 spoint = List->value[i];
378 G_debug(4,
" spoint = %d anchor = %d", spoint,
379 XPnts[spoint].anchor);
381 if (spoint == Index[v] || spoint == Index[v + 1])
383 if (XPnts[spoint].anchor > 0)
389 XPnts[spoint].
y, 0, x1, y1, 0,
393 G_debug(4,
" distance = %lf", sqrt(dist2));
395 if (dist2 <= thresh2) {
396 G_debug(4,
" anchor in thresh, along = %lf", along);
400 New = (
NEW *) G_realloc(New, anew *
sizeof(
NEW));
402 New[nnew].
anchor = spoint;
403 New[nnew].
along = along;
407 G_debug(3,
" nnew = %d", nnew);
411 qsort(New,
sizeof(
char) * nnew,
sizeof(
NEW), sort_new);
413 for (i = 0; i < nnew; i++) {
425 v = Points->n_points - 1;
430 if (NPoints->n_points > 1 || ltype &
GV_LINES) {
441 G_percent(line_idx, List_lines->n_values, 2);
456 static int sort_new(
const void *pa,
const void *pb)
482 struct Map_info *Err)
484 int line, nlines, ltype;
492 for (line = 1; line <= nlines; line++) {
536 struct line_pnts *Points,
double thresh,
537 int *nsnapped,
int *ncreated)
539 struct line_pnts *LPoints, *NPoints;
540 struct line_cats *Cats;
541 int i, v, line, nlines;
548 int apoints, nvertices;
555 struct Node *pnt_tree,
572 point = Points->n_points;
574 if (point != Points->n_points)
577 nlines = reflist->n_values;
588 thresh2 = thresh * thresh;
597 nlines = reflist->n_values;
598 for (i = 0; i < nlines; i++) {
600 line = reflist->value[i];
609 for (v = 0; v < LPoints->n_points; v++) {
610 G_debug(3,
" vertex v = %d", v);
622 G_debug(3,
"List : nvalues = %d", List->n_values);
624 if (List->n_values == 0) {
629 if ((point - 1) == apoints) {
632 (
XPNT *) G_realloc(XPnts,
633 (apoints + 1) *
sizeof(
XPNT));
635 XPnts[
point].
x = LPoints->x[v];
636 XPnts[
point].
y = LPoints->y[v];
645 if (LPoints->x[v - 1] < LPoints->x[v]) {
646 rect.
boundary[0] = LPoints->x[v - 1];
651 rect.
boundary[3] = LPoints->x[v - 1];
653 if (LPoints->y[v - 1] < LPoints->y[v]) {
654 rect.
boundary[1] = LPoints->y[v - 1];
659 rect.
boundary[4] = LPoints->y[v - 1];
666 if ((segment - 1) == asegments) {
669 (
XSEG *) G_realloc(XSegs,
670 (asegments + 1) *
sizeof(
XSEG));
672 XSegs[segment].
x1 = LPoints->x[v - 1];
673 XSegs[segment].
x2 = LPoints->x[v];
674 XSegs[segment].
y1 = LPoints->y[v - 1];
675 XSegs[segment].
y2 = LPoints->y[v];
683 for (v = 0; v < Points->n_points; v++) {
684 double dist2, tmpdist2;
687 dist2 = thresh2 + thresh2;
692 rect.
boundary[0] = Points->x[v] - thresh;
693 rect.
boundary[3] = Points->x[v] + thresh;
694 rect.
boundary[1] = Points->y[v] - thresh;
695 rect.
boundary[4] = Points->y[v] + thresh;
700 RTreeSearch(pnt_tree, &rect, (
void *)add_item, List);
702 for (i = 0; i < List->n_values; i++) {
705 point = List->value[i];
707 dx = Points->x[v] - XPnts[
point].
x;
708 dy = Points->y[v] - XPnts[
point].
y;
710 tmpdist2 = dx * dx + dy * dy;
712 if (tmpdist2 < dist2) {
720 if (dist2 <= thresh2 && dist2 > 0) {
731 for (v = 0; v < Points->n_points; v++) {
732 double dist2, tmpdist2;
735 dist2 = thresh2 + thresh2;
740 rect.
boundary[0] = Points->x[v] - thresh;
741 rect.
boundary[3] = Points->x[v] + thresh;
742 rect.
boundary[1] = Points->y[v] - thresh;
743 rect.
boundary[4] = Points->y[v] + thresh;
748 RTreeSearch(seg_tree, &rect, (
void *)add_item, List);
750 for (i = 0; i < List->n_values; i++) {
754 segment = List->value[i];
767 0, &tmpx, &tmpy,
NULL,
770 if (tmpdist2 < dist2 && status == 0) {
778 if (dist2 <= thresh2 && dist2 > 0) {
793 for (v = 0; v < Points->n_points - 1; v++) {
794 double x1, x2, y1, y2;
798 x2 = Points->x[v + 1];
800 y2 = Points->y[v + 1];
830 RTreeSearch(pnt_tree, &rect, (
void *)add_item, List);
832 G_debug(3,
" %d points in box", List->n_values);
836 for (i = 0; i < List->n_values; i++) {
840 point = List->value[i];
842 if (Points->x[v] == XPnts[i].
x &&
843 Points->y[v] == XPnts[i].
y)
846 if (Points->x[v + 1] == XPnts[i].
x &&
847 Points->y[v + 1] == XPnts[i].
y)
856 NULL, &along, &status);
858 if (dist2 <= thresh2 && status == 0) {
859 G_debug(4,
" anchor in thresh, along = %lf", along);
863 New = (
NEW2 *) G_realloc(New, anew *
sizeof(
NEW2));
865 New[nnew].
x = XPnts[i].
x;
866 New[nnew].
y = XPnts[i].
y;
867 New[nnew].
along = along;
870 G_debug(3,
"dist: %g, thresh: %g", dist2, thresh2);
872 G_debug(3,
" nnew = %d", nnew);
876 qsort(New, nnew,
sizeof(
NEW2), sort_new2);
878 for (i = 0; i < nnew; i++) {
888 v = Points->n_points - 1;
891 if (Points->n_points != NPoints->n_points) {
RectReal boundary[NUMSIDES]
int Vect_destroy_list(struct ilist *list)
Frees all memory associated with a struct ilist, including the struct itself.
void G_free(void *buf)
Free allocated memory.
int dig_list_add(struct ilist *list, int val)
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int RTreeSearch(struct Node *N, struct Rect *R, SearchHitCallback shcb, void *cbarg)
void RTreeDestroyNode(struct Node *)
int Vect_append_points(struct line_pnts *Points, struct line_pnts *APoints, int direction)
Appends points to the end of a line.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
double dig_distance2_point_to_line(double x, double y, double z, double x1, double y1, double z1, double x2, double y2, double z2, int with_z, double *px, double *py, double *pz, double *pdist, int *status)
int RTreeInsertRect(struct Rect *R, int Tid, struct Node **Root, int Level)
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
void Vect_snap_lines(struct Map_info *Map, int type, double thresh, struct Map_info *Err)
Snap lines in vector map to existing vertex in threshold.
int G_percent(long n, long d, int s)
Print percent complete messages.
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
int Vect_rewrite_line(struct Map_info *Map, int line, int type, struct line_pnts *points, struct line_cats *cats)
Rewrites feature info at the given offset.
ITEM * find_item(PAD *pad, const char *name)
void Vect_snap_lines_list(struct Map_info *Map, struct ilist *List_lines, double thresh, struct Map_info *Err)
Snap selected lines to existing vertex in threshold.
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_destroy_cats_struct(struct line_cats *p)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_line_alive(struct Map_info *Map, int line)
Check if feature is alive or dead.
struct line_cats * Vect_new_cats_struct()
Creates and initializes line_cats structure.
int Vect_line_prune(struct line_pnts *Points)
Remove duplicate points, i.e. zero length segments.
int Vect_get_num_lines(struct Map_info *map)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
int G_debug(int level, const char *msg,...)
Print debugging message.
int Vect_delete_line(struct Map_info *Map, int line)
Delete feature.
struct Node * RTreeNewIndex(void)
long Vect_write_line(struct Map_info *Map, int type, struct line_pnts *points, struct line_cats *cats)
Writes new feature to the end of file (table)
int Vect_snap_line(struct Map_info *Map, struct ilist *reflist, struct line_pnts *Points, double thresh, int *nsnapped, int *ncreated)
Snap a line to reference lines in Map with threshold.
int Vect_destroy_line_struct(struct line_pnts *p)
Frees all memory associated with a struct line_pnts, including the struct itself. ...
int Vect_read_line(struct Map_info *Map, struct line_pnts *line_p, struct line_cats *line_c, int line)
Read vector feature.