This project introduces a new GeoCoord data type for PostgreSQL, implemented in C, to represent geographical coordinates. It includes input / output functions, comparison operators, and indexing support.
The implementation consists of two parts:
gcoord.c: Contains the C functions for theGeoCoorddata type.gcoord.source: Contains the SQL commands to install theGeoCoorddata type in PostgreSQL.
PostgreSQL's extensibility model allows adding new data types to the server. To compile and install this project:
-
Install PostgreSQL from source (see PostgreSQL installation guide).
-
Start the PostgreSQL server.
-
Copy
gcoord.candgcoord.sourcetoSOURCE_FOLDER/src/tutorial. -
Edit the
Makefilein the directory and addgcoordtoMODULESandgcoord.sqltoDATA_built:MODULES = complex funcs gcoord DATA_built = advanced.sql basics.sql complex.sql funcs.sql syscat.sql gcoord.sql
-
Run
maketo compile and install the data type.
To uninstall, use DROP TYPE GeoCoord CASCADE.
- A geographical coordinate has three parts:
LocationName,Latitude, andLongitude. LocationNameconsists of one or more words separated by spaces, with each word being a sequence of letters.LatitudeandLongitudeconsist of a coordinate value and a direction:- The coordinate value is a non-negative real number with up to four decimal places.
- The latitude value must be ≤ 90, and the longitude value must be ≤ 180.
- Latitude directions: 'N' (North) or 'S' (South).
- Longitude directions: 'W' (West) or 'E' (East).
Valid Examples:
Melbourne,37.84°S,144.95°E
San Francisco,37.77°N,122.42°W
Invalid Examples:
Melbourne,37.84S,144.95E
Melbourne,37.84,144.95
Melbourne:37.84°S,144.95°E
37.84°S,144.95°E
- Two geographical coordinates are equivalent if their
LocationName,Longitude, andLatitudematch in their canonical forms. - The extension also supports
<>operation.
GeoCoord1is greater if its latitude is closer to the equator. If latitudes are equal, the one in the North is greater.- If latitudes are equal,
GeoCoord1is greater if its longitude is closer to the prime meridian. If longitudes are equal, the one in the East is greater. - If both latitude and longitude are equal,
LocationNamedetermines the ordering. - The extension also supports
<,>,>=,<=operations.
- Two coordinates are in the same time zone if their longitudes, divided by 15 and floored, are equal.
- Longitude direction is considered in the calculation.
- The extension also supports
!~operation.
Converts decimal coordinates to DMS (Degrees, Minutes, Seconds) format:
D = floor(A)
M = floor(60 × |A - D|)
S = floor(3600 × |A -D| - 60 × M)
Ais the coordinate value in latitude and longitude.- If
MorSis 0, it is not displayed.
- Ordering is primarily based on latitude and longitude.
- If both are equal,
LocationNameis used, sorted lexically and case-insensitively.
To create an indexed table using GeoCoord:
CREATE TABLE StoreInfo (
id INTEGER PRIMARY KEY,
location GeoCoord
);
INSERT INTO StoreInfo(id, location) VALUES
(1, 'Sydney,33.86°S,151.21°E'),
(2, 'Melbourne,37.84°S,144.95°E');
CREATE INDEX ON StoreInfo USING hash (location);
EXPLAIN ANALYZE SELECT * FROM StoreInfo WHERE location='Melbourne,37.84°S,144.95°E';This will use a hash-based index for faster queries.