PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ _lwt_AddEdge()

static LWT_ELEMID _lwt_AddEdge ( LWT_TOPOLOGY topo,
LWT_ELEMID  start_node,
LWT_ELEMID  end_node,
LWLINE geom,
int  skipChecks,
int  modFace 
)
static
Parameters
modFacecan be 0 - have two new faces replace a splitted face 1 - modify a splitted face, adding a new one -1 - do not check at all for face splitting

Definition at line 2284 of file lwgeom_topo.c.

2287 {
2288  LWT_ISO_EDGE newedge;
2289  LWGEOM *cleangeom;
2290  edgeend span; /* start point analisys */
2291  edgeend epan; /* end point analisys */
2292  POINT2D p1, pn, p2;
2293  POINTARRAY *pa;
2294  LWT_ELEMID node_ids[2];
2295  const LWPOINT *start_node_geom = NULL;
2296  const LWPOINT *end_node_geom = NULL;
2297  uint64_t num_nodes;
2298  LWT_ISO_NODE *endpoints;
2299  uint64_t i;
2300  int prev_left;
2301  int prev_right;
2302  LWT_ISO_EDGE seledge;
2303  LWT_ISO_EDGE updedge;
2304 
2305  if ( ! skipChecks )
2306  {
2307  /* curve must be simple */
2308  if ( ! lwgeom_is_simple(lwline_as_lwgeom(geom)) )
2309  {
2310  lwerror("SQL/MM Spatial exception - curve not simple");
2311  return -1;
2312  }
2313  }
2314 
2315  newedge.start_node = start_node;
2316  newedge.end_node = end_node;
2317  newedge.geom = geom;
2318  newedge.face_left = -1;
2319  newedge.face_right = -1;
2320  /* TODO: should do the repeated points removal in 2D space */
2321  cleangeom = lwgeom_remove_repeated_points( lwline_as_lwgeom(geom), 0 );
2322 
2323  pa = lwgeom_as_lwline(cleangeom)->points;
2324  if ( pa->npoints < 2 ) {
2325  lwgeom_free(cleangeom);
2326  lwerror("Invalid edge (no two distinct vertices exist)");
2327  return -1;
2328  }
2329 
2330  /* Initialize endpoint info (some of that ) */
2331  span.cwFace = span.ccwFace =
2332  epan.cwFace = epan.ccwFace = -1;
2333 
2334  /* Compute azimuth of first edge end on start node */
2335  getPoint2d_p(pa, 0, &p1);
2336  if ( ! _lwt_FirstDistinctVertex2D(pa, &p1, 0, 1, &pn) )
2337  {
2338  lwgeom_free(cleangeom);
2339  lwerror("Invalid edge (no two distinct vertices exist)");
2340  return -1;
2341  }
2342  if ( ! azimuth_pt_pt(&p1, &pn, &span.myaz) ) {
2343  lwgeom_free(cleangeom);
2344  lwerror("error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]",
2345  p1.x, p1.y, pn.x, pn.y);
2346  return -1;
2347  }
2348  LWDEBUGF(1, "edge's start node is %g,%g", p1.x, p1.y);
2349 
2350  /* Compute azimuth of last edge end on end node */
2351  getPoint2d_p(pa, pa->npoints-1, &p2);
2352  if ( ! _lwt_FirstDistinctVertex2D(pa, &p2, pa->npoints-1, -1, &pn) )
2353  {
2354  lwgeom_free(cleangeom);
2355  /* This should never happen as we checked the edge while computing first edgend */
2356  lwerror("Invalid clean edge (no two distinct vertices exist) - should not happen");
2357  return -1;
2358  }
2359  lwgeom_free(cleangeom);
2360  if ( ! azimuth_pt_pt(&p2, &pn, &epan.myaz) ) {
2361  lwerror("error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]",
2362  p2.x, p2.y, pn.x, pn.y);
2363  return -1;
2364  }
2365  LWDEBUGF(1, "edge's end node is %g,%g", p2.x, p2.y);
2366 
2367  /*
2368  * Check endpoints existence, match with Curve geometry
2369  * and get face information (if any)
2370  */
2371 
2372  if ( start_node != end_node ) {
2373  num_nodes = 2;
2374  node_ids[0] = start_node;
2375  node_ids[1] = end_node;
2376  } else {
2377  num_nodes = 1;
2378  node_ids[0] = start_node;
2379  }
2380 
2381  endpoints = lwt_be_getNodeById( topo, node_ids, &num_nodes, LWT_COL_NODE_ALL );
2382  if (num_nodes == UINT64_MAX)
2383  {
2384  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2385  return -1;
2386  }
2387  for ( i=0; i<num_nodes; ++i )
2388  {
2389  LWT_ISO_NODE* node = &(endpoints[i]);
2390  if ( modFace != -1 && node->containing_face != -1 )
2391  {
2392  if ( newedge.face_left == -1 )
2393  {
2394  newedge.face_left = newedge.face_right = node->containing_face;
2395  }
2396  else if ( newedge.face_left != node->containing_face )
2397  {
2398  _lwt_release_nodes(endpoints, num_nodes);
2399  lwerror("SQL/MM Spatial exception - geometry crosses an edge"
2400  " (endnodes in faces %" LWTFMT_ELEMID " and %" LWTFMT_ELEMID ")",
2401  newedge.face_left, node->containing_face);
2402  }
2403  }
2404 
2405  LWDEBUGF(1, "Node %d, with geom %p (looking for %d and %d)",
2406  node->node_id, node->geom, start_node, end_node);
2407  if ( node->node_id == start_node ) {
2408  start_node_geom = node->geom;
2409  }
2410  if ( node->node_id == end_node ) {
2411  end_node_geom = node->geom;
2412  }
2413  }
2414 
2415  if ( ! skipChecks )
2416  {
2417  if ( ! start_node_geom )
2418  {
2419  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2420  lwerror("SQL/MM Spatial exception - non-existent node");
2421  return -1;
2422  }
2423  else
2424  {
2425  pa = start_node_geom->point;
2426  getPoint2d_p(pa, 0, &pn);
2427  if ( ! P2D_SAME_STRICT(&pn, &p1) )
2428  {
2429  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2430  lwerror("SQL/MM Spatial exception"
2431  " - start node not geometry start point."
2432  //" - start node not geometry start point (%g,%g != %g,%g).", pn.x, pn.y, p1.x, p1.y
2433  );
2434  return -1;
2435  }
2436  }
2437 
2438  if ( ! end_node_geom )
2439  {
2440  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2441  lwerror("SQL/MM Spatial exception - non-existent node");
2442  return -1;
2443  }
2444  else
2445  {
2446  pa = end_node_geom->point;
2447  getPoint2d_p(pa, 0, &pn);
2448  if ( ! P2D_SAME_STRICT(&pn, &p2) )
2449  {
2450  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2451  lwerror("SQL/MM Spatial exception"
2452  " - end node not geometry end point."
2453  //" - end node not geometry end point (%g,%g != %g,%g).", pn.x, pn.y, p2.x, p2.y
2454  );
2455  return -1;
2456  }
2457  }
2458 
2459  if ( num_nodes ) _lwt_release_nodes(endpoints, num_nodes);
2460 
2461  if ( _lwt_CheckEdgeCrossing( topo, start_node, end_node, geom, 0 ) )
2462  return -1;
2463 
2464  } /* ! skipChecks */
2465 
2466  /*
2467  * All checks passed, time to prepare the new edge
2468  */
2469 
2470  newedge.edge_id = lwt_be_getNextEdgeId( topo );
2471  if ( newedge.edge_id == -1 ) {
2472  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2473  return -1;
2474  }
2475 
2476  /* Find adjacent edges to each endpoint */
2477  int isclosed = start_node == end_node;
2478  int found;
2479  found = _lwt_FindAdjacentEdges( topo, start_node, &span,
2480  isclosed ? &epan : NULL, -1 );
2481  if ( found ) {
2482  span.was_isolated = 0;
2483  newedge.next_right = span.nextCW ? span.nextCW : -newedge.edge_id;
2484  prev_left = span.nextCCW ? -span.nextCCW : newedge.edge_id;
2485  LWDEBUGF(1, "New edge %d is connected on start node, "
2486  "next_right is %d, prev_left is %d",
2487  newedge.edge_id, newedge.next_right, prev_left);
2488  if ( modFace != -1 )
2489  {
2490  if ( newedge.face_right == -1 ) {
2491  newedge.face_right = span.cwFace;
2492  }
2493  if ( newedge.face_left == -1 ) {
2494  newedge.face_left = span.ccwFace;
2495  }
2496  }
2497  } else {
2498  span.was_isolated = 1;
2499  newedge.next_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2500  prev_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2501  LWDEBUGF(1, "New edge %d is isolated on start node, "
2502  "next_right is %d, prev_left is %d",
2503  newedge.edge_id, newedge.next_right, prev_left);
2504  }
2505 
2506  found = _lwt_FindAdjacentEdges( topo, end_node, &epan,
2507  isclosed ? &span : NULL, -1 );
2508  if ( found ) {
2509  epan.was_isolated = 0;
2510  newedge.next_left = epan.nextCW ? epan.nextCW : newedge.edge_id;
2511  prev_right = epan.nextCCW ? -epan.nextCCW : -newedge.edge_id;
2512  LWDEBUGF(1, "New edge %d is connected on end node, "
2513  "next_left is %d, prev_right is %d",
2514  newedge.edge_id, newedge.next_left, prev_right);
2515  if ( modFace != -1 )
2516  {
2517  if ( newedge.face_right == -1 ) {
2518  newedge.face_right = span.ccwFace;
2519  } else if ( newedge.face_right != epan.ccwFace ) {
2520  /* side-location conflict */
2521  lwerror("Side-location conflict: "
2522  "new edge starts in face"
2523  " %" LWTFMT_ELEMID " and ends in face"
2524  " %" LWTFMT_ELEMID,
2525  newedge.face_right, epan.ccwFace
2526  );
2527  return -1;
2528  }
2529  if ( newedge.face_left == -1 ) {
2530  newedge.face_left = span.cwFace;
2531  } else if ( newedge.face_left != epan.cwFace ) {
2532  /* side-location conflict */
2533  lwerror("Side-location conflict: "
2534  "new edge starts in face"
2535  " %" LWTFMT_ELEMID " and ends in face"
2536  " %" LWTFMT_ELEMID,
2537  newedge.face_left, epan.cwFace
2538  );
2539  return -1;
2540  }
2541  }
2542  } else {
2543  epan.was_isolated = 1;
2544  newedge.next_left = isclosed ? newedge.edge_id : -newedge.edge_id;
2545  prev_right = isclosed ? -newedge.edge_id : newedge.edge_id;
2546  LWDEBUGF(1, "New edge %d is isolated on end node, "
2547  "next_left is %d, prev_right is %d",
2548  newedge.edge_id, newedge.next_left, prev_right);
2549  }
2550 
2551  /*
2552  * If we don't have faces setup by now we must have encountered
2553  * a malformed topology (no containing_face on isolated nodes, no
2554  * left/right faces on adjacent edges or mismatching values)
2555  */
2556  if ( modFace > -1 )
2557  {
2558  if ( newedge.face_left != newedge.face_right )
2559  {
2560  lwerror("Left(%" LWTFMT_ELEMID ")/right(%" LWTFMT_ELEMID ")"
2561  " faces mismatch: invalid topology ?",
2562  newedge.face_left, newedge.face_right);
2563  return -1;
2564  }
2565  else if ( newedge.face_left == -1 )
2566  {
2567  lwerror("Could not derive edge face from linked primitives:"
2568  " invalid topology ?");
2569  return -1;
2570  }
2571  }
2572 
2573  /*
2574  * Insert the new edge, and update all linking
2575  */
2576 
2577  int ret = lwt_be_insertEdges(topo, &newedge, 1);
2578  if ( ret == -1 ) {
2579  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2580  return -1;
2581  } else if ( ret == 0 ) {
2582  lwerror("Insertion of split edge failed (no reason)");
2583  return -1;
2584  }
2585 
2586  int updfields;
2587 
2588  /* Link prev_left to us
2589  * (if it's not us already) */
2590  if ( llabs(prev_left) != newedge.edge_id )
2591  {
2592  if ( prev_left > 0 )
2593  {
2594  /* its next_left_edge is us */
2595  updfields = LWT_COL_EDGE_NEXT_LEFT;
2596  updedge.next_left = newedge.edge_id;
2597  seledge.edge_id = prev_left;
2598  }
2599  else
2600  {
2601  /* its next_right_edge is us */
2602  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2603  updedge.next_right = newedge.edge_id;
2604  seledge.edge_id = -prev_left;
2605  }
2606 
2607  ret = lwt_be_updateEdges(topo,
2608  &seledge, LWT_COL_EDGE_EDGE_ID,
2609  &updedge, updfields,
2610  NULL, 0);
2611  if ( ret == -1 ) {
2612  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2613  return -1;
2614  }
2615  }
2616 
2617  /* Link prev_right to us
2618  * (if it's not us already) */
2619  if ( llabs(prev_right) != newedge.edge_id )
2620  {
2621  if ( prev_right > 0 )
2622  {
2623  /* its next_left_edge is -us */
2624  updfields = LWT_COL_EDGE_NEXT_LEFT;
2625  updedge.next_left = -newedge.edge_id;
2626  seledge.edge_id = prev_right;
2627  }
2628  else
2629  {
2630  /* its next_right_edge is -us */
2631  updfields = LWT_COL_EDGE_NEXT_RIGHT;
2632  updedge.next_right = -newedge.edge_id;
2633  seledge.edge_id = -prev_right;
2634  }
2635 
2636  ret = lwt_be_updateEdges(topo,
2637  &seledge, LWT_COL_EDGE_EDGE_ID,
2638  &updedge, updfields,
2639  NULL, 0);
2640  if ( ret == -1 ) {
2641  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2642  return -1;
2643  }
2644  }
2645 
2646  /* NOT IN THE SPECS...
2647  * set containing_face = null for start_node and end_node
2648  * if they where isolated
2649  *
2650  */
2651  LWT_ISO_NODE updnode, selnode;
2652  updnode.containing_face = -1;
2653  if ( span.was_isolated )
2654  {
2655  selnode.node_id = start_node;
2656  ret = lwt_be_updateNodes(topo,
2657  &selnode, LWT_COL_NODE_NODE_ID,
2658  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2659  NULL, 0);
2660  if ( ret == -1 ) {
2661  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2662  return -1;
2663  }
2664  }
2665  if ( epan.was_isolated )
2666  {
2667  selnode.node_id = end_node;
2668  ret = lwt_be_updateNodes(topo,
2669  &selnode, LWT_COL_NODE_NODE_ID,
2670  &updnode, LWT_COL_NODE_CONTAINING_FACE,
2671  NULL, 0);
2672  if ( ret == -1 ) {
2673  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2674  return -1;
2675  }
2676  }
2677 
2678  /* Check face splitting, if required */
2679 
2680  if ( modFace > -1 ) {
2681 
2682  if ( ! isclosed && ( epan.was_isolated || span.was_isolated ) )
2683  {
2684  LWDEBUG(1, "New edge is dangling, so it cannot split any face");
2685  return newedge.edge_id; /* no split */
2686  }
2687 
2688  int newface1 = -1;
2689 
2690  /* IDEA: avoid building edge ring if input is closed, which means we
2691  * know in advance it splits a face */
2692 
2693  if ( ! modFace )
2694  {
2695  newface1 = _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 0 );
2696  if ( newface1 == 0 ) {
2697  LWDEBUG(1, "New edge does not split any face");
2698  return newedge.edge_id; /* no split */
2699  }
2700  }
2701 
2702  int newface = _lwt_AddFaceSplit( topo, newedge.edge_id,
2703  newedge.face_left, 0 );
2704  if ( modFace )
2705  {
2706  if ( newface == 0 ) {
2707  LWDEBUG(1, "New edge does not split any face");
2708  return newedge.edge_id; /* no split */
2709  }
2710 
2711  if ( newface < 0 )
2712  {
2713  /* face on the left is the universe face */
2714  /* must be forming a maximal ring in universal face */
2715  newface = _lwt_AddFaceSplit( topo, -newedge.edge_id,
2716  newedge.face_left, 0 );
2717  if ( newface < 0 ) return newedge.edge_id; /* no split */
2718  }
2719  else
2720  {
2721  _lwt_AddFaceSplit( topo, -newedge.edge_id, newedge.face_left, 1 );
2722  }
2723  }
2724 
2725  /*
2726  * Update topogeometries, if needed
2727  */
2728  if ( newedge.face_left != 0 )
2729  {
2730  ret = lwt_be_updateTopoGeomFaceSplit(topo, newedge.face_left,
2731  newface, newface1);
2732  if ( ret == 0 ) {
2733  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2734  return -1;
2735  }
2736 
2737  if ( ! modFace )
2738  {
2739  /* drop old face from the face table */
2740  ret = lwt_be_deleteFacesById(topo, &(newedge.face_left), 1);
2741  if ( ret == -1 ) {
2742  lwerror("Backend error: %s", lwt_be_lastErrorMessage(topo->be_iface));
2743  return -1;
2744  }
2745  }
2746  }
2747 
2748  } // end of face split checking
2749 
2750  return newedge.edge_id;
2751 }
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:179
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
Definition: measures.c:2462
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1155
int lwgeom_is_simple(const LWGEOM *lwgeom)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:342
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
Definition: lwgeom.c:1471
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_NEXT_RIGHT
#define LWT_COL_NODE_CONTAINING_FACE
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_NEXT_LEFT
#define LWT_COL_NODE_NODE_ID
Node fields.
#define LWT_COL_NODE_ALL
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
Definition: lwgeom_topo.c:125
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
Definition: lwgeom_topo.c:208
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
Definition: lwgeom_topo.c:1412
LWT_ELEMID lwt_be_getNextEdgeId(LWT_TOPOLOGY *topo)
Definition: lwgeom_topo.c:220
static int lwt_be_updateTopoGeomFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_face, LWT_ELEMID new_face1, LWT_ELEMID new_face2)
Definition: lwgeom_topo.c:335
static int _lwt_CheckEdgeCrossing(LWT_TOPOLOGY *topo, LWT_ELEMID start_node, LWT_ELEMID end_node, const LWLINE *geom, LWT_ELEMID myself)
Definition: lwgeom_topo.c:615
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
Definition: lwgeom_topo.c:481
int lwt_be_updateEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_fields, const LWT_ISO_EDGE *upd_edge, int upd_fields, const LWT_ISO_EDGE *exc_edge, int exc_fields)
Definition: lwgeom_topo.c:273
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, int myedge_id)
Definition: lwgeom_topo.c:1509
LWT_ISO_NODE * lwt_be_getNodeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
Definition: lwgeom_topo.c:161
static LWT_ELEMID _lwt_AddFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID sedge, LWT_ELEMID face, int mbr_only)
Definition: lwgeom_topo.c:1874
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
Definition: lwgeom_topo.c:267
#define LWTFMT_ELEMID
Definition: lwgeom_topo.c:43
#define P2D_SAME_STRICT(a, b)
Definition: lwgeom_topo.c:50
static int lwt_be_updateNodes(LWT_TOPOLOGY *topo, const LWT_ISO_NODE *sel_node, int sel_fields, const LWT_ISO_NODE *upd_node, int upd_fields, const LWT_ISO_NODE *exc_node, int exc_fields)
Definition: lwgeom_topo.c:285
POINTARRAY * points
Definition: liblwgeom.h:483
POINTARRAY * point
Definition: liblwgeom.h:471
LWT_ELEMID face_right
LWT_ELEMID next_right
LWT_ELEMID end_node
LWT_ELEMID face_left
LWLINE * geom
LWT_ELEMID next_left
LWT_ELEMID edge_id
LWT_ELEMID start_node
LWT_ELEMID node_id
LWT_ELEMID containing_face
LWPOINT * geom
const LWT_BE_IFACE * be_iface
double y
Definition: liblwgeom.h:390
double x
Definition: liblwgeom.h:390
uint32_t npoints
Definition: liblwgeom.h:427
double myaz
Definition: lwgeom_topo.c:1399
LWT_ELEMID nextCCW
Definition: lwgeom_topo.c:1395
LWT_ELEMID ccwFace
Definition: lwgeom_topo.c:1397
int was_isolated
Definition: lwgeom_topo.c:1398
LWT_ELEMID cwFace
Definition: lwgeom_topo.c:1393
LWT_ELEMID nextCW
Definition: lwgeom_topo.c:1391

References _lwt_AddFaceSplit(), _lwt_CheckEdgeCrossing(), _lwt_FindAdjacentEdges(), _lwt_FirstDistinctVertex2D(), _lwt_release_nodes(), azimuth_pt_pt(), LWT_TOPOLOGY_T::be_iface, edgeend_t::ccwFace, LWT_ISO_NODE::containing_face, edgeend_t::cwFace, LWT_ISO_EDGE::edge_id, LWT_ISO_EDGE::end_node, LWT_ISO_EDGE::face_left, LWT_ISO_EDGE::face_right, LWT_ISO_NODE::geom, LWT_ISO_EDGE::geom, getPoint2d_p(), LWDEBUG, LWDEBUGF, lwerror(), lwgeom_as_lwline(), lwgeom_free(), lwgeom_is_simple(), lwgeom_remove_repeated_points(), lwline_as_lwgeom(), lwt_be_deleteFacesById(), lwt_be_getNextEdgeId(), lwt_be_getNodeById(), lwt_be_insertEdges(), lwt_be_lastErrorMessage(), lwt_be_updateEdges(), lwt_be_updateNodes(), lwt_be_updateTopoGeomFaceSplit(), LWT_COL_EDGE_EDGE_ID, LWT_COL_EDGE_NEXT_LEFT, LWT_COL_EDGE_NEXT_RIGHT, LWT_COL_NODE_ALL, LWT_COL_NODE_CONTAINING_FACE, LWT_COL_NODE_NODE_ID, LWTFMT_ELEMID, edgeend_t::myaz, LWT_ISO_EDGE::next_left, LWT_ISO_EDGE::next_right, edgeend_t::nextCCW, edgeend_t::nextCW, LWT_ISO_NODE::node_id, POINTARRAY::npoints, P2D_SAME_STRICT, LWPOINT::point, LWLINE::points, LWT_ISO_EDGE::start_node, edgeend_t::was_isolated, POINT2D::x, and POINT2D::y.

Referenced by _lwt_AddLineEdge(), lwt_AddEdgeModFace(), and lwt_AddEdgeNewFaces().

Here is the call graph for this function:
Here is the caller graph for this function: