123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- #include <stdlib.h>
- #include <grass/gis.h>
- #include <grass/vector.h>
- #include <grass/glocale.h>
- #include "proto.h"
- void select_lines(struct Map_info *aIn, int atype, int afield,
- struct Map_info *bIn, int btype, int bfield,
- int cat_flag, int operator, const char *relate,
- int *ALines, int *AAreas, int* nskipped)
- {
- int i;
- int nalines, aline, ltype;
-
- struct line_pnts *APoints, *BPoints;
- struct ilist *BoundList, *LList;
- struct boxlist *List, *TmpList;
- #ifdef HAVE_GEOS
- initGEOS(G_message, G_fatal_error);
- GEOSGeometry *AGeom = NULL;
- #else
- void *AGeom = NULL;
- #endif
- nskipped[0] = nskipped[1] = 0;
- APoints = Vect_new_line_struct();
- BPoints = Vect_new_line_struct();
- List = Vect_new_boxlist(1);
- TmpList = Vect_new_boxlist(1);
- BoundList = Vect_new_list();
- LList = Vect_new_list();
- nalines = Vect_get_num_lines(aIn);
-
- /* Lines in A. Go through all lines and mark those that meets condition */
- if (atype & (GV_POINTS | GV_LINES)) {
- G_message(_("Processing features..."));
-
- G_percent(0, nalines, 2);
- for (aline = 1; aline <= nalines; aline++) {
- struct bound_box abox;
- G_debug(3, "aline = %d", aline);
- G_percent(aline, nalines, 2); /* must be before any continue */
- /* Check category */
- if (!cat_flag && Vect_get_line_cat(aIn, aline, afield) < 0) {
- nskipped[0]++;
- continue;
- }
- /* Read line and check type */
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- AGeom = Vect_read_line_geos(aIn, aline, <ype);
- #endif
- if (!(ltype & (GV_POINT | GV_LINE)))
- continue;
- if (!AGeom)
- G_fatal_error(_("Unable to read line id %d from vector map <%s>"),
- aline, Vect_get_full_name(aIn));
- }
- else {
- ltype = Vect_read_line(aIn, APoints, NULL, aline);
- }
-
- if (!(ltype & atype))
- continue;
-
- Vect_get_line_box(aIn, aline, &abox);
- /* Check if this line overlaps any feature in B */
- /* x Lines in B */
- if (btype & (GV_POINTS | GV_LINES)) {
- int found = 0;
-
- /* Lines */
- Vect_select_lines_by_box(bIn, &abox, btype, List);
- for (i = 0; i < List->n_values; i++) {
- int bline;
-
- bline = List->id[i];
- G_debug(3, " bline = %d", bline);
-
- /* Check category */
- if (!cat_flag &&
- Vect_get_line_cat(bIn, bline, bfield) < 0) {
- nskipped[1]++;
- continue;
- }
-
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- if(line_relate_geos(bIn, AGeom,
- bline, operator, relate)) {
- found = 1;
- break;
- }
- #endif
- }
- else {
- Vect_read_line(bIn, BPoints, NULL, bline);
- if (Vect_line_check_intersection2(APoints, BPoints, 0)) {
- found = 1;
- break;
- }
- }
- }
-
- if (found) {
- ALines[aline] = 1;
- continue; /* Go to next A line */
- }
- }
-
- /* x Areas in B. */
- if (btype & GV_AREA) {
-
- Vect_select_areas_by_box(bIn, &abox, List);
- for (i = 0; i < List->n_values; i++) {
- int barea;
-
- barea = List->id[i];
- G_debug(3, " barea = %d", barea);
-
- if (Vect_get_area_cat(bIn, barea, bfield) < 0) {
- nskipped[1]++;
- continue;
- }
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- if(area_relate_geos(bIn, AGeom,
- barea, operator, relate)) {
- ALines[aline] = 1;
- break;
- }
- #endif
- }
- else {
- if (line_overlap_area(APoints, bIn, barea)) {
- ALines[aline] = 1;
- break;
- }
- }
- }
- }
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- GEOSGeom_destroy(AGeom);
- #endif
- AGeom = NULL;
- }
- }
- }
-
- /* Areas in A. */
- if (atype & GV_AREA) {
- int aarea, naareas;
- G_message(_("Processing areas..."));
-
- naareas = Vect_get_num_areas(aIn);
- G_percent(0, naareas, 2);
- for (aarea = 1; aarea <= naareas; aarea++) {
- struct bound_box abox;
- G_percent(aarea, naareas, 1);
- if (Vect_get_area_cat(aIn, aarea, afield) < 0) {
- nskipped[0]++;
- continue;
- }
-
- Vect_get_area_box(aIn, aarea, &abox);
- abox.T = PORT_DOUBLE_MAX;
- abox.B = -PORT_DOUBLE_MAX;
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- AGeom = Vect_read_area_geos(aIn, aarea);
- #endif
- if (!AGeom)
- G_fatal_error(_("Unable to read area id %d from vector map <%s>"),
- aarea, Vect_get_full_name(aIn));
- }
- /* x Lines in B */
- if (btype & (GV_POINTS | GV_LINES)) {
- Vect_select_lines_by_box(bIn, &abox, btype, List);
- for (i = 0; i < List->n_values; i++) {
- int bline;
- bline = List->id[i];
- if (!cat_flag &&
- Vect_get_line_cat(bIn, bline, bfield) < 0) {
- nskipped[1]++;
- continue;
- }
-
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- if(line_relate_geos(bIn, AGeom,
- bline, operator, relate)) {
- add_aarea(aIn, aarea, ALines, AAreas);
- break;
- }
- #endif
- }
- else {
- Vect_read_line(bIn, BPoints, NULL, bline);
- if (line_overlap_area(BPoints, aIn, aarea)) {
- add_aarea(aIn, aarea, ALines, AAreas);
- continue;
- }
- }
- }
- }
- /* x Areas in B */
- if (btype & GV_AREA) {
- int naisles;
- int found = 0;
- /* List of areas B */
- /* Make a list of features forming area A */
- Vect_reset_list(LList);
- Vect_get_area_boundaries(aIn, aarea, BoundList);
- for (i = 0; i < BoundList->n_values; i++) {
- Vect_list_append(LList, abs(BoundList->value[i]));
- }
- naisles = Vect_get_area_num_isles(aIn, aarea);
- for (i = 0; i < naisles; i++) {
- int j, aisle;
- aisle = Vect_get_area_isle(aIn, aarea, i);
- Vect_get_isle_boundaries(aIn, aisle, BoundList);
- for (j = 0; j < BoundList->n_values; j++) {
- Vect_list_append(LList, BoundList->value[j]);
- }
- }
- Vect_select_areas_by_box(bIn, &abox, TmpList);
- for (i = 0; i < LList->n_values; i++) {
- int j;
- aline = abs(LList->value[i]);
- Vect_read_line(aIn, APoints, NULL, aline);
- for (j = 0; j < TmpList->n_values; j++) {
- int barea, bcentroid;
- barea = TmpList->id[j];
- G_debug(3, " barea = %d", barea);
- if (Vect_get_area_cat(bIn, barea, bfield) < 0) {
- nskipped[1]++;
- continue;
- }
- /* Check if any centroid of area B is in area A.
- * This test is important in if area B is completely within area A */
- if ((bcentroid = Vect_get_area_centroid(bIn, barea)) > 0)
- Vect_read_line(bIn, BPoints, NULL, bcentroid);
- else {
- double x, y;
- Vect_get_point_in_area(bIn, barea, &x, &y);
- Vect_reset_line(BPoints);
- Vect_append_point(BPoints, x, y, 0.0);
- }
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- if(area_relate_geos(bIn, AGeom,
- barea, operator, relate)) {
- found = 1;
- break;
- }
- #endif
- }
- else {
- if (Vect_point_in_area(BPoints->x[0], BPoints->y[0], aIn,
- aarea, &abox)) {
- found = 1;
- break;
- }
-
- /* Check intersectin of lines from List with area B */
- if (line_overlap_area(APoints, bIn, barea)) {
- found = 1;
- break;
- }
- }
- }
- if (found) {
- add_aarea(aIn, aarea, ALines, AAreas);
- break;
- }
- }
- }
- if (operator != OP_OVERLAP) {
- #ifdef HAVE_GEOS
- GEOSGeom_destroy(AGeom);
- #endif
- AGeom = NULL;
- }
- }
- }
- Vect_destroy_line_struct(APoints);
- Vect_destroy_line_struct(BPoints);
- Vect_destroy_list(BoundList);
- Vect_destroy_list(LList);
- Vect_destroy_boxlist(List);
- Vect_destroy_boxlist(TmpList);
- return;
- }
|