4489{
4492 int caseno = 0;
4494 uint64_t num_node_edges;
4499 uint64_t nedges, i;
4500 int e1freenode;
4501 int e2sign, e2freenode;
4503 char buf[256];
4504 char *ptr;
4505 size_t bufleft = 256;
4506
4507 ptr = buf;
4508
4509
4510 if ( eid1 == eid2 )
4511 {
4513 " with itself, try with another", eid1);
4514 return -1;
4515 }
4516 ids[0] = eid1;
4517 ids[1] = eid2;
4518 nedges = 2;
4520 if ((nedges == UINT64_MAX) || (edges == NULL))
4521 {
4523 return -1;
4524 }
4525 for ( i=0; i<nedges; ++i )
4526 {
4527 if ( edges[i].edge_id == eid1 ) {
4528 if ( e1 ) {
4530 lwerror(
"Corrupted topology: multiple edges have id %"
4532 return -1;
4533 }
4534 e1 = &(edges[i]);
4535 }
4536 else if ( edges[i].edge_id == eid2 ) {
4537 if ( e2 ) {
4539 lwerror(
"Corrupted topology: multiple edges have id %"
4541 return -1;
4542 }
4543 e2 = &(edges[i]);
4544 }
4545 }
4546 if ( ! e1 )
4547 {
4550 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4551 eid1);
4552 return -1;
4553 }
4554 if ( ! e2 )
4555 {
4558 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4559 eid2);
4560 return -1;
4561 }
4562
4563
4565 {
4569 return -1;
4570 }
4572 {
4576 return -1;
4577 }
4578
4579
4580
4582 {
4584 caseno = 1;
4585 }
4587 {
4589 caseno = 2;
4590 }
4591
4592 if ( commonnode != -1 )
4593 {
4594 num_node_edges = 1;
4597 if (num_node_edges == UINT64_MAX)
4598 {
4601 return -1;
4602 }
4603 for (i=0; i<num_node_edges; ++i)
4604 {
4606 if ( node_edges[i].edge_id == eid1 ) continue;
4607 if ( node_edges[i].edge_id == eid2 ) continue;
4608 commonnode = -1;
4609
4610 if ( bufleft > 0 ) {
4612 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4613 if (
r >= (
int) bufleft )
4614 {
4615 bufleft = 0;
4616 buf[252] = '.';
4617 buf[253] = '.';
4618 buf[254] = '.';
4619 buf[255] = '\0';
4620 }
4621 else
4622 {
4625 }
4626 }
4627 }
4629 }
4630
4631 if ( commonnode == -1 )
4632 {
4634 {
4636 caseno = 3;
4637 }
4639 {
4641 caseno = 4;
4642 }
4643
4644 if ( commonnode != -1 )
4645 {
4646 num_node_edges = 1;
4649 if (num_node_edges == UINT64_MAX)
4650 {
4653 return -1;
4654 }
4655 for (i=0; i<num_node_edges; ++i)
4656 {
4658 if ( node_edges[i].edge_id == eid1 ) continue;
4659 if ( node_edges[i].edge_id == eid2 ) continue;
4660 commonnode = -1;
4661
4662 if ( bufleft > 0 ) {
4664 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4665 if (
r >= (
int) bufleft )
4666 {
4667 bufleft = 0;
4668 buf[252] = '.';
4669 buf[253] = '.';
4670 buf[254] = '.';
4671 buf[255] = '\0';
4672 }
4673 else
4674 {
4677 }
4678 }
4679 }
4680 if ( num_node_edges )
lwfree(node_edges);
4681 }
4682 }
4683
4684 if ( commonnode == -1 )
4685 {
4687 if ( ptr != buf )
4688 {
4689 lwerror(
"SQL/MM Spatial exception - other edges connected (%s)",
4690 buf);
4691 }
4692 else
4693 {
4694 lwerror(
"SQL/MM Spatial exception - non-connected edges");
4695 }
4696 return -1;
4697 }
4698
4700 eid1, eid2 ) )
4701 {
4704 return -1;
4705 }
4706
4707
4708 switch (caseno)
4709 {
4710 case 1:
4712
4718 e1freenode = 1;
4719 e2freenode = -1;
4720 e2sign = 1;
4721 break;
4722 case 2:
4723 {
4728
4735 e1freenode = 1;
4736 e2freenode = 1;
4737 e2sign = -1;
4738 break;
4739 }
4740 case 3:
4743
4749 e1freenode = -1;
4750 e2freenode = -1;
4751 e2sign = -1;
4752 break;
4753 case 4:
4755
4761 e1freenode = -1;
4762 e2freenode = 1;
4763 e2sign = 1;
4764 break;
4765 default:
4766 pa = NULL;
4767 e1freenode = 0;
4768 e2freenode = 0;
4769 e2sign = 0;
4771 lwerror(
"Coding error: caseno=%d should never happen", caseno);
4772 return -1;
4773 break;
4774 }
4776
4777 if ( modEdge )
4778 {
4779
4782 &newedge,
4783 1,
4787 {
4791 return -1;
4792 }
4794 {
4797 lwerror(
"Unexpected error: %" PRIu64
" edges updated when expecting 1", i);
4798 return -1;
4799 }
4800 }
4801 else
4802 {
4803
4809 {
4813 return -1;
4814 }
4816 {
4819 lwerror(
"Insertion of split edge failed (no reason)");
4820 return -1;
4821 }
4822 }
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4844 {
4847 return -1;
4848 }
4849
4850
4855 {
4858 return -1;
4859 }
4860
4861 if ( ! modEdge )
4862 {
4863
4868 {
4871 return -1;
4872 }
4873
4874
4879 {
4882 return -1;
4883 }
4884 }
4885
4886
4889 {
4892 return -1;
4893 }
4894 if ( ! modEdge ) {
4897 {
4900 return -1;
4901 }
4902 }
4903
4905
4906
4909 {
4911 return -1;
4912 }
4913
4914
4915
4916
4917
4918
4919
4920
4921
4923 eid1, eid2, newedge.
edge_id) )
4924 {
4926 return -1;
4927 }
4928
4929 return modEdge ? commonnode : newedge.
edge_id;
4930}
char result[OUT_DOUBLE_BUFFER_SIZE]
int ptarray_append_ptarray(POINTARRAY *pa1, POINTARRAY *pa2, double gap_tolerance)
Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
void ptarray_free(POINTARRAY *pa)
void lwline_free(LWLINE *line)
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
void ptarray_reverse_in_place(POINTARRAY *pa)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_START_NODE
#define LWT_COL_EDGE_NEXT_RIGHT
#define LWT_COL_EDGE_EDGE_ID
Edge fields.
#define LWT_COL_EDGE_END_NODE
#define LWT_COL_EDGE_NEXT_LEFT
#define LWT_COL_EDGE_GEOM
#define PGTOPO_BE_ERROR()
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static int lwt_be_deleteNodesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
static int lwt_be_updateTopoGeomEdgeHeal(LWT_TOPOLOGY *topo, LWT_ELEMID edge1, LWT_ELEMID edge2, LWT_ELEMID newedge)
static int lwt_be_checkTopoGeomRemNode(LWT_TOPOLOGY *topo, LWT_ELEMID node_id, LWT_ELEMID eid1, LWT_ELEMID eid2)
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)
int lwt_be_deleteEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_fields)
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
int lwt_be_updateEdgesById(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *edges, int numedges, int upd_fields)
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
LWT_ISO_EDGE * lwt_be_getEdgeByNode(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
const LWT_BE_IFACE * be_iface