2423{
2431 const LWPOINT *start_node_geom = NULL;
2432 const LWPOINT *end_node_geom = NULL;
2433 uint64_t num_nodes;
2435 uint64_t i;
2440
2441 if ( ! skipChecks )
2442 {
2443
2445 {
2446 lwerror(
"SQL/MM Spatial exception - curve not simple");
2447 return -1;
2448 }
2449 }
2450
2453 newedge.
geom = geom;
2456
2458
2462 lwerror(
"Invalid edge (no two distinct vertices exist)");
2463 return -1;
2464 }
2465
2466
2469
2470
2473 {
2475 lwerror(
"Invalid edge (no two distinct vertices exist)");
2476 return -1;
2477 }
2480 lwerror(
"error computing azimuth of first edgeend [%.15g %.15g,%.15g %.15g]",
2481 p1.
x, p1.
y, pn.
x, pn.
y);
2482 return -1;
2483 }
2484 LWDEBUGF(1,
"edge's start node is %g,%g", p1.
x, p1.
y);
2485
2486
2489 {
2491
2492 lwerror(
"Invalid clean edge (no two distinct vertices exist) - should not happen");
2493 return -1;
2494 }
2497 lwerror(
"error computing azimuth of last edgeend [%.15g %.15g,%.15g %.15g]",
2498 p2.
x, p2.
y, pn.
x, pn.
y);
2499 return -1;
2500 }
2501 LWDEBUGF(1,
"edge's end node is %g,%g", p2.
x, p2.
y);
2502
2503
2504
2505
2506
2507
2508 if ( start_node != end_node ) {
2509 num_nodes = 2;
2510 node_ids[0] = start_node;
2511 node_ids[1] = end_node;
2512 } else {
2513 num_nodes = 1;
2514 node_ids[0] = start_node;
2515 }
2516
2518 if (num_nodes == UINT64_MAX)
2519 {
2521 return -1;
2522 }
2523 for ( i=0; i<num_nodes; ++i )
2524 {
2527 {
2529 {
2531 }
2533 {
2535 lwerror(
"SQL/MM Spatial exception - geometry crosses an edge"
2538 }
2539 }
2540
2544 if ( node->
node_id == start_node ) {
2545 start_node_geom = node->
geom;
2546 }
2547 if ( node->
node_id == end_node ) {
2548 end_node_geom = node->
geom;
2549 }
2550 }
2551
2552 if ( ! skipChecks )
2553 {
2554 if ( ! start_node_geom )
2555 {
2557 lwerror(
"SQL/MM Spatial exception - non-existent node");
2558 return -1;
2559 }
2560 else
2561 {
2562 pa = start_node_geom->
point;
2565 {
2567 lwerror(
"SQL/MM Spatial exception"
2568 " - start node not geometry start point."
2569
2570 );
2571 return -1;
2572 }
2573 }
2574
2575 if ( ! end_node_geom )
2576 {
2578 lwerror(
"SQL/MM Spatial exception - non-existent node");
2579 return -1;
2580 }
2581 else
2582 {
2583 pa = end_node_geom->
point;
2586 {
2588 lwerror(
"SQL/MM Spatial exception"
2589 " - end node not geometry end point."
2590
2591 );
2592 return -1;
2593 }
2594 }
2595
2597
2599 return -1;
2600
2601 }
2602
2603
2604
2605
2606
2608 if ( newedge.
edge_id == -1 ) {
2610 return -1;
2611 }
2612
2613
2614 int isclosed = start_node == end_node;
2615 int found;
2617 isclosed ? &epan : NULL, -1 );
2618 if ( found ) {
2626 if ( modFace != -1 )
2627 {
2630 }
2633 }
2634 }
2635 } else {
2643 }
2644
2646 isclosed ? &span : NULL, -1 );
2647 if ( found ) {
2655 if ( modFace != -1 )
2656 {
2660
2661 lwerror(
"Side-location conflict: "
2662 "new edge starts in face"
2666 );
2667 return -1;
2668 }
2672
2673 lwerror(
"Side-location conflict: "
2674 "new edge starts in face"
2678 );
2679 return -1;
2680 }
2681 }
2682 } else {
2690 }
2691
2692
2693
2694
2695
2696
2697 if ( modFace > -1 )
2698 {
2700 {
2702 " faces mismatch: invalid topology ?",
2704 return -1;
2705 }
2707 {
2708 lwerror(
"Could not derive edge face from linked primitives:"
2709 " invalid topology ?");
2710 return -1;
2711 }
2712 }
2713
2714
2715
2716
2717
2719 if ( ret == -1 ) {
2721 return -1;
2722 } else if ( ret == 0 ) {
2723 lwerror(
"Insertion of split edge failed (no reason)");
2724 return -1;
2725 }
2726
2727 int updfields;
2728
2729
2730
2731 if ( llabs(prev_left) != newedge.
edge_id )
2732 {
2733 if ( prev_left > 0 )
2734 {
2735
2739 }
2740 else
2741 {
2742
2746 }
2747
2750 &updedge, updfields,
2751 NULL, 0);
2752 if ( ret == -1 ) {
2754 return -1;
2755 }
2756 }
2757
2758
2759
2760 if ( llabs(prev_right) != newedge.
edge_id )
2761 {
2762 if ( prev_right > 0 )
2763 {
2764
2768 }
2769 else
2770 {
2771
2774 seledge.
edge_id = -prev_right;
2775 }
2776
2779 &updedge, updfields,
2780 NULL, 0);
2781 if ( ret == -1 ) {
2783 return -1;
2784 }
2785 }
2786
2787
2788
2789
2790
2791
2795 {
2800 NULL, 0);
2801 if ( ret == -1 ) {
2803 return -1;
2804 }
2805 }
2807 {
2812 NULL, 0);
2813 if ( ret == -1 ) {
2815 return -1;
2816 }
2817 }
2818
2819
2820
2821 if ( modFace > -1 ) {
2822
2824 {
2825 LWDEBUG(1,
"New edge is dangling, so it cannot split any face");
2827 }
2828
2829 int newface1 = -1;
2830
2831
2832
2833
2834 if ( ! modFace )
2835 {
2837 if ( newface1 == 0 ) {
2838 LWDEBUG(1,
"New edge does not split any face");
2840 }
2841 }
2842
2845 if ( modFace )
2846 {
2847 if ( newface == 0 ) {
2848 LWDEBUG(1,
"New edge does not split any face");
2850 }
2851
2852 if ( newface < 0 )
2853 {
2854
2855
2858 if ( newface < 0 )
return newedge.
edge_id;
2859 }
2860 else
2861 {
2863 }
2864 }
2865
2866
2867
2868
2870 {
2872 newface, newface1);
2873 if ( ret == 0 ) {
2875 return -1;
2876 }
2877
2878 if ( ! modFace )
2879 {
2880
2882 if ( ret == -1 ) {
2884 return -1;
2885 }
2886 }
2887 }
2888
2889 }
2890
2892}
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)
#define P2D_SAME_STRICT(a, b)
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 PGTOPO_BE_ERROR()
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
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 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)
static int _lwt_FirstDistinctVertex2D(const POINTARRAY *pa, const POINT2D *ref, int from, int dir, POINT2D *op)
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)
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, LWT_ELEMID myedge_id)
LWT_ELEMID containing_face