Skip to content

Commit df75911

Browse files
author
stepan-neretin7
committed
[ISSUE #16] Implemented a function and tests to extract vertices from spoly by index
1 parent 04456c7 commit df75911

16 files changed

+328
-11
lines changed

Diff for: doc/functions.sgm

+87-2
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@
463463
Positions at a path
464464
</title>
465465
<para>
466-
<application>pgSphere</application> provides two functions to
466+
<application>pgSphere</application> provides three functions to
467467
get points at a path.
468468
</para>
469469
<funcsynopsis>
@@ -477,6 +477,10 @@
477477
<paramdef>spath <parameter>path</parameter></paramdef>
478478
<paramdef>float8 <parameter>f</parameter></paramdef>
479479
</funcprototype>
480+
<funcprototype>
481+
<funcdef><function>spath_as_array</function></funcdef>
482+
<paramdef>spath <parameter>path</parameter></paramdef>
483+
</funcprototype>
480484
</funcsynopsis>
481485
<para>
482486
The first function returns the <parameter>i</parameter>-th
@@ -495,6 +499,36 @@
495499
<![CDATA[ spoint]]>
496500
<![CDATA[------------]]>
497501
<![CDATA[ (15d , 0d)]]>
502+
<![CDATA[(1 row)]]>
503+
</programlisting>
504+
</example>
505+
<example>
506+
<title>
507+
Get i-th point of a path
508+
</title>
509+
<programlisting>
510+
<![CDATA[sql> SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );]]>
511+
<![CDATA[ spoint ]]>
512+
<![CDATA[------------]]>
513+
<![CDATA[ (0 , 0) ]]>
514+
<![CDATA[(1 row)]]>
515+
<![CDATA[]]>
516+
<![CDATA[sql> SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );]]>
517+
<![CDATA[ spoint ]]>
518+
<![CDATA[------------]]>
519+
<![CDATA[ (1 , 1) ]]>
520+
<![CDATA[(1 row)]]>
521+
</programlisting>
522+
</example>
523+
<example>
524+
<title>
525+
Get array representation of points
526+
</title>
527+
<programlisting>
528+
<![CDATA[sql> SELECT spath_as_array( spath '{(0, 0),(1, 1)}');]]>
529+
<![CDATA[ spath_as_array ]]>
530+
<![CDATA[-----------------------]]>
531+
<![CDATA[ {"(0 , 0)","(1 , 1)"}]]>
498532
<![CDATA[(1 row)]]>
499533
</programlisting>
500534
</example>
@@ -532,7 +566,58 @@
532566
</example>
533567

534568
</sect3>
535-
569+
<sect3 id="funcs.spoly.pos">
570+
<title>
571+
Positions at a polygon
572+
</title>
573+
<para>
574+
<application>pgSphere</application> provides two functions to
575+
get points at a path.
576+
</para>
577+
<funcsynopsis>
578+
<funcprototype>
579+
<funcdef><function>spoint</function></funcdef>
580+
<paramdef>spoly <parameter>path</parameter></paramdef>
581+
<paramdef>int4 <parameter>i</parameter></paramdef>
582+
</funcprototype>
583+
<funcprototype>
584+
<funcdef><function>spoly_as_array</function></funcdef>
585+
<paramdef>spath <parameter>path</parameter></paramdef>
586+
</funcprototype>
587+
</funcsynopsis>
588+
<example>
589+
<title>Get by index</title>
590+
<programlisting>
591+
<![CDATA[sql> SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );]]>
592+
<![CDATA[ spoint ]]>
593+
<![CDATA[---------]]>
594+
<![CDATA[ (0 , 0)]]>
595+
<![CDATA[ (1 row)]]>
596+
<![CDATA[]]>
597+
<![CDATA[sql> SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );]]>
598+
<![CDATA[ spoint ]]>
599+
<![CDATA[---------]]>
600+
<![CDATA[ (1 , 0)]]>
601+
<![CDATA[ (1 row)]]>
602+
<![CDATA[]]>
603+
<![CDATA[sql> SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );]]>
604+
<![CDATA[ spoint ]]>
605+
<![CDATA[---------]]>
606+
<![CDATA[ (1 , 1)]]>
607+
<![CDATA[ (1 row)]]>
608+
</programlisting>
609+
</example>
610+
<example>
611+
<title>Represent points as array</title>
612+
<programlisting>
613+
<![CDATA[sql> SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );]]>
614+
<![CDATA[ spoly_as_array ]]>
615+
<![CDATA[---------------------------------]]>
616+
<![CDATA[ {"(0 , 0)","(1 , 0)","(1 , 1)"}]]>
617+
<![CDATA[(1 row)]]>
618+
</programlisting>
619+
</example>
620+
</sect3>
536621
</sect2>
537622

538623
<sect2 id="funcs.sbox">

Diff for: expected/init_test.out.in

+7-7
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell
2424
psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined
2525
DETAIL: Creating a shell type definition.
2626
psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell
27-
psql:pg_sphere.test.sql:8568: NOTICE: type "spherekey" is not yet defined
27+
psql:pg_sphere.test.sql:8594: NOTICE: type "spherekey" is not yet defined
2828
DETAIL: Creating a shell type definition.
29-
psql:pg_sphere.test.sql:8575: NOTICE: argument type spherekey is only a shell
30-
psql:pg_sphere.test.sql:8589: NOTICE: type "pointkey" is not yet defined
29+
psql:pg_sphere.test.sql:8601: NOTICE: argument type spherekey is only a shell
30+
psql:pg_sphere.test.sql:8615: NOTICE: type "pointkey" is not yet defined
3131
DETAIL: Creating a shell type definition.
32-
psql:pg_sphere.test.sql:8596: NOTICE: argument type pointkey is only a shell
33-
psql:pg_sphere.test.sql:8602: NOTICE: argument type pointkey is only a shell
34-
psql:pg_sphere.test.sql:8608: NOTICE: argument type pointkey is only a shell
35-
psql:pg_sphere.test.sql:8614: NOTICE: argument type pointkey is only a shell
32+
psql:pg_sphere.test.sql:8622: NOTICE: argument type pointkey is only a shell
33+
psql:pg_sphere.test.sql:8628: NOTICE: argument type pointkey is only a shell
34+
psql:pg_sphere.test.sql:8634: NOTICE: argument type pointkey is only a shell
35+
psql:pg_sphere.test.sql:8640: NOTICE: argument type pointkey is only a shell

Diff for: expected/init_test_healpix.out.in

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
psql:pg_sphere.test.sql:9181: NOTICE: return type smoc is only a shell
2-
psql:pg_sphere.test.sql:9187: NOTICE: argument type smoc is only a shell
1+
psql:pg_sphere.test.sql:9207: NOTICE: return type smoc is only a shell
2+
psql:pg_sphere.test.sql:9213: NOTICE: argument type smoc is only a shell

Diff for: expected/path.out

+25
Original file line numberDiff line numberDiff line change
@@ -468,3 +468,28 @@ SELECT spoint(p,2) FROM spheretmp6 WHERE id=2;
468468
(1d , -5d)
469469
(1 row)
470470

471+
SELECT set_sphere_output( 'RAD' );
472+
set_sphere_output
473+
-------------------
474+
SET RAD
475+
(1 row)
476+
477+
-- get n-th point and array representation path points tests
478+
SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );
479+
spoint
480+
---------
481+
(0 , 0)
482+
(1 row)
483+
484+
SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );
485+
spoint
486+
---------
487+
(1 , 1)
488+
(1 row)
489+
490+
SELECT spath_as_array( spath '{(0, 0),(1, 1)}');
491+
spath_as_array
492+
-----------------------
493+
{"(0 , 0)","(1 , 1)"}
494+
(1 row)
495+

Diff for: expected/poly.out

+30
Original file line numberDiff line numberDiff line change
@@ -1760,3 +1760,33 @@ SELECT npoints( spoly '{
17601760
4
17611761
(1 row)
17621762

1763+
SELECT set_sphere_output( 'RAD' );
1764+
set_sphere_output
1765+
-------------------
1766+
SET RAD
1767+
(1 row)
1768+
1769+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );
1770+
spoint
1771+
---------
1772+
(0 , 0)
1773+
(1 row)
1774+
1775+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );
1776+
spoint
1777+
---------
1778+
(1 , 0)
1779+
(1 row)
1780+
1781+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );
1782+
spoint
1783+
---------
1784+
(1 , 1)
1785+
(1 row)
1786+
1787+
SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );
1788+
spoly_as_array
1789+
---------------------------------
1790+
{"(0 , 0)","(1 , 0)","(1 , 1)"}
1791+
(1 row)
1792+

Diff for: pgs_path.sql.in

+8
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@ CREATE FUNCTION spoint(spath, float8)
3434
COMMENT ON FUNCTION spoint(spath, float8) IS
3535
'returns n-th point of spherical path using linear interpolation';
3636

37+
CREATE FUNCTION spath_as_array(spath)
38+
RETURNS spoint[]
39+
AS 'MODULE_PATHNAME', 'spherepath_get_array'
40+
LANGUAGE 'c'
41+
IMMUTABLE STRICT PARALLEL SAFE;
42+
43+
COMMENT ON FUNCTION spath_as_array(spath) IS
44+
'returns spath as array of points';
3745

3846
-- ******************************
3947
--

Diff for: pgs_polygon.sql.in

+18
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,24 @@ CREATE FUNCTION npoints(spoly)
1111
COMMENT ON FUNCTION npoints(spoly) IS
1212
'returns number of points of spherical polygon';
1313

14+
CREATE FUNCTION spoint(spoly, int4)
15+
RETURNS spoint
16+
AS 'MODULE_PATHNAME', 'spherepoly_get_point'
17+
LANGUAGE 'c'
18+
IMMUTABLE STRICT PARALLEL SAFE;
19+
20+
COMMENT ON FUNCTION spoint(spoly, int4) IS
21+
'returns n-th point of spherical polygon';
22+
23+
CREATE FUNCTION spoly_as_array(spoly)
24+
RETURNS spoint[]
25+
AS 'MODULE_PATHNAME', 'spherepoly_get_array'
26+
LANGUAGE 'c'
27+
IMMUTABLE STRICT PARALLEL SAFE;
28+
29+
COMMENT ON FUNCTION spoly_as_array(spoly) IS
30+
'returns spoly as array of points';
31+
1432
CREATE FUNCTION area(spoly)
1533
RETURNS FLOAT8
1634
AS 'MODULE_PATHNAME', 'spherepoly_area'

Diff for: sql/path.sql

+6
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,9 @@ SELECT set_sphere_output( 'DEG' );
104104
-- test stored data
105105
SELECT spoint(p,2) FROM spheretmp6 WHERE id=2;
106106

107+
SELECT set_sphere_output( 'RAD' );
108+
109+
-- get n-th point and array representation path points tests
110+
SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );
111+
SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );
112+
SELECT spath_as_array( spath '{(0, 0),(1, 1)}');

Diff for: sql/poly.sql

+7
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,10 @@ SELECT npoints( spoly '{
603603
(1.5121581120647 , -1.93925472462553e-05),
604604
(1.51214841579108 , -1.93925472462553e-05)
605605
}');
606+
607+
SELECT set_sphere_output( 'RAD' );
608+
609+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );
610+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );
611+
SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );
612+
SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );

Diff for: src/path.c

+29
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "path.h"
2+
#include "point.h"
3+
#include <catalog/namespace.h>
24

35
/*
46
* Path functions
@@ -50,6 +52,7 @@ PG_FUNCTION_INFO_V1(spheretrans_path);
5052
PG_FUNCTION_INFO_V1(spheretrans_path_inverse);
5153
PG_FUNCTION_INFO_V1(spherepath_add_point);
5254
PG_FUNCTION_INFO_V1(spherepath_add_points_finalize);
55+
PG_FUNCTION_INFO_V1(spherepath_get_array);
5356

5457

5558
/*
@@ -555,6 +558,32 @@ spherepath_get_point(PG_FUNCTION_ARGS)
555558
PG_RETURN_NULL();
556559
}
557560

561+
Datum
562+
spherepath_get_array(PG_FUNCTION_ARGS)
563+
{
564+
SPATH *path = PG_GETARG_SPATH(0);
565+
Datum *datum_arr = (Datum *) palloc(sizeof(Datum) * path->npts);
566+
ArrayType *res;
567+
SPoint *p = (SPoint *) palloc(sizeof(SPoint) * path->npts);
568+
569+
for (size_t i = 0; i < path->npts; i++)
570+
{
571+
if (!spath_get_point(&p[i], path, i))
572+
{
573+
// Clean up and return NULL
574+
for (size_t j = 0; j < i; j++)
575+
pfree(DatumGetPointer(datum_arr[j]));
576+
pfree(datum_arr);
577+
PG_RETURN_NULL();
578+
}
579+
datum_arr[i] = PointerGetDatum(&p[i]);
580+
}
581+
582+
res = construct_array(datum_arr, path->npts, get_spoint_type_oid(), sizeof(SPoint), false, 'd');
583+
584+
PG_RETURN_ARRAYTYPE_P(res);
585+
}
586+
558587
Datum
559588
spherepath_point(PG_FUNCTION_ARGS)
560589
{

Diff for: src/path.h

+5
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ Datum spherepath_in(PG_FUNCTION_ARGS);
7171
*/
7272
Datum spherepath_get_point(PG_FUNCTION_ARGS);
7373

74+
/*
75+
* Returns spath as array of points
76+
*/
77+
Datum spherepath_get_array(PG_FUNCTION_ARGS);
78+
7479
/*
7580
* This function interpolates between points of path. Returns the
7681
* n-th point of a path where n is a float.

Diff for: src/point.c

+12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "point.h"
22
#include "pgs_util.h"
3+
#include <catalog/namespace.h>
34

45
/* This file contains definitions for spherical point functions. */
56

@@ -15,6 +16,17 @@ PG_FUNCTION_INFO_V1(spherepoint_z);
1516
PG_FUNCTION_INFO_V1(spherepoint_xyz);
1617
PG_FUNCTION_INFO_V1(spherepoint_equal);
1718

19+
static Oid point_id = InvalidOid;
20+
21+
Oid get_spoint_type_oid(void)
22+
{
23+
if (point_id == InvalidOid)
24+
{
25+
point_id = TypenameGetTypid("spoint");
26+
}
27+
return point_id;
28+
}
29+
1830
bool
1931
spoint_eq(const SPoint *p1, const SPoint *p2)
2032
{

Diff for: src/point.h

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ typedef struct
1515
float8 lat; /* latitude value in radians */
1616
} SPoint;
1717

18+
Oid get_spoint_type_oid(void);
19+
1820
/*
1921
* Calculate the distance between two spherical points in radians.
2022
*/

0 commit comments

Comments
 (0)