4205{
4208 int caseno = 0;
4210 uint64_t num_node_edges;
4215 uint64_t nedges, i;
4216 int e1freenode;
4217 int e2sign, e2freenode;
4219 char buf[256];
4220 char *ptr;
4221 size_t bufleft = 256;
4222
4223 ptr = buf;
4224
4225
4226 if ( eid1 == eid2 )
4227 {
4229 " with itself, try with another", eid1);
4230 return -1;
4231 }
4232 ids[0] = eid1;
4233 ids[1] = eid2;
4234 nedges = 2;
4236 if ((nedges == UINT64_MAX) || (edges == NULL))
4237 {
4239 return -1;
4240 }
4241 for ( i=0; i<nedges; ++i )
4242 {
4243 if ( edges[i].edge_id == eid1 ) {
4244 if ( e1 ) {
4246 lwerror(
"Corrupted topology: multiple edges have id %"
4248 return -1;
4249 }
4250 e1 = &(edges[i]);
4251 }
4252 else if ( edges[i].edge_id == eid2 ) {
4253 if ( e2 ) {
4255 lwerror(
"Corrupted topology: multiple edges have id %"
4257 return -1;
4258 }
4259 e2 = &(edges[i]);
4260 }
4261 }
4262 if ( ! e1 )
4263 {
4266 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4267 eid1);
4268 return -1;
4269 }
4270 if ( ! e2 )
4271 {
4274 "SQL/MM Spatial exception - non-existent edge %" LWTFMT_ELEMID,
4275 eid2);
4276 return -1;
4277 }
4278
4279
4281 {
4285 return -1;
4286 }
4288 {
4292 return -1;
4293 }
4294
4295
4296
4298 {
4300 caseno = 1;
4301 }
4303 {
4305 caseno = 2;
4306 }
4307
4308 if ( commonnode != -1 )
4309 {
4310 num_node_edges = 1;
4313 if (num_node_edges == UINT64_MAX)
4314 {
4317 return -1;
4318 }
4319 for (i=0; i<num_node_edges; ++i)
4320 {
4322 if ( node_edges[i].edge_id == eid1 ) continue;
4323 if ( node_edges[i].edge_id == eid2 ) continue;
4324 commonnode = -1;
4325
4326 if ( bufleft > 0 ) {
4328 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4329 if (
r >= (
int) bufleft )
4330 {
4331 bufleft = 0;
4332 buf[252] = '.';
4333 buf[253] = '.';
4334 buf[254] = '.';
4335 buf[255] = '\0';
4336 }
4337 else
4338 {
4341 }
4342 }
4343 }
4345 }
4346
4347 if ( commonnode == -1 )
4348 {
4350 {
4352 caseno = 3;
4353 }
4355 {
4357 caseno = 4;
4358 }
4359
4360 if ( commonnode != -1 )
4361 {
4362 num_node_edges = 1;
4365 if (num_node_edges == UINT64_MAX)
4366 {
4369 return -1;
4370 }
4371 for (i=0; i<num_node_edges; ++i)
4372 {
4374 if ( node_edges[i].edge_id == eid1 ) continue;
4375 if ( node_edges[i].edge_id == eid2 ) continue;
4376 commonnode = -1;
4377
4378 if ( bufleft > 0 ) {
4380 ( ptr==buf ? "" : "," ), node_edges[i].edge_id);
4381 if (
r >= (
int) bufleft )
4382 {
4383 bufleft = 0;
4384 buf[252] = '.';
4385 buf[253] = '.';
4386 buf[254] = '.';
4387 buf[255] = '\0';
4388 }
4389 else
4390 {
4393 }
4394 }
4395 }
4396 if ( num_node_edges )
lwfree(node_edges);
4397 }
4398 }
4399
4400 if ( commonnode == -1 )
4401 {
4403 if ( ptr != buf )
4404 {
4405 lwerror(
"SQL/MM Spatial exception - other edges connected (%s)",
4406 buf);
4407 }
4408 else
4409 {
4410 lwerror(
"SQL/MM Spatial exception - non-connected edges");
4411 }
4412 return -1;
4413 }
4414
4416 eid1, eid2 ) )
4417 {
4420 return -1;
4421 }
4422
4423
4424 switch (caseno)
4425 {
4426 case 1:
4428
4434 e1freenode = 1;
4435 e2freenode = -1;
4436 e2sign = 1;
4437 break;
4438 case 2:
4439 {
4444
4451 e1freenode = 1;
4452 e2freenode = 1;
4453 e2sign = -1;
4454 break;
4455 }
4456 case 3:
4459
4465 e1freenode = -1;
4466 e2freenode = -1;
4467 e2sign = -1;
4468 break;
4469 case 4:
4471
4477 e1freenode = -1;
4478 e2freenode = 1;
4479 e2sign = 1;
4480 break;
4481 default:
4482 pa = NULL;
4483 e1freenode = 0;
4484 e2freenode = 0;
4485 e2sign = 0;
4487 lwerror(
"Coding error: caseno=%d should never happen", caseno);
4488 break;
4489 }
4491
4492 if ( modEdge )
4493 {
4494
4497 &newedge,
4498 1,
4501 if (result == -1)
4502 {
4506 return -1;
4507 }
4508 else if (result != 1)
4509 {
4512 lwerror(
"Unexpected error: %d edges updated when expecting 1", i);
4513 return -1;
4514 }
4515 }
4516 else
4517 {
4518
4523 if (result == -1)
4524 {
4528 return -1;
4529 }
4530 else if (result == 0)
4531 {
4534 lwerror(
"Insertion of split edge failed (no reason)");
4535 return -1;
4536 }
4537 }
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4558 if (result == -1)
4559 {
4562 return -1;
4563 }
4564
4565
4569 if (result == -1)
4570 {
4573 return -1;
4574 }
4575
4576 if ( ! modEdge )
4577 {
4578
4582 if (result == -1)
4583 {
4586 return -1;
4587 }
4588
4589
4593 if (result == -1)
4594 {
4597 return -1;
4598 }
4599 }
4600
4601
4603 if (result == -1)
4604 {
4607 return -1;
4608 }
4609 if ( ! modEdge ) {
4611 if (result == -1)
4612 {
4615 return -1;
4616 }
4617 }
4618
4620
4621
4623 if (result == -1)
4624 {
4626 return -1;
4627 }
4628
4629
4630
4631
4632
4633
4634
4635
4636
4638 eid1, eid2, newedge.
edge_id) )
4639 {
4641 return -1;
4642 }
4643
4644 return modEdge ? commonnode : newedge.
edge_id;
4645}
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
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static LWT_ISO_EDGE * lwt_be_getEdgeByNode(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
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)
int lwt_be_insertEdges(LWT_TOPOLOGY *topo, LWT_ISO_EDGE *edge, uint64_t numelems)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
static int lwt_be_updateEdgesById(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *edges, int numedges, int upd_fields)
const LWT_BE_IFACE * be_iface