PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ _lwt_AddLine()

static LWT_ELEMID* _lwt_AddLine ( LWT_TOPOLOGY topo,
LWLINE line,
double  tol,
int *  nedges,
int  handleFaceSplit,
int  maxNewEdges 
)
static

Definition at line 7136 of file lwgeom_topo.c.

7138 {
7139  LWGEOM *geomsbuf[1];
7140  LWGEOM **geoms;
7141  uint32_t ngeoms;
7142  LWGEOM *noded, *tmp;
7143  LWCOLLECTION *col;
7144  LWT_ELEMID *ids;
7145  LWT_ISO_EDGE *edges;
7146  LWT_ISO_NODE *nodes;
7147  uint64_t num, numedges = 0, numnodes = 0;
7148  int num_new_edges = 0;
7149  uint64_t i;
7150  GBOX qbox;
7151  int forward;
7152  int input_was_closed = 0;
7153  POINT4D originalStartPoint;
7154 
7155  if ( lwline_is_empty(line) )
7156  {
7157  *nedges = 0;
7158  return NULL;
7159  }
7160 
7161  if ( lwline_is_closed(line) )
7162  {
7163  input_was_closed = 1;
7164  getPoint4d_p( line->points, 0, &originalStartPoint);
7165  LWDEBUGF(1, "Input line is closed, original point is %g,%g", originalStartPoint.x, originalStartPoint.y);
7166  }
7167 
7168  *nedges = -1; /* error condition, by default */
7169 
7170  /* Get tolerance, if 0 was given */
7171  if ( tol == -1 ) tol = _LWT_MINTOLERANCE( topo, (LWGEOM*)line );
7172  LWDEBUGF(1, "Working tolerance:%.15g", tol);
7173  LWDEBUGF(1, "Input line has srid=%d", line->srid);
7174 
7175  /* Remove consecutive vertices below given tolerance upfront */
7176  if ( tol )
7177  {{
7179  tmp = lwline_as_lwgeom(clean); /* NOTE: might collapse to non-simple */
7180  LWDEBUGG(1, tmp, "Repeated-point removed");
7181  }} else tmp=(LWGEOM*)line;
7182 
7183  /* 1. Self-node */
7184  noded = lwgeom_node((LWGEOM*)tmp);
7185  if ( tmp != (LWGEOM*)line ) lwgeom_free(tmp);
7186  if ( ! noded ) return NULL; /* should have called lwerror already */
7187  LWDEBUGG(1, noded, "Noded");
7188 
7189  qbox = *lwgeom_get_bbox( lwline_as_lwgeom(line) );
7190  LWDEBUGF(1, "Line BOX is %.15g %.15g, %.15g %.15g", qbox.xmin, qbox.ymin,
7191  qbox.xmax, qbox.ymax);
7192  gbox_expand(&qbox, tol);
7193  LWDEBUGF(1, "BOX expanded by %g is %.15g %.15g, %.15g %.15g",
7194  tol, qbox.xmin, qbox.ymin, qbox.xmax, qbox.ymax);
7195 
7196  LWGEOM **nearby = 0;
7197  int nearbyindex = 0;
7198  int nearbycount = 0;
7199 
7200  /* 2.0. Find edges falling within tol distance */
7201  edges = lwt_be_getEdgeWithinBox2D( topo, &qbox, &numedges, LWT_COL_EDGE_ALL, 0 );
7202  if (numedges == UINT64_MAX)
7203  {
7204  lwgeom_free(noded);
7205  PGTOPO_BE_ERROR();
7206  return NULL;
7207  }
7208  LWDEBUGF(1, "Line has %u points, its bbox intersects %llu edges bboxes",
7209  line->points->npoints, numedges);
7210  if ( numedges )
7211  {{
7212  /* TODO: compute earlier for reuse later ? */
7213  GEOSGeometry *noded_g = LWGEOM2GEOS(noded, 0);
7214  /* collect those whose distance from us is < tol */
7215  nearbycount += numedges;
7216  nearby = lwalloc(numedges * sizeof(LWGEOM *));
7217  for (i=0; i<numedges; ++i)
7218  {{
7219  LW_ON_INTERRUPT(return NULL);
7220  LWT_ISO_EDGE *e = &(edges[i]);
7221  LWGEOM *g = lwline_as_lwgeom(e->geom);
7222  GEOSGeometry *edge_g = LWGEOM2GEOS(g, 0);
7223  LWDEBUGF(2, "Computing distance from edge %" LWTFMT_ELEMID " with %u points", i, e->geom->points->npoints);
7224  double dist;
7225  if ( 0 == GEOSDistanceIndexed(edge_g, noded_g, &dist) ) {
7226  GEOSGeom_destroy(edge_g);
7227  GEOSGeom_destroy(noded_g);
7228  lwgeom_free(noded);
7229  lwerror("GEOSDistanceIndexed error: %s", lwgeom_geos_errmsg);
7230  return NULL;
7231  }
7232  GEOSGeom_destroy(edge_g);
7233  if ( dist && dist >= tol ) continue;
7234  nearby[nearbyindex++] = g;
7235  }}
7236  LWDEBUGF(1, "Found %d edges closer than tolerance (%g)", nearbyindex, tol);
7237  GEOSGeom_destroy(noded_g);
7238  }}
7239  int nearbyedgecount = nearbyindex;
7240 
7241  /* 2.1. Find isolated nodes falling within tol distance
7242  *
7243  * TODO: add backend-interface support for only getting isolated nodes
7244  */
7245  nodes = lwt_be_getNodeWithinBox2D( topo, &qbox, &numnodes, LWT_COL_NODE_ALL, 0 );
7246  if (numnodes == UINT64_MAX)
7247  {
7248  lwgeom_free(noded);
7249  PGTOPO_BE_ERROR();
7250  return NULL;
7251  }
7252  LWDEBUGF(1, "Line bbox intersects %llu nodes bboxes", numnodes);
7253  if ( numnodes )
7254  {{
7255  /* collect those whose distance from us is < tol */
7256  nearbycount = nearbyedgecount + numnodes;
7257  nearby = nearby ?
7258  lwrealloc(nearby, nearbycount * sizeof(LWGEOM *))
7259  :
7260  lwalloc(nearbycount * sizeof(LWGEOM *))
7261  ;
7262  int nn = 0;
7263  for (i=0; i<numnodes; ++i)
7264  {
7265  LWT_ISO_NODE *n = &(nodes[i]);
7266  if ( n->containing_face == -1 ) continue; /* skip not-isolated nodes */
7267  LWGEOM *g = lwpoint_as_lwgeom(n->geom);
7268  double dist = lwgeom_mindistance2d(g, noded);
7269  /* must be closer than tolerated, unless distance is zero */
7270  if ( dist && dist >= tol )
7271  {
7272  LWDEBUGF(1, "Node %" LWTFMT_ELEMID " is %g units away, we tolerate only %g", n->node_id, dist, tol);
7273  continue;
7274  }
7275  nearby[nearbyindex++] = g;
7276  nn = nn + 1;
7277  }
7278  LWDEBUGF(1, "Found %d isolated nodes closer than tolerance (%g)", nn, tol);
7279  }}
7280  int nearbynodecount = nearbyindex - nearbyedgecount;
7281  nearbycount = nearbyindex;
7282 
7283  LWDEBUGF(1, "Number of nearby elements is %d", nearbycount);
7284 
7285  /* 2.2. Snap to nearby elements */
7286  if ( nearbycount )
7287  {{
7288  LWCOLLECTION *col;
7289  LWGEOM *elems;
7290 
7292  NULL, nearbycount, nearby);
7293  elems = lwcollection_as_lwgeom(col);
7294 
7295  LWDEBUGG(1, elems, "Collected nearby elements");
7296 
7297  tmp = _lwt_toposnap(noded, elems, tol);
7298  lwgeom_free(noded);
7299  noded = tmp;
7300  LWDEBUGG(1, noded, "Elements-snapped");
7301  if ( input_was_closed )
7302  {{
7303  /* Recompute start point in case it moved */
7304  LWLINE *scrolled = lwgeom_as_lwline(noded);
7305  if (scrolled)
7306  {
7307  getPoint4d_p( scrolled->points, 0, &originalStartPoint);
7308  LWDEBUGF(1, "Closed input line start point after snap %g,%g", originalStartPoint.x, originalStartPoint.y);
7309  }
7310  }}
7311 
7312  /* will not release the geoms array */
7313  lwcollection_release(col);
7314 
7315  /*
7316  -- re-node to account for ST_Snap introduced self-intersections
7317  -- See http://trac.osgeo.org/postgis/ticket/1714
7318  -- TODO: consider running UnaryUnion once after all noding
7319  */
7320  tmp = lwgeom_unaryunion(noded);
7321  lwgeom_free(noded);
7322  noded = tmp;
7323  LWDEBUGG(1, noded, "Unary-unioned");
7324  }}
7325 
7326  /* 2.3. Node with nearby edges */
7327  if ( nearbyedgecount )
7328  {{
7329  LWCOLLECTION *col;
7330  LWGEOM *iedges; /* just an alias for col */
7331  LWGEOM *diff, *xset;
7332 
7333  LWDEBUGF(1, "Line intersects %d edges", nearbyedgecount);
7334 
7336  NULL, nearbyedgecount, nearby);
7337  iedges = lwcollection_as_lwgeom(col);
7338  LWDEBUGG(1, iedges, "Collected edges");
7339 
7340  LWDEBUGF(1, "Diffing noded, with srid=%d "
7341  "and intersecting edges, with srid=%d",
7342  noded->srid, iedges->srid);
7343  diff = lwgeom_difference(noded, iedges);
7344  LWDEBUGG(1, diff, "Differenced");
7345 
7346  LWDEBUGF(1, "Intersecting noded, with srid=%d "
7347  "and intersecting edges, with srid=%d",
7348  noded->srid, iedges->srid);
7349  xset = lwgeom_intersection(noded, iedges);
7350  LWDEBUGG(1, xset, "Intersected");
7351  lwgeom_free(noded);
7352 
7353  /* We linemerge here because INTERSECTION, as of GEOS 3.8,
7354  * will result in shared segments being output as multiple
7355  * lines rather than a single line. Example:
7356 
7357  INTERSECTION(
7358  'LINESTRING(0 0, 5 0, 8 0, 10 0,12 0)',
7359  'LINESTRING(5 0, 8 0, 10 0)'
7360  )
7361  ==
7362  MULTILINESTRING((5 0,8 0),(8 0,10 0))
7363 
7364  * We will re-split in a subsequent step, by splitting
7365  * the final line with pre-existing nodes
7366  */
7367  LWDEBUG(1, "Linemerging intersection");
7368  tmp = lwgeom_linemerge(xset);
7369  LWDEBUGG(1, tmp, "Linemerged");
7370  lwgeom_free(xset);
7371  xset = tmp;
7372 
7373  /*
7374  * Here we union the (linemerged) intersection with
7375  * the difference (new lines)
7376  */
7377  LWDEBUG(1, "Unioning difference and (linemerged) intersection");
7378  noded = lwgeom_union(diff, xset);
7379  LWDEBUGG(1, noded, "Diff-Xset Unioned");
7380  lwgeom_free(xset);
7381  lwgeom_free(diff);
7382 
7383  /* will not release the geoms array */
7384  lwcollection_release(col);
7385 
7386  if ( input_was_closed )
7387  {{
7388  LWLINE *scrolled = lwgeom_as_lwline(noded);
7389  if (scrolled) {
7390  if ( lwline_is_closed(scrolled) ) {
7391  ptarray_scroll_in_place(scrolled->points, &originalStartPoint);
7392  }
7393  else {
7394  LWDEBUGG(1, lwline_as_lwgeom(scrolled), "Closed input became non closed");
7395  }
7396  }
7397  else {
7398  LWDEBUGG(1, noded, "Diff-Xset Unioned cannot be scrolled");
7399  }
7400  }}
7401 
7402 
7403  }}
7404 
7405 
7406  /* 2.4. Split by pre-existing nodes
7407  *
7408  * Pre-existing nodes are isolated nodes AND endpoints
7409  * of intersecting edges
7410  */
7411  if ( nearbyedgecount )
7412  {
7413  nearbycount += nearbyedgecount * 2; /* make space for endpoints */
7414  nearby = lwrealloc(nearby, nearbycount * sizeof(LWGEOM *));
7415  for (int i=0; i<nearbyedgecount; i++)
7416  {
7417  LWLINE *edge = lwgeom_as_lwline(nearby[i]);
7418  LWPOINT *startNode = lwline_get_lwpoint(edge, 0);
7419  LWPOINT *endNode = lwline_get_lwpoint(edge, edge->points->npoints-1);
7420  /* TODO: only add if within distance to noded AND if not duplicated */
7421  nearby[nearbyindex++] = lwpoint_as_lwgeom(startNode);
7422  nearbynodecount++;
7423  nearby[nearbyindex++] = lwpoint_as_lwgeom(endNode);
7424  nearbynodecount++;
7425  }
7426  }
7427  if ( nearbynodecount )
7428  {
7430  NULL, nearbynodecount,
7431  nearby + nearbyedgecount);
7432  LWGEOM *inodes = lwcollection_as_lwgeom(col);
7433  /* TODO: use lwgeom_split of lwgeom_union ... */
7434  tmp = _lwt_split_by_nodes(noded, inodes);
7435  lwgeom_free(noded);
7436  noded = tmp;
7437  LWDEBUGG(1, noded, "Node-split");
7438  /* will not release the geoms array */
7439  lwcollection_release(col);
7440  }
7441 
7442 
7443  LWDEBUG(1, "Freeing up nearby elements");
7444 
7445  /* TODO: free up endpoints of nearbyedges */
7446  if ( nearby ) lwfree(nearby);
7447  if ( nodes ) _lwt_release_nodes(nodes, numnodes);
7448  if ( edges ) _lwt_release_edges(edges, numedges);
7449 
7450  LWDEBUGG(2, noded, "Finally-noded");
7451 
7452  /* 3. For each (now-noded) segment, insert an edge */
7453  col = lwgeom_as_lwcollection(noded);
7454  if ( col )
7455  {
7456  LWDEBUG(1, "Noded line was a collection");
7457  geoms = col->geoms;
7458  ngeoms = col->ngeoms;
7459  }
7460  else
7461  {
7462  LWDEBUG(1, "Noded line was a single geom");
7463  geomsbuf[0] = noded;
7464  geoms = geomsbuf;
7465  ngeoms = 1;
7466  }
7467 
7468  LWDEBUGF(1, "Line was split into %d edges", ngeoms);
7469 
7470  /* TODO: refactor to first add all nodes (re-snapping edges if
7471  * needed) and then check all edges for existing already
7472  * ( so to save a DB scan for each edge to be added )
7473  */
7474  ids = lwalloc(sizeof(LWT_ELEMID)*ngeoms);
7475  num = 0;
7476  for ( i=0; i<ngeoms; ++i )
7477  {
7478  int edgeNewEdges;
7479  LWT_ELEMID id;
7480  LWGEOM *g = geoms[i];
7481  g->srid = noded->srid;
7482 
7483 #if POSTGIS_DEBUG_LEVEL > 0
7484  {
7485  size_t sz;
7486  char *wkt1 = lwgeom_to_wkt(g, WKT_EXTENDED, 15, &sz);
7487  LWDEBUGF(1, "Component %llu of split line is: %s", i, wkt1);
7488  lwfree(wkt1);
7489  }
7490 #endif
7491 
7492  forward = -1; /* will be set to either 0 or 1 if the edge already existed */
7493  id = _lwt_AddLineEdge( topo, lwgeom_as_lwline(g), tol, handleFaceSplit, &forward, &edgeNewEdges );
7494  num_new_edges += edgeNewEdges;
7495  /* if forward is still == -1 this was NOT an existing edge ? */
7496  if ( forward == -1 )
7497  {
7498  ++num_new_edges;
7499  }
7500 
7501  LWDEBUGF(1, "_lwt_AddLineEdge returned %" LWTFMT_ELEMID
7502  " (forward ? %d), reported to create %d new edges (total new edges: %d)",
7503  id, forward, edgeNewEdges, num_new_edges);
7504  if ( id < 0 )
7505  {
7506  lwgeom_free(noded);
7507  lwfree(ids);
7508  return NULL;
7509  }
7510 
7511  if ( maxNewEdges >= 0 && num_new_edges > maxNewEdges )
7512  {
7513  lwgeom_free(noded);
7514  lwfree(ids);
7515  lwerror("Adding line to topology requires creating more edges than the requested limit of %d", maxNewEdges);
7516  return NULL;
7517  }
7518 
7519  if ( ! id )
7520  {
7521  LWDEBUGF(1, "Component %llu of split line collapsed", i);
7522  continue;
7523  }
7524 
7525  LWDEBUGF(1, "Component %llu of split line is %s edge %" LWTFMT_ELEMID,
7526  i, forward ? "forward" : "backward", id);
7527  ids[num++] = forward ? id : -id; /* TODO: skip duplicates */
7528  }
7529 
7530  LWDEBUGG(2, noded, "Noded before free");
7531  lwgeom_free(noded);
7532 
7533  /* TODO: XXX remove duplicated ids if not done before */
7534 
7535  *nedges = num;
7536  return ids;
7537 }
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
Definition: gbox.c:97
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition: lwgeom.c:207
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:367
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:337
#define COLLECTIONTYPE
Definition: liblwgeom.h:108
LWGEOM * lwgeom_node(const LWGEOM *lwgeom_in)
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1246
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
#define WKT_EXTENDED
Definition: liblwgeom.h:2221
#define MULTIPOINTTYPE
Definition: liblwgeom.h:105
LWGEOM * lwgeom_difference(const LWGEOM *geom1, const LWGEOM *geom2)
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:242
void lwfree(void *mem)
Definition: lwutil.c:248
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:372
LWGEOM * lwgeom_unaryunion(const LWGEOM *geom1)
void lwcollection_release(LWCOLLECTION *lwcollection)
Definition: lwcollection.c:36
double lwgeom_mindistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing min distance calculation.
Definition: measures.c:212
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition: lwgeom_api.c:125
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
Definition: lwout_wkt.c:708
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition: lwgeom.c:771
LWGEOM * lwgeom_linemerge(const LWGEOM *geom1)
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition: lwgeom.c:261
LWGEOM * lwgeom_union(const LWGEOM *geom1, const LWGEOM *geom2)
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition: lwline.c:319
LWGEOM * lwline_remove_repeated_points(const LWLINE *in, double tolerance)
Definition: lwline.c:449
int lwline_is_empty(const LWLINE *line)
#define LW_ON_INTERRUPT(x)
int lwline_is_closed(const LWLINE *line)
Definition: lwline.c:455
int ptarray_scroll_in_place(POINTARRAY *pa, const POINT4D *newbase)
Definition: ptarray.c:2337
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWT_COL_EDGE_ALL
#define LWT_COL_NODE_ALL
#define PGTOPO_BE_ERROR()
#define LWTFMT_ELEMID
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
#define LWDEBUGG(level, geom, msg)
Definition: lwgeom_log.h:111
static LWGEOM * _lwt_split_by_nodes(const LWGEOM *g, const LWGEOM *nodes)
Definition: lwgeom_topo.c:7114
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
Definition: lwgeom_topo.c:470
LWT_ISO_EDGE * lwt_be_getEdgeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
Definition: lwgeom_topo.c:173
void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
Definition: lwgeom_topo.c:460
static LWT_ISO_NODE * lwt_be_getNodeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
Definition: lwgeom_topo.c:167
#define _LWT_MINTOLERANCE(topo, geom)
Definition: lwgeom_topo.c:5062
static LWGEOM * _lwt_toposnap(LWGEOM *src, LWGEOM *tgt, double tol)
Definition: lwgeom_topo.c:423
static LWT_ELEMID _lwt_AddLineEdge(LWT_TOPOLOGY *topo, LWLINE *edge, double tol, int handleFaceSplit, int *forward, int *numNewEdges)
Definition: lwgeom_topo.c:6903
double ymax
Definition: liblwgeom.h:357
double xmax
Definition: liblwgeom.h:355
double ymin
Definition: liblwgeom.h:356
double xmin
Definition: liblwgeom.h:354
uint32_t ngeoms
Definition: liblwgeom.h:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
int32_t srid
Definition: liblwgeom.h:460
POINTARRAY * points
Definition: liblwgeom.h:483
int32_t srid
Definition: liblwgeom.h:484
LWLINE * geom
LWT_ELEMID node_id
LWT_ELEMID containing_face
LWPOINT * geom
double x
Definition: liblwgeom.h:414
double y
Definition: liblwgeom.h:414
uint32_t npoints
Definition: liblwgeom.h:427

References _lwt_AddLineEdge(), _LWT_MINTOLERANCE, _lwt_release_edges(), _lwt_release_nodes(), _lwt_split_by_nodes(), _lwt_toposnap(), COLLECTIONTYPE, LWT_ISO_NODE::containing_face, gbox_expand(), LWT_ISO_NODE::geom, LWT_ISO_EDGE::geom, LWCOLLECTION::geoms, getPoint4d_p(), LW_ON_INTERRUPT, lwalloc(), lwcollection_as_lwgeom(), lwcollection_construct(), lwcollection_release(), LWDEBUG, LWDEBUGF, LWDEBUGG, lwerror(), lwfree(), LWGEOM2GEOS(), lwgeom_as_lwcollection(), lwgeom_as_lwline(), lwgeom_difference(), lwgeom_free(), lwgeom_geos_errmsg, lwgeom_get_bbox(), lwgeom_intersection(), lwgeom_linemerge(), lwgeom_mindistance2d(), lwgeom_node(), lwgeom_to_wkt(), lwgeom_unaryunion(), lwgeom_union(), lwline_as_lwgeom(), lwline_get_lwpoint(), lwline_is_closed(), lwline_is_empty(), lwline_remove_repeated_points(), lwpoint_as_lwgeom(), lwrealloc(), lwt_be_getEdgeWithinBox2D(), lwt_be_getNodeWithinBox2D(), LWT_COL_EDGE_ALL, LWT_COL_NODE_ALL, LWTFMT_ELEMID, MULTIPOINTTYPE, LWCOLLECTION::ngeoms, LWT_ISO_NODE::node_id, POINTARRAY::npoints, PGTOPO_BE_ERROR, LWLINE::points, ptarray_scroll_in_place(), LWGEOM::srid, LWLINE::srid, LWT_TOPOLOGY_T::srid, WKT_EXTENDED, POINT4D::x, GBOX::xmax, GBOX::xmin, POINT4D::y, GBOX::ymax, and GBOX::ymin.

Referenced by lwt_AddLine(), and lwt_AddLineNoFace().

Here is the call graph for this function:
Here is the caller graph for this function: