123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858 |
- /****************************************************************
- *
- * MODULE: v.generalize
- *
- * AUTHOR(S): Daniel Bundala, Markus Metz
- *
- * PURPOSE: miscellaneous functions of v.generalize
- *
- *
- * COPYRIGHT: (C) 2002-2005 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 <stdlib.h>
- #include <grass/gis.h>
- #include <grass/vector.h>
- #include <grass/dbmi.h>
- #include <grass/glocale.h>
- #include "misc.h"
- static int topo_debug = 0;
- int set_topo_debug(void)
- {
- if (getenv("GRASS_VECTOR_TOPO_DEBUG"))
- topo_debug = 1;
- return topo_debug;
- }
- int type_mask(struct Option *type_opt)
- {
- int res = 0;
- int i;
- for (i = 0; type_opt->answers[i]; i++)
- switch (type_opt->answers[i][0]) {
- case 'l':
- res |= GV_LINE;
- break;
- case 'b':
- res |= GV_BOUNDARY;
- break;
- case 'a':
- res |= GV_BOUNDARY;
- }
- return res;
- }
- int get_furthest(struct line_pnts *Points, int a, int b, int with_z,
- double *dist)
- {
- int index = a;
- double d = 0;
- int i;
- double x0 = Points->x[a];
- double x1 = Points->x[b];
- double y0 = Points->y[a];
- double y1 = Points->y[b];
- double z0 = Points->z[a];
- double z1 = Points->z[b];
- double px, py, pz, pdist, di;
- int status;
- for (i = a + 1; i < b; i++) {
- di = dig_distance2_point_to_line(Points->x[i], Points->y[i],
- Points->z[i], x0, y0, z0, x1, y1, z1,
- with_z, &px, &py, &pz, &pdist,
- &status);
- if (di > d) {
- d = di;
- index = i;
- }
- }
- *dist = d;
- return index;
- }
- /* TODO: The collection of categories is horrible in current version!
- * Everything repeats many times. We need some data structure
- * implementing set! */
- int copy_tables_by_cats(struct Map_info *In, struct Map_info *Out)
- {
- /* this is the (mostly) code from v.extract, it should be moved to
- * some vector library (probably) */
- int nlines, line, nfields;
- int ttype, ntabs = 0;
- struct field_info *IFi, *OFi;
- struct line_cats *Cats;
- int **ocats, *nocats, *fields;
- int i;
- /* Collect list of output cats */
- Cats = Vect_new_cats_struct();
- nfields = Vect_cidx_get_num_fields(In);
- ocats = (int **)G_malloc(nfields * sizeof(int *));
- nocats = (int *)G_malloc(nfields * sizeof(int));
- fields = (int *)G_malloc(nfields * sizeof(int));
- for (i = 0; i < nfields; i++) {
- nocats[i] = 0;
- ocats[i] =
- (int *)G_malloc(Vect_cidx_get_num_cats_by_index(In, i) *
- sizeof(int));
- fields[i] = Vect_cidx_get_field_number(In, i);
- }
- nlines = Vect_get_num_lines(Out);
- for (line = 1; line <= nlines; line++) {
- Vect_read_line(Out, NULL, Cats, line);
- for (i = 0; i < Cats->n_cats; i++) {
- int f = 0, j;
- for (j = 0; j < nfields; j++) { /* find field */
- if (fields[j] == Cats->field[i]) {
- f = j;
- break;
- }
- }
- ocats[f][nocats[f]] = Cats->cat[i];
- nocats[f]++;
- }
- }
- /* Copy tables */
- G_message(_("Writing attributes..."));
- /* Number of output tabs */
- for (i = 0; i < Vect_get_num_dblinks(In); i++) {
- int j, f = -1;
- IFi = Vect_get_dblink(In, i);
- for (j = 0; j < nfields; j++) { /* find field */
- if (fields[j] == IFi->number) {
- f = j;
- break;
- }
- }
- if (f >= 0 && nocats[f] > 0)
- ntabs++;
- }
- if (ntabs > 1)
- ttype = GV_MTABLE;
- else
- ttype = GV_1TABLE;
- for (i = 0; i < nfields; i++) {
- int ret;
- if (fields[i] == 0)
- continue;
- if (nocats[i] == 0)
- continue;
- /* if ( fields[i] == field && new_cat != -1 ) continue; */
- G_message(_("Layer %d"), fields[i]);
- /* Make a list of categories */
- IFi = Vect_get_field(In, fields[i]);
- if (!IFi) { /* no table */
- G_warning(_("Database connection not defined for layer %d"),
- fields[i]);
- continue;
- }
- OFi = Vect_default_field_info(Out, IFi->number, IFi->name, ttype);
- ret = db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
- OFi->driver, Vect_subst_var(OFi->database,
- Out),
- OFi->table, IFi->key, ocats[i],
- nocats[i]);
- if (ret == DB_FAILED) {
- G_warning(_("Unable to copy table <%s>"), IFi->table);
- }
- else {
- Vect_map_add_dblink(Out, OFi->number, OFi->name, OFi->table,
- IFi->key, OFi->database, OFi->driver);
- }
- }
- for (i = 0; i < nfields; i++)
- G_free(ocats[i]);
- G_free(ocats);
- G_free(nocats);
- G_free(fields);
- return 1;
- }
- static int cmp(const void *a, const void *b)
- {
- int ai = *(int *)a;
- int bi = *(int *)b;
- return (ai < bi ? -1 : (ai > bi));
- }
- /* check topology corruption by boundary modification
- * return 0 on corruption, 1 if modification is ok */
- int check_topo(struct Map_info *Out, int line, struct line_pnts *APoints,
- struct line_pnts *Points, struct line_cats *Cats)
- {
- int i, j, k, intersect, newline;
- struct bound_box box, abox, tbox;
- struct bound_box lbox, rbox, areabox;
- struct line_pnts **AXLines, **BXLines;
- int naxlines, nbxlines;
- static struct line_pnts *BPoints = NULL;
- static struct boxlist *List = NULL;
- static struct line_pnts *BPoints2 = NULL;
- static struct ilist *BList = NULL;
- int area, isle, centr;
- int left_o, left_n, right_o, right_n;
- int node, node_n_lines;
- float angle1, angle2;
- off_t offset;
- /* topology debugging */
- int area_l_o, area_r_o, area_l_n, area_r_n;
- int centr_l_o, centr_r_o, centr_l_n, centr_r_n;
- int *isles_l_o, nisles_l_o, *isles_l_n, nisles_l_n;
- int *isles_r_o, nisles_r_o, *isles_r_n, nisles_r_n;
- int found;
- if (!BPoints) {
- BPoints = Vect_new_line_struct();
- BPoints2 = Vect_new_line_struct();
- List = Vect_new_boxlist(1);
- BList = Vect_new_list();
- }
- if (APoints->n_points == Points->n_points) {
- int same = 1;
-
- for (i = 0; i < APoints->n_points; i++) {
- if (APoints->x[i] != Points->x[i] || APoints->y[i] != Points->y[i]) {
- same = 0;
- break;
- }
- }
- if (same)
- return 1;
- }
- i = APoints->n_points - 1;
- if (APoints->x[0] == APoints->x[i] && APoints->y[0] == APoints->y[i]) {
- i = Points->n_points - 1;
- if (Points->x[0] != Points->x[i] || Points->y[0] != Points->y[i]) {
- /* input line forms a loop, output not */
- return 0;
- }
- }
- /* test node angles
- * an area can be built only if there are no two lines with the same
- * angle at the same node */
- /* line start */
- angle1 = dig_calc_begin_angle(Points, 0);
- if (angle1 == -9)
- return 0;
- node = dig_find_node(&(Out->plus), Points->x[0], Points->y[0], Points->z[0]);
- if (node) {
- /* if another line exists with the same angle at this node,
- * an area can not be constructed -> error */
- node_n_lines = Vect_get_node_n_lines(Out, node);
- for (i = 0; i < node_n_lines; i++) {
- if (abs(Vect_get_node_line(Out, node, i)) == line)
- continue;
- if (angle1 == Vect_get_node_line_angle(Out, node, i))
- return 0;
- }
- }
-
- /* line end */
- angle2 = dig_calc_end_angle(Points, 0);
- if (angle2 == -9)
- return 0;
- i = Points->n_points - 1;
- if (Points->x[0] == Points->x[i] && Points->y[0] == Points->y[i]) {
- if (angle1 == angle2) {
- /* same angle, same start and end coordinates,
- * an area can not be constructed -> error */
- return 0;
- }
- }
- else {
- node = dig_find_node(&(Out->plus), Points->x[i], Points->y[i], Points->z[i]);
- }
- if (node) {
- /* if another line exists with the same angle at this node,
- * an area can not be constructed -> error */
- node_n_lines = Vect_get_node_n_lines(Out, node);
- for (i = 0; i < node_n_lines; i++) {
- if (abs(Vect_get_node_line(Out, node, i)) == line)
- continue;
- if (angle2 == Vect_get_node_line_angle(Out, node, i))
- return 0;
- }
- }
- Vect_line_box(Points, &box);
- /* Check the modified boundary for self-intersection */
- AXLines = BXLines = NULL;
- Vect_line_intersection2(Points, NULL, &box, &box, &AXLines, &BXLines,
- &naxlines, &nbxlines, 0);
- /* Free */
- if (naxlines > 0) {
- for (j = 0; j < naxlines; j++) {
- Vect_destroy_line_struct(AXLines[j]);
- }
- }
- if (AXLines)
- G_free(AXLines);
- if (naxlines > 0)
- return 0;
- /* Check intersection of the modified boundary with other boundaries */
- Vect_select_lines_by_box(Out, &box, GV_BOUNDARY, List);
- intersect = 0;
- for (i = 0; i < List->n_values; i++) {
- int bline;
- bline = List->id[i];
- if (bline == line)
- continue;
- Vect_read_line(Out, BPoints, NULL, bline);
- /* Vect_line_intersection is quite slow, hopefully not so bad because only few
- * intersections should be found if any */
- AXLines = BXLines = NULL;
- Vect_line_intersection2(Points, BPoints, &box, &List->box[i],
- &AXLines, &BXLines,
- &naxlines, &nbxlines, 0);
- G_debug(4,
- "bline = %d intersect = %d naxlines = %d nbxlines = %d",
- bline, intersect, naxlines, nbxlines);
- /* Free */
- if (naxlines > 0) {
- for (j = 0; j < naxlines; j++) {
- Vect_destroy_line_struct(AXLines[j]);
- }
- }
- if (AXLines)
- G_free(AXLines);
- if (nbxlines > 0) {
- for (j = 0; j < nbxlines; j++) {
- Vect_destroy_line_struct(BXLines[j]);
- }
- }
- if (BXLines)
- G_free(BXLines);
- if (naxlines > 1 || nbxlines > 1) {
- intersect = 1;
- break;
- }
- }
-
- /* modified boundary intersects another boundary */
- if (intersect)
- return 0;
- /* test centroid attachment (point-in-poly) */
- Vect_get_line_areas(Out, line, &left_o, &right_o);
- Vect_line_box(APoints, &abox);
- /* centroid on the left side */
- isle = centr = 0;
- area = left_o;
- if (area < 0) {
- isle = -area;
- area = Vect_get_isle_area(Out, isle);
- }
- if (area > 0)
- centr = Vect_get_area_centroid(Out, area);
- centr_l_o = centr;
- area_l_o = area;
- lbox = box;
- if (isle)
- Vect_get_isle_boundaries(Out, isle, BList);
- else
- Vect_get_area_boundaries(Out, area, BList);
- Vect_reset_line(BPoints2);
- for (i = 0; i < BList->n_values; i++) {
- int bline = BList->value[i];
- int dir = bline > 0 ? GV_FORWARD : GV_BACKWARD;
- if (abs(bline) != line) {
- Vect_read_line(Out, BPoints, NULL, abs(bline));
- Vect_line_box(BPoints, &tbox);
- Vect_box_extend(&lbox, &tbox);
- Vect_append_points(BPoints2, BPoints, dir);
- }
- else
- Vect_append_points(BPoints2, Points, dir);
- BPoints2->n_points--; /* skip last point, avoids duplicates */
- }
- BPoints2->n_points++; /* close polygon */
- if (centr > 0) {
- int ret;
- double cx, cy, cz;
- Vect_read_line(Out, BPoints, NULL, centr);
- cx = BPoints->x[0];
- cy = BPoints->y[0];
- cz = BPoints->z[0];
- if (Vect_point_in_box(cx, cy, cz, &box) ||
- Vect_point_in_box(cx, cy, cz, &abox)) {
- ret = Vect_point_in_poly(cx, cy, BPoints2);
- if (!isle) {
- /* area: centroid must be inside */
- if (ret != 1)
- return 0;
- }
- else {
- /* isle: centroid must be outside */
- if (ret > 0)
- return 0;
- }
- }
- }
- /* centroid on the right side */
- isle = centr = 0;
- area = right_o;
- if (area < 0) {
- isle = -area;
- area = Vect_get_isle_area(Out, isle);
- }
- if (area > 0)
- centr = Vect_get_area_centroid(Out, area);
- centr_r_o = centr;
- area_r_o = area;
- rbox = box;
- if (isle)
- Vect_get_isle_boundaries(Out, isle, BList);
- else
- Vect_get_area_boundaries(Out, area, BList);
- Vect_reset_line(BPoints2);
- for (i = 0; i < BList->n_values; i++) {
- int bline = BList->value[i];
- int dir = bline > 0 ? GV_FORWARD : GV_BACKWARD;
- if (abs(bline) != line) {
- Vect_read_line(Out, BPoints, NULL, abs(bline));
- Vect_line_box(BPoints, &tbox);
- Vect_box_extend(&rbox, &tbox);
- Vect_append_points(BPoints2, BPoints, dir);
- }
- else
- Vect_append_points(BPoints2, Points, dir);
- BPoints2->n_points--; /* skip last point, avoids duplicates */
- }
- BPoints2->n_points++; /* close polygon */
- if (centr > 0) {
- int ret;
- double cx, cy, cz;
- Vect_read_line(Out, BPoints, NULL, centr);
- cx = BPoints->x[0];
- cy = BPoints->y[0];
- cz = BPoints->z[0];
- if (Vect_point_in_box(cx, cy, cz, &box) ||
- Vect_point_in_box(cx, cy, cz, &abox)) {
- ret = Vect_point_in_poly(cx, cy, BPoints2);
- if (!isle) {
- /* area: centroid must be inside */
- if (ret != 1)
- return 0;
- }
- else {
- /* isle: centroid must be outside */
- if (ret > 0)
- return 0;
- }
- }
- }
- /* all fine:
- * areas/isles can be built
- * no intersection with another boundary, e.g. isle attachment will be preserved
- * centroids are still on the correct side of the boundary */
- if (!topo_debug) {
- /* update only those parts of topology that actually get changed */
- /* boundary:
- * node in case of loop support
- * node angles
- * bounding box */
-
- /* rewrite boundary on level 1 */
- offset = Out->plus.Line[line]->offset;
- Out->level = 1;
- offset = Vect_rewrite_line(Out, offset, GV_BOUNDARY, Points, Cats);
- Out->level = 2;
- /* delete line from topo */
- dig_del_line(&Out->plus, line, APoints->x[0], APoints->y[0], APoints->z[0]);
- /* restore line in topo */
- dig_restore_line(&Out->plus, line, GV_BOUNDARY, Points, &box, offset);
- /* update area/isle box to the left */
- if (left_o < 0) {
- dig_spidx_del_isle(&Out->plus, -left_o);
- dig_spidx_add_isle(&Out->plus, -left_o, &lbox);
- }
- else if (left_o > 0) {
- dig_spidx_del_area(&Out->plus, left_o);
- dig_spidx_add_area(&Out->plus, left_o, &lbox);
- }
- /* update area/isle box to the right */
- if (right_o < 0) {
- dig_spidx_del_isle(&Out->plus, -right_o);
- dig_spidx_add_isle(&Out->plus, -right_o, &rbox);
- }
- else if (right_o > 0) {
- dig_spidx_del_area(&Out->plus, right_o);
- dig_spidx_add_area(&Out->plus, right_o, &rbox);
- }
-
- /* done */
- return 1;
- }
- /* debug topology */
- /* record isles of the old areas to the left and right */
- nisles_l_o = 0;
- isles_l_o = NULL;
- if (area_l_o) {
- nisles_l_o = Out->plus.Area[area_l_o]->n_isles;
- if (nisles_l_o) {
- isles_l_o = G_malloc(nisles_l_o * sizeof(int));
- for (i = 0; i < nisles_l_o; i++) {
- isles_l_o[i] = Out->plus.Area[area_l_o]->isles[i];
- }
- qsort(isles_l_o, nisles_l_o, sizeof(int), cmp);
- }
- }
- nisles_r_o = 0;
- isles_r_o = NULL;
- if (area_r_o) {
- nisles_r_o = Out->plus.Area[area_r_o]->n_isles;
- if (nisles_r_o) {
- isles_r_o = G_malloc(nisles_r_o * sizeof(int));
- for (i = 0; i < nisles_r_o; i++) {
- isles_r_o[i] = Out->plus.Area[area_r_o]->isles[i];
- }
- qsort(isles_r_o, nisles_r_o, sizeof(int), cmp);
- }
- }
- /* OK, rewrite modified boundary */
- newline = Vect_rewrite_line(Out, line, GV_BOUNDARY, Points, Cats);
- if (newline != line)
- G_fatal_error("Vect_rewrite_line(): new line id %d != old line id %d",
- newline, line);
- /* get new area and centroid ids to the left and right */
- centr_l_n = centr_r_n = 0;
- Vect_get_line_areas(Out, newline, &left_n, &right_n);
- area = left_n;
- if (area < 0)
- area = Vect_get_isle_area(Out, -area);
- if (area > 0)
- centr_l_n = Vect_get_area_centroid(Out, area);
- area_l_n = area;
-
- area = right_n;
- if (area < 0)
- area = Vect_get_isle_area(Out, -area);
- if (area > 0)
- centr_r_n = Vect_get_area_centroid(Out, area);
- area_r_n = area;
- /* record isles of the new areas to the left and right */
- nisles_l_n = 0;
- isles_l_n = NULL;
- if (area_l_n) {
- nisles_l_n = Out->plus.Area[area_l_n]->n_isles;
- if (nisles_l_n) {
- isles_l_n = G_malloc(nisles_l_n * sizeof(int));
- for (i = 0; i < nisles_l_n; i++) {
- isles_l_n[i] = Out->plus.Area[area_l_n]->isles[i];
- }
- qsort(isles_l_n, nisles_l_n, sizeof(int), cmp);
- }
- }
- nisles_r_n = 0;
- isles_r_n = NULL;
- if (area_r_n) {
- nisles_r_n = Out->plus.Area[area_r_n]->n_isles;
- if (nisles_r_n) {
- isles_r_n = G_malloc(nisles_r_n * sizeof(int));
- for (i = 0; i < nisles_r_n; i++) {
- isles_r_n[i] = Out->plus.Area[area_r_n]->isles[i];
- }
- qsort(isles_r_n, nisles_r_n, sizeof(int), cmp);
- }
- }
- /* compare isle numbers and ids on the left and right */
- /* left */
- if (nisles_l_o != nisles_l_n)
- G_fatal_error("Number of isles to the left differ: old %d, new %d",
- nisles_l_o, nisles_l_n);
- found = 0;
- k = 0;
- for (i = 0; i < nisles_l_o; i++) {
- if (isles_l_o[i] != isles_l_n[k]) {
- if (!found) {
- found = 1;
- k--;
- }
- else {
- for (j = 0; j < nisles_l_o; j++) {
- G_message("old %d new %d", isles_l_o[j], isles_l_n[j]);
- }
- G_fatal_error("New isle to the left %d is wrong",
- isles_l_n[i]);
- }
- }
- k++;
- }
- /* right */
- if (nisles_r_o != nisles_r_n)
- G_fatal_error("Number of isles to the left differ: old %d, new %d",
- nisles_r_o, nisles_r_n);
- found = 0;
- k = 0;
- for (i = 0; i < nisles_r_o; i++) {
- if (isles_r_o[i] != isles_r_n[k]) {
- if (!found) {
- found = 1;
- k--;
- }
- else {
- for (j = 0; j < nisles_r_o; j++) {
- G_message("old %d new %d", isles_r_o[j], isles_r_n[j]);
- }
- G_fatal_error("New isle to the right %d is wrong",
- isles_l_n[i]);
- }
- }
- k++;
- }
- /* Check position of centroids */
- if (centr_l_n != centr_l_o || centr_r_n != centr_r_o) {
- /* should not happen if the above topo checks work as expected */
- G_warning("The modified boundary changes attachment of centroid -> topo checks failed");
- if (centr_l_n != centr_l_o) {
- G_warning("Left area/isle old: %d, new: %d", left_o, left_n);
- G_warning("Left centroid old: %d, new: %d", centr_l_o, centr_l_n);
- if (centr_l_o) {
- int ret1, ret2, ret3;
- Vect_read_line(Out, BPoints, NULL, centr_l_o);
- Vect_get_area_box(Out, area_l_n, &abox);
- ret1 = (BPoints->x[0] >= abox.W && BPoints->x[0] <= abox.E &&
- BPoints->y[0] >= abox.S && BPoints->y[0] <= abox.N);
- ret2 = Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_l_n, &abox);
- Vect_get_area_points(Out, area_l_n, BPoints2);
- ret3 = Vect_point_in_poly(BPoints->x[0], BPoints->y[0], BPoints2);
- if (ret2 != ret3) {
- G_warning("Left old centroid in new area box: %d", ret1);
- G_warning("Left old centroid in new area outer ring: %d", ret2);
- G_warning("Left old centroid in new area as poly: %d", ret3);
- }
- }
- }
- if (centr_r_n != centr_r_o) {
- G_warning("Right area/isle old: %d, new: %d", right_o, right_n);
- G_warning("Right centroid old: %d, new: %d", centr_r_o, centr_r_n);
- if (centr_r_o) {
- int ret1, ret2, ret3;
- Vect_read_line(Out, BPoints, NULL, centr_r_o);
- Vect_get_area_box(Out, area_r_n, &abox);
- ret1 = (BPoints->x[0] >= abox.W && BPoints->x[0] <= abox.E &&
- BPoints->y[0] >= abox.S && BPoints->y[0] <= abox.N);
- ret2 = Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_r_n, &abox);
- Vect_get_area_points(Out, area_r_n, BPoints2);
- ret3 = Vect_point_in_poly(BPoints->x[0], BPoints->y[0], BPoints2);
- if (ret2 != ret3) {
- G_warning("Right old centroid in new area box: %d", ret1);
- G_warning("Right old centroid in new area outer ring: %d", ret2);
- G_warning("Right old centroid in new area as poly: %d", ret3);
- }
- }
- }
- /* rewrite old line */
- newline = Vect_rewrite_line(Out, newline, GV_BOUNDARY, APoints, Cats);
- centr_l_n = centr_r_n = 0;
- Vect_get_line_areas(Out, newline, &area_l_n, &area_r_n);
- area = area_l_n;
- if (area < 0)
- area = Vect_get_isle_area(Out, -area);
- if (area > 0)
- centr_l_n = Vect_get_area_centroid(Out, area);
- area_l_n = area;
-
- area = area_r_n;
- if (area < 0)
- area = Vect_get_isle_area(Out, -area);
- if (area > 0)
- centr_r_n = Vect_get_area_centroid(Out, area);
- area_r_n = area;
- if (centr_l_n != centr_l_o) {
- Vect_get_area_box(Out, area_l_n, &areabox);
-
- if (centr_l_n > 0) {
- Vect_read_line(Out, BPoints, NULL, centr_l_n);
- if (Vect_point_in_area(BPoints->x[0], BPoints->y[0], Out,
- area_l_n, &areabox)) {
- G_warning("New left centroid is in new left area %d", area_l_n);
- G_warning("New left centroid on outer ring: %d",
- Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_l_n, &areabox));
- G_warning("Best area for new left centroid: %d",
- Vect_find_area(Out, BPoints->x[0], BPoints->y[0]));
- }
- else
- G_warning("New left centroid is not in new left area");
- }
- if (centr_l_o > 0) {
- Vect_read_line(Out, BPoints, NULL, centr_l_o);
- if (Vect_point_in_area(BPoints->x[0], BPoints->y[0], Out,
- area_l_n, &areabox)) {
- G_warning("Old left centroid is in new left area %d", area_l_n);
- G_warning("Old left centroid on outer ring: %d",
- Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_l_n, &areabox));
- G_warning("Best area for old left centroid: %d",
- Vect_find_area(Out, BPoints->x[0], BPoints->y[0]));
- }
- else
- G_warning("Old left centroid is not in new left area");
- }
- G_fatal_error("Left centroid old %d, restored %d", centr_l_o, centr_l_n);
- return 0;
- }
- if (centr_r_n != centr_r_o) {
- Vect_get_area_box(Out, area_r_n, &areabox);
- if (centr_r_n > 0) {
- Vect_read_line(Out, BPoints, NULL, centr_r_n);
- if (Vect_point_in_area(BPoints->x[0], BPoints->y[0], Out,
- area_r_n, &areabox)) {
- G_warning("New right centroid is in new right area %d", area_r_n);
- G_warning("New right centroid on outer ring: %d",
- Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_r_n, &areabox));
- G_warning("Best area for new right centroid: %d",
- Vect_find_area(Out, BPoints->x[0], BPoints->y[0]));
- }
- else
- G_warning("New right centroid is not in new right area");
- }
- if (centr_r_o > 0) {
- Vect_read_line(Out, BPoints, NULL, centr_r_o);
- if (Vect_point_in_area(BPoints->x[0], BPoints->y[0], Out,
- area_r_n, &areabox)) {
- G_warning("Old right centroid is in new right area %d", area_r_n);
- G_warning("Old right centroid on outer ring: %d",
- Vect_point_in_area_outer_ring(BPoints->x[0], BPoints->y[0], Out,
- area_r_n, &areabox));
- G_warning("Best area for old right centroid: %d",
- Vect_find_area(Out, BPoints->x[0], BPoints->y[0]));
- }
- else
- G_warning("Old right centroid is not in new right area");
- }
- G_fatal_error("Right centroid old %d, restored %d", centr_r_o, centr_r_n);
- return 0;
- }
- G_fatal_error("Topology check failure");
- return 0;
- }
- if (isles_l_o)
- G_free(isles_l_o);
- if (isles_r_o)
- G_free(isles_r_o);
- if (isles_l_n)
- G_free(isles_l_n);
- if (isles_r_n)
- G_free(isles_r_n);
-
- return 1;
- }
|