5533{
5536 uint32_t ngeoms;
5542 uint64_t num, numedges = 0, numnodes = 0;
5543 uint64_t i;
5545
5547 {
5548 *nedges = 0;
5549 return NULL;
5550 }
5551
5552 *nedges = -1;
5553
5554
5556 LWDEBUGF(1,
"Working tolerance:%.15g", tol);
5558
5559
5560 if ( tol )
5561 {{
5564 LWDEBUGG(1, tmp,
"Repeated-point removed");
5565 }}
else tmp=(
LWGEOM*)line;
5566
5567
5570 if ( ! noded ) return NULL;
5572
5577 LWDEBUGF(1,
"BOX expanded by %g is %.15g %.15g, %.15g %.15g",
5579
5581 int nearbyindex = 0;
5582 int nearbycount = 0;
5583
5584
5586 if (numedges == UINT64_MAX)
5587 {
5590 return NULL;
5591 }
5592 LWDEBUGF(1,
"Line has %d points, its bbox intersects %d edges bboxes",
5593 line->points->npoints, numedges);
5594 if ( numedges )
5595 {{
5596
5597 nearbycount += numedges;
5599 for (i=0; i<numedges; ++i)
5600 {
5606
5607 if ( dist && dist >= tol ) continue;
5608 nearby[nearbyindex++] = g;
5609 }
5610 LWDEBUGF(1,
"Found %d edges closer than tolerance (%g)", nearbyindex, tol);
5611 }}
5612 int nearbyedgecount = nearbyindex;
5613
5614
5615
5617 if (numnodes == UINT64_MAX)
5618 {
5621 return NULL;
5622 }
5623 LWDEBUGF(1,
"Line bbox intersects %d nodes bboxes", numnodes);
5624 if ( numnodes )
5625 {{
5626
5627 nearbycount = nearbyedgecount + numnodes;
5628 nearby = nearby ?
5630 :
5632 ;
5633 int nn = 0;
5634 for (i=0; i<numnodes; ++i)
5635 {
5639
5640 if ( dist && dist >= tol )
5641 {
5642 LWDEBUGF(1,
"Node %d is %g units away, we tolerate only %g", n->
node_id, dist, tol);
5643 continue;
5644 }
5645 nearby[nearbyindex++] = g;
5646 ++nn;
5647 }
5648 LWDEBUGF(1,
"Found %d nodes closer than tolerance (%g)", nn, tol);
5649 }}
5650 int nearbynodecount = nearbyindex - nearbyedgecount;
5651 nearbycount = nearbyindex;
5652
5653 LWDEBUGF(1,
"Number of nearby elements is %d", nearbycount);
5654
5655
5656 if ( nearbycount )
5657 {{
5660
5662 NULL, nearbycount, nearby);
5664
5665 LWDEBUGG(1, elems,
"Collected nearby elements");
5666
5669 noded = tmp;
5670 LWDEBUGG(1, noded,
"Elements-snapped");
5671
5672
5674
5675
5676
5677
5678
5679
5682 noded = tmp;
5683 LWDEBUGG(1, noded,
"Unary-unioned");
5684 }}
5685
5686
5687 if ( nearbyedgecount )
5688 {{
5692
5693 LWDEBUGF(1,
"Line intersects %d edges", nearbyedgecount);
5694
5696 NULL, nearbyedgecount, nearby);
5698 LWDEBUGG(1, iedges,
"Collected edges");
5699
5700 LWDEBUGF(1,
"Diffing noded, with srid=%d "
5701 "and interesecting edges, with srid=%d",
5705
5706 LWDEBUGF(1,
"Intersecting noded, with srid=%d "
5707 "and interesecting edges, with srid=%d",
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727 LWDEBUG(1,
"Linemerging intersection");
5731 xset = tmp;
5732
5733
5734
5735
5736
5737 LWDEBUG(1,
"Unioning difference and (linemerged) intersection");
5739 LWDEBUGG(1, noded,
"Diff-Xset Unioned");
5742
5743
5745 }}
5746
5747
5748
5749
5750
5751
5752
5753 if ( nearbyedgecount )
5754 {
5755 nearbycount += nearbyedgecount * 2;
5757 for (int i=0; i<nearbyedgecount; i++)
5758 {
5762
5764 nearbynodecount++;
5766 nearbynodecount++;
5767 }
5768 }
5769 if ( nearbynodecount )
5770 {
5772 NULL, nearbynodecount,
5773 nearby + nearbyedgecount);
5775
5778 noded = tmp;
5780
5782 }
5783
5784
5785 LWDEBUG(1,
"Freeing up nearby elements");
5786
5787
5788 if ( nearby )
lwfree(nearby);
5791
5792 LWDEBUGG(1, noded,
"Finally-noded");
5793
5794
5796 if ( col )
5797 {
5798 LWDEBUG(1,
"Noded line was a collection");
5801 }
5802 else
5803 {
5804 LWDEBUG(1,
"Noded line was a single geom");
5805 geomsbuf[0] = noded;
5806 geoms = geomsbuf;
5807 ngeoms = 1;
5808 }
5809
5810 LWDEBUGF(1,
"Line was split into %d edges", ngeoms);
5811
5812
5813
5814
5815
5817 num = 0;
5818 for ( i=0; i<ngeoms; ++i )
5819 {
5823
5824#if POSTGIS_DEBUG_LEVEL > 0
5825 {
5826 size_t sz;
5828 LWDEBUGF(1,
"Component %d of split line is: %s", i, wkt1);
5830 }
5831#endif
5832
5835 if ( id < 0 )
5836 {
5839 return NULL;
5840 }
5841 if ( ! id )
5842 {
5843 LWDEBUGF(1,
"Component %d of split line collapsed", i);
5844 continue;
5845 }
5846
5848 i, id);
5849 ids[num++] = id;
5850 }
5851
5852 LWDEBUGG(1, noded,
"Noded before free");
5854
5855
5856
5857 *nedges = num;
5858 return ids;
5859}
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
LWGEOM * lwgeom_unaryunion(const LWGEOM *geom1)
void * lwrealloc(void *mem, size_t size)
LWGEOM * lwgeom_node(const LWGEOM *lwgeom_in)
LWGEOM * lwgeom_linemerge(const LWGEOM *geom1)
void lwgeom_free(LWGEOM *geom)
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
char * lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out)
WKT emitter function.
void * lwalloc(size_t size)
LWGEOM * lwgeom_intersection(const LWGEOM *geom1, const LWGEOM *geom2)
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
LWGEOM * lwgeom_difference(const LWGEOM *geom1, const LWGEOM *geom2)
void lwcollection_release(LWCOLLECTION *lwcollection)
double lwgeom_mindistance2d(const LWGEOM *lw1, const LWGEOM *lw2)
Function initializing min distance calculation.
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
LWGEOM * lwgeom_union(const LWGEOM *geom1, const LWGEOM *geom2)
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
LWGEOM * lwline_remove_repeated_points(const LWLINE *in, double tolerance)
int lwline_is_empty(const LWLINE *line)
#define LW_ON_INTERRUPT(x)
LWT_INT64 LWT_ELEMID
Identifier of topology element.
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
#define LWDEBUGG(level, geom, msg)
static LWGEOM * _lwt_toposnap(LWGEOM *src, LWGEOM *tgt, double tol)
static LWT_ISO_EDGE * lwt_be_getEdgeWithinBox2D(const LWT_TOPOLOGY *topo, const GBOX *box, uint64_t *numelems, int fields, uint64_t limit)
static void _lwt_release_nodes(LWT_ISO_NODE *nodes, int num_nodes)
static LWT_ELEMID _lwt_AddLineEdge(LWT_TOPOLOGY *topo, LWLINE *edge, double tol, int handleFaceSplit)
static LWGEOM * _lwt_split_by_nodes(const LWGEOM *g, const LWGEOM *nodes)
#define _LWT_MINTOLERANCE(topo, geom)
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)
static void _lwt_release_edges(LWT_ISO_EDGE *edges, int num_edges)
const LWT_BE_IFACE * be_iface