2270{
2278 const LWPOINT *start_node_geom = NULL;
2279 const LWPOINT *end_node_geom = NULL;
2280 uint64_t num_nodes;
2282 uint64_t i;
2283 int prev_left;
2284 int prev_right;
2287
2288 if ( ! skipChecks )
2289 {
2290
2292 {
2293 lwerror(
"SQL/MM Spatial exception - curve not simple");
2294 return -1;
2295 }
2296 }
2297
2300 newedge.
geom = geom;
2303
2305
2309 lwerror(
"Invalid edge (no two distinct vertices exist)");
2310 return -1;
2311 }
2312
2313
2316
2317
2320 {
2322 lwerror(
"Invalid edge (no two distinct vertices exist)");
2323 return -1;
2324 }
2327 lwerror(
"error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]",
2328 p1.
x, p1.
y, pn.
x, pn.
y);
2329 return -1;
2330 }
2331 LWDEBUGF(1,
"edge's start node is %g,%g", p1.
x, p1.
y);
2332
2333
2336 {
2338
2339 lwerror(
"Invalid clean edge (no two distinct vertices exist) - should not happen");
2340 return -1;
2341 }
2344 lwerror(
"error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]",
2345 p2.
x, p2.
y, pn.
x, pn.
y);
2346 return -1;
2347 }
2348 LWDEBUGF(1,
"edge's end node is %g,%g", p2.
x, p2.
y);
2349
2350
2351
2352
2353
2354
2355 if ( start_node != end_node ) {
2356 num_nodes = 2;
2357 node_ids[0] = start_node;
2358 node_ids[1] = end_node;
2359 } else {
2360 num_nodes = 1;
2361 node_ids[0] = start_node;
2362 }
2363
2365 if (num_nodes == UINT64_MAX)
2366 {
2368 return -1;
2369 }
2370 for ( i=0; i<num_nodes; ++i )
2371 {
2374 {
2376 {
2378 }
2380 {
2382 lwerror(
"SQL/MM Spatial exception - geometry crosses an edge"
2385 }
2386 }
2387
2388 LWDEBUGF(1,
"Node %d, with geom %p (looking for %d and %d)",
2390 if ( node->
node_id == start_node ) {
2391 start_node_geom = node->
geom;
2392 }
2393 if ( node->
node_id == end_node ) {
2394 end_node_geom = node->
geom;
2395 }
2396 }
2397
2398 if ( ! skipChecks )
2399 {
2400 if ( ! start_node_geom )
2401 {
2403 lwerror(
"SQL/MM Spatial exception - non-existent node");
2404 return -1;
2405 }
2406 else
2407 {
2408 pa = start_node_geom->
point;
2411 {
2413 lwerror(
"SQL/MM Spatial exception"
2414 " - start node not geometry start point."
2415
2416 );
2417 return -1;
2418 }
2419 }
2420
2421 if ( ! end_node_geom )
2422 {
2424 lwerror(
"SQL/MM Spatial exception - non-existent node");
2425 return -1;
2426 }
2427 else
2428 {
2429 pa = end_node_geom->
point;
2432 {
2434 lwerror(
"SQL/MM Spatial exception"
2435 " - end node not geometry end point."
2436
2437 );
2438 return -1;
2439 }
2440 }
2441
2443
2445 return -1;
2446
2447 }
2448
2449
2450
2451
2452
2454 if ( newedge.
edge_id == -1 ) {
2456 return -1;
2457 }
2458
2459
2460 int isclosed = start_node == end_node;
2461 int found;
2463 isclosed ? &epan : NULL, -1 );
2464 if ( found ) {
2468 LWDEBUGF(1,
"New edge %d is connected on start node, "
2469 "next_right is %d, prev_left is %d",
2473 }
2476 }
2477 } else {
2481 LWDEBUGF(1,
"New edge %d is isolated on start node, "
2482 "next_right is %d, prev_left is %d",
2484 }
2485
2487 isclosed ? &span : NULL, -1 );
2488 if ( found ) {
2492 LWDEBUGF(1,
"New edge %d is connected on end node, "
2493 "next_left is %d, prev_right is %d",
2498
2499 lwerror(
"Side-location conflict: "
2500 "new edge starts in face"
2504 );
2505 return -1;
2506 }
2510
2511 lwerror(
"Side-location conflict: "
2512 "new edge starts in face"
2516 );
2517 return -1;
2518 }
2519 } else {
2523 LWDEBUGF(1,
"New edge %d is isolated on end node, "
2524 "next_left is %d, prev_right is %d",
2526 }
2527
2528
2529
2530
2531
2532
2534 {
2536 "faces mismatch: invalid topology ?",
2538 return -1;
2539 }
2540 else if ( newedge.
face_left == -1 && modFace > -1 )
2541 {
2542 lwerror(
"Could not derive edge face from linked primitives:"
2543 " invalid topology ?");
2544 return -1;
2545 }
2546
2547
2548
2549
2550
2552 if ( ret == -1 ) {
2554 return -1;
2555 } else if ( ret == 0 ) {
2556 lwerror(
"Insertion of split edge failed (no reason)");
2557 return -1;
2558 }
2559
2560 int updfields;
2561
2562
2563
2564 if ( llabs(prev_left) != newedge.
edge_id )
2565 {
2566 if ( prev_left > 0 )
2567 {
2568
2572 }
2573 else
2574 {
2575
2579 }
2580
2583 &updedge, updfields,
2584 NULL, 0);
2585 if ( ret == -1 ) {
2587 return -1;
2588 }
2589 }
2590
2591
2592
2593 if ( llabs(prev_right) != newedge.
edge_id )
2594 {
2595 if ( prev_right > 0 )
2596 {
2597
2601 }
2602 else
2603 {
2604
2607 seledge.
edge_id = -prev_right;
2608 }
2609
2612 &updedge, updfields,
2613 NULL, 0);
2614 if ( ret == -1 ) {
2616 return -1;
2617 }
2618 }
2619
2620
2621
2622
2623
2624
2628 {
2633 NULL, 0);
2634 if ( ret == -1 ) {
2636 return -1;
2637 }
2638 }
2640 {
2645 NULL, 0);
2646 if ( ret == -1 ) {
2648 return -1;
2649 }
2650 }
2651
2652
2653
2654 if ( modFace > -1 ) {
2655
2657 {
2658 LWDEBUG(1,
"New edge is dangling, so it cannot split any face");
2660 }
2661
2662 int newface1 = -1;
2663
2664
2665
2666
2667 if ( ! modFace )
2668 {
2670 if ( newface1 == 0 ) {
2671 LWDEBUG(1,
"New edge does not split any face");
2673 }
2674 }
2675
2678 if ( modFace )
2679 {
2680 if ( newface == 0 ) {
2681 LWDEBUG(1,
"New edge does not split any face");
2683 }
2684
2685 if ( newface < 0 )
2686 {
2687
2688
2691 if ( newface < 0 )
return newedge.
edge_id;
2692 }
2693 else
2694 {
2696 }
2697 }
2698
2699
2700
2701
2703 {
2705 newface, newface1);
2706 if ( ret == 0 ) {
2708 return -1;
2709 }
2710
2711 if ( ! modFace )
2712 {
2713
2715 if ( ret == -1 ) {
2717 return -1;
2718 }
2719 }
2720 }
2721
2722 }
2723
2725}
int azimuth_pt_pt(const POINT2D *p1, const POINT2D *p2, double *ret)
Compute the azimuth of segment AB in radians.
void lwgeom_free(LWGEOM *geom)
int lwgeom_is_simple(const LWGEOM *lwgeom)
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWGEOM * lwgeom_remove_repeated_points(const LWGEOM *in, double tolerance)
int p2d_same(const POINT2D *p1, const POINT2D *p2)
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 LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, POINT2D *ref, int from, int dir, POINT2D *op)
LWT_ELEMID lwt_be_getNextEdgeId(LWT_TOPOLOGY *topo)
static int lwt_be_updateTopoGeomFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_face, LWT_ELEMID new_face1, LWT_ELEMID new_face2)
static int _lwt_CheckEdgeCrossing(LWT_TOPOLOGY *topo, LWT_ELEMID start_node, LWT_ELEMID end_node, const LWLINE *geom, LWT_ELEMID myself)
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
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)
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, int myedge_id)
static LWT_ELEMID _lwt_AddFaceSplit(LWT_TOPOLOGY *topo, LWT_ELEMID sedge, LWT_ELEMID face, int mbr_only)
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
LWT_ISO_NODE * lwt_be_getNodeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
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)
LWT_ELEMID containing_face
const LWT_BE_IFACE * be_iface