PostGIS  2.1.10dev-r@@SVN_REVISION@@
static LWGEOM * lwline_split_by_line ( const LWLINE lwgeom_in,
const LWLINE blade_in 
)
static

Definition at line 52 of file lwgeom_geos_split.c.

References COLLECTIONTYPE, LWLINE::flags, FLAGS_GET_Z, GEOS2LWGEOM(), lwalloc(), lwcollection_construct(), lwerror(), LWGEOM2GEOS(), lwgeom_as_lwcollection(), lwgeom_geos_errmsg, lwgeom_geos_error(), lwgeom_set_srid(), LWLINE::srid, and LWCOLLECTION::type.

Referenced by lwline_split().

53 {
54  LWGEOM** components;
55  LWGEOM* diff;
56  LWCOLLECTION* out;
57  GEOSGeometry* gdiff; /* difference */
58  GEOSGeometry* g1;
59  GEOSGeometry* g2;
60  int ret;
61 
62  /* Possible outcomes:
63  *
64  * 1. The lines do not cross or overlap
65  * -> Return a collection with single element
66  * 2. The lines cross
67  * -> Return a collection of all elements resulting from the split
68  */
69 
71 
72  g1 = LWGEOM2GEOS((LWGEOM*)lwline_in);
73  if ( ! g1 )
74  {
75  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
76  return NULL;
77  }
78  g2 = LWGEOM2GEOS((LWGEOM*)blade_in);
79  if ( ! g2 )
80  {
81  GEOSGeom_destroy(g1);
82  lwerror("LWGEOM2GEOS: %s", lwgeom_geos_errmsg);
83  return NULL;
84  }
85 
86  /* If interior intersecton is linear we can't split */
87  ret = GEOSRelatePattern(g1, g2, "1********");
88  if ( 2 == ret )
89  {
90  lwerror("GEOSRelatePattern: %s", lwgeom_geos_errmsg);
91  GEOSGeom_destroy(g1);
92  GEOSGeom_destroy(g2);
93  return NULL;
94  }
95  if ( ret )
96  {
97  GEOSGeom_destroy(g1);
98  GEOSGeom_destroy(g2);
99  lwerror("Splitter line has linear intersection with input");
100  return NULL;
101  }
102 
103 
104  gdiff = GEOSDifference(g1,g2);
105  GEOSGeom_destroy(g1);
106  GEOSGeom_destroy(g2);
107  if (gdiff == NULL)
108  {
109  lwerror("GEOSDifference: %s", lwgeom_geos_errmsg);
110  return NULL;
111  }
112 
113  diff = GEOS2LWGEOM(gdiff, FLAGS_GET_Z(lwline_in->flags));
114  GEOSGeom_destroy(gdiff);
115  if (NULL == diff)
116  {
117  lwerror("GEOS2LWGEOM: %s", lwgeom_geos_errmsg);
118  return NULL;
119  }
120 
121  out = lwgeom_as_lwcollection(diff);
122  if ( ! out )
123  {
124  components = lwalloc(sizeof(LWGEOM*)*1);
125  components[0] = diff;
126  out = lwcollection_construct(COLLECTIONTYPE, lwline_in->srid,
127  NULL, 1, components);
128  }
129  else
130  {
131  /* Set SRID */
132  lwgeom_set_srid((LWGEOM*)out, lwline_in->srid);
133  /* Force collection type */
134  out->type = COLLECTIONTYPE;
135  }
136 
137 
138  return (LWGEOM*)out;
139 }
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
uint8_t type
Definition: liblwgeom.h:459
char lwgeom_geos_errmsg[LWGEOM_GEOS_ERRMSG_MAXSIZE]
GEOSGeometry * LWGEOM2GEOS(const LWGEOM *lwgeom)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
void lwgeom_geos_error(const char *fmt,...)
int32_t srid
Definition: liblwgeom.h:462
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:106
LWCOLLECTION * lwgeom_as_lwcollection(const LWGEOM *lwgeom)
Definition: lwgeom.c:143
LWGEOM * GEOS2LWGEOM(const GEOSGeometry *geom, char want3d)
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 * lwalloc(size_t size)
Definition: lwutil.c:175
#define COLLECTIONTYPE
Definition: liblwgeom.h:66

Here is the call graph for this function:

Here is the caller graph for this function: