Skip to content

[ISSUE #22] Created spoint_deg, scircle_deg, spoly_deg functions. #38

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ DATA_built = $(RELEASE_SQL) \
pg_sphere--1.1.5beta4gavo--1.2.0.sql \
pg_sphere--1.2.0--1.2.1.sql \
pg_sphere--1.2.1--1.2.2.sql \
pg_sphere--1.2.2--1.2.3.sql
pg_sphere--1.2.2--1.2.3.sql \
pg_sphere--1.2.3--1.3.0.sql

DOCS = README.pg_sphere COPYRIGHT.pg_sphere
REGRESS = init tables points euler circle line ellipse poly path box index \
Expand Down Expand Up @@ -260,6 +261,9 @@ endif
pg_sphere--1.2.2--1.2.3.sql:
cat upgrade_scripts/[email protected] > $@

pg_sphere--1.2.3--1.3.0.sql:
cat upgrade_scripts/[email protected] > $@

# end of local stuff

src/sscan.o : src/sparse.c
Expand Down
16 changes: 16 additions & 0 deletions expected/circle.out
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@
(1 row)

-- Input/Output ---
SELECT scircle_deg(spoint(10,10), 90);
scircle_deg
------------------------------------------
<(0.57522204 , -0.57522204) , 1.5707963>
(1 row)

SELECT scircle_deg(spoint(10,10), 91);
ERROR: radius must not be greater than 90 degrees or less than 0
SELECT scircle_deg(spoint(0,0), 0);
scircle_deg
---------------
<(0 , 0) , 0>
(1 row)

SELECT scircle_deg(spoint(10,10), -1);
ERROR: radius must not be greater than 90 degrees or less than 0
SELECT set_sphere_output( 'RAD' );
set_sphere_output
-------------------
Expand Down
22 changes: 11 additions & 11 deletions expected/init_test.out.in
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ psql:pg_sphere.test.sql:108: NOTICE: argument type sellipse is only a shell
psql:pg_sphere.test.sql:126: NOTICE: type "spoly" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:133: NOTICE: argument type spoly is only a shell
psql:pg_sphere.test.sql:152: NOTICE: type "spath" is not yet defined
psql:pg_sphere.test.sql:151: NOTICE: type "spath" is not yet defined
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:159: NOTICE: argument type spath is only a shell
psql:pg_sphere.test.sql:178: NOTICE: type "sbox" is not yet defined
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:185: NOTICE: argument type sbox is only a shell
psql:pg_sphere.test.sql:8540: NOTICE: type "spherekey" is not yet defined
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
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:8547: NOTICE: argument type spherekey is only a shell
psql:pg_sphere.test.sql:8561: NOTICE: type "pointkey" is not yet defined
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
DETAIL: Creating a shell type definition.
psql:pg_sphere.test.sql:8568: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8574: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8580: NOTICE: argument type pointkey is only a shell
psql:pg_sphere.test.sql:8586: NOTICE: argument type pointkey is only a shell
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
4 changes: 2 additions & 2 deletions expected/init_test_healpix.out.in
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
psql:pg_sphere.test.sql:9153: NOTICE: return type smoc is only a shell
psql:pg_sphere.test.sql:9159: NOTICE: argument type smoc is only a shell
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
18 changes: 18 additions & 0 deletions expected/points.out
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,24 @@ SELECT spoint(0.0109083078249646 , -0.000727220521664407);
(0.625d , -0.041666667d)
(1 row)

SELECT spoint_deg(57.2958, 57.2958);
spoint_deg
-----------------------
(57.2958d , 57.2958d)
(1 row)

SELECT spoint_deg(0, 0);
spoint_deg
------------
(0d , 0d)
(1 row)

SELECT spoint_deg(114.5916, 0);
spoint_deg
------------------
(114.5916d , 0d)
(1 row)

SELECT set_sphere_output( 'RAD' );
set_sphere_output
-------------------
Expand Down
22 changes: 22 additions & 0 deletions expected/poly.out
Original file line number Diff line number Diff line change
Expand Up @@ -318,11 +318,33 @@ SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}';
{(10d , 0d),(10d , 1d),(15d , 0d)}
(1 row)

SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
spoly_deg
---------------------------------
{(1d , 2d),(3d , 4d),(5d , 6d)}
(1 row)

SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);
spoly_deg
------------------------------------
{(10d , 0d),(10d , 1d),(15d , 0d)}
(1 row)

-- incorrect input -----
SELECT spoly '{(10d,0d),(10d,1d)}';
ERROR: spherepoly_in: more than two points needed
LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}';
^
SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);
ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6)
SELECT spoly_deg(ARRAY[]::float8[]);
ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6)
SELECT spoly_deg(NULL::float8[]);
spoly_deg
-----------

(1 row)

--- self-crossing input -----
SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}';
ERROR: spherepoly_from_array: a line segment overlaps or polygon too large
Expand Down
8 changes: 8 additions & 0 deletions pgs_circle.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ CREATE FUNCTION scircle(spoint, float8)
COMMENT ON FUNCTION scircle(spoint, float8) IS
'spherical circle with spherical point as center and float8 as radius in radians';

CREATE FUNCTION scircle_deg(spoint, float8)
RETURNS scircle
AS 'MODULE_PATHNAME' , 'spherecircle_by_center_deg'
LANGUAGE 'c'
IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION scircle_deg(spoint, float8) IS
'spherical circle with spherical point as center and float8 as radius in degrees';

--
-- Casting point as circle
Expand Down
9 changes: 9 additions & 0 deletions pgs_point.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ CREATE FUNCTION spoint(FLOAT8, FLOAT8)
LANGUAGE 'c'
IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION spoint_deg(FLOAT8, FLOAT8)
RETURNS spoint
AS 'MODULE_PATHNAME', 'spherepoint_from_long_lat_deg'
LANGUAGE 'c'
IMMUTABLE STRICT PARALLEL SAFE;

CREATE FUNCTION set_sphere_output_precision(INT4)
RETURNS CSTRING
AS 'MODULE_PATHNAME', 'set_sphere_output_precision'
Expand All @@ -28,6 +34,9 @@ CREATE FUNCTION set_sphere_output(CSTRING)
COMMENT ON FUNCTION spoint(FLOAT8, FLOAT8) IS
'returns a spherical point from longitude (arg1), latitude (arg2)';

COMMENT ON FUNCTION spoint_deg(FLOAT8, FLOAT8) IS
'returns a spherical point from longitude (arg1, in degrees), latitude (arg2, in degrees)';

CREATE FUNCTION long(spoint)
RETURNS FLOAT8
AS 'MODULE_PATHNAME', 'spherepoint_long'
Expand Down
12 changes: 12 additions & 0 deletions pgs_polygon.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,18 @@ CREATE FUNCTION spoly_add_point_aggr (spoly, spoint)
COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS
'adds a spherical point to spherical polygon. Do not use it standalone!';

CREATE FUNCTION spoly_deg(float8[])
RETURNS spoly
AS 'MODULE_PATHNAME', 'spherepoly_deg'
LANGUAGE 'c'
IMMUTABLE STRICT;

COMMENT ON FUNCTION spoly_deg(float8[]) IS
' Create spoly from array of points.
Two consecutive numbers among those present
refer to the same occurrence and cover its
latitude and longitude, respectively.';

CREATE FUNCTION spoly_add_points_fin_aggr (spoly)
RETURNS spoly
AS 'MODULE_PATHNAME', 'spherepoly_add_points_finalize'
Expand Down
1 change: 0 additions & 1 deletion pgs_types.sql.in
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ CREATE FUNCTION spoly_out(spoly)
LANGUAGE 'c'
IMMUTABLE STRICT;


CREATE TYPE spoly (
internallength = VARIABLE,
input = spoly_in,
Expand Down
8 changes: 8 additions & 0 deletions sql/circle.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ SET extra_float_digits = 0;

-- Input/Output ---

SELECT scircle_deg(spoint(10,10), 90);

SELECT scircle_deg(spoint(10,10), 91);

SELECT scircle_deg(spoint(0,0), 0);

SELECT scircle_deg(spoint(10,10), -1);

SELECT set_sphere_output( 'RAD' );

SELECT '< (1h 2m 30s , +1d 2m 30s), 1.0d >'::scircle;
Expand Down
6 changes: 6 additions & 0 deletions sql/points.sql
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ SELECT '(0.0109083078249646 , -0.000727220521664407)'::spoint;

SELECT spoint(0.0109083078249646 , -0.000727220521664407);

SELECT spoint_deg(57.2958, 57.2958);

SELECT spoint_deg(0, 0);

SELECT spoint_deg(114.5916, 0);

SELECT set_sphere_output( 'RAD' );

SELECT spoint(7.28318530717958623 , 0.00);
Expand Down
10 changes: 10 additions & 0 deletions sql/poly.sql
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ SELECT spoly '{(359d,0d),(359d,1d),(4d,0d)}';

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

SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);

SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]);

-- incorrect input -----

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

SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]);

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

SELECT spoly_deg(NULL::float8[]);

--- self-crossing input -----

SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}';
Expand Down
20 changes: 18 additions & 2 deletions src/circle.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "circle.h"
#include "pgs_util.h"

/* Circle functions */

Expand All @@ -22,6 +23,7 @@ PG_FUNCTION_INFO_V1(spherecircle_center);
PG_FUNCTION_INFO_V1(spherecircle_radius);
PG_FUNCTION_INFO_V1(spherepoint_to_circle);
PG_FUNCTION_INFO_V1(spherecircle_by_center);
PG_FUNCTION_INFO_V1(spherecircle_by_center_deg);
PG_FUNCTION_INFO_V1(spherecircle_area);
PG_FUNCTION_INFO_V1(spherecircle_circ);
PG_FUNCTION_INFO_V1(spheretrans_circle);
Expand Down Expand Up @@ -79,7 +81,7 @@ spherecircle_in(PG_FUNCTION_ARGS)
{
pfree(c);
c = NULL;
elog(ERROR, "spherecircle_in: radius must be not greater than 90 degrees");
elog(ERROR, "spherecircle_in: radius must not be greater than 90 degrees or less than 0");
}
else if (FPeq(c->radius, PIH))
{
Expand Down Expand Up @@ -361,7 +363,7 @@ spherecircle_by_center(PG_FUNCTION_ARGS)

if (FPgt(rad, PIH) || FPlt(rad, 0.0))
{
elog(ERROR, "radius must be not greater than 90 degrees or less than 0");
elog(ERROR, "radius must not be greater than 90 degrees or less than 0");
PG_RETURN_NULL();
}
c = (SCIRCLE *) palloc(sizeof(SCIRCLE));
Expand All @@ -370,6 +372,20 @@ spherecircle_by_center(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(c);
}

Datum
spherecircle_by_center_deg(PG_FUNCTION_ARGS)
{
Datum res;
SPoint *p = (SPoint *) PG_GETARG_POINTER(0);
const float8 rad = deg_to_rad(PG_GETARG_FLOAT8(1));
res = DirectFunctionCall2(
spherecircle_by_center,
PointerGetDatum(p),
Float8GetDatum(rad)
);
PG_RETURN_DATUM(res);
}

Datum
spherecircle_area(PG_FUNCTION_ARGS)
{
Expand Down
5 changes: 5 additions & 0 deletions src/circle.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ Datum spherepoint_to_circle(PG_FUNCTION_ARGS);
*/
Datum spherecircle_by_center(PG_FUNCTION_ARGS);

/*
* Creates a circle from center and radius(in degrees).
*/
Datum spherecircle_by_center_deg(PG_FUNCTION_ARGS);

/*
* Calculates the area of a circle in square radians.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/pgs_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@ conv_theta(double x)
return y;
}

static inline double deg_to_rad(double in)
{
return in * PI / 180;
}

#endif
28 changes: 25 additions & 3 deletions src/point.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "point.h"
#include "pgs_util.h"

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

PG_FUNCTION_INFO_V1(spherepoint_in);
PG_FUNCTION_INFO_V1(spherepoint_from_long_lat);
PG_FUNCTION_INFO_V1(spherepoint_from_long_lat_deg);
PG_FUNCTION_INFO_V1(spherepoint_distance);
PG_FUNCTION_INFO_V1(spherepoint_long);
PG_FUNCTION_INFO_V1(spherepoint_lat);
Expand Down Expand Up @@ -141,18 +143,38 @@ spherepoint_in(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(sp);
}

void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat)
{
p->lat = lat;
p->lng = lng;
spoint_check(p);
}

Datum
spherepoint_from_long_lat(PG_FUNCTION_ARGS)
{
SPoint *p = (SPoint *) palloc(sizeof(SPoint));

p->lng = PG_GETARG_FLOAT8(0);
p->lat = PG_GETARG_FLOAT8(1);
spoint_check(p);
const float8 lng = PG_GETARG_FLOAT8(0);
const float8 lat = PG_GETARG_FLOAT8(1);
create_spherepoint_from_long_lat(p, lng, lat);
PG_RETURN_POINTER(p);
}

Datum
spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS)
{
Datum res;
const float8 lng = deg_to_rad(PG_GETARG_FLOAT8(0));
const float8 lat = deg_to_rad(PG_GETARG_FLOAT8(1));
res = DirectFunctionCall2(
spherepoint_from_long_lat,
Float8GetDatum(lng),
Float8GetDatum(lat)
);
PG_RETURN_DATUM(res);
}

static double
norm2(double a, double b)
{
Expand Down
Loading