pgLatLon

diff latlon-v0003.c @ 10:684a78d2f9f0

Introduced lossy overlap operator (&&+) and fixed ecircle overlap searches on GiST-indexed ecluster columns
author jbe
date Fri Sep 02 14:08:01 2016 +0200 (2016-09-02)
parents dc8da756b761
children
line diff
     1.1 --- a/latlon-v0003.c	Fri Sep 02 14:04:04 2016 +0200
     1.2 +++ b/latlon-v0003.c	Fri Sep 02 14:08:01 2016 +0200
     1.3 @@ -2107,6 +2107,19 @@
     1.4    PG_RETURN_BOOL(retval);
     1.5  }
     1.6  
     1.7 +/* check if point may be inside cluster (lossy overl. operator "&&+") in SQL */
     1.8 +PG_FUNCTION_INFO_V1(pgl_epoint_ecluster_may_overlap);
     1.9 +Datum pgl_epoint_ecluster_may_overlap(PG_FUNCTION_ARGS) {
    1.10 +  pgl_point *point = (pgl_point *)PG_GETARG_POINTER(0);
    1.11 +  pgl_cluster *cluster = (pgl_cluster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
    1.12 +  bool retval = pgl_distance(
    1.13 +    point->lat, point->lon,
    1.14 +    cluster->bounding.center.lat, cluster->bounding.center.lon
    1.15 +  ) <= cluster->bounding.radius;
    1.16 +  PG_FREE_IF_COPY(cluster, 1);
    1.17 +  PG_RETURN_BOOL(retval);
    1.18 +}
    1.19 +
    1.20  /* check if two boxes overlap (overlap operator "&&") in SQL */
    1.21  PG_FUNCTION_INFO_V1(pgl_ebox_overlap);
    1.22  Datum pgl_ebox_overlap(PG_FUNCTION_ARGS) {
    1.23 @@ -2115,6 +2128,29 @@
    1.24    PG_RETURN_BOOL(pgl_boxes_overlap(box1, box2));
    1.25  }
    1.26  
    1.27 +/* check if box and circle may overlap (lossy overl. operator "&&+") in SQL */
    1.28 +PG_FUNCTION_INFO_V1(pgl_ebox_ecircle_may_overlap);
    1.29 +Datum pgl_ebox_ecircle_may_overlap(PG_FUNCTION_ARGS) {
    1.30 +  pgl_box *box = (pgl_box *)PG_GETARG_POINTER(0);
    1.31 +  pgl_circle *circle = (pgl_circle *)PG_GETARG_POINTER(1);
    1.32 +  PG_RETURN_BOOL(
    1.33 +    pgl_estimate_point_box_distance(&circle->center, box) <= circle->radius
    1.34 +  );
    1.35 +}
    1.36 +
    1.37 +/* check if box and cluster may overlap (lossy overl. operator "&&+") in SQL */
    1.38 +PG_FUNCTION_INFO_V1(pgl_ebox_ecluster_may_overlap);
    1.39 +Datum pgl_ebox_ecluster_may_overlap(PG_FUNCTION_ARGS) {
    1.40 +  pgl_box *box = (pgl_box *)PG_GETARG_POINTER(0);
    1.41 +  pgl_cluster *cluster = (pgl_cluster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
    1.42 +  bool retval = pgl_estimate_point_box_distance(
    1.43 +    &cluster->bounding.center,
    1.44 +    box
    1.45 +  ) <= cluster->bounding.radius;
    1.46 +  PG_FREE_IF_COPY(cluster, 1);
    1.47 +  PG_RETURN_BOOL(retval);
    1.48 +}
    1.49 +
    1.50  /* check if two circles overlap (overlap operator "&&") in SQL */
    1.51  PG_FUNCTION_INFO_V1(pgl_ecircle_overlap);
    1.52  Datum pgl_ecircle_overlap(PG_FUNCTION_ARGS) {
    1.53 @@ -2140,6 +2176,33 @@
    1.54    PG_RETURN_BOOL(retval);
    1.55  }
    1.56  
    1.57 +/* check if circle and cluster may be overlap (l. ov. operator "&&+") in SQL */
    1.58 +PG_FUNCTION_INFO_V1(pgl_ecircle_ecluster_may_overlap);
    1.59 +Datum pgl_ecircle_ecluster_may_overlap(PG_FUNCTION_ARGS) {
    1.60 +  pgl_circle *circle = (pgl_circle *)PG_GETARG_POINTER(0);
    1.61 +  pgl_cluster *cluster = (pgl_cluster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
    1.62 +  bool retval = pgl_distance(
    1.63 +    circle->center.lat, circle->center.lon,
    1.64 +    cluster->bounding.center.lat, cluster->bounding.center.lon
    1.65 +  ) <= circle->radius + cluster->bounding.radius;
    1.66 +  PG_FREE_IF_COPY(cluster, 1);
    1.67 +  PG_RETURN_BOOL(retval);
    1.68 +}
    1.69 +
    1.70 +/* check if two clusters may overlap (lossy overlap operator "&&+") in SQL */
    1.71 +PG_FUNCTION_INFO_V1(pgl_ecluster_may_overlap);
    1.72 +Datum pgl_ecluster_may_overlap(PG_FUNCTION_ARGS) {
    1.73 +  pgl_cluster *cluster1 = (pgl_cluster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
    1.74 +  pgl_cluster *cluster2 = (pgl_cluster *)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
    1.75 +  bool retval = pgl_distance(
    1.76 +    cluster1->bounding.center.lat, cluster1->bounding.center.lon,
    1.77 +    cluster2->bounding.center.lat, cluster2->bounding.center.lon
    1.78 +  ) <= cluster1->bounding.radius + cluster2->bounding.radius;
    1.79 +  PG_FREE_IF_COPY(cluster1, 0);
    1.80 +  PG_FREE_IF_COPY(cluster2, 1);
    1.81 +  PG_RETURN_BOOL(retval);
    1.82 +}
    1.83 +
    1.84  /* calculate distance between two points ("<->" operator) in SQL */
    1.85  PG_FUNCTION_INFO_V1(pgl_epoint_distance);
    1.86  Datum pgl_epoint_distance(PG_FUNCTION_ARGS) {
    1.87 @@ -2285,6 +2348,8 @@
    1.88    bool *recheck = (bool *)PG_GETARG_POINTER(4);
    1.89    /* demand recheck because index and query methods are lossy */
    1.90    *recheck = true;
    1.91 +  /* strategy number aliases for different operators using the same strategy */
    1.92 +  strategy %= 100;
    1.93    /* strategy number 11: equality of two points */
    1.94    if (strategy == 11) {
    1.95      /* query datum is another point */
    1.96 @@ -2653,6 +2718,8 @@
    1.97    /* demand recheck because distance is just an estimation */
    1.98    /* (real distance may be bigger) */
    1.99    *recheck = true;
   1.100 +  /* strategy number aliases for different operators using the same strategy */
   1.101 +  strategy %= 100;
   1.102    /* strategy number 31: distance to point */
   1.103    if (strategy == 31) {
   1.104      /* query datum is a point */

Impressum / About Us