Skip to content

Commit c62d296

Browse files
committed
Add function to create spoly from an array of numbers in radians.
1 parent 6f19a10 commit c62d296

File tree

6 files changed

+127
-17
lines changed

6 files changed

+127
-17
lines changed

expected/poly.out

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,18 @@ SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}';
318318
{(10d , 0d),(10d , 1d),(15d , 0d)}
319319
(1 row)
320320

321+
SELECT spoly(ARRAY[0.017453292519943295, 0.03490658503988659, 0.05235987755982988, 0.06981317007977318, 0.08726646259971647, 0.10471975511965977]);
322+
spoly
323+
---------------------------------
324+
{(1d , 2d),(3d , 4d),(5d , 6d)}
325+
(1 row)
326+
327+
SELECT spoly(ARRAY[0.17453292519943295, 0.0, 0.17453292519943295, 0.017453292519943295, 0.2617993877991494, 0.0]);
328+
spoly
329+
------------------------------------
330+
{(10d , 0d),(10d , 1d),(15d , 0d)}
331+
(1 row)
332+
321333
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
322334
spoly_deg
323335
---------------------------------
@@ -335,6 +347,16 @@ SELECT spoly '{(10d,0d),(10d,1d)}';
335347
ERROR: spherepoly_in: more than two points needed
336348
LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}';
337349
^
350+
SELECT spoly(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
351+
ERROR: spherepoly_rad: invalid number of arguments (must be even and >= 6)
352+
SELECT spoly(ARRAY[]::float8[]);
353+
ERROR: spherepoly_rad: invalid number of arguments (must be even and >= 6)
354+
SELECT spoly(NULL::float8[]);
355+
spoly
356+
-------
357+
358+
(1 row)
359+
338360
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
339361
ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6)
340362
SELECT spoly_deg(ARRAY[]::float8[]);

pgs_polygon.sql.in

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
1+
-- **************************
2+
--
23
-- spherical polygon functions
3-
4+
--
5+
-- **************************
46

57
CREATE FUNCTION npoints(spoly)
68
RETURNS INT4
@@ -934,17 +936,17 @@ COMMENT ON OPERATOR !&& (sellipse, spoly) IS
934936

935937

936938
--
937-
-- Aggregate functions to add points to polygon
939+
-- Functions to create a polygon from arrays
938940
--
939941

940-
CREATE FUNCTION spoly_add_point_aggr (spoly, spoint)
941-
RETURNS spoly
942-
AS 'MODULE_PATHNAME', 'spherepoly_add_point'
943-
LANGUAGE 'c'
944-
IMMUTABLE PARALLEL SAFE;
942+
CREATE FUNCTION spoly(float8[])
943+
RETURNS spoly
944+
AS 'MODULE_PATHNAME', 'spherepoly_rad'
945+
LANGUAGE 'c'
946+
IMMUTABLE STRICT;
945947

946-
COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS
947-
'adds a spherical point to spherical polygon. Do not use it standalone!';
948+
COMMENT ON FUNCTION spoly(float8[]) IS
949+
'creates spoly from array of numbers in radians';
948950

949951
CREATE FUNCTION spoly_deg(float8[])
950952
RETURNS spoly
@@ -953,10 +955,21 @@ CREATE FUNCTION spoly_deg(float8[])
953955
IMMUTABLE STRICT;
954956

955957
COMMENT ON FUNCTION spoly_deg(float8[]) IS
956-
' Create spoly from array of points.
957-
Two consecutive numbers among those present
958-
refer to the same occurrence and cover its
959-
latitude and longitude, respectively.';
958+
'creates spoly from array of numbers in degrees';
959+
960+
961+
--
962+
-- Aggregate functions to add points to polygon
963+
--
964+
965+
CREATE FUNCTION spoly_add_point_aggr (spoly, spoint)
966+
RETURNS spoly
967+
AS 'MODULE_PATHNAME', 'spherepoly_add_point'
968+
LANGUAGE 'c'
969+
IMMUTABLE PARALLEL SAFE;
970+
971+
COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS
972+
'adds a spherical point to spherical polygon. Do not use it standalone!';
960973

961974
CREATE FUNCTION spoly_add_points_fin_aggr (spoly)
962975
RETURNS spoly

sql/poly.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ SELECT spoly '{(359d,0d),(359d,1d),(4d,0d)}';
7878

7979
SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}';
8080

81+
SELECT spoly(ARRAY[0.017453292519943295, 0.03490658503988659, 0.05235987755982988, 0.06981317007977318, 0.08726646259971647, 0.10471975511965977]);
82+
83+
SELECT spoly(ARRAY[0.17453292519943295, 0.0, 0.17453292519943295, 0.017453292519943295, 0.2617993877991494, 0.0]);
84+
8185
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
8286

8387
SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);
@@ -86,6 +90,12 @@ SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);
8690

8791
SELECT spoly '{(10d,0d),(10d,1d)}';
8892

93+
SELECT spoly(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
94+
95+
SELECT spoly(ARRAY[]::float8[]);
96+
97+
SELECT spoly(NULL::float8[]);
98+
8999
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
90100

91101
SELECT spoly_deg(ARRAY[]::float8[]);

src/polygon.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
PG_FUNCTION_INFO_V1(spherepoly_in);
88
PG_FUNCTION_INFO_V1(spherepoly_deg);
9+
PG_FUNCTION_INFO_V1(spherepoly_rad);
910
PG_FUNCTION_INFO_V1(spherepoly_equal);
1011
PG_FUNCTION_INFO_V1(spherepoly_equal_neg);
1112
PG_FUNCTION_INFO_V1(spherepoly_circ);
@@ -906,6 +907,51 @@ spherepoly_in(PG_FUNCTION_ARGS)
906907
PG_RETURN_POINTER(poly);
907908
}
908909

910+
Datum
911+
spherepoly_rad(PG_FUNCTION_ARGS)
912+
{
913+
int i,
914+
np;
915+
ArrayType *float_vector = PG_GETARG_ARRAYTYPE_P(0);
916+
float8 *array_data;
917+
SPoint *points;
918+
919+
np = ArrayGetNItems(ARR_NDIM(float_vector), ARR_DIMS(float_vector));
920+
921+
if (np < 6 || np % 2 != 0)
922+
{
923+
elog(
924+
ERROR,
925+
"spherepoly_rad: invalid number of arguments (must be even and >= 6)"
926+
);
927+
PG_RETURN_NULL();
928+
}
929+
930+
np /= 2;
931+
932+
points = (SPoint *) palloc(np * sizeof(SPoint));
933+
if (points == NULL)
934+
{
935+
elog(
936+
ERROR,
937+
"spherepoly_rad: failed to allocate memory for points array"
938+
);
939+
PG_RETURN_NULL();
940+
}
941+
942+
array_data = (float8 *) ARR_DATA_PTR(float_vector);
943+
944+
for (i = 0; i < np; i++)
945+
{
946+
create_spherepoint_from_long_lat(
947+
&points[i],
948+
array_data[2 * i],
949+
array_data[2 * i + 1]
950+
);
951+
}
952+
PG_RETURN_POINTER(spherepoly_from_array(points, np));
953+
}
954+
909955
Datum
910956
spherepoly_deg(PG_FUNCTION_ARGS)
911957
{
@@ -933,7 +979,7 @@ spherepoly_deg(PG_FUNCTION_ARGS)
933979
{
934980
elog(
935981
ERROR,
936-
"spherepoly_deg: failed for allocate memory for points array"
982+
"spherepoly_deg: failed to allocate memory for points array"
937983
);
938984
PG_RETURN_NULL();
939985
}

src/polygon.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,14 @@ Datum spherepoly_get_point(PG_FUNCTION_ARGS);
8787
int8 poly_line_pos(const SPOLY *poly, const SLine *line);
8888

8989
/*
90-
* Input of a spherical from sequence of pairconsecutive numbers(lng, lat).
90+
* Input of a spherical from array of pair-consecutive numbers (lng, lat), in radians.
9191
*/
92-
Datum spherepoly_deg(PG_FUNCTION_ARGS);
92+
Datum spherepoly_rad(PG_FUNCTION_ARGS);
93+
94+
/*
95+
* Input of a spherical from array of pair-consecutive numbers (lng, lat), in degrees.
96+
*/
97+
Datum spherepoly_deg(PG_FUNCTION_ARGS);
9398

9499
/*
95100
* Input of a spherical polygon.

upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,17 @@ $$;
1616
-- remove legacy spellings of operators
1717
DROP OPERATOR IF EXISTS @(bigint, smoc);
1818
DROP OPERATOR IF EXISTS @(spoint, smoc);
19+
20+
-- add spoly function that takes an array of float8 values in radians
21+
CREATE FUNCTION spoly(float8[])
22+
RETURNS spoly
23+
AS 'MODULE_PATHNAME', 'spherepoly_rad'
24+
LANGUAGE 'c'
25+
IMMUTABLE STRICT;
26+
27+
COMMENT ON FUNCTION spoly(float8[]) IS
28+
'creates spoly from array of numbers in radians';
29+
30+
-- update comment on spoly_deg function
31+
COMMENT ON FUNCTION spoly_deg(float8[]) IS
32+
'creates spoly from array of numbers in degrees';

0 commit comments

Comments
 (0)