/*! \file lib/vector/Vlib/overlay.c \brief Vector library - overlays Higher level functions for reading/writing/manipulating vectors. This is file is just example and starting point for writing overlay functions!!! (C) 2001-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. \author Radim Blazek */ #include #include #include int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *, int, struct ilist *, struct ilist *, struct Map_info *); /*! \brief Get operator code from string \param str operator code string \return operator code \return -1 on error */ int Vect_overlay_str_to_operator(const char *str) { if (strcmp(str, GV_ON_AND) == 0) return GV_O_AND; else if (strcmp(str, GV_ON_OVERLAP) == 0) return GV_O_OVERLAP; return -1; } /*! \brief Overlay 2 vector maps and create new one \param AMap vector map A \param atype feature type for A \param AList unused ? \param AAList unused ? \param BMap vector map B \param btype feature type for B \param BList unused ? \param BAList unused ? \param operator operator code \param[out] OMap output vector map \return 0 on success */ int Vect_overlay(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, /* map A */ struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, /* map B */ int operator, struct Map_info *OMap) { /* output map */ switch (operator) { case GV_O_AND: Vect_overlay_and(AMap, atype, AList, AAList, BMap, btype, BList, BAList, OMap); break; default: G_fatal_error("Vect_overlay(): %s", _("unknown operator")); } return 0; } /*! \brief Overlay 2 vector maps with AND. AND supports:point line area point + - + line - - - area + - - \param AMap vector map A \param atype feature type for A \param AList unused ? \param AAList unused ? \param BMap vector map B \param btype feature type for B \param BList unused ? \param BAList unused ? \param OMap output vector map \return 1 on success \return 0 on error */ int Vect_overlay_and(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, struct Map_info *OMap) { int i, j, k, line, altype, bltype, oltype, area, centr; struct line_pnts *Points; struct line_cats *ACats, *BCats, *OCats; struct ilist *AOList, *BOList; struct boxlist *boxlist; struct bound_box box; /* TODO: support Lists */ Points = Vect_new_line_struct(); ACats = Vect_new_cats_struct(); BCats = Vect_new_cats_struct(); OCats = Vect_new_cats_struct(); AOList = Vect_new_list(); BOList = Vect_new_list(); boxlist = Vect_new_boxlist(0); /* TODO: support all types; at present only point x point, area x point and point x area supported */ if ((atype & GV_LINES) || (btype & GV_LINES)) G_warning(_("Overlay: line/boundary types not supported by AND operator")); if ((atype & GV_AREA) && (btype & GV_AREA)) G_warning(_("Overlay: area x area types not supported by AND operator")); /* TODO: more points in one node in one map */ /* point x point: select all points with identical coordinates in both maps */ if ((atype & GV_POINTS) && (btype & GV_POINTS)) { /* both points and centroids */ G_debug(3, "overlay: AND: point x point"); for (i = 1; i <= Vect_get_num_lines(AMap); i++) { altype = Vect_read_line(AMap, Points, ACats, i); if (!(altype & GV_POINTS)) continue; box.E = box.W = Points->x[0]; box.N = box.S = Points->y[0]; box.T = box.B = Points->z[0]; Vect_select_lines_by_box(BMap, &box, GV_POINTS, boxlist); Vect_reset_cats(OCats); for (j = 0; j < boxlist->n_values; j++) { line = boxlist->id[j]; bltype = Vect_read_line(BMap, NULL, BCats, line); if (!(bltype & GV_POINTS)) continue; /* Identical points found -> write out */ /* TODO: do something if fields in ACats and BCats are identical */ for (k = 0; k < ACats->n_cats; k++) Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); for (k = 0; k < BCats->n_cats; k++) Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); /* TODO: what to do if one type is GV_POINT and second GV_CENTROID */ oltype = altype; Vect_write_line(OMap, oltype, Points, OCats); Vect_list_append(AOList, i); /* add to list of written lines */ Vect_list_append(BOList, line); break; } } } /* TODO: check only labeled areas */ /* point x area: select points from A in areas in B */ if ((atype & GV_POINTS) && (btype & GV_AREA)) { /* both points and centroids */ G_debug(3, "overlay: AND: point x area"); for (i = 1; i <= Vect_get_num_lines(AMap); i++) { altype = Vect_read_line(AMap, Points, ACats, i); if (!(altype & GV_POINTS)) continue; area = Vect_find_area(BMap, Points->x[0], Points->y[0]); if (area == 0) continue; Vect_reset_cats(OCats); /* TODO: do something if fields in ACats and BCats are identical */ for (k = 0; k < ACats->n_cats; k++) Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); centr = Vect_get_area_centroid(BMap, area); if (centr > 0) { bltype = Vect_read_line(BMap, NULL, BCats, centr); for (k = 0; k < BCats->n_cats; k++) Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); } /* Check if not yet written */ if (!(Vect_val_in_list(AOList, i))) { Vect_write_line(OMap, altype, Points, OCats); Vect_list_append(AOList, i); } } } /* area x point: select points from B in areas in A */ if ((btype & GV_POINTS) && (atype & GV_AREA)) { /* both points and centroids */ G_debug(3, "overlay: AND: area x point"); for (i = 1; i <= Vect_get_num_lines(BMap); i++) { bltype = Vect_read_line(BMap, Points, BCats, i); if (!(bltype & GV_POINTS)) continue; area = Vect_find_area(AMap, Points->x[0], Points->y[0]); if (area == 0) continue; Vect_reset_cats(OCats); /* TODO: do something if fields in ACats and BCats are identical */ for (k = 0; k < BCats->n_cats; k++) Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); centr = Vect_get_area_centroid(AMap, area); if (centr > 0) { altype = Vect_read_line(AMap, NULL, ACats, centr); for (k = 0; k < ACats->n_cats; k++) Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); } /* Check if not yet written */ if (!(Vect_val_in_list(BOList, i))) { Vect_write_line(OMap, bltype, Points, OCats); Vect_list_append(BOList, i); } } } Vect_destroy_line_struct(Points); Vect_destroy_cats_struct(ACats); Vect_destroy_cats_struct(BCats); Vect_destroy_cats_struct(OCats); Vect_destroy_list(AOList); Vect_destroy_list(BOList); Vect_destroy_boxlist(boxlist); return 0; }