PostGIS  2.2.8dev-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 1928 of file measures.c.

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().

1929 {
1930  /*here we define two lists to hold our calculated "z"-values and the order number in the geometry*/
1931 
1932  double k, thevalue;
1933  float deltaX, deltaY, c1m, c2m;
1934  POINT2D c1, c2;
1935  const POINT2D *theP;
1936  float min1X, max1X, max1Y, min1Y,min2X, max2X, max2Y, min2Y;
1937  int t;
1938  int n1 = l1->npoints;
1939  int n2 = l2->npoints;
1940 
1941  LISTSTRUCT *list1, *list2;
1942  list1 = (LISTSTRUCT*)lwalloc(sizeof(LISTSTRUCT)*n1);
1943  list2 = (LISTSTRUCT*)lwalloc(sizeof(LISTSTRUCT)*n2);
1944 
1945  LWDEBUG(2, "lw_dist2d_fast_ptarray_ptarray is called");
1946 
1947  max1X = box1->xmax;
1948  min1X = box1->xmin;
1949  max1Y = box1->ymax;
1950  min1Y = box1->ymin;
1951  max2X = box2->xmax;
1952  min2X = box2->xmin;
1953  max2Y = box2->ymax;
1954  min2Y = box2->ymin;
1955  /*we want the center of the bboxes, and calculate the slope between the centerpoints*/
1956  c1.x = min1X + (max1X-min1X)/2;
1957  c1.y = min1Y + (max1Y-min1Y)/2;
1958  c2.x = min2X + (max2X-min2X)/2;
1959  c2.y = min2Y + (max2Y-min2Y)/2;
1960 
1961  deltaX=(c2.x-c1.x);
1962  deltaY=(c2.y-c1.y);
1963 
1964 
1965  /*Here we calculate where the line perpendicular to the center-center line crosses the axes for each vertex
1966  if the center-center line is vertical the perpendicular line will be horizontal and we find it's crossing the Y-axes with z = y-kx */
1967  if ((deltaX*deltaX)<(deltaY*deltaY)) /*North or South*/
1968  {
1969  k = -deltaX/deltaY;
1970  for (t=0; t<n1; t++) /*for each segment in L1 */
1971  {
1972  theP = getPoint2d_cp(l1, t);
1973  thevalue = theP->y - (k * theP->x);
1974  list1[t].themeasure=thevalue;
1975  list1[t].pnr=t;
1976 
1977  }
1978  for (t=0; t<n2; t++) /*for each segment in L2*/
1979  {
1980  theP = getPoint2d_cp(l2, t);
1981  thevalue = theP->y - (k * theP->x);
1982  list2[t].themeasure=thevalue;
1983  list2[t].pnr=t;
1984 
1985  }
1986  c1m = c1.y-(k*c1.x);
1987  c2m = c2.y-(k*c2.x);
1988  }
1989 
1990 
1991  /*if the center-center line is horizontal the perpendicular line will be vertical. To eliminate problems with deviding by zero we are here mirroring the coordinate-system
1992  and we find it's crossing the X-axes with z = x-(1/k)y */
1993  else /*West or East*/
1994  {
1995  k = -deltaY/deltaX;
1996  for (t=0; t<n1; t++) /*for each segment in L1 */
1997  {
1998  theP = getPoint2d_cp(l1, t);
1999  thevalue = theP->x - (k * theP->y);
2000  list1[t].themeasure=thevalue;
2001  list1[t].pnr=t;
2002  /* lwnotice("l1 %d, measure=%f",t,thevalue ); */
2003  }
2004  for (t=0; t<n2; t++) /*for each segment in L2*/
2005  {
2006  theP = getPoint2d_cp(l2, t);
2007  thevalue = theP->x - (k * theP->y);
2008  list2[t].themeasure=thevalue;
2009  list2[t].pnr=t;
2010  /* lwnotice("l2 %d, measure=%f",t,thevalue ); */
2011  }
2012  c1m = c1.x-(k*c1.y);
2013  c2m = c2.x-(k*c2.y);
2014  }
2015 
2016  /*we sort our lists by the calculated values*/
2017  qsort(list1, n1, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2018  qsort(list2, n2, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2019 
2020  if (c1m < c2m)
2021  {
2022  if (!lw_dist2d_pre_seg_seg(l1,l2,list1,list2,k,dl))
2023  {
2024  lwfree(list1);
2025  lwfree(list2);
2026  return LW_FALSE;
2027  }
2028  }
2029  else
2030  {
2031  dl->twisted= ((dl->twisted) * (-1));
2032  if (!lw_dist2d_pre_seg_seg(l2,l1,list2,list1,k,dl))
2033  {
2034  lwfree(list1);
2035  lwfree(list2);
2036  return LW_FALSE;
2037  }
2038  }
2039  lwfree(list1);
2040  lwfree(list2);
2041  return LW_TRUE;
2042 }
void lwfree(void *mem)
Definition: lwutil.c:214
int npoints
Definition: liblwgeom.h:355
int struct_cmp_by_measure(const void *a, const void *b)
Definition: measures.c:2045
double xmax
Definition: liblwgeom.h:277
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
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:2057
double themeasure
Definition: measures.h:34
double x
Definition: liblwgeom.h:312
double ymin
Definition: liblwgeom.h:278
double xmin
Definition: liblwgeom.h:276
#define LW_FALSE
Definition: liblwgeom.h:62
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, int n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from...
Definition: lwgeom_api.c:472
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
double ymax
Definition: liblwgeom.h:279
double y
Definition: liblwgeom.h:312
int twisted
Definition: measures.h:28
void * lwalloc(size_t size)
Definition: lwutil.c:199
int pnr
Definition: measures.h:35
Here is the call graph for this function:
Here is the caller graph for this function: