PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ ptarray_append_ptarray()

int ptarray_append_ptarray ( POINTARRAY pa1,
POINTARRAY pa2,
double  gap_tolerance 
)

Append a POINTARRAY, pa2 to the end of an existing POINTARRAY, pa1.

If gap_tolerance is >= 0 then the end point of pa1 will be checked for being within gap_tolerance 2d distance from start point of pa2 or an error will be raised and LW_FAILURE returned. A gap_tolerance < 0 disables the check.

If end point of pa1 and start point of pa2 are 2d-equal, then pa2 first point will not be appended.

Definition at line 177 of file ptarray.c.

178 {
179  unsigned int poff = 0;
180  unsigned int npoints;
181  unsigned int ncap;
182  unsigned int ptsize;
183 
184  /* Check for pathology */
185  if( ! pa1 || ! pa2 )
186  {
187  lwerror("ptarray_append_ptarray: null input");
188  return LW_FAILURE;
189  }
190 
191  npoints = pa2->npoints;
192 
193  if ( ! npoints ) return LW_SUCCESS; /* nothing more to do */
194 
195  if( FLAGS_GET_READONLY(pa1->flags) )
196  {
197  lwerror("ptarray_append_ptarray: target pointarray is read-only");
198  return LW_FAILURE;
199  }
200 
201  if( FLAGS_GET_ZM(pa1->flags) != FLAGS_GET_ZM(pa2->flags) )
202  {
203  lwerror("ptarray_append_ptarray: appending mixed dimensionality is not allowed");
204  return LW_FAILURE;
205  }
206 
207  ptsize = ptarray_point_size(pa1);
208 
209  /* Check for duplicate end point */
210  if ( pa1->npoints )
211  {
212  POINT2D tmp1, tmp2;
213  getPoint2d_p(pa1, pa1->npoints-1, &tmp1);
214  getPoint2d_p(pa2, 0, &tmp2);
215 
216  /* If the end point and start point are the same, then don't copy start point */
217  if (p2d_same(&tmp1, &tmp2)) {
218  poff = 1;
219  --npoints;
220  }
221  else if ( gap_tolerance == 0 || ( gap_tolerance > 0 &&
222  distance2d_pt_pt(&tmp1, &tmp2) > gap_tolerance ) )
223  {
224  lwerror("Second line start point too far from first line end point");
225  return LW_FAILURE;
226  }
227  }
228 
229  /* Check if we need extra space */
230  ncap = pa1->npoints + npoints;
231  if ( pa1->maxpoints < ncap )
232  {
233  pa1->maxpoints = ncap > pa1->maxpoints*2 ?
234  ncap : pa1->maxpoints*2;
235  pa1->serialized_pointlist = lwrealloc(pa1->serialized_pointlist, ptsize * pa1->maxpoints);
236  }
237 
238  memcpy(getPoint_internal(pa1, pa1->npoints),
239  getPoint_internal(pa2, poff), ptsize * npoints);
240 
241  pa1->npoints = ncap;
242 
243  return LW_SUCCESS;
244 }
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2397
#define LW_FAILURE
Definition: liblwgeom.h:110
#define LW_SUCCESS
Definition: liblwgeom.h:111
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:349
#define FLAGS_GET_READONLY(flags)
Definition: liblwgeom.h:183
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:194
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:50
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
static size_t ptarray_point_size(const POINTARRAY *pa)
Definition: lwinline.h:48
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: lwinline.h:67
lwflags_t flags
Definition: liblwgeom.h:417
uint32_t maxpoints
Definition: liblwgeom.h:414
uint32_t npoints
Definition: liblwgeom.h:413
uint8_t * serialized_pointlist
Definition: liblwgeom.h:420

References distance2d_pt_pt(), POINTARRAY::flags, FLAGS_GET_READONLY, FLAGS_GET_ZM, getPoint2d_p(), getPoint_internal(), LW_FAILURE, LW_SUCCESS, lwerror(), lwrealloc(), POINTARRAY::maxpoints, POINTARRAY::npoints, p2d_same(), ptarray_point_size(), and POINTARRAY::serialized_pointlist.

Referenced by _lwt_HealEdges(), _lwt_MakeRingShell(), lwline_from_lwgeom_array(), and test_ptarray_append_ptarray().

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