diff --git a/doc/functions.sgm b/doc/functions.sgm
index 30118bf..5cdc3aa 100644
--- a/doc/functions.sgm
+++ b/doc/functions.sgm
@@ -463,7 +463,7 @@
Positions at a path
- pgSphere provides two functions to
+ pgSphere provides three functions to
get points at a path.
@@ -477,6 +477,10 @@
spath path
float8 f
+
+ spath_as_array
+ spath path
+
The first function returns the i-th
@@ -495,6 +499,36 @@
+
+
+
+
+
+ Get i-th point of a path
+
+
+ SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );]]>
+
+
+
+
+
+ SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );]]>
+
+
+
+
+
+
+
+
+ Get array representation of points
+
+
+ SELECT spath_as_array( spath '{(0, 0),(1, 1)}');]]>
+
+
+
@@ -532,7 +566,58 @@
-
+
+
+ Positions at a polygon
+
+
+ pgSphere provides two functions to
+ get points at a path.
+
+
+
+ spoint
+ spoly path
+ int4 i
+
+
+ spoly_as_array
+ spath path
+
+
+
+ Get by index
+
+ SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );]]>
+
+
+
+
+
+ SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );]]>
+
+
+
+
+
+ SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );]]>
+
+
+
+
+
+
+
+ Represent points as array
+
+ SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );]]>
+
+
+
+
+
+
+
diff --git a/expected/init_test.out.in b/expected/init_test.out.in
index 4b0671c..1276622 100644
--- a/expected/init_test.out.in
+++ b/expected/init_test.out.in
@@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell
psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell
-psql:pg_sphere.test.sql:8568: NOTICE: type "spherekey" is not yet defined
+psql:pg_sphere.test.sql:8594: NOTICE: type "spherekey" is not yet defined
DETAIL: Creating a shell type definition.
-psql:pg_sphere.test.sql:8575: NOTICE: argument type spherekey is only a shell
-psql:pg_sphere.test.sql:8589: NOTICE: type "pointkey" is not yet defined
+psql:pg_sphere.test.sql:8601: NOTICE: argument type spherekey is only a shell
+psql:pg_sphere.test.sql:8615: NOTICE: type "pointkey" is not yet defined
DETAIL: Creating a shell type definition.
-psql:pg_sphere.test.sql:8596: NOTICE: argument type pointkey is only a shell
-psql:pg_sphere.test.sql:8602: NOTICE: argument type pointkey is only a shell
-psql:pg_sphere.test.sql:8608: NOTICE: argument type pointkey is only a shell
-psql:pg_sphere.test.sql:8614: NOTICE: argument type pointkey is only a shell
+psql:pg_sphere.test.sql:8622: NOTICE: argument type pointkey is only a shell
+psql:pg_sphere.test.sql:8628: NOTICE: argument type pointkey is only a shell
+psql:pg_sphere.test.sql:8634: NOTICE: argument type pointkey is only a shell
+psql:pg_sphere.test.sql:8640: NOTICE: argument type pointkey is only a shell
diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in
index 7e725f8..147d4f9 100644
--- a/expected/init_test_healpix.out.in
+++ b/expected/init_test_healpix.out.in
@@ -1,2 +1,2 @@
-psql:pg_sphere.test.sql:9181: NOTICE: return type smoc is only a shell
-psql:pg_sphere.test.sql:9187: NOTICE: argument type smoc is only a shell
+psql:pg_sphere.test.sql:9207: NOTICE: return type smoc is only a shell
+psql:pg_sphere.test.sql:9213: NOTICE: argument type smoc is only a shell
diff --git a/expected/path.out b/expected/path.out
index 1734d8c..9f62534 100644
--- a/expected/path.out
+++ b/expected/path.out
@@ -468,3 +468,28 @@ SELECT spoint(p,2) FROM spheretmp6 WHERE id=2;
(1d , -5d)
(1 row)
+SELECT set_sphere_output( 'RAD' );
+ set_sphere_output
+-------------------
+ SET RAD
+(1 row)
+
+-- get n-th point and array representation path points tests
+SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );
+ spoint
+---------
+ (0 , 0)
+(1 row)
+
+SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );
+ spoint
+---------
+ (1 , 1)
+(1 row)
+
+SELECT spath_as_array( spath '{(0, 0),(1, 1)}');
+ spath_as_array
+-----------------------
+ {"(0 , 0)","(1 , 1)"}
+(1 row)
+
diff --git a/expected/poly.out b/expected/poly.out
index a705483..bf7bc0b 100644
--- a/expected/poly.out
+++ b/expected/poly.out
@@ -1760,3 +1760,33 @@ SELECT npoints( spoly '{
4
(1 row)
+SELECT set_sphere_output( 'RAD' );
+ set_sphere_output
+-------------------
+ SET RAD
+(1 row)
+
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );
+ spoint
+---------
+ (0 , 0)
+(1 row)
+
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );
+ spoint
+---------
+ (1 , 0)
+(1 row)
+
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );
+ spoint
+---------
+ (1 , 1)
+(1 row)
+
+SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );
+ spoly_as_array
+---------------------------------
+ {"(0 , 0)","(1 , 0)","(1 , 1)"}
+(1 row)
+
diff --git a/pgs_path.sql.in b/pgs_path.sql.in
index 94f3222..58268d4 100644
--- a/pgs_path.sql.in
+++ b/pgs_path.sql.in
@@ -34,6 +34,14 @@ CREATE FUNCTION spoint(spath, float8)
COMMENT ON FUNCTION spoint(spath, float8) IS
'returns n-th point of spherical path using linear interpolation';
+CREATE FUNCTION spath_as_array(spath)
+ RETURNS spoint[]
+ AS 'MODULE_PATHNAME', 'spherepath_get_array'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spath_as_array(spath) IS
+ 'returns spath as array of points';
-- ******************************
--
diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in
index df5a614..5db17c6 100644
--- a/pgs_polygon.sql.in
+++ b/pgs_polygon.sql.in
@@ -11,6 +11,24 @@ CREATE FUNCTION npoints(spoly)
COMMENT ON FUNCTION npoints(spoly) IS
'returns number of points of spherical polygon';
+CREATE FUNCTION spoint(spoly, int4)
+ RETURNS spoint
+ AS 'MODULE_PATHNAME', 'spherepoly_get_point'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spoint(spoly, int4) IS
+ 'returns n-th point of spherical polygon';
+
+CREATE FUNCTION spoly_as_array(spoly)
+ RETURNS spoint[]
+ AS 'MODULE_PATHNAME', 'spherepoly_get_array'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spoly_as_array(spoly) IS
+ 'returns spoly as array of points';
+
CREATE FUNCTION area(spoly)
RETURNS FLOAT8
AS 'MODULE_PATHNAME', 'spherepoly_area'
diff --git a/sql/path.sql b/sql/path.sql
index fef5c1f..85fb3ff 100644
--- a/sql/path.sql
+++ b/sql/path.sql
@@ -104,3 +104,9 @@ SELECT set_sphere_output( 'DEG' );
-- test stored data
SELECT spoint(p,2) FROM spheretmp6 WHERE id=2;
+SELECT set_sphere_output( 'RAD' );
+
+-- get n-th point and array representation path points tests
+SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );
+SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );
+SELECT spath_as_array( spath '{(0, 0),(1, 1)}');
diff --git a/sql/poly.sql b/sql/poly.sql
index 52cedd7..9d7b600 100644
--- a/sql/poly.sql
+++ b/sql/poly.sql
@@ -603,3 +603,10 @@ SELECT npoints( spoly '{
(1.5121581120647 , -1.93925472462553e-05),
(1.51214841579108 , -1.93925472462553e-05)
}');
+
+SELECT set_sphere_output( 'RAD' );
+
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );
+SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );
+SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );
diff --git a/src/path.c b/src/path.c
index b72a753..f6d9495 100644
--- a/src/path.c
+++ b/src/path.c
@@ -1,4 +1,6 @@
#include "path.h"
+#include "point.h"
+#include
/*
* Path functions
@@ -50,6 +52,7 @@ PG_FUNCTION_INFO_V1(spheretrans_path);
PG_FUNCTION_INFO_V1(spheretrans_path_inverse);
PG_FUNCTION_INFO_V1(spherepath_add_point);
PG_FUNCTION_INFO_V1(spherepath_add_points_finalize);
+PG_FUNCTION_INFO_V1(spherepath_get_array);
/*
@@ -555,6 +558,30 @@ spherepath_get_point(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
+Datum
+spherepath_get_array(PG_FUNCTION_ARGS)
+{
+ SPATH *path = PG_GETARG_SPATH(0);
+ Datum *datum_arr = (Datum *) palloc(sizeof(Datum) * path->npts);
+ ArrayType *res;
+ SPoint *p = (SPoint *) palloc(sizeof(SPoint) * path->npts);
+
+ for (size_t i = 0; i < path->npts; i++)
+ {
+ if (!spath_get_point(&p[i], path, i))
+ {
+ pfree(p);
+ pfree(datum_arr);
+ PG_RETURN_NULL();
+ }
+ datum_arr[i] = PointerGetDatum(&p[i]);
+ }
+
+ res = construct_array(datum_arr, path->npts, get_spoint_type_oid(), sizeof(SPoint), false, 'd');
+
+ PG_RETURN_ARRAYTYPE_P(res);
+}
+
Datum
spherepath_point(PG_FUNCTION_ARGS)
{
diff --git a/src/path.h b/src/path.h
index 1d0fc35..29c687b 100644
--- a/src/path.h
+++ b/src/path.h
@@ -71,6 +71,11 @@ Datum spherepath_in(PG_FUNCTION_ARGS);
*/
Datum spherepath_get_point(PG_FUNCTION_ARGS);
+/*
+ * Returns spath as array of points
+ */
+Datum spherepath_get_array(PG_FUNCTION_ARGS);
+
/*
* This function interpolates between points of path. Returns the
* n-th point of a path where n is a float.
diff --git a/src/point.c b/src/point.c
index c68ee71..0cbfa00 100644
--- a/src/point.c
+++ b/src/point.c
@@ -1,5 +1,6 @@
#include "point.h"
#include "pgs_util.h"
+#include
/* This file contains definitions for spherical point functions. */
@@ -15,6 +16,17 @@ PG_FUNCTION_INFO_V1(spherepoint_z);
PG_FUNCTION_INFO_V1(spherepoint_xyz);
PG_FUNCTION_INFO_V1(spherepoint_equal);
+static Oid point_id = InvalidOid;
+
+Oid get_spoint_type_oid(void)
+{
+ if (point_id == InvalidOid)
+ {
+ point_id = TypenameGetTypid("spoint");
+ }
+ return point_id;
+}
+
bool
spoint_eq(const SPoint *p1, const SPoint *p2)
{
diff --git a/src/point.h b/src/point.h
index 89197d0..9269cf7 100644
--- a/src/point.h
+++ b/src/point.h
@@ -15,6 +15,8 @@ typedef struct
float8 lat; /* latitude value in radians */
} SPoint;
+Oid get_spoint_type_oid(void);
+
/*
* Calculate the distance between two spherical points in radians.
*/
diff --git a/src/polygon.c b/src/polygon.c
index 17f4841..54eb2a6 100644
--- a/src/polygon.c
+++ b/src/polygon.c
@@ -11,6 +11,8 @@ PG_FUNCTION_INFO_V1(spherepoly_equal_neg);
PG_FUNCTION_INFO_V1(spherepoly_circ);
PG_FUNCTION_INFO_V1(spherepoly_npts);
PG_FUNCTION_INFO_V1(spherepoly_area);
+PG_FUNCTION_INFO_V1(spherepoly_get_point);
+PG_FUNCTION_INFO_V1(spherepoly_get_array);
PG_FUNCTION_INFO_V1(spherepoly_cont_point);
PG_FUNCTION_INFO_V1(spherepoly_cont_point_neg);
PG_FUNCTION_INFO_V1(spherepoly_cont_point_com);
@@ -556,6 +558,57 @@ spoly_segment(SLine *sl, const SPOLY *poly, int32 i)
}
}
+static bool
+spoly_get_point(SPoint *sp, const SPOLY *poly, int32 i)
+{
+ if (i >= 0 && i < poly->npts)
+ {
+ memcpy((void *) sp, (void *) &poly->p[i], sizeof(SPoint));
+ return true;
+ }
+ return false;
+}
+
+Datum
+spherepoly_get_point(PG_FUNCTION_ARGS)
+{
+ int32 i;
+ SPOLY *poly = PG_GETARG_SPOLY(0);
+ SPoint *sp = (SPoint *) palloc(sizeof(SPoint));
+
+ i = PG_GETARG_INT32(1);
+ if (spoly_get_point(sp, poly, i - 1))
+ {
+ PG_RETURN_POINTER(sp);
+ }
+ pfree(sp);
+ PG_RETURN_NULL();
+}
+
+Datum
+spherepoly_get_array(PG_FUNCTION_ARGS)
+{
+ SPOLY *poly = PG_GETARG_SPOLY(0);
+ Datum *datum_arr = (Datum *) palloc(sizeof(Datum) * poly->npts);
+ ArrayType *res;
+ SPoint *p = (SPoint *) palloc(sizeof(SPoint) * poly->npts);
+
+ for (int i = 0; i < poly->npts; i++)
+ {
+ if (!spoly_get_point(&p[i], poly, i))
+ {
+ pfree(p);
+ pfree(datum_arr);
+ PG_RETURN_NULL();
+ }
+ datum_arr[i] = PointerGetDatum(&p[i]);
+ }
+
+ res = construct_array(datum_arr, poly->npts, get_spoint_type_oid(), sizeof(SPoint), false, 'd');
+
+ PG_RETURN_ARRAYTYPE_P(res);
+}
+
/*
* Checks whether a polygon contains a point.
*
diff --git a/src/polygon.h b/src/polygon.h
index eefd099..c7daf13 100644
--- a/src/polygon.h
+++ b/src/polygon.h
@@ -72,6 +72,11 @@ bool spoly_segment(SLine *sl, const SPOLY *poly, int32 i);
*/
bool spoly_contains_point(const SPOLY *pg, const SPoint *sp);
+/*
+ * Returns the n-th point of a spoly.
+ */
+Datum spherepoly_get_point(PG_FUNCTION_ARGS);
+
/*
* Returns the relationship between a polygon and a line as
* PGS_LINE_POLY_REL int8 value.
@@ -348,4 +353,9 @@ Datum spherepoly_add_point(PG_FUNCTION_ARGS);
*/
Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS);
+/*
+ * Returns spoly as array of points
+ */
+Datum spherepoly_get_array(PG_FUNCTION_ARGS);
+
#endif
diff --git a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in
index 86cc233..3791852 100644
--- a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in
+++ b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in
@@ -27,3 +27,30 @@ COMMENT ON FUNCTION spoly_deg(float8[]) IS
Two consecutive numbers among those present
refer to the same occurrence and cover its
latitude and longitude, respectively.';
+
+CREATE FUNCTION spath_as_array(spath)
+ RETURNS spoint[]
+ AS 'MODULE_PATHNAME', 'spherepath_get_array'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spath_as_array(spath) IS
+ 'returns spath as array of points';
+
+CREATE FUNCTION spoint(spoly, int4)
+ RETURNS spoint
+ AS 'MODULE_PATHNAME', 'spherepoly_get_point'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spoint(spoly, int4) IS
+ 'returns n-th point of spherical polygon';
+
+CREATE FUNCTION spoly_as_array(spoly)
+ RETURNS spoint[]
+ AS 'MODULE_PATHNAME', 'spherepoly_get_array'
+ LANGUAGE 'c'
+ IMMUTABLE STRICT PARALLEL SAFE;
+
+COMMENT ON FUNCTION spoly_as_array(spoly) IS
+ 'returns spoly as array of points';