mirror of https://github.com/postgres/postgres
parent
b4672e29df
commit
5815523b0e
@ -0,0 +1,15 @@ |
|||||||
|
# PGLIB is probably /usr/local/pgsql/lib
|
||||||
|
|
||||||
|
PGINCLUDE=${PGLIB}/../include
|
||||||
|
CFLAGS+=-I${PGINCLUDE}
|
||||||
|
|
||||||
|
install-earthdistance: ${PGLIB}/earthdistance.so |
||||||
|
|
||||||
|
${PGLIB}/earthdistance.so: earthdistance.so |
||||||
|
sudo install -C -g bin -o bin earthdistance.so ${PGLIB}
|
||||||
|
|
||||||
|
earthdistance.so: earthdistance.o |
||||||
|
$(LD) -o $@ -Bshareable $<
|
||||||
|
|
||||||
|
earthdistance.o: earthdistance.c |
||||||
|
$(CC) -o $@ -c $(CFLAGS) $<
|
@ -0,0 +1,31 @@ |
|||||||
|
Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST) |
||||||
|
From: Hal Snyder <hal@vailsys.com> |
||||||
|
To: vmehr@ctp.com |
||||||
|
Subject: [QUESTIONS] Re: Spatial data, R-Trees |
||||||
|
|
||||||
|
> From: Vivek Mehra <vmehr@ctp.com> |
||||||
|
> Date: Wed, 1 Apr 1998 10:06:50 -0500 |
||||||
|
|
||||||
|
> Am just starting out with PostgreSQL and would like to learn more about |
||||||
|
> the spatial data handling ablilities of postgreSQL - in terms of using |
||||||
|
> R-tree indexes, user defined types, operators and functions. |
||||||
|
> |
||||||
|
> Would you be able to suggest where I could find some code and SQL to |
||||||
|
> look at to create these? |
||||||
|
|
||||||
|
Here's the setup for adding an operator '<@>' to give distance in |
||||||
|
statute miles between two points on the earth's surface. Coordinates |
||||||
|
are in degrees. Points are taken as (longitude, latitude) and not vice |
||||||
|
versa as longitude is closer to the intuitive idea of x-axis and |
||||||
|
latitude to y-axis. |
||||||
|
|
||||||
|
There's C source, Makefile for FreeBSD, and SQL for installing and |
||||||
|
testing the function. |
||||||
|
|
||||||
|
Let me know if anything looks fishy! |
||||||
|
|
||||||
|
A note on testing C extensions - it seems not enough to drop a function |
||||||
|
and re-create it - if I change a function, I have to stop and restart |
||||||
|
the backend for the new version to be seen. I guess it would be too |
||||||
|
messy to track which functions are added from a .so and do a dlclose |
||||||
|
when the last one is dropped. |
@ -0,0 +1,65 @@ |
|||||||
|
#include <math.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <postgres.h> |
||||||
|
#include <utils/geo_decls.h> /* for Pt */ |
||||||
|
#include <utils/palloc.h> /* for palloc */ |
||||||
|
|
||||||
|
/* Earth's radius is in statute miles. */ |
||||||
|
const EARTH_RADIUS = 3958.747716; |
||||||
|
const TWO_PI = 2.0 * M_PI; |
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
* |
||||||
|
* degtorad - convert degrees to radians |
||||||
|
* |
||||||
|
* arg: double, angle in degrees |
||||||
|
* |
||||||
|
* returns: double, same angle in radians |
||||||
|
******************************************************/ |
||||||
|
|
||||||
|
static double |
||||||
|
degtorad (double degrees) { |
||||||
|
return (degrees / 360.0) * TWO_PI; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/******************************************************
|
||||||
|
* |
||||||
|
* geo_distance - distance between points |
||||||
|
* |
||||||
|
* args: |
||||||
|
* a pair of points - for each point, |
||||||
|
* x-coordinate is longitude in degrees west of Greenwich |
||||||
|
* y-coordinate is latitude in degrees above equator |
||||||
|
* |
||||||
|
* returns: double |
||||||
|
* distance between the points in miles on earth's surface |
||||||
|
******************************************************/ |
||||||
|
|
||||||
|
double * |
||||||
|
geo_distance (Point *pt1, Point *pt2) { |
||||||
|
|
||||||
|
double long1, lat1, long2, lat2; |
||||||
|
double longdiff; |
||||||
|
double * resultp = palloc (sizeof(double)); |
||||||
|
|
||||||
|
/* convert degrees to radians */ |
||||||
|
|
||||||
|
long1 = degtorad (pt1->x); |
||||||
|
lat1 = degtorad (pt1->y); |
||||||
|
|
||||||
|
long2 = degtorad (pt2->x); |
||||||
|
lat2 = degtorad (pt2->y); |
||||||
|
|
||||||
|
/* compute difference in longitudes - want < 180 degrees */ |
||||||
|
longdiff = fabs (long1 - long2); |
||||||
|
if (longdiff > M_PI) |
||||||
|
longdiff = TWO_PI - longdiff; |
||||||
|
|
||||||
|
* resultp = EARTH_RADIUS * acos |
||||||
|
(sin (lat1) * sin (lat2) + cos (lat1) * cos (lat2) * cos (longdiff)); |
||||||
|
|
||||||
|
return resultp; |
||||||
|
} |
@ -0,0 +1,23 @@ |
|||||||
|
|
||||||
|
--------------- geo_distance |
||||||
|
|
||||||
|
DROP FUNCTION geo_distance (point, point); |
||||||
|
CREATE FUNCTION geo_distance (point, point) RETURNS float8 |
||||||
|
AS '/usr/local/pgsql/lib/earthdistance.so' LANGUAGE 'c'; |
||||||
|
|
||||||
|
SELECT geo_distance ('(1,2)'::point, '(3,4)'::point); |
||||||
|
|
||||||
|
--------------- geo_distance as operator <@> |
||||||
|
|
||||||
|
DROP OPERATOR <@> (point, point); |
||||||
|
CREATE OPERATOR <@> ( |
||||||
|
leftarg = point, |
||||||
|
rightarg = point, |
||||||
|
procedure = geo_distance, |
||||||
|
commutator = <@> |
||||||
|
); |
||||||
|
|
||||||
|
-- ( 87.6, 41.8) is in Chicago |
||||||
|
-- (106.7, 35.1) is in Albuquerque |
||||||
|
-- The cities are about 1100 miles apart |
||||||
|
SELECT '(87.6,41.8)'::point <@> '(106.7,35.1)'::point; |
@ -0,0 +1,84 @@ |
|||||||
|
<html> |
||||||
|
<head> |
||||||
|
<title>PostgreSQL: Getting the source via CVS</title> |
||||||
|
</head> |
||||||
|
<body bgcolor=white text=black link=blue vlink=purple> |
||||||
|
|
||||||
|
<font size="+3">Getting the source via CVS</font> |
||||||
|
|
||||||
|
<p>If you would like to keep up with the current sources on a regular |
||||||
|
basis, you can fetch them from our CVS server and then use CVS to |
||||||
|
retrieve updates from time to time. |
||||||
|
|
||||||
|
<P>To do this you first need a local copy of CVS (Concurrent Version Control |
||||||
|
System), which you can get from |
||||||
|
<A HREF="http://www.cyclic.com/">http://www.cyclic.com/</A> or |
||||||
|
any GNU software archive site. Currently we recommend version 1.9. |
||||||
|
|
||||||
|
<P>Once you have installed the CVS software, do this: |
||||||
|
<PRE> |
||||||
|
cvs -d :pserver:anoncvs@postgresql.org:/usr/local/cvsroot login |
||||||
|
</PRE> |
||||||
|
You will be prompted for a password; enter '<tt>postgresql</tt>'. |
||||||
|
You should only need to do this once, since the password will be |
||||||
|
saved in <tt>.cvspass</tt> in your home directory. |
||||||
|
|
||||||
|
<P>Having logged in, you are ready to fetch the PostgreSQL sources. |
||||||
|
Do this: |
||||||
|
<PRE> |
||||||
|
cvs -z3 -d :pserver:anoncvs@postgresql.org:/usr/local/cvsroot co -P pgsql |
||||||
|
</PRE> |
||||||
|
which will install the PostgreSQL sources into a subdirectory <tt>pgsql</tt> |
||||||
|
of the directory you are currently in. |
||||||
|
|
||||||
|
<P>(If you have a fast link to the Internet, you may not need <tt>-z3</tt>, |
||||||
|
which instructs CVS to use gzip compression for transferred data. But |
||||||
|
on a modem-speed link, it's a very substantial win.) |
||||||
|
|
||||||
|
<P>This initial checkout is a little slower than simply downloading |
||||||
|
a <tt>tar.gz</tt> file; expect it to take 40 minutes or so if you |
||||||
|
have a 28.8K modem. The advantage of CVS doesn't show up until you |
||||||
|
want to update the file set later on. |
||||||
|
|
||||||
|
<P>Whenever you want to update to the latest CVS sources, <tt>cd</tt> into |
||||||
|
the <tt>pgsql</tt> subdirectory, and issue |
||||||
|
<PRE> |
||||||
|
cvs -z3 update -d -P |
||||||
|
</PRE> |
||||||
|
This will fetch only the changes since the last time you updated. |
||||||
|
You can update in just a couple of minutes, typically, even over |
||||||
|
a modem-speed line. |
||||||
|
|
||||||
|
<P>You can save yourself some typing by making a file <tt>.cvsrc</tt> |
||||||
|
in your home directory that contains |
||||||
|
|
||||||
|
<PRE> |
||||||
|
cvs -z3 |
||||||
|
update -d -P |
||||||
|
</PRE> |
||||||
|
|
||||||
|
This supplies the <tt>-z3</tt> option to all cvs commands, and the |
||||||
|
<tt>-d</tt> and <tt>-P</tt> options to cvs update. Then you just have |
||||||
|
to say |
||||||
|
<PRE> |
||||||
|
cvs update |
||||||
|
</PRE> |
||||||
|
to update your files. |
||||||
|
|
||||||
|
<P><strong>CAUTION:</strong> some versions of CVS have a bug that |
||||||
|
causes all checked-out files to be stored world-writable in your |
||||||
|
directory. If you see that this has happened, you can do something like |
||||||
|
<PRE> |
||||||
|
chmod -R go-w pgsql |
||||||
|
</PRE> |
||||||
|
to set the permissions properly. This bug is allegedly fixed in the |
||||||
|
latest beta version of CVS, 1.9.28 ... but it may have other, less |
||||||
|
predictable bugs. |
||||||
|
|
||||||
|
<P>CVS can do a lot of other things, such as fetching prior revisions |
||||||
|
of the PostgreSQL sources rather than the latest development version. |
||||||
|
For more info consult the manual that comes with CVS, or see the online |
||||||
|
documentation at <A HREF="http://www.cyclic.com/">http://www.cyclic.com/</A>. |
||||||
|
|
||||||
|
</body> |
||||||
|
</html> |
Loading…
Reference in new issue