Skip to content

Commit 4199d35

Browse files
author
stepan-neretin7
committed
[ISSUE #22] Created spoint_deg, scircle_deg functions.
1 parent 612f06b commit 4199d35

22 files changed

+314
-20
lines changed

Diff for: Makefile

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ DATA_built = $(RELEASE_SQL) \
2727
pg_sphere--1.1.5beta4gavo--1.2.0.sql \
2828
pg_sphere--1.2.0--1.2.1.sql \
2929
pg_sphere--1.2.1--1.2.2.sql \
30-
pg_sphere--1.2.2--1.2.3.sql
30+
pg_sphere--1.2.2--1.2.3.sql \
31+
pg_sphere--1.2.3--1.3.0.sql
3132

3233
DOCS = README.pg_sphere COPYRIGHT.pg_sphere
3334
REGRESS = init tables points euler circle line ellipse poly path box index \
@@ -260,6 +261,9 @@ endif
260261
pg_sphere--1.2.2--1.2.3.sql:
261262
cat upgrade_scripts/$@.in > $@
262263

264+
pg_sphere--1.2.3--1.3.0.sql:
265+
cat upgrade_scripts/$@.in > $@
266+
263267
# end of local stuff
264268

265269
src/sscan.o : src/sparse.c

Diff for: expected/circle.out

+16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
(1 row)
66

77
-- Input/Output ---
8+
SELECT scircle_deg(spoint(10,10), 90);
9+
scircle_deg
10+
------------------------------------------
11+
<(0.57522204 , -0.57522204) , 1.5707963>
12+
(1 row)
13+
14+
SELECT scircle_deg(spoint(10,10), 91);
15+
ERROR: radius must not be greater than 90 degrees or less than 0
16+
SELECT scircle_deg(spoint(0,0), 0);
17+
scircle_deg
18+
---------------
19+
<(0 , 0) , 0>
20+
(1 row)
21+
22+
SELECT scircle_deg(spoint(10,10), -1);
23+
ERROR: radius must not be greater than 90 degrees or less than 0
824
SELECT set_sphere_output( 'RAD' );
925
set_sphere_output
1026
-------------------

Diff for: expected/init_test.out.in

+11-11
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ psql:pg_sphere.test.sql:108: NOTICE: argument type sellipse is only a shell
1818
psql:pg_sphere.test.sql:126: NOTICE: type "spoly" is not yet defined
1919
DETAIL: Creating a shell type definition.
2020
psql:pg_sphere.test.sql:133: NOTICE: argument type spoly is only a shell
21-
psql:pg_sphere.test.sql:152: NOTICE: type "spath" is not yet defined
21+
psql:pg_sphere.test.sql:151: NOTICE: type "spath" is not yet defined
2222
DETAIL: Creating a shell type definition.
23-
psql:pg_sphere.test.sql:159: NOTICE: argument type spath is only a shell
24-
psql:pg_sphere.test.sql:178: NOTICE: type "sbox" is not yet defined
23+
psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell
24+
psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined
2525
DETAIL: Creating a shell type definition.
26-
psql:pg_sphere.test.sql:185: NOTICE: argument type sbox is only a shell
27-
psql:pg_sphere.test.sql:8540: NOTICE: type "spherekey" is not yet defined
26+
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
2828
DETAIL: Creating a shell type definition.
29-
psql:pg_sphere.test.sql:8547: NOTICE: argument type spherekey is only a shell
30-
psql:pg_sphere.test.sql:8561: NOTICE: type "pointkey" is not yet defined
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
3131
DETAIL: Creating a shell type definition.
32-
psql:pg_sphere.test.sql:8568: NOTICE: argument type pointkey is only a shell
33-
psql:pg_sphere.test.sql:8574: NOTICE: argument type pointkey is only a shell
34-
psql:pg_sphere.test.sql:8580: NOTICE: argument type pointkey is only a shell
35-
psql:pg_sphere.test.sql:8586: NOTICE: argument type pointkey is only a shell
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

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:9153: NOTICE: return type smoc is only a shell
2-
psql:pg_sphere.test.sql:9159: NOTICE: argument type smoc is only a shell
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

Diff for: expected/points.out

+18
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,24 @@ SELECT spoint(0.0109083078249646 , -0.000727220521664407);
239239
(0.625d , -0.041666667d)
240240
(1 row)
241241

242+
SELECT spoint_deg(57.2958, 57.2958);
243+
spoint_deg
244+
-----------------------
245+
(57.2958d , 57.2958d)
246+
(1 row)
247+
248+
SELECT spoint_deg(0, 0);
249+
spoint_deg
250+
------------
251+
(0d , 0d)
252+
(1 row)
253+
254+
SELECT spoint_deg(114.5916, 0);
255+
spoint_deg
256+
------------------
257+
(114.5916d , 0d)
258+
(1 row)
259+
242260
SELECT set_sphere_output( 'RAD' );
243261
set_sphere_output
244262
-------------------

Diff for: expected/poly.out

+22
Original file line numberDiff line numberDiff line change
@@ -318,11 +318,33 @@ SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}';
318318
{(10d , 0d),(10d , 1d),(15d , 0d)}
319319
(1 row)
320320

321+
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
322+
spoly_deg
323+
---------------------------------
324+
{(1d , 2d),(3d , 4d),(5d , 6d)}
325+
(1 row)
326+
327+
SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);
328+
spoly_deg
329+
------------------------------------
330+
{(10d , 0d),(10d , 1d),(15d , 0d)}
331+
(1 row)
332+
321333
-- incorrect input -----
322334
SELECT spoly '{(10d,0d),(10d,1d)}';
323335
ERROR: spherepoly_in: more than two points needed
324336
LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}';
325337
^
338+
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
339+
ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6)
340+
SELECT spoly_deg(ARRAY[]::float8[]);
341+
ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6)
342+
SELECT spoly_deg(NULL::float8[]);
343+
spoly_deg
344+
-----------
345+
346+
(1 row)
347+
326348
--- self-crossing input -----
327349
SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}';
328350
ERROR: spherepoly_from_array: a line segment overlaps or polygon too large

Diff for: pgs_circle.sql.in

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ CREATE FUNCTION scircle(spoint, float8)
3232
COMMENT ON FUNCTION scircle(spoint, float8) IS
3333
'spherical circle with spherical point as center and float8 as radius in radians';
3434

35+
CREATE FUNCTION scircle_deg(spoint, float8)
36+
RETURNS scircle
37+
AS 'MODULE_PATHNAME' , 'spherecircle_by_center_deg'
38+
LANGUAGE 'c'
39+
IMMUTABLE STRICT PARALLEL SAFE;
40+
41+
COMMENT ON FUNCTION scircle_deg(spoint, float8) IS
42+
'spherical circle with spherical point as center and float8 as radius in degrees';
3543

3644
--
3745
-- Casting point as circle

Diff for: pgs_point.sql.in

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ CREATE FUNCTION spoint(FLOAT8, FLOAT8)
1515
LANGUAGE 'c'
1616
IMMUTABLE STRICT PARALLEL SAFE;
1717

18+
CREATE FUNCTION spoint_deg(FLOAT8, FLOAT8)
19+
RETURNS spoint
20+
AS 'MODULE_PATHNAME', 'spherepoint_from_long_lat_deg'
21+
LANGUAGE 'c'
22+
IMMUTABLE STRICT PARALLEL SAFE;
23+
1824
CREATE FUNCTION set_sphere_output_precision(INT4)
1925
RETURNS CSTRING
2026
AS 'MODULE_PATHNAME', 'set_sphere_output_precision'
@@ -28,6 +34,9 @@ CREATE FUNCTION set_sphere_output(CSTRING)
2834
COMMENT ON FUNCTION spoint(FLOAT8, FLOAT8) IS
2935
'returns a spherical point from longitude (arg1), latitude (arg2)';
3036

37+
COMMENT ON FUNCTION spoint_deg(FLOAT8, FLOAT8) IS
38+
'returns a spherical point from longitude (arg1, in degrees), latitude (arg2, in degrees)';
39+
3140
CREATE FUNCTION long(spoint)
3241
RETURNS FLOAT8
3342
AS 'MODULE_PATHNAME', 'spherepoint_long'

Diff for: pgs_polygon.sql.in

+12
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,18 @@ CREATE FUNCTION spoly_add_point_aggr (spoly, spoint)
928928
COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS
929929
'adds a spherical point to spherical polygon. Do not use it standalone!';
930930

931+
CREATE FUNCTION spoly_deg(float8[])
932+
RETURNS spoly
933+
AS 'MODULE_PATHNAME', 'spherepoly_deg'
934+
LANGUAGE 'c'
935+
IMMUTABLE STRICT;
936+
937+
COMMENT ON FUNCTION spoly_deg(float8[]) IS
938+
' Create spoly from array of points.
939+
Two consecutive numbers among those present
940+
refer to the same occurrence and cover its
941+
latitude and longitude, respectively.';
942+
931943
CREATE FUNCTION spoly_add_points_fin_aggr (spoly)
932944
RETURNS spoly
933945
AS 'MODULE_PATHNAME', 'spherepoly_add_points_finalize'

Diff for: pgs_types.sql.in

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ CREATE FUNCTION spoly_out(spoly)
132132
LANGUAGE 'c'
133133
IMMUTABLE STRICT;
134134

135-
136135
CREATE TYPE spoly (
137136
internallength = VARIABLE,
138137
input = spoly_in,

Diff for: sql/circle.sql

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ SET extra_float_digits = 0;
55

66
-- Input/Output ---
77

8+
SELECT scircle_deg(spoint(10,10), 90);
9+
10+
SELECT scircle_deg(spoint(10,10), 91);
11+
12+
SELECT scircle_deg(spoint(0,0), 0);
13+
14+
SELECT scircle_deg(spoint(10,10), -1);
15+
816
SELECT set_sphere_output( 'RAD' );
917

1018
SELECT '< (1h 2m 30s , +1d 2m 30s), 1.0d >'::scircle;

Diff for: sql/points.sql

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ SELECT '(0.0109083078249646 , -0.000727220521664407)'::spoint;
8686

8787
SELECT spoint(0.0109083078249646 , -0.000727220521664407);
8888

89+
SELECT spoint_deg(57.2958, 57.2958);
90+
91+
SELECT spoint_deg(0, 0);
92+
93+
SELECT spoint_deg(114.5916, 0);
94+
8995
SELECT set_sphere_output( 'RAD' );
9096

9197
SELECT spoint(7.28318530717958623 , 0.00);

Diff for: sql/poly.sql

+10
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,20 @@ SELECT spoly '{(359d,0d),(359d,1d),(4d,0d)}';
7878

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

81+
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
82+
83+
SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);
84+
8185
-- incorrect input -----
8286

8387
SELECT spoly '{(10d,0d),(10d,1d)}';
8488

89+
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
90+
91+
SELECT spoly_deg(ARRAY[]::float8[]);
92+
93+
SELECT spoly_deg(NULL::float8[]);
94+
8595
--- self-crossing input -----
8696

8797
SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}';

Diff for: src/circle.c

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "circle.h"
2+
#include "pgs_util.h"
23

34
/* Circle functions */
45

@@ -22,6 +23,7 @@ PG_FUNCTION_INFO_V1(spherecircle_center);
2223
PG_FUNCTION_INFO_V1(spherecircle_radius);
2324
PG_FUNCTION_INFO_V1(spherepoint_to_circle);
2425
PG_FUNCTION_INFO_V1(spherecircle_by_center);
26+
PG_FUNCTION_INFO_V1(spherecircle_by_center_deg);
2527
PG_FUNCTION_INFO_V1(spherecircle_area);
2628
PG_FUNCTION_INFO_V1(spherecircle_circ);
2729
PG_FUNCTION_INFO_V1(spheretrans_circle);
@@ -79,7 +81,7 @@ spherecircle_in(PG_FUNCTION_ARGS)
7981
{
8082
pfree(c);
8183
c = NULL;
82-
elog(ERROR, "spherecircle_in: radius must be not greater than 90 degrees");
84+
elog(ERROR, "spherecircle_in: radius must not be greater than 90 degrees or less than 0");
8385
}
8486
else if (FPeq(c->radius, PIH))
8587
{
@@ -361,7 +363,7 @@ spherecircle_by_center(PG_FUNCTION_ARGS)
361363

362364
if (FPgt(rad, PIH) || FPlt(rad, 0.0))
363365
{
364-
elog(ERROR, "radius must be not greater than 90 degrees or less than 0");
366+
elog(ERROR, "radius must not be greater than 90 degrees or less than 0");
365367
PG_RETURN_NULL();
366368
}
367369
c = (SCIRCLE *) palloc(sizeof(SCIRCLE));
@@ -370,6 +372,20 @@ spherecircle_by_center(PG_FUNCTION_ARGS)
370372
PG_RETURN_POINTER(c);
371373
}
372374

375+
Datum
376+
spherecircle_by_center_deg(PG_FUNCTION_ARGS)
377+
{
378+
Datum res;
379+
SPoint *p = (SPoint *) PG_GETARG_POINTER(0);
380+
const float8 rad = deg_to_rad(PG_GETARG_FLOAT8(1));
381+
res = DirectFunctionCall2(
382+
spherecircle_by_center,
383+
PointerGetDatum(p),
384+
Float8GetDatum(rad)
385+
);
386+
PG_RETURN_DATUM(res);
387+
}
388+
373389
Datum
374390
spherecircle_area(PG_FUNCTION_ARGS)
375391
{

Diff for: src/circle.h

+5
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ Datum spherepoint_to_circle(PG_FUNCTION_ARGS);
132132
*/
133133
Datum spherecircle_by_center(PG_FUNCTION_ARGS);
134134

135+
/*
136+
* Creates a circle from center and radius(in degrees).
137+
*/
138+
Datum spherecircle_by_center_deg(PG_FUNCTION_ARGS);
139+
135140
/*
136141
* Calculates the area of a circle in square radians.
137142
*/

Diff for: src/pgs_util.h

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifndef __PGS_UTIL_H__
22
#define __PGS_UTIL_H__
3+
#include <c.h>
34

45
#define PI 3.14159265358979323846 /* pi */
56
#define PIH 1.57079632679489661923 /* pi/2 */
@@ -26,4 +27,9 @@ conv_theta(double x)
2627
return y;
2728
}
2829

30+
static inline float8 deg_to_rad(float8 in)
31+
{
32+
return in * PI / 180;
33+
}
34+
2935
#endif

Diff for: src/point.c

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#include "point.h"
2+
#include "pgs_util.h"
23

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

56
PG_FUNCTION_INFO_V1(spherepoint_in);
67
PG_FUNCTION_INFO_V1(spherepoint_from_long_lat);
8+
PG_FUNCTION_INFO_V1(spherepoint_from_long_lat_deg);
79
PG_FUNCTION_INFO_V1(spherepoint_distance);
810
PG_FUNCTION_INFO_V1(spherepoint_long);
911
PG_FUNCTION_INFO_V1(spherepoint_lat);
@@ -141,18 +143,38 @@ spherepoint_in(PG_FUNCTION_ARGS)
141143
PG_RETURN_POINTER(sp);
142144
}
143145

146+
void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat)
147+
{
148+
p->lat = lat;
149+
p->lng = lng;
150+
spoint_check(p);
151+
}
144152

145153
Datum
146154
spherepoint_from_long_lat(PG_FUNCTION_ARGS)
147155
{
148156
SPoint *p = (SPoint *) palloc(sizeof(SPoint));
149157

150-
p->lng = PG_GETARG_FLOAT8(0);
151-
p->lat = PG_GETARG_FLOAT8(1);
152-
spoint_check(p);
158+
const float8 lng = PG_GETARG_FLOAT8(0);
159+
const float8 lat = PG_GETARG_FLOAT8(1);
160+
create_spherepoint_from_long_lat(p, lng, lat);
153161
PG_RETURN_POINTER(p);
154162
}
155163

164+
Datum
165+
spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS)
166+
{
167+
Datum res;
168+
const float8 lng = deg_to_rad(PG_GETARG_FLOAT8(0));
169+
const float8 lat = deg_to_rad(PG_GETARG_FLOAT8(1));
170+
res = DirectFunctionCall2(
171+
spherepoint_from_long_lat,
172+
Float8GetDatum(lng),
173+
Float8GetDatum(lat)
174+
);
175+
PG_RETURN_DATUM(res);
176+
}
177+
156178
static double
157179
norm2(double a, double b)
158180
{

0 commit comments

Comments
 (0)