PostGIS  2.5.7dev-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 187 of file ptarray.c.

188 {
189  unsigned int poff = 0;
190  unsigned int npoints;
191  unsigned int ncap;
192  unsigned int ptsize;
193 
194  /* Check for pathology */
195  if( ! pa1 || ! pa2 )
196  {
197  lwerror("ptarray_append_ptarray: null input");
198  return LW_FAILURE;
199  }
200 
201  npoints = pa2->npoints;
202 
203  if ( ! npoints ) return LW_SUCCESS; /* nothing more to do */
204 
205  if( FLAGS_GET_READONLY(pa1->flags) )
206  {
207  lwerror("ptarray_append_ptarray: target pointarray is read-only");
208  return LW_FAILURE;
209  }
210 
211  if( FLAGS_GET_ZM(pa1->flags) != FLAGS_GET_ZM(pa2->flags) )
212  {
213  lwerror("ptarray_append_ptarray: appending mixed dimensionality is not allowed");
214  return LW_FAILURE;
215  }
216 
217  ptsize = ptarray_point_size(pa1);
218 
219  /* Check for duplicate end point */
220  if ( pa1->npoints )
221  {
222  POINT2D tmp1, tmp2;
223  getPoint2d_p(pa1, pa1->npoints-1, &tmp1);
224  getPoint2d_p(pa2, 0, &tmp2);
225 
226  /* If the end point and start point are the same, then don't copy start point */
227  if (p2d_same(&tmp1, &tmp2)) {
228  poff = 1;
229  --npoints;
230  }
231  else if ( gap_tolerance == 0 || ( gap_tolerance > 0 &&
232  distance2d_pt_pt(&tmp1, &tmp2) > gap_tolerance ) )
233  {
234  lwerror("Second line start point too far from first line end point");
235  return LW_FAILURE;
236  }
237  }
238 
239  /* Check if we need extra space */
240  ncap = pa1->npoints + npoints;
241  if ( pa1->maxpoints < ncap )
242  {
243  pa1->maxpoints = ncap > pa1->maxpoints*2 ?
244  ncap : pa1->maxpoints*2;
245  pa1->serialized_pointlist = lwrealloc(pa1->serialized_pointlist, ptsize * pa1->maxpoints);
246  }
247 
248  memcpy(getPoint_internal(pa1, pa1->npoints),
249  getPoint_internal(pa2, poff), ptsize * npoints);
250 
251  pa1->npoints = ncap;
252 
253  return LW_SUCCESS;
254 }
double distance2d_pt_pt(const POINT2D *p1, const POINT2D *p2)
Definition: measures.c:2314
#define LW_FAILURE
Definition: liblwgeom.h:79
#define LW_SUCCESS
Definition: liblwgeom.h:80
int getPoint2d_p(const POINTARRAY *pa, uint32_t n, POINT2D *point)
Definition: lwgeom_api.c:348
#define FLAGS_GET_READONLY(flags)
Definition: liblwgeom.h:144
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:153
int p2d_same(const POINT2D *p1, const POINT2D *p2)
Definition: lwalgorithm.c:49
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: ptarray.c:1750
size_t ptarray_point_size(const POINTARRAY *pa)
Definition: ptarray.c:54
uint32_t maxpoints
Definition: liblwgeom.h:375
uint32_t npoints
Definition: liblwgeom.h:374
uint8_t * serialized_pointlist
Definition: liblwgeom.h:369
uint8_t flags
Definition: liblwgeom.h:372

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: