Changes the shape of an edge without affecting the topology structure.
3190{
3194 uint64_t i;
3195 int isclosed = 0;
3196
3197
3199 {
3200 lwerror(
"SQL/MM Spatial exception - curve not simple");
3201 return -1;
3202 }
3203
3204 i = 1;
3206 if ( ! oldedge )
3207 {
3209 "lwt_be_getEdgeById returned NULL and set i=%d", i);
3210 if (i == UINT64_MAX)
3211 {
3213 return -1;
3214 }
3215 else if ( i == 0 )
3216 {
3217 lwerror(
"SQL/MM Spatial exception - non-existent edge %"
3219 return -1;
3220 }
3221 else
3222 {
3223 lwerror(
"Backend coding error: getEdgeById callback returned NULL "
3224 "but numelements output parameter has value %d "
3225 "(expected 0 or 1)", i);
3226 return -1;
3227 }
3228 }
3229
3231 "old edge has %d points, new edge has %d points",
3233
3234
3235
3236
3240 {
3242 lwerror(
"SQL/MM Spatial exception - "
3243 "start node not geometry start point.");
3244 return -1;
3245 }
3246
3247
3248
3249
3251 {
3254 " has less than 2 vertices", oldedge->
edge_id);
3255 return -1;
3256 }
3259 {
3261 lwerror(
"Invalid edge: less than 2 vertices");
3262 return -1;
3263 }
3266 {
3268 lwerror(
"SQL/MM Spatial exception - "
3269 "end node not geometry end point.");
3270 return -1;
3271 }
3272
3273
3274
3275
3276
3278 {
3279 isclosed = 1;
3280#if 1
3281
3283 {
3285 lwerror(
"Invalid edge (no two distinct vertices exist)");
3286 return -1;
3287 }
3288#endif
3289
3292 {
3294 lwerror(
"Edge twist at node POINT(%g %g)", p1.
x, p1.
y);
3295 return -1;
3296 }
3297 }
3298
3300 oldedge->
end_node, geom, edge_id ) )
3301 {
3302
3304 return -1;
3305 }
3306
3307 LWDEBUG(1,
"lwt_ChangeEdgeGeom: "
3308 "edge crossing check passed ");
3309
3310
3311
3312
3313
3314
3315
3316
3321
3323 uint64_t numnodes;
3326 LWDEBUGF(1,
"lwt_be_getNodeWithinBox2D returned %d nodes", numnodes);
3327 if (numnodes == UINT64_MAX)
3328 {
3331 return -1;
3332 }
3333
3334 if ( numnodes > ( 1 + isclosed ? 0 : 1 ) )
3335 {{
3336
3337 for (i=0; i<numnodes; ++i)
3338 {
3345 if (ocont != ncont)
3346 {
3347 size_t sz;
3350 lwerror(
"Edge motion collision at %s", wkt);
3352 return -1;
3353 }
3354 }
3355 }}
3357
3358 LWDEBUG(1,
"nodes containment check passed");
3359
3360
3361
3362
3363
3364
3366
3368 if (res)
3369 return -1;
3371 isclosed ? &epan_pre : NULL, edge_id );
3373 isclosed ? &span_pre : NULL, edge_id );
3374
3380
3381
3383 newedge.
geom = geom;
3385 if (res == -1)
3386 {
3389 return -1;
3390 }
3391 if (!res)
3392 {
3394 lwerror(
"Unexpected error: %d edges updated when expecting 1", i);
3395 return -1;
3396 }
3397
3398
3399
3400
3402
3404 if (res)
3405 return -1;
3407 isclosed ? &epan_post : NULL, edge_id );
3409 isclosed ? &span_post : NULL, edge_id );
3410
3416
3417
3418
3421 {{
3424 lwerror(
"Edge changed disposition around start node %"
3426 return -1;
3427 }}
3428
3429
3432 {{
3435 lwerror(
"Edge changed disposition around end node %"
3437 return -1;
3438 }}
3439
3440
3441
3442
3443
3444
3445
3446
3447
3451 {
3452 uint64_t facestoupdate = 0;
3457 {
3459 if ( ! nface1 )
3460 {
3461 lwerror(
"lwt_ChangeEdgeGeom could not construct face %"
3464 return -1;
3465 }
3466 #if 0
3467 {
3468 size_t sz;
3470 LWDEBUGF(1,
"new geometry of face left (%d): %s", (
int)oldedge->
face_left, wkt);
3472 }
3473 #endif
3475 if ( ! nface1->
bbox )
3476 {
3477 lwerror(
"Corrupted topology: face %d, left of edge %d, has no bbox",
3479 return -1;
3480 }
3482
3483 faces[facestoupdate++].
mbr = nface1->
bbox;
3484 }
3486
3488 {
3490 if ( ! nface2 )
3491 {
3492 lwerror(
"lwt_ChangeEdgeGeom could not construct face %"
3495 return -1;
3496 }
3497 #if 0
3498 {
3499 size_t sz;
3503 }
3504 #endif
3506 if ( ! nface2->
bbox )
3507 {
3508 lwerror(
"Corrupted topology: face %d, right of edge %d, has no bbox",
3510 return -1;
3511 }
3513 faces[facestoupdate++].
mbr = nface2->
bbox;
3514 }
3515 LWDEBUGF(1,
"%d faces to update", facestoupdate);
3516 if ( facestoupdate )
3517 {
3519 if (updatedFaces != facestoupdate)
3520 {
3521 if (nface1)
3523 if (nface2)
3526 if (updatedFaces == UINT64_MAX)
3528 else
3529 lwerror(
"Unexpected error: %d faces found when expecting 1", i);
3530 return -1;
3531 }
3532 }
3535 }
3536 else
3537 {
3538 lwnotice(
"BBOX of changed edge did not change");
3539 }
3540
3541 LWDEBUG(1,
"all done, cleaning up edges");
3542
3544 return 0;
3545}
int gbox_same(const GBOX *g1, const GBOX *g2)
Check if 2 given Gbox are the same.
int gbox_union(const GBOX *g1, const GBOX *g2, GBOX *gout)
Update the output GBOX to be large enough to include both inputs.
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
void lwgeom_free(LWGEOM *geom)
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
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)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
void lwgeom_add_bbox(LWGEOM *lwgeom)
Compute a bbox if not already computed.
int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
#define LW_INSIDE
Constants for point-in-polygon return values.
int ptarray_isccw(const POINTARRAY *pa)
int p2d_same(const POINT2D *p1, const POINT2D *p2)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_GEOM
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
static uint64_t lwt_be_updateFacesById(LWT_TOPOLOGY *topo, const LWT_ISO_FACE *faces, uint64_t numfaces)
static int _lwt_InitEdgeEndByLine(edgeend *fee, edgeend *lee, LWLINE *edge, POINT2D *fp, POINT2D *lp)
static int _lwt_GetInteriorEdgePoint(const LWLINE *edge, POINT2D *ip)
LWT_ISO_EDGE * lwt_be_getEdgeById(LWT_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *numelems, int fields)
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)
static int _lwt_FindAdjacentEdges(LWT_TOPOLOGY *topo, LWT_ELEMID node, edgeend *data, edgeend *other, int myedge_id)
const char * lwt_be_lastErrorMessage(const LWT_BE_IFACE *be)
static LWT_ISO_NODE * lwt_be_getNodeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
LWGEOM * lwt_GetFaceGeometry(LWT_TOPOLOGY *topo, LWT_ELEMID faceid)
Return the geometry of a face.
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)
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
const LWT_BE_IFACE * be_iface