25#include <grass/kdtree.h>
47static int sort_new(
const void *
pa,
const void *pb)
52 return (
p1->along < p2->along ? -1 : (
p1->along > p2->along));
64 double x, y, z, along;
68static int sort_new2(
const void *
pa,
const void *pb)
70 NEW2 *
p1 = (NEW2 *)
pa;
71 NEW2 *p2 = (NEW2 *)pb;
73 return (
p1->along < p2->along ? -1 : (
p1->along > p2->along));
93static int find_item_box(
int id,
const struct RTree_Rect *rect,
void *
list)
111static int add_item_box(
int id,
const struct RTree_Rect *rect,
void *
list)
127static void Vect_snap_lines_list_rtree(
struct Map_info *,
const struct ilist *,
130static void Vect_snap_lines_list_kdtree(
struct Map_info *,
const struct ilist *,
173 if (
getenv(
"GRASS_VECTOR_LOWMEM"))
179static void Vect_snap_lines_list_kdtree(
struct Map_info *
Map,
236 for (v = 0; v < Points->
n_points; v++) {
238 G_debug(3,
" vertex v = %d", v);
251 XPnts[point].x = Points->
x[v];
252 XPnts[point].y = Points->
y[v];
253 XPnts[point].anchor = -1;
267 for (point = 1; point <= npoints; point++) {
272 G_debug(3,
" point = %d", point);
274 if (
XPnts[point].anchor >= 0)
277 XPnts[point].anchor = 0;
280 c[0] =
XPnts[point].x;
281 c[1] =
XPnts[point].y;
289 double dx, dy, dist2;
297 dist2 = dx * dx + dy * dy;
356 G_debug(3,
"Snap all vertices");
357 for (v = 0; v < Points->
n_points; v++) {
373 Points->
x[v] =
XPnts[anchor].x;
374 Points->
y[v] =
XPnts[anchor].y;
388 G_debug(3,
"Snap all segments");
389 for (v = 0; v < Points->
n_points - 1; v++) {
391 double x1, x2, y1, y2, xmin, xmax, ymin, ymax;
394 G_debug(3,
" segment = %d end anchors : %d %d", v,
Index[v],
398 x2 = Points->
x[v + 1];
400 y2 = Points->
y[v + 1];
425 G_debug(3,
" search anchors for segment %g,%g to %g,%g", x1, y1,
462 if (status == 0 && dist2 <=
thresh2) {
463 G_debug(4,
" anchor in thresh, along = %lf", along);
483 for (i = 0; i <
nnew; i++) {
484 anchor =
New[i].anchor;
527static void Vect_snap_lines_list_rtree(
struct Map_info *
Map,
564 if (
getenv(
"GRASS_VECTOR_LOWMEM")) {
572 if (
remove(filename) != 0) {
573 G_warning(
_(
"Unable to remove temporary file <%s>: %s"), filename,
602 for (v = 0; v < Points->
n_points; v++) {
603 G_debug(3,
" vertex v = %d", v);
618 if (
List->n_values == 0) {
626 XPnts[point].x = Points->
x[v];
627 XPnts[point].y = Points->
y[v];
628 XPnts[point].anchor = -1;
642 for (point = 1; point <= npoints; point++) {
647 G_debug(3,
" point = %d", point);
649 if (
XPnts[point].anchor >= 0)
652 XPnts[point].anchor = 0;
664 G_debug(4,
" %d points in threshold box",
List->n_values);
666 for (i = 0; i <
List->n_values; i++) {
668 double dx, dy, dist2;
676 dist2 = dx * dx + dy * dy;
730 for (v = 0; v < Points->
n_points; v++) {
748 Points->
x[v] =
XPnts[anchor].x;
749 Points->
y[v] =
XPnts[anchor].y;
763 for (v = 0; v < Points->
n_points - 1; v++) {
765 double x1, x2, y1, y2, xmin, xmax, ymin, ymax;
767 G_debug(3,
" segment = %d end anchors : %d %d", v,
Index[v],
771 x2 = Points->
x[v + 1];
773 y2 = Points->
y[v + 1];
811 for (i = 0; i <
List->n_values; i++) {
831 if (status == 0 && dist2 <=
thresh2) {
832 G_debug(4,
" anchor in thresh, along = %lf", along);
849 for (i = 0; i <
nnew; i++) {
850 anchor =
New[i].anchor;
910 int line, nlines,
ltype;
918 for (line = 1; line <= nlines; line++) {
966 int i, v, line, nlines;
1011 with_z = (with_z != 0);
1019 point = segment = 1;
1025 for (i = 0; i < nlines; i++) {
1029 G_debug(3,
"line = %d", line);
1036 for (v = 0; v <
LPoints->n_points; v++) {
1037 G_debug(3,
" vertex v = %d", v);
1052 G_debug(3,
"List : nvalues = %d",
List->n_values);
1054 if (
List->n_values == 0) {
1112 for (v = 0; v < Points->
n_points; v++) {
1135 for (i = 0; i <
List->n_values; i++) {
1136 double dx =
List->box[i].E - Points->
x[v];
1137 double dy =
List->box[i].N - Points->
y[v];
1141 dz =
List->box[i].T - Points->
z[v];
1143 tmpdist2 = dx * dx + dy * dy + dz * dz;
1167 for (v = 0; v < Points->
n_points; v++) {
1190 for (i = 0; i <
List->n_values; i++) {
1191 double x1, y1, z1, x2, y2, z2;
1195 segment =
List->id[i];
1198 x1 =
List->box[i].W;
1199 x2 =
List->box[i].E;
1202 x1 =
List->box[i].E;
1203 x2 =
List->box[i].W;
1206 y1 =
List->box[i].S;
1207 y2 =
List->box[i].N;
1210 y1 =
List->box[i].N;
1211 y2 =
List->box[i].S;
1214 z1 =
List->box[i].B;
1215 z2 =
List->box[i].T;
1218 z1 =
List->box[i].T;
1219 z2 =
List->box[i].B;
1224 Points->
x[v], Points->
y[v], Points->
z[v], x1, y1, z1, x2, y2,
1227 if (
tmpdist2 < dist2 && status == 0) {
1252 for (v = 0; v < Points->
n_points - 1; v++) {
1253 double x1, x2, y1, y2, z1, z2;
1254 double xmin, xmax, ymin, ymax, zmin, zmax;
1257 x2 = Points->
x[v + 1];
1259 y2 = Points->
y[v + 1];
1262 z2 = Points->
z[v + 1];
1311 for (i = 0; i <
List->n_values; i++) {
1312 double dist2, along;
1318 if (Points->
x[v] ==
List->box[i].E &&
1319 Points->
y[v] ==
List->box[i].N &&
1320 Points->
z[v] ==
List->box[i].T)
1323 if (Points->
x[v + 1] ==
List->box[i].E &&
1324 Points->
y[v + 1] ==
List->box[i].N &&
1325 Points->
z[v + 1] ==
List->box[i].T)
1330 List->box[i].E,
List->box[i].N,
List->box[i].T, x1, y1, z1, x2,
1333 if (dist2 <=
thresh2 && status == 0) {
1334 G_debug(4,
" anchor in thresh, along = %lf", along);
1354 for (i = 0; i <
nnew; i++) {
void Vect_snap_lines_list(struct Map_info *Map, const struct ilist *List_lines, double thresh, struct Map_info *Err)
Snap selected lines to existing vertex in threshold.
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 Vect_snap_line(struct Map_info *Map, struct ilist *reflist, struct line_pnts *Points, double thresh, int with_z, int *nsnapped, int *ncreated)
Snap a line to reference lines in Map with threshold.
void G_percent(long, long, int)
Print percent complete messages.
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
void void G_verbose_message(const char *,...) __attribute__((format(printf
char * G_tempfile(void)
Returns a temporary file name.
void void void G_important_message(const char *,...) __attribute__((format(printf
void G_ilist_add(struct ilist *, int)
Add item to ilist.
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *, const struct line_cats *)
Rewrites existing feature (topological level required)
int Vect_reset_boxlist(struct boxlist *)
Reset boxlist structure.
plus_t Vect_get_num_lines(struct Map_info *)
Fetch number of features (points, lines, boundaries, centroids) in vector map.
struct boxlist * Vect_new_boxlist(int)
Creates and initializes a struct boxlist.
void Vect_destroy_boxlist(struct boxlist *)
Frees all memory associated with a struct boxlist, including the struct itself.
void Vect_destroy_list(struct ilist *)
Frees all memory associated with a struct ilist, including the struct itself.
void Vect_destroy_cats_struct(struct line_cats *)
Frees all memory associated with line_cats structure, including the struct itself.
int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *, int)
Read vector feature (topological level required)
int Vect_line_alive(struct Map_info *, int)
Check if feature is alive or dead (topological level required)
int Vect_delete_line(struct Map_info *, off_t)
Delete existing feature (topological level required)
struct line_cats * Vect_new_cats_struct(void)
Creates and initializes line_cats structure.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *, const struct line_cats *)
Writes a new feature.
void Vect_reset_line(struct line_pnts *)
Reset line.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_reset_list(struct ilist *)
Reset ilist structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
int Vect_append_points(struct line_pnts *, const struct line_pnts *, int)
Appends points to the end of a line.
#define GV_FORWARD
Line direction indicator forward/backward.
double dig_distance2_point_to_line(double, double, double, double, double, double, double, double, double, int, double *, double *, double *, double *, int *)
int dig_boxlist_add(struct boxlist *, int, const struct bound_box *)
Header file for msvc/fcntl.c.
#define G_UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
int kdtree_rnn(struct kdtree *t, double *c, int **puid, int *skip)
struct kdtree * kdtree_create(char ndims, int *btol)
int kdtree_insert(struct kdtree *t, double *c, int uid, int dc)
int kdtree_knn(struct kdtree *t, double *c, int *uid, double *d, int k, int *skip)
void kdtree_destroy(struct kdtree *t)
int kdtree_dnn(struct kdtree *t, double *c, int **puid, double **pd, double maxdist, int *skip)
List of bounding boxes with id.
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.
double * z
Array of Z coordinates.
void RTreeSetOverflow(struct RTree *t, char overflow)
Enable/disable R*-tree forced reinsertion (overflow)
struct RTree * RTreeCreateTree(int fd, off_t rootpos, int ndims)
Create new empty R*-Tree.
int RTreeInsertRect(struct RTree_Rect *r, int tid, struct RTree *t)
Insert an item into a R*-Tree.
void RTreeDestroyTree(struct RTree *t)
Destroy an R*-Tree.
int RTreeSearch(struct RTree *t, struct RTree_Rect *r, SearchHitCallback *shcb, void *cbarg)
Search an R*-Tree.