PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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 2035 of file measures.c.

2036{
2037 /*here we define two lists to hold our calculated "z"-values and the order number in the geometry*/
2038
2039 double k, thevalue;
2040 float deltaX, deltaY, c1m, c2m;
2041 POINT2D c1, c2;
2042 const POINT2D *theP;
2043 float min1X, max1X, max1Y, min1Y, min2X, max2X, max2Y, min2Y;
2044 int t;
2045 int n1 = l1->npoints;
2046 int n2 = l2->npoints;
2047
2048 LISTSTRUCT *list1, *list2;
2049 list1 = (LISTSTRUCT *)lwalloc(sizeof(LISTSTRUCT) * n1);
2050 list2 = (LISTSTRUCT *)lwalloc(sizeof(LISTSTRUCT) * n2);
2051
2052 LWDEBUG(2, "lw_dist2d_fast_ptarray_ptarray is called");
2053
2054 max1X = box1->xmax;
2055 min1X = box1->xmin;
2056 max1Y = box1->ymax;
2057 min1Y = box1->ymin;
2058 max2X = box2->xmax;
2059 min2X = box2->xmin;
2060 max2Y = box2->ymax;
2061 min2Y = box2->ymin;
2062 /*we want the center of the bboxes, and calculate the slope between the centerpoints*/
2063 c1.x = min1X + (max1X - min1X) / 2;
2064 c1.y = min1Y + (max1Y - min1Y) / 2;
2065 c2.x = min2X + (max2X - min2X) / 2;
2066 c2.y = min2Y + (max2Y - min2Y) / 2;
2067
2068 deltaX = (c2.x - c1.x);
2069 deltaY = (c2.y - c1.y);
2070
2071 /*Here we calculate where the line perpendicular to the center-center line crosses the axes for each vertex
2072 if the center-center line is vertical the perpendicular line will be horizontal and we find it's crossing the
2073 Y-axes with z = y-kx */
2074 if ((deltaX * deltaX) < (deltaY * deltaY)) /*North or South*/
2075 {
2076 k = -deltaX / deltaY;
2077 for (t = 0; t < n1; t++) /*for each segment in L1 */
2078 {
2079 theP = getPoint2d_cp(l1, t);
2080 thevalue = theP->y - (k * theP->x);
2081 list1[t].themeasure = thevalue;
2082 list1[t].pnr = t;
2083 }
2084 for (t = 0; t < n2; t++) /*for each segment in L2*/
2085 {
2086 theP = getPoint2d_cp(l2, t);
2087 thevalue = theP->y - (k * theP->x);
2088 list2[t].themeasure = thevalue;
2089 list2[t].pnr = t;
2090 }
2091 c1m = c1.y - (k * c1.x);
2092 c2m = c2.y - (k * c2.x);
2093 }
2094
2095 /*if the center-center line is horizontal the perpendicular line will be vertical. To eliminate problems with
2096 dividing by zero we are here mirroring the coordinate-system and we find it's crossing the X-axes with z =
2097 x-(1/k)y */
2098 else /*West or East*/
2099 {
2100 k = -deltaY / deltaX;
2101 for (t = 0; t < n1; t++) /*for each segment in L1 */
2102 {
2103 theP = getPoint2d_cp(l1, t);
2104 thevalue = theP->x - (k * theP->y);
2105 list1[t].themeasure = thevalue;
2106 list1[t].pnr = t;
2107 /* lwnotice("l1 %d, measure=%f",t,thevalue ); */
2108 }
2109 for (t = 0; t < n2; t++) /*for each segment in L2*/
2110 {
2111 theP = getPoint2d_cp(l2, t);
2112 thevalue = theP->x - (k * theP->y);
2113 list2[t].themeasure = thevalue;
2114 list2[t].pnr = t;
2115 /* lwnotice("l2 %d, measure=%f",t,thevalue ); */
2116 }
2117 c1m = c1.x - (k * c1.y);
2118 c2m = c2.x - (k * c2.y);
2119 }
2120
2121 /*we sort our lists by the calculated values*/
2122 qsort(list1, n1, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2123 qsort(list2, n2, sizeof(LISTSTRUCT), struct_cmp_by_measure);
2124
2125 if (c1m < c2m)
2126 {
2127 if (!lw_dist2d_pre_seg_seg(l1, l2, list1, list2, k, dl))
2128 {
2129 lwfree(list1);
2130 lwfree(list2);
2131 return LW_FALSE;
2132 }
2133 }
2134 else
2135 {
2136 dl->twisted = ((dl->twisted) * (-1));
2137 if (!lw_dist2d_pre_seg_seg(l2, l1, list2, list1, k, dl))
2138 {
2139 lwfree(list1);
2140 lwfree(list2);
2141 return LW_FALSE;
2142 }
2143 }
2144 lwfree(list1);
2145 lwfree(list2);
2146 return LW_TRUE;
2147}
#define LW_FALSE
Definition liblwgeom.h:108
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:242
#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:91
int struct_cmp_by_measure(const void *a, const void *b)
Definition measures.c:2150
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:2159
int twisted
Definition measures.h:55
double ymax
Definition liblwgeom.h:343
double xmax
Definition liblwgeom.h:341
double ymin
Definition liblwgeom.h:342
double xmin
Definition liblwgeom.h:340
double themeasure
Definition measures.h:61
double y
Definition liblwgeom.h:376
double x
Definition liblwgeom.h:376
uint32_t npoints
Definition liblwgeom.h:413

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: