4372{
4375 int caseno = 0;
4377 uint64_t num_node_edges;
4382 uint64_t nedges, i;
4383 int e1freenode;
4384 int e2sign, e2freenode;
4386 char buf[256];
4387 char *ptr;
4388 size_t bufleft = 256;
4389
4390 ptr = buf;
4391
4392
4393 if ( eid1 == eid2 )
4394 {
4396 " with itself, try with another", eid1);
4397 return -1;
4398 }
4399 ids[0] = eid1;
4400 ids[1] = eid2;
4401 nedges = 2;
4403 if ((nedges == UINT64_MAX) || (edges == NULL))
4404 {
4406 return -1;
4407 }
4408 for ( i=0; i<nedges; ++i )
4409 {
4410 if ( edges[i].edge_id == eid1 ) {
4411 if ( e1 ) {
4413 lwerror(
"Corrupted topology: multiple edges have id %"
4415 return -1;
4416 }
4417 e1 = &(edges[i]);
4418 }
4419 else if ( edges[i].edge_id == eid2 ) {
4420 if ( e2 ) {
4422 lwerror(
"Corrupted topology: multiple edges have id %"
4424 return -1;
4425 }
4426 e2 = &(edges[i]);
4427 }
4428 }
4429 if ( ! e1 )
4430 {
4433 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4434 eid1);
4435 return -1;
4436 }
4437 if ( ! e2 )
4438 {
4441 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4442 eid2);
4443 return -1;
4444 }
4445
4446
4448 {
4452 return -1;
4453 }
4455 {
4459 return -1;
4460 }
4461
4462
4463
4465 {
4467 caseno = 1;
4468 }
4470 {
4472 caseno = 2;
4473 }
4474
4475 if ( commonnode != -1 )
4476 {
4477 num_node_edges = 1;
4480 if (num_node_edges == UINT64_MAX)
4481 {
4484 return -1;
4485 }
4486 for (i=0; i<num_node_edges; ++i)
4487 {
4489 if ( node_edges[i].edge_id == eid1 ) continue;
4490 if ( node_edges[i].edge_id == eid2 ) continue;
4491 commonnode = -1;
4492
4493 if ( bufleft > 0 ) {
4495 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4496 if (
r >= (
int) bufleft )
4497 {
4498 bufleft = 0;
4499 buf[252] = '.';
4500 buf[253] = '.';
4501 buf[254] = '.';
4502 buf[255] = '\0';
4503 }
4504 else
4505 {
4508 }
4509 }
4510 }
4512 }
4513
4514 if ( commonnode == -1 )
4515 {
4517 {
4519 caseno = 3;
4520 }
4522 {
4524 caseno = 4;
4525 }
4526
4527 if ( commonnode != -1 )
4528 {
4529 num_node_edges = 1;
4532 if (num_node_edges == UINT64_MAX)
4533 {
4536 return -1;
4537 }
4538 for (i=0; i<num_node_edges; ++i)
4539 {
4541 if ( node_edges[i].edge_id == eid1 ) continue;
4542 if ( node_edges[i].edge_id == eid2 ) continue;
4543 commonnode = -1;
4544
4545 if ( bufleft > 0 ) {
4547 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4548 if (
r >= (
int) bufleft )
4549 {
4550 bufleft = 0;
4551 buf[252] = '.';
4552 buf[253] = '.';
4553 buf[254] = '.';
4554 buf[255] = '\0';
4555 }
4556 else
4557 {
4560 }
4561 }
4562 }
4563 if ( num_node_edges )
lwfree(node_edges);
4564 }
4565 }
4566
4567 if ( commonnode == -1 )
4568 {
4570 if ( ptr != buf )
4571 {
4572 lwerror(
"SQL/MM Spatial exception - other edges connected (%s)",
4573 buf);
4574 }
4575 else
4576 {
4577 lwerror(
"SQL/MM Spatial exception - non-connected edges");
4578 }
4579 return -1;
4580 }
4581
4583 eid1, eid2 ) )
4584 {
4587 return -1;
4588 }
4589
4590
4591 switch (caseno)
4592 {
4593 case 1:
4595
4601 e1freenode = 1;
4602 e2freenode = -1;
4603 e2sign = 1;
4604 break;
4605 case 2:
4606 {
4611
4618 e1freenode = 1;
4619 e2freenode = 1;
4620 e2sign = -1;
4621 break;
4622 }
4623 case 3:
4626
4632 e1freenode = -1;
4633 e2freenode = -1;
4634 e2sign = -1;
4635 break;
4636 case 4:
4638
4644 e1freenode = -1;
4645 e2freenode = 1;
4646 e2sign = 1;
4647 break;
4648 default:
4649 pa = NULL;
4650 e1freenode = 0;
4651 e2freenode = 0;
4652 e2sign = 0;
4654 lwerror(
"Coding error: caseno=%d should never happen", caseno);
4655 return -1;
4656 break;
4657 }
4659
4660 if ( modEdge )
4661 {
4662
4665 &newedge,
4666 1,
4670 {
4674 return -1;
4675 }
4677 {
4680 lwerror(
"Unexpected error: %" PRIu64
" edges updated when expecting 1", i);
4681 return -1;
4682 }
4683 }
4684 else
4685 {
4686
4692 {
4696 return -1;
4697 }
4699 {
4702 lwerror(
"Insertion of split edge failed (no reason)");
4703 return -1;
4704 }
4705 }
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4727 {
4730 return -1;
4731 }
4732
4733
4738 {
4741 return -1;
4742 }
4743
4744 if ( ! modEdge )
4745 {
4746
4751 {
4754 return -1;
4755 }
4756
4757
4762 {
4765 return -1;
4766 }
4767 }
4768
4769
4772 {
4775 return -1;
4776 }
4777 if ( ! modEdge ) {
4780 {
4783 return -1;
4784 }
4785 }
4786
4788
4789
4792 {
4794 return -1;
4795 }
4796
4797
4798
4799
4800
4801
4802
4803
4804
4806 eid1, eid2, newedge.
edge_id) )
4807 {
4809 return -1;
4810 }
4811
4812 return modEdge ? commonnode : newedge.
edge_id;
4813}
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