diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 6929f3bb183..0932c812da5 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -3562,8 +3562,9 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
Polygons are represented by lists of points (the vertexes of the
- polygon). Polygons are very similar to closed paths, but are
- stored differently and have their own set of support routines.
+ polygon). Polygons are very similar to closed paths; the essential
+ difference is that a polygon is considered to include the area
+ within it, while a path is not.
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 9484dbc2273..e9c347cb8c6 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -3798,11 +3798,9 @@ poly_same(PG_FUNCTION_ARGS)
/*-----------------------------------------------------------------
* Determine if polygon A overlaps polygon B
*-----------------------------------------------------------------*/
-Datum
-poly_overlap(PG_FUNCTION_ARGS)
+static bool
+poly_overlap_internal(POLYGON *polya, POLYGON *polyb)
{
- POLYGON *polya = PG_GETARG_POLYGON_P(0);
- POLYGON *polyb = PG_GETARG_POLYGON_P(1);
bool result;
Assert(polya->npts > 0 && polyb->npts > 0);
@@ -3854,6 +3852,18 @@ poly_overlap(PG_FUNCTION_ARGS)
}
}
+ return result;
+}
+
+Datum
+poly_overlap(PG_FUNCTION_ARGS)
+{
+ POLYGON *polya = PG_GETARG_POLYGON_P(0);
+ POLYGON *polyb = PG_GETARG_POLYGON_P(1);
+ bool result;
+
+ result = poly_overlap_internal(polya, polyb);
+
/*
* Avoid leaking memory for toasted inputs ... needed for rtree indexes
*/
@@ -4071,16 +4081,63 @@ pt_contained_poly(PG_FUNCTION_ARGS)
Datum
poly_distance(PG_FUNCTION_ARGS)
{
-#ifdef NOT_USED
POLYGON *polya = PG_GETARG_POLYGON_P(0);
POLYGON *polyb = PG_GETARG_POLYGON_P(1);
-#endif
+ float8 min = 0.0; /* initialize to keep compiler quiet */
+ bool have_min = false;
+ float8 tmp;
+ int i,
+ j;
+ LSEG seg1,
+ seg2;
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("function \"poly_distance\" not implemented")));
+ /*
+ * Distance is zero if polygons overlap. We must check this because the
+ * path distance will not give the right answer if one poly is entirely
+ * within the other.
+ */
+ if (poly_overlap_internal(polya, polyb))
+ PG_RETURN_FLOAT8(0.0);
- PG_RETURN_NULL();
+ /*
+ * When they don't overlap, the distance calculation is identical to that
+ * for closed paths (i.e., we needn't care about the fact that polygons
+ * include their contained areas). See path_distance().
+ */
+ for (i = 0; i < polya->npts; i++)
+ {
+ int iprev;
+
+ if (i > 0)
+ iprev = i - 1;
+ else
+ iprev = polya->npts - 1;
+
+ for (j = 0; j < polyb->npts; j++)
+ {
+ int jprev;
+
+ if (j > 0)
+ jprev = j - 1;
+ else
+ jprev = polyb->npts - 1;
+
+ statlseg_construct(&seg1, &polya->p[iprev], &polya->p[i]);
+ statlseg_construct(&seg2, &polyb->p[jprev], &polyb->p[j]);
+
+ tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
+ if (!have_min || float8_lt(tmp, min))
+ {
+ min = tmp;
+ have_min = true;
+ }
+ }
+ }
+
+ if (!have_min)
+ PG_RETURN_NULL();
+
+ PG_RETURN_FLOAT8(min);
}
diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out
index 974e2ec43a4..eb717d36434 100644
--- a/src/test/regress/expected/geometry.out
+++ b/src/test/regress/expected/geometry.out
@@ -4189,7 +4189,59 @@ SELECT p1.f1, p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2 WHERE p1.f1 |&> p2.f1;
-- Distance to polygon
SELECT p1.f1, p2.f1, p1.f1 <-> p2.f1 FROM POLYGON_TBL p1, POLYGON_TBL p2;
-ERROR: function "poly_distance" not implemented
+ f1 | f1 | ?column?
+----------------------------+----------------------------+----------------
+ ((2,0),(2,4),(0,0)) | ((2,0),(2,4),(0,0)) | 0
+ ((2,0),(2,4),(0,0)) | ((3,1),(3,3),(1,0)) | 0
+ ((2,0),(2,4),(0,0)) | ((1,2),(3,4),(5,6),(7,8)) | 0
+ ((2,0),(2,4),(0,0)) | ((7,8),(5,6),(3,4),(1,2)) | 0
+ ((2,0),(2,4),(0,0)) | ((1,2),(7,8),(5,6),(3,-4)) | 0
+ ((2,0),(2,4),(0,0)) | ((0,0)) | 0
+ ((2,0),(2,4),(0,0)) | ((0,1),(0,1)) | 0.4472135955
+ ((3,1),(3,3),(1,0)) | ((2,0),(2,4),(0,0)) | 0
+ ((3,1),(3,3),(1,0)) | ((3,1),(3,3),(1,0)) | 0
+ ((3,1),(3,3),(1,0)) | ((1,2),(3,4),(5,6),(7,8)) | 0.707106781187
+ ((3,1),(3,3),(1,0)) | ((7,8),(5,6),(3,4),(1,2)) | 0.707106781187
+ ((3,1),(3,3),(1,0)) | ((1,2),(7,8),(5,6),(3,-4)) | 0
+ ((3,1),(3,3),(1,0)) | ((0,0)) | 1
+ ((3,1),(3,3),(1,0)) | ((0,1),(0,1)) | 1.38675049056
+ ((1,2),(3,4),(5,6),(7,8)) | ((2,0),(2,4),(0,0)) | 0
+ ((1,2),(3,4),(5,6),(7,8)) | ((3,1),(3,3),(1,0)) | 0.707106781187
+ ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(3,4),(5,6),(7,8)) | 0
+ ((1,2),(3,4),(5,6),(7,8)) | ((7,8),(5,6),(3,4),(1,2)) | 0
+ ((1,2),(3,4),(5,6),(7,8)) | ((1,2),(7,8),(5,6),(3,-4)) | 0
+ ((1,2),(3,4),(5,6),(7,8)) | ((0,0)) | 2.2360679775
+ ((1,2),(3,4),(5,6),(7,8)) | ((0,1),(0,1)) | 1.41421356237
+ ((7,8),(5,6),(3,4),(1,2)) | ((2,0),(2,4),(0,0)) | 0
+ ((7,8),(5,6),(3,4),(1,2)) | ((3,1),(3,3),(1,0)) | 0.707106781187
+ ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(3,4),(5,6),(7,8)) | 0
+ ((7,8),(5,6),(3,4),(1,2)) | ((7,8),(5,6),(3,4),(1,2)) | 0
+ ((7,8),(5,6),(3,4),(1,2)) | ((1,2),(7,8),(5,6),(3,-4)) | 0
+ ((7,8),(5,6),(3,4),(1,2)) | ((0,0)) | 2.2360679775
+ ((7,8),(5,6),(3,4),(1,2)) | ((0,1),(0,1)) | 1.41421356237
+ ((1,2),(7,8),(5,6),(3,-4)) | ((2,0),(2,4),(0,0)) | 0
+ ((1,2),(7,8),(5,6),(3,-4)) | ((3,1),(3,3),(1,0)) | 0
+ ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(3,4),(5,6),(7,8)) | 0
+ ((1,2),(7,8),(5,6),(3,-4)) | ((7,8),(5,6),(3,4),(1,2)) | 0
+ ((1,2),(7,8),(5,6),(3,-4)) | ((1,2),(7,8),(5,6),(3,-4)) | 0
+ ((1,2),(7,8),(5,6),(3,-4)) | ((0,0)) | 1.58113883008
+ ((1,2),(7,8),(5,6),(3,-4)) | ((0,1),(0,1)) | 1.26491106407
+ ((0,0)) | ((2,0),(2,4),(0,0)) | 0
+ ((0,0)) | ((3,1),(3,3),(1,0)) | 1
+ ((0,0)) | ((1,2),(3,4),(5,6),(7,8)) | 2.2360679775
+ ((0,0)) | ((7,8),(5,6),(3,4),(1,2)) | 2.2360679775
+ ((0,0)) | ((1,2),(7,8),(5,6),(3,-4)) | 1.58113883008
+ ((0,0)) | ((0,0)) | 0
+ ((0,0)) | ((0,1),(0,1)) | 1
+ ((0,1),(0,1)) | ((2,0),(2,4),(0,0)) | 0.4472135955
+ ((0,1),(0,1)) | ((3,1),(3,3),(1,0)) | 1.38675049056
+ ((0,1),(0,1)) | ((1,2),(3,4),(5,6),(7,8)) | 1.41421356237
+ ((0,1),(0,1)) | ((7,8),(5,6),(3,4),(1,2)) | 1.41421356237
+ ((0,1),(0,1)) | ((1,2),(7,8),(5,6),(3,-4)) | 1.26491106407
+ ((0,1),(0,1)) | ((0,0)) | 1
+ ((0,1),(0,1)) | ((0,1),(0,1)) | 0
+(49 rows)
+
--
-- Circles
--