5309 if ( splitC->
ngeoms != 2 )
5311 lwerror(
"Split of edge resulted in %d components", splitC->
ngeoms);
5316 if ( ! firstNodeEdges ) {
5317 lwerror(
"No edges found in DB to be incident to split edge's first node");
5321 if ( ! lastNodeEdges ) {
5322 lwerror(
"No edges found in DB to be incident to split edge's last node");
5326 if ( ! splitNodeEdges ) {
5327 lwerror(
"No edges found in DB to be incident to split node");
5332 for ( uint64_t t=0; t<firstNodeEdges->
numEdges; t++ )
5336 edge = &(firstNodeEdges->
edges[t]);
5365 for ( n=0; n<2; ++n)
5370 if ( existingEdgeId == -1 )
5375 existingEdges[n] = NULL;
5376 if ( existingEdgeId == 0 )
5378 LWDEBUGF(1,
"Split component %llu is a new edge, computing edgeEndInfo", n);
5394 lwerror(
"No distinct vertices found on second part of split edge");
5408 lwerror(
"No distinct vertices found on first part of split edge");
5412 if ( !
azimuth_pt_pt(pt, &op, &(splitNodeEdgeEnds[n].myaz)) ) {
5413 lwerror(
"error computing azimuth of split endpoint [%.15g %.15g,%.15g %.15g]",
5419 LWDEBUGF(1,
"Azimuth of split component %llu edgeend [%.15g %.15g,%.15g %.15g] is %.15g",
5420 n, op.
x, op.
y, pt->
x, pt->
y, splitNodeEdgeEnds[n].myaz);
5423 lwerror(
"Unexpected backend return: _lwt_FindAdjacentEdges(%"
5424 LWTFMT_ELEMID ") found no edges when we previously split edge %"
5431 n, edge->
edge_id, splitNodeEdgeEnds[n].nextCW, splitNodeEdgeEnds[n].nextCCW);
5437 " (%s)", n, existingEdgeId, forward ?
"forward" :
"backward" );
5439 for ( uint64_t t=0; t<splitNodeEdges->
numEdges; t++ )
5441 if ( splitNodeEdges->
edges[t].
edge_id == existingEdgeId )
5443 existingEdges[n] = &(splitNodeEdges->
edges[t]);
5447 if (existingEdges[n] == NULL)
5449 lwerror(
"could not find edge %" LWTFMT_ELEMID " in database, but _lwt_GetEqualEdges said it was there", existingEdgeId );
5454 replacedBy[n] = existingEdgeId;
5462 if ( ( replacedBy[0] != 0 && replacedBy[1] == 0 ) ||
5463 ( replacedBy[1] != 0 && replacedBy[0] == 0 ) )
5468 edgeend *splitNodeEdgeEndInfo;
5469 LWLINE *newSplitEdgeLine;
5470 int splitNodeNewEdgeOutgoing;
5472 if ( replacedBy[1] == 0 )
5475 existingEdge = existingEdges[0];
5477 splitNodeEdgeEndInfo = &(splitNodeEdgeEnds[1]);
5478 splitNodeNewEdgeOutgoing = 1;
5483 existingEdge = existingEdges[1];
5485 splitNodeEdgeEndInfo = &(splitNodeEdgeEnds[0]);
5486 splitNodeNewEdgeOutgoing = 0;
5518 if ( splitNodeNewEdgeOutgoing ) {
5528 splitNodeEdgeEndInfo->
nextCCW,
5532 if ( splitNodeEdgeEndInfo->
nextCCW > 0 )
5561 &updatedEdge, updateFlags,
5566 }
else if ( ret == 0 ) {
5569 }
else if ( ret > 1 ) {
5570 lwerror(
"More than a single edge found with id %"
5579 if ( splitNodeNewEdgeOutgoing ) {
5587 splitNodeEdgeEndInfo->
nextCW, sideFace
5590 if ( splitNodeEdgeEndInfo->
nextCW > 0 )
5596 ", outgoing next CW of new split edge on split node",
5605 ", incoming next CW of new split edge on split node",
5611 &updatedEdge, updateFlags,
5616 }
else if ( ret == 0 ) {
5619 }
else if ( ret > 1 ) {
5620 lwerror(
"More than a single edge found with edge_id %"
5633 int nextCCWEdgeIsIncoming = 0;
5634 int collapsedEdgeIsIncoming;
5639 if ( replacedBy[0] ) {
5640 commonNodeEdges = firstNodeEdges;
5642 collapsedEdgeIsIncoming = 0;
5644 commonNodeEdges = lastNodeEdges;
5646 collapsedEdgeIsIncoming = 1;
5654 LWDEBUGF(1,
"Looking for next CCW edge of split edge %"
5656 " having %llu attached edges",
5658 commonNodeID, commonNodeEdges->
numEdges
5662 for ( uint64_t t=0; t<commonNodeEdges->
numEdges; t++ )
5676 if ( et->
next_right == signedCollapsedEdgeID )
5679 nextCCWEdgeIsIncoming = 0;
5683 else if ( et->
end_node == commonNodeID )
5685 if ( et->
next_left == signedCollapsedEdgeID )
5688 nextCCWEdgeIsIncoming = 1;
5693 if ( ! nextCCWEdge )
5701 LWDEBUGF(1,
"Next CCW edge of split edge %"
5706 nextCCWEdgeIsIncoming ?
"incoming" :
"outgoing",
5712 LWDEBUG(1,
"Next CCW edge is existing/collapse edge, will not update here");
5729 if ( nextCCWEdgeIsIncoming ) {
5732 LWDEBUGF(1,
"Updating next_left of incoming next CCW edge %"
5741 LWDEBUGF(1,
"Updating next_right of outgoing next CCW edge %"
5750 &updatedEdge, updateFlags,
5755 }
else if ( ret == 0 ) {
5758 }
else if ( ret > 1 ) {
5759 lwerror(
"More than a single edge found with next_left %"
5778 LWDEBUGF(1,
"Will update next_left of existing edge %"
5788 LWDEBUGF(1,
"Will update next_right of existing edge %"
5798 LWDEBUGF(1,
"Will update next_left of existing edge %"
5808 LWDEBUGF(1,
"Will update next_right of existing edge %"
5818 &updatedEdge, updateFlags,
5823 }
else if ( ret == 0 ) {
5826 }
else if ( ret > 1 ) {
5827 lwerror(
"More than a single edge found with id %"
5840 updatedEdge.
geom = newSplitEdgeLine;
5842 if ( splitNodeNewEdgeOutgoing ) {
5871 &updatedEdge, updateFlags,
5876 }
else if ( ret == 0 ) {
5879 }
else if ( ret > 1 ) {
5880 lwerror(
"More than a single edge found with id %"
5969 else if ( replacedBy[0] == 0 && replacedBy[1] == 0 )
5977 if ( newEdge.
edge_id == -1 ) {
6001 for ( uint64_t t=0; t<splitNodeEdges->
numEdges; t++ )
6023 int splitFaceOnLeft = 1;
6026 splitFaceOnLeft = 0;
6054 }
else if ( ret == 0 ) {
6057 }
else if ( ret > 1 ) {
6058 lwerror(
"More than a single edge found with id %"
6082 &updatedEdge, updateFlags,
6087 }
else if ( ret == 0 ) {
6090 }
else if ( ret > 1 ) {
6091 lwerror(
"More than a single edge found with id %"
6116 &updatedEdge, updateFlags,
6121 }
else if ( ret == 0 ) {
6124 }
else if ( ret > 1 ) {
6125 lwerror(
"More than a single edge found with id %"
6134 for ( uint64_t t=0; t<lastNodeEdges->
numEdges; t++ )
6156 if ( updateFlags != 0 )
6163 &updatedEdge, updateFlags,
6168 }
else if ( ret == 0 ) {
6171 }
else if ( ret > 1 ) {
6172 lwerror(
"More than a single edge found with id %"
6182 if ( splitFaceOnLeft ) {
6206 -newEdge.
edge_id, newFaceId1);
6231 newFaceId1, newFaceId2, oldFaceId);
6232 if ( newFaceId1 || newFaceId2 )
6236 newFaceId1 ? newFaceId1 : oldFaceId,
6237 newFaceId2 ? newFaceId2 : oldFaceId
6244 if ( newFaceId1 && newFaceId2 )
6258 else if ( replacedBy[0] != 0 && replacedBy[1] != 0 )
6292 for ( uint64_t t=0; t<firstNodeEdges->
numEdges; t++ )
6321 if ( updateFlags != 0 )
6328 &updatedEdge, updateFlags,
6333 }
else if ( ret == 0 ) {
6336 }
else if ( ret > 1 ) {
6337 lwerror(
"More than a single edge found with id %"
6345 for ( uint64_t t=0; t<lastNodeEdges->
numEdges; t++ )
6372 if ( updateFlags != 0 )
6379 &updatedEdge, updateFlags,
6384 }
else if ( ret == 0 ) {
6387 }
else if ( ret > 1 ) {
6388 lwerror(
"More than a single edge found with id %"
6414 &updatedEdge, updateFlags,
6419 }
else if ( ret == 0 ) {
6422 }
else if ( ret > 1 ) {
6423 lwerror(
"More than a single edge found with id %"
6448 &updatedEdge, updateFlags,
6453 }
else if ( ret == 0 ) {
6456 }
else if ( ret > 1 ) {
6457 lwerror(
"More than a single edge found with id %"
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
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)
LWGEOM * lwgeom_split(const LWGEOM *lwgeom_in, const LWGEOM *blade_in)
LWGEOM * lwgeom_snap(const LWGEOM *geom1, const LWGEOM *geom2, double tolerance)
Snap vertices and segments of a geometry to another using a given tolerance.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
#define LWT_COL_EDGE_FACE_RIGHT
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_START_NODE
#define LWT_COL_EDGE_FACE_LEFT
#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()
#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.
#define LWDEBUGG(level, geom, msg)
static uint64_t lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, uint64_t numfaces)
static int lwt_be_deleteFacesById(const LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t numelems)
LWGEOM * lwt_GetFaceGeometry(LWT_TOPOLOGY *topo, LWT_ELEMID faceid)
Return the geometry of a face.
static int _lwt_SnapEdge_checkMotion(LWT_TOPOLOGY *topo, const LWCOLLECTION *splitC, const LWT_ISO_EDGE *edge, LWT_ISO_EDGE *existingEdge, const LWT_NODE_EDGES *splitNodeEdges)
Check the motion of a snapped edge, invoke lwerror if the movement hits any other edge or node.
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_be_updateTopoGeomFaceHeal(LWT_TOPOLOGY *topo, LWT_ELEMID face1, LWT_ELEMID face2, LWT_ELEMID newface)
int lwt_be_updateTopoGeomEdgeSplit(LWT_TOPOLOGY *topo, LWT_ELEMID split_edge, LWT_ELEMID new_edge1, LWT_ELEMID new_edge2)
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_GetEqualEdge(LWT_TOPOLOGY *topo, LWLINE *edge, int *forward)
int lwt_be_deleteEdges(LWT_TOPOLOGY *topo, const LWT_ISO_EDGE *sel_edge, int sel_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)
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, LWT_ELEMID myedge_id)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
static LWPOINT * lwgeom_as_lwpoint(const LWGEOM *lwgeom)
const LWT_EDGEEND * lwt_edgeEndStar_getNextCW(LWT_EDGEEND_STAR *star, LWT_ISO_EDGE *edge, int outgoing)
LWT_EDGEEND_STAR * lwt_edgeEndStar_init(LWT_ELEMID nodeID)
const LWT_EDGEEND * lwt_edgeEndStar_getNextCCW(LWT_EDGEEND_STAR *star, LWT_ISO_EDGE *edge, int outgoing)
void lwt_EdgeEndStar_debugPrint(const LWT_EDGEEND_STAR *star)
void lwt_edgeEndStar_addEdge(LWT_EDGEEND_STAR *star, const LWT_ISO_EDGE *edge)
LWT_NODE_EDGES * lwt_nodeEdges_loadFromDB(LWT_TOPOLOGY *topo, LWT_ELEMID node_id, int fields)
const LWT_ISO_EDGE * edge