PostGIS  2.1.10dev-r@@SVN_REVISION@@
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 172 of file ptarray.c.

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 lwline_from_lwgeom_array(), and test_ptarray_append_ptarray().

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

Here is the call graph for this function:

Here is the caller graph for this function: