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 */