PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ lwline_split_by_line()

static LWGEOM * lwline_split_by_line ( const LWLINE lwgeom_in,
const LWGEOM blade_in 
)
static

Definition at line 43 of file lwgeom_geos_split.c.

44 {
45  LWGEOM** components;
46  LWGEOM* diff;
47  LWCOLLECTION* out;
48  GEOSGeometry* gdiff; /* difference */
49  GEOSGeometry* g1;
50  GEOSGeometry* g2;
51  int ret;
52 
53  /* ASSERT blade_in is LINE or MULTILINE */
54  assert (blade_in->type == LINETYPE ||
55  blade_in->type == MULTILINETYPE ||
56  blade_in->type == POLYGONTYPE ||
57  blade_in->type == MULTIPOLYGONTYPE );
58 
59  /* Possible outcomes:
60  *
61  * 1. The lines do not cross or overlap
62  * -> Return a collection with single element
63  * 2. The lines cross
64  * -> Return a collection of all elements resulting from the split
65  */
66 
68 
69  g1 = LWGEOM2GEOS((LWGEOM*)lwline_in, 0);
70  if ( ! g1 )
71  {
72  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
73  return NULL;
74  }
75  g2 = LWGEOM2GEOS(blade_in, 0);
76  if ( ! g2 )
77  {
78  GEOSGeom_destroy(g1);
79  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
80  return NULL;
81  }
82 
83  /* If blade is a polygon, pick its boundary */
84  if ( blade_in->type == POLYGONTYPE || blade_in->type == MULTIPOLYGONTYPE )
85  {
86  gdiff = GEOSBoundary(g2);
87  GEOSGeom_destroy(g2);
88  if ( ! gdiff )
89  {
90  GEOSGeom_destroy(g1);
91  lwerror("GEOSBoundary: %s", lwgeom_geos_errmsg);
92  return NULL;
93  }
94  g2 = gdiff; gdiff = NULL;
95  }
96 
97  /* If interior intersecton is linear we can't split */
98  ret = GEOSRelatePattern(g1, g2, "1********");
99  if ( 2 == ret )
100  {
101  lwerror("GEOSRelatePattern: %s", lwgeom_geos_errmsg);
102  GEOSGeom_destroy(g1);
103  GEOSGeom_destroy(g2);
104  return NULL;
105  }
106  if ( ret )
107  {
108  GEOSGeom_destroy(g1);
109  GEOSGeom_destroy(g2);
110  lwerror("Splitter line has linear intersection with input");
111  return NULL;
112  }
113 
114 
115  gdiff = GEOSDifference(g1,g2);
116  GEOSGeom_destroy(g1);
117  GEOSGeom_destroy(g2);
118  if (gdiff == NULL)
119  {
120  lwerror("GEOSDifference: %s", lwgeom_geos_errmsg);
121  return NULL;
122  }
123 
124  diff = GEOS2LWGEOM(gdiff, FLAGS_GET_Z(lwline_in->flags));
125  GEOSGeom_destroy(gdiff);
126  if (NULL == diff)
127  {
128  lwerror("GEOS2LWGEOM: %s", lwgeom_geos_errmsg);
129  return NULL;
130  }
131 
132  out = lwgeom_as_lwcollection(diff);
133  if ( ! out )
134  {
135  components = lwalloc(sizeof(LWGEOM*)*1);
136  components[0] = diff;
137  out = lwcollection_construct(COLLECTIONTYPE, lwline_in->srid,
138  NULL, 1, components);
139  }
140  else
141  {
142  /* Set SRID */
143  lwgeom_set_srid((LWGEOM*)out, lwline_in->srid);
144  /* Force collection type */
145  out->type = COLLECTIONTYPE;
146  }
147 
148 
149  return (LWGEOM*)out;
150 }
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom, uint8_t autofix)
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, uint8_t want3d)
void lwgeom_geos_error(const char *fmt,...)
#define COLLECTIONTYPE
Definition: liblwgeom.h:91
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define LINETYPE
Definition: liblwgeom.h:86
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:140
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:90
#define POLYGONTYPE
Definition: liblwgeom.h:87
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
void * lwalloc(size_t size)
Definition: lwutil.c:229
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition: lwgeom.c:224
void lwgeom_set_srid(LWGEOM *geom, int srid)
Set the SRID on an LWGEOM For collections, only the parent gets an SRID, all the children get SRID_UN...
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
uint8_t type
Definition: liblwgeom.h:506
uint8_t type
Definition: liblwgeom.h:399

References COLLECTIONTYPE, LWLINE::flags, FLAGS_GET_Z, GEOS2LWGEOM(), LINETYPE, lwalloc(), lwcollection_construct(), lwerror(), LWGEOM2GEOS(), lwgeom_as_lwcollection(), lwgeom_geos_errmsg, lwgeom_geos_error(), lwgeom_set_srid(), MULTILINETYPE, MULTIPOLYGONTYPE, POLYGONTYPE, LWLINE::srid, and LWGEOM::type.

Referenced by lwline_split().

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