PostGIS  3.1.6dev-r@@SVN_REVISION@@

◆ lw_dist2d_fast_ptarray_ptarray()

int lw_dist2d_fast_ptarray_ptarray ( POINTARRAY l1,
POINTARRAY l2,
DISTPTS dl,
GBOX box1,
GBOX box2 
)

The new faster calculation comparing pointarray to another pointarray the arrays can come from both polygons and linestrings.

The naming is not good but comes from that it compares a chosen selection of the points not all of them

Definition at line 1980 of file measures.c.

1981 {
1982  /*here we define two lists to hold our calculated "z"-values and the order number in the geometry*/
1983 
1984  double k, thevalue;
1985  float deltaX, deltaY, c1m, c2m;
1986  POINT2D c1, c2;
1987  const POINT2D *theP;
1988  float min1X, max1X, max1Y, min1Y, min2X, max2X, max2Y, min2Y;
1989  int t;
1990  int n1 = l1->npoints;
1991  int n2 = l2->npoints;
1992 
1993  LISTSTRUCT *list1, *list2;
1994  list1 = (LISTSTRUCT *)lwalloc(sizeof(LISTSTRUCT) * n1);
1995  list2 = (LISTSTRUCT *)lwalloc(sizeof(LISTSTRUCT) * n2);
1996 
1997  LWDEBUG(2, "lw_dist2d_fast_ptarray_ptarray is called");
1998 
1999  max1X = box1->xmax;
2000  min1X = box1->xmin;
2001  max1Y = box1->ymax;
2002  min1Y = box1->ymin;
2003  max2X = box2->xmax;
2004  min2X = box2->xmin;
2005  max2Y = box2->ymax;
2006  min2Y = box2->ymin;
2007  /*we want the center of the bboxes, and calculate the slope between the centerpoints*/
2008  c1.x = min1X + (max1X - min1X) / 2;
2009  c1.y = min1Y + (max1Y - min1Y) / 2;
2010  c2.x = min2X + (max2X - min2X) / 2;
2011  c2.y = min2Y + (max2Y - min2Y) / 2;
2012 
2013  deltaX = (c2.x - c1.x);
2014  deltaY = (c2.y - c1.y);
2015 
2016  /*Here we calculate where the line perpendicular to the center-center line crosses the axes for each vertex
2017  if the center-center line is vertical the perpendicular line will be horizontal and we find it's crossing the
2018  Y-axes with z = y-kx */
2019  if ((deltaX * deltaX) < (deltaY * deltaY)) /*North or South*/
2020  {
2021  k = -deltaX / deltaY;
2022  for (t = 0; t < n1; t++) /*for each segment in L1 */
2023  {
2024  theP = getPoint2d_cp(l1, t);
2025  thevalue = theP->y - (k * theP->x);
2026  list1[t].themeasure = thevalue;
2027  list1[t].pnr = t;
2028  }
2029  for (t = 0; t < n2; t++) /*for each segment in L2*/
2030  {
2031  theP = getPoint2d_cp(l2, t);
2032  thevalue = theP->y - (k * theP->x);
2033  list2[t].themeasure = thevalue;
2034  list2[t].pnr = t;
2035  }
2036  c1m = c1.y - (k * c1.x);
2037  c2m = c2.y - (k * c2.x);
2038  }
2039 
2040  /*if the center-center line is horizontal the perpendicular line will be vertical. To eliminate problems with
2041  dividing by zero we are here mirroring the coordinate-system and we find it's crossing the X-axes with z =
2042  x-(1/k)y */
2043  else /*West or East*/
2044  {
2045  k = -deltaY / deltaX;
2046  for (t = 0; t < n1; t++) /*for each segment in L1 */
2047  {
2048  theP = getPoint2d_cp(l1, t);
2049  thevalue = theP->x - (k * theP->y);
2050  list1[t].themeasure = thevalue;
2051  list1[t].pnr = t;
2052  /* lwnotice("l1 %d, measure=%f",t,thevalue ); */
2053  }
2054  for (t = 0; t < n2; t++) /*for each segment in L2*/
2055  {
2056  theP = getPoint2d_cp(l2, t);
2057  thevalue = theP->x - (k * theP->y);
2058  list2[t].themeasure = thevalue;
2059  list2[t].pnr = t;
2060  /* lwnotice("l2 %d, measure=%f",t,thevalue ); */
2061  }
2062  c1m = c1.x - (k * c1.y);
2063  c2m = c2.x - (k * c2.y);
2064  }
2065 
2066  /*we sort our lists by the calculated values*/
2067  qsort(list1, n1, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2068  qsort(list2, n2, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2069 
2070  if (c1m < c2m)
2071  {
2072  if (!lw_dist2d_pre_seg_seg(l1, l2, list1, list2, k, dl))
2073  {
2074  lwfree(list1);
2075  lwfree(list2);
2076  return LW_FALSE;
2077  }
2078  }
2079  else
2080  {
2081  dl->twisted = ((dl->twisted) * (-1));
2082  if (!lw_dist2d_pre_seg_seg(l2, l1, list2, list1, k, dl))
2083  {
2084  lwfree(list1);
2085  lwfree(list2);
2086  return LW_FALSE;
2087  }
2088  }
2089  lwfree(list1);
2090  lwfree(list2);
2091  return LW_TRUE;
2092 }
#define LW_FALSE
Definition: liblwgeom.h:108
void lwfree(void *mem)
Definition: lwutil.c:242
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:107
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
Definition: lwinline.h:101
int struct_cmp_by_measure(const void *a, const void *b)
Definition: measures.c:2095
int lw_dist2d_pre_seg_seg(POINTARRAY *l1, POINTARRAY *l2, LISTSTRUCT *list1, LISTSTRUCT *list2, double k, DISTPTS *dl)
preparation before lw_dist2d_seg_seg.
Definition: measures.c:2104
int twisted
Definition: measures.h:55
double ymax
Definition: liblwgeom.h:371
double xmax
Definition: liblwgeom.h:369
double ymin
Definition: liblwgeom.h:370
double xmin
Definition: liblwgeom.h:368
int pnr
Definition: measures.h:62
double themeasure
Definition: measures.h:61
double y
Definition: liblwgeom.h:404
double x
Definition: liblwgeom.h:404
uint32_t npoints
Definition: liblwgeom.h:441

References getPoint2d_cp(), lw_dist2d_pre_seg_seg(), LW_FALSE, LW_TRUE, lwalloc(), LWDEBUG, lwfree(), POINTARRAY::npoints, LISTSTRUCT::pnr, struct_cmp_by_measure(), LISTSTRUCT::themeasure, DISTPTS::twisted, POINT2D::x, GBOX::xmax, GBOX::xmin, POINT2D::y, GBOX::ymax, and GBOX::ymin.

Referenced by lw_dist2d_distribute_fast().

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