pgLatLon
diff README.mkd @ 0:3b70e93cc07d
Version 0.1 (initial commit)
author | jbe |
---|---|
date | Sun Aug 21 17:43:48 2016 +0200 (2016-08-21) |
parents | |
children | 4f07a22f4d45 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/README.mkd Sun Aug 21 17:43:48 2016 +0200 1.3 @@ -0,0 +1,438 @@ 1.4 +pgLatLon v0.1 documentation 1.5 +=========================== 1.6 + 1.7 +pgLatLon is a spatial database extension for the PostgreSQL object-relational 1.8 +database management system providing geographic data types and spatial indexing 1.9 +for the WGS-84 spheroid. 1.10 + 1.11 +While many other spatial databases still use imprecise bounding boxes for many 1.12 +operations, pgLatLon supports more precise geometric calculations for all 1.13 +implemented operators. Efficient indexing of geometric objects is provided 1.14 +using fractal indices. Optimizations on bit level (including logarithmic 1.15 +compression) allow for a highly memory-efficient non-overlapping index suitable 1.16 +for huge datasets. 1.17 + 1.18 +Unlike competing spatial extensions for PostgreSQL, pgLatLon is available under 1.19 +the permissive MIT/X11 license to avoid problems with viral licenses like the 1.20 +GPLv2/v3. 1.21 + 1.22 + 1.23 +Installation 1.24 +------------ 1.25 + 1.26 +### Automatic installation 1.27 + 1.28 +Prerequisites: 1.29 + 1.30 +* Ensure that the `pg_config` binary is in your path (shipped with PostgreSQL). 1.31 +* Ensure that GNU Make is available (either as `make` or `gmake`). 1.32 + 1.33 +Then simply type: 1.34 + 1.35 + make install 1.36 + 1.37 +### Manual installation 1.38 + 1.39 +It is also possible to compile and install the extension without GNU Make as 1.40 +follows: 1.41 + 1.42 + cc -Wall -O2 -fPIC -shared -I `pg_config --includedir-server` -o latlon-v0001.so latlon-v0001.c 1.43 + cp latlon-v0001.so `pg_config --pkglibdir` 1.44 + cp latlon.control `pg_config --sharedir`/extension/ 1.45 + cp latlon--0.1.sql `pg_config --sharedir`/extension/ 1.46 + 1.47 +### Loading the extension 1.48 + 1.49 +After installation, you can create a database and load the extension as 1.50 +follows: 1.51 + 1.52 + % createdb test_database 1.53 + % psql test_database 1.54 + psql (9.5.4) 1.55 + Type "help" for help. 1.56 + 1.57 + test_database=# CREATE EXTENSION latlon; 1.58 + 1.59 + 1.60 +Reference 1.61 +--------- 1.62 + 1.63 +### 1. Types 1.64 + 1.65 +pgLatLon provides four geographic types: `epoint`, `ebox`, `ecircle`, and 1.66 +`ecluster`. 1.67 + 1.68 +#### `epoint` 1.69 + 1.70 +A point on the earth spheroid (WGS-84). 1.71 + 1.72 +The text input format is `'[N|S]<float> [E|W]<float>'`, where each float is in 1.73 +degrees. Note the required white space between the latitude and longitude 1.74 +components. Each floating point number may have a sign, in which case `N`/`S` 1.75 +or `E`/`W` are switched respectively (e.g. `E-5` is the same as `W5`). 1.76 + 1.77 +An `epoint` may also be created from two floating point numbers by calling 1.78 +`epoint(latitude, longitude)`, where positive latitudes are used for the 1.79 +northern hemisphere, negative latitudes are used for the southern hemisphere, 1.80 +positive longitudes indicate positions east of the prime meridian, and negative 1.81 +longitudes indicate positions west of the prime meridian. 1.82 + 1.83 +Latitudes exceeding -90 or +90 degrees are truncated to -90 or +90 1.84 +respectively, in which case a warning will be issued. Longitudes exceeding -180 1.85 +or +180 degrees will be converted to values between -180 and +180 (both 1.86 +inclusive) by adding or substracting a multiple of 360 degrees, in which case a 1.87 +notice will be issued. 1.88 + 1.89 +If the latitude is -90 or +90 (south pole or north pole), a longitude value is 1.90 +still stored in the datum, and if a point is on the prime meridian or the 1.91 +180th meridian, the east/west bit is also stored in the datum. In case of the 1.92 +prime meridian, this is done by storing a floating point value of -0 for 1.93 +0 degrees west and a value of +0 for 0 degrees east. In case of the 1.94 +180th meridian, this is done by storing -180 or +180 respectively. The equality 1.95 +operator, however, returns true when the same points on earth are described, 1.96 +i.e. the longitude is ignored for the poles, and 180 degrees west is considered 1.97 +to be equal to 180 degrees east. 1.98 + 1.99 +#### `ebox` 1.100 + 1.101 +An area on earth demarcated by a southern and northern latitude, and a western 1.102 +and eastern longitude (all given in WGS-84). 1.103 + 1.104 +The text input format is 1.105 +`'{N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float>'`, where each float is in 1.106 +degrees. The ordering of the four white-space separated blocks is not 1.107 +significant. To include the 180th meridian, one longitude boundary must be 1.108 +equal to or exceed `W180` or `E180`, e.g. `'N10 N20 E170 E190'`. 1.109 + 1.110 +A special value is the empty area, denoted by the text represenation `'empty'`. 1.111 +Such an `ebox` does not contain any point. 1.112 + 1.113 +An `ebox` may also be created from four floating point numbers by calling 1.114 +`ebox(min_latitude, max_latitude, min_longitude, max_longitude)`, where 1.115 +positive values are used for north and east, and negative values are used for 1.116 +south and west. If `min_latitude` is strictly greater than `max_latitude`, an 1.117 +empty `ebox` is created. If `min_longitude` is greater than `max_longitude` and 1.118 +if both longitudes are between -180 and +180 degrees, then the area oriented in 1.119 +such way that the 180th meridian is included. 1.120 + 1.121 +If the longitude span is less than 120 degrees, an `ebox` may be alternatively 1.122 +created from two `epoints` in the following way: `ebox(epoint(lat1, lon1), 1.123 +epoint(lat2, lon2))`. In this case `lat1` and `lat2` as well as `lon1` and 1.124 +`lon2` can be swapped without any impact. 1.125 + 1.126 +#### `ecircle` 1.127 + 1.128 +An area containing all points not farther away from a given center point 1.129 +(WGS-84) than a given radius. 1.130 + 1.131 +The text input format is `'{N|S}<float> {E|W}<float> <float>'`, where the first 1.132 +two floats denote the center point in degrees and the third float denotes the 1.133 +radius in meters. A radius equal to minus infinity denotes an empty circle 1.134 +which contains no point at all (despite having a center), while a radius equal 1.135 +to zero denotes a circle that includes a single point. 1.136 + 1.137 +An `ecircle` may also be created by calling `ecircle(epoint(...), radius)` or 1.138 +from three floating point numbers by calling `ecircle(latitude, longitude, 1.139 +radius)`. 1.140 + 1.141 +#### `ecluster` 1.142 + 1.143 +A collection of points, paths, polygons, and outlines on the WGS-84 spheroid. 1.144 +Each path, polygon, or outline must cover a longitude range of less than 1.145 +180 degrees to avoid ambiguities. 1.146 + 1.147 +The text input format is a white-space separated list of the following items: 1.148 + 1.149 +* `point ({N|S}<float> {E|W}<float>)` 1.150 +* `path ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` 1.151 +* `outline ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` 1.152 +* `polygon ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` 1.153 + 1.154 +Paths are open by default (i.e. there is no connection from the last point in 1.155 +the list to the first point in the list). Outlines and polygons, in contrast, 1.156 +are automatically closed (i.e. there is a line segment from the last point in 1.157 +the list to the first point in the list) which means the first point should not 1.158 +be repeated as last point in the list. Polygons are filled, outlines are not. 1.159 + 1.160 +### 2. Indices 1.161 + 1.162 +Two kinds of indices are supported: B-tree and GiST indices. 1.163 + 1.164 +#### B-tree indices 1.165 + 1.166 +A B-tree index can be used for simple equality searches and is supported by the 1.167 +`epoint`, `ebox`, and `ecircle` data types. B-tree indices can not be used for 1.168 +geographic searches. 1.169 + 1.170 +#### GiST indices 1.171 + 1.172 +For geographic searches, GiST indices must be used. The `epoint`, `ecircle`, 1.173 +and `ecluster` data types support GiST indexing. A GiST index for geographic 1.174 +searches can be created as follows: 1.175 + 1.176 + CREATE TABLE tbl ( 1.177 + id serial4 PRIMARY KEY, 1.178 + loc epoint NOT NULL ); 1.179 + 1.180 + CREATE INDEX name_of_index ON tbl USING gist (loc); 1.181 + 1.182 +GiST indices also support nearest neighbor searches when using the distance 1.183 +operator (`<->`) in the ORDER BY clause. 1.184 + 1.185 +#### Indices on other data types (e.g. GeoJSON) 1.186 + 1.187 +Note that further types can be indexed by using an index on an expression with 1.188 +a conversion function. One conversion function provided by pgLatLon is the 1.189 +`GeoJSON_to_ecluster(float8, float8, text)` function: 1.190 + 1.191 + CREATE TABLE tbl ( 1.192 + id serial4 PRIMARY KEY, 1.193 + loc jsonb NOT NULL ); 1.194 + 1.195 + CREATE INDEX name_of_index ON tbl USING gist((GeoJSON_to_ecluster("loc"))); 1.196 + 1.197 +When using the conversion function in an expression, the index will be used 1.198 +automatically: 1.199 + 1.200 + SELECT * FROM tbl WHERE GeoJSON_to_ecluster("loc") && 'N50 E10 10000'::ecircle; 1.201 + 1.202 +### 3. Operators 1.203 + 1.204 +#### Equality operator `=` 1.205 + 1.206 +Tests if two geographic objects are equal. 1.207 + 1.208 +The longitude is ignored for the poles, and 180 degrees west is considered to 1.209 +be equal to 180 degrees east. 1.210 + 1.211 +For boxes and circles, two empty objects are considered equal. (Note that a 1.212 +circle is not empty if the radius is zero but only if it is negative infinity, 1.213 +i.e. smaller than zero.) Two circles with a positive infinite radius are also 1.214 +considered equal. 1.215 + 1.216 +Implemented for: 1.217 + 1.218 +* `epoint = epoint` 1.219 +* `ebox = ebox` 1.220 +* `ecircle = ecircle` 1.221 + 1.222 +The negation is the inequality operator (`<>` or `!=`). 1.223 + 1.224 +#### Linear ordering operators `<<<`, `<<<=`, `>>>=`, `>>>` 1.225 + 1.226 +These operators create an arbitrary (but well-defined) linear ordering of 1.227 +geographic objects, which is used internally for B-tree indexing and merge 1.228 +joins. These operators will usually not be used by an application programmer. 1.229 + 1.230 +#### Overlap operator `&&` 1.231 + 1.232 +Tests if two geographic objects have at least one point in common. Currently 1.233 +implemented for: 1.234 + 1.235 +* `epoint && ebox` 1.236 +* `epoint && ecircle` 1.237 +* `epoint && ecluster` 1.238 +* `ebox && ebox` 1.239 +* `ecircle && ecircle` 1.240 +* `ecircle && ecluster` 1.241 + 1.242 +The `&&` operator is commutative, i.e. `a && b` is the same as `b && a`. Each 1.243 +commutation is supported as well. 1.244 + 1.245 +#### Distance operator `<->` 1.246 + 1.247 +Calculates the shortest distance between two geographic objects in meters (zero 1.248 +if the objects are overlapping). Currently implemented for: 1.249 + 1.250 +* `epoint <-> epoint` 1.251 +* `epoint <-> ecircle` 1.252 +* `epoint <-> ecluster` 1.253 +* `ecircle <-> ecircle` 1.254 +* `ecircle <-> ecluster` 1.255 + 1.256 +The `<->` operator is commutative, i.e. `a <-> b` is the same as `b <-> a`. 1.257 +Each commutation is supported as well. 1.258 + 1.259 +For short distances, the result is very accurate (i.e. respects the dimensions 1.260 +of the WGS-84 spheroid). For longer distances in the order of magnitude of 1.261 +earth's radius or greater, the value is only approximate (but the error is 1.262 +still less than 0.2% as long as no polygons with very long edges are involved). 1.263 + 1.264 +The functions `distance(epoint, epoint)` and `distance(ecluster, epoint)` can 1.265 +be used as an alias for this operator. 1.266 + 1.267 +Note: In case of radial searches with a fixed radius, this operator should 1.268 +not be used. Instead, an `ecircle` should be created and used in combination 1.269 +with the overlap operator (`&&`). Alternatively, the functions 1.270 +`distance_within(epoint, epoint, float8)` or `distance_within(ecluster, epoint, 1.271 +float8)` can be used for fixed-radius searches. 1.272 + 1.273 +### 4. Functions 1.274 + 1.275 +#### `center(circle)` 1.276 + 1.277 +Returns the center of an `ecircle` as an `epoint`. 1.278 + 1.279 +#### `distance(epoint, epoint)` 1.280 + 1.281 +Calculates the distance between two `epoint` datums in meters. This function is 1.282 +an alias for the distance operator `<->`. 1.283 + 1.284 +Note: In case of radial searches with a fixed radius, this function should not be 1.285 +used. Use `distance_within(epoint, epoint, float8)` instead. 1.286 + 1.287 +#### `distance(ecluster, epoint)` 1.288 + 1.289 +Calculates the distance from an `ecluster` to an `epoint` in meters. This 1.290 +function is an alias for the distance operator `<->`. 1.291 + 1.292 +Note: In case of radial searches with a fixed radius, this function should not be 1.293 +used. Use `distance_within(epoint, epoint, float8)` instead. 1.294 + 1.295 +#### `distance_within(`variable `epoint,` fixed `epoint,` radius `float8)` 1.296 + 1.297 +Checks if the distance between two `epoint` datums is not greater than a given 1.298 +value (search radius). 1.299 + 1.300 +Note: In case of radial searches with a fixed radius, the first argument must 1.301 +be used for the table column, while the second argument must be used for the 1.302 +search center. Otherwise an existing index cannot be used. 1.303 + 1.304 +#### `distance_within(`variable `ecluster,` fixed `epoint,` radius `float8)` 1.305 + 1.306 +Checks if the distance from an `ecluster` to an `epoint` is not greater than a 1.307 +given value (search radius). 1.308 + 1.309 +#### `ebox(`latmin `float8,` latmax `float8,` lonmin `float8,` lonmax `float8)` 1.310 + 1.311 +Creates a new `ebox` with the given boundaries. 1.312 +See "1. Types", subsection `ebox` for details. 1.313 + 1.314 +#### `ebox(epoint, epoint)` 1.315 + 1.316 +Creates a new `ebox`. This function may only be used if the longitude 1.317 +difference is less than or equal to 120 degrees. 1.318 +See "1. Types", subsection `ebox` for details. 1.319 + 1.320 +#### `ecircle(epoint, float8)` 1.321 + 1.322 +Creates an `ecircle` with the given center point and radius. 1.323 + 1.324 +#### `ecircle(`latitude `float8,` longitude `float8,` radius `float8)` 1.325 + 1.326 +Creates an `ecircle` with the given center point and radius. 1.327 + 1.328 +#### `ecluster_concat(ecluster, ecluster)` 1.329 + 1.330 +Combines two clusters to form a new `ecluster` by uniting all entries of both 1.331 +clusters. Note that two overlapping areas of polygons annihilate each other 1.332 +(which may be used to create polygons with holes). 1.333 + 1.334 +#### `ecluster_concat(ecluster[])` 1.335 + 1.336 +Creates a new `ecluster` that unites all entries of all clusters in the passed 1.337 +array. Note that two overlapping areas of polygons annihilate each other (which 1.338 +may be used to create polygons with holes). 1.339 + 1.340 +#### `ecluster_create_multipoint(epoint[])` 1.341 + 1.342 +Creates a new `ecluster` which contains multiple points. 1.343 + 1.344 +#### `ecluster_create_outline(epoint[])` 1.345 + 1.346 +Creates a new `ecluster` that is an outline given by the passed points. 1.347 + 1.348 +#### `ecluster_create_path(epoint[])` 1.349 + 1.350 +Creates a new `ecluster` that is a path given by the passed points. 1.351 + 1.352 +#### `ecluster_create_polygon(epoint[])` 1.353 + 1.354 +Creates a new `ecluster` that is a polygon given by the passed points. 1.355 + 1.356 +#### `ecluster_extract_outlines(ecluster)` 1.357 + 1.358 +Set-returning function that returns the outlines of an `ecluster` as `epoint[]` 1.359 +rows. 1.360 + 1.361 +#### `ecluster_extract_paths(ecluster)` 1.362 + 1.363 +Set-returning function that returns the paths of an `ecluster` as `epoint[]` 1.364 +rows. 1.365 + 1.366 +#### `ecluster_extract_points(ecluster)` 1.367 + 1.368 +Set-returning function that returns the points of an `ecluster` as `epoint` 1.369 +rows. 1.370 + 1.371 +#### `ecluster_extract_polygons(ecluster)` 1.372 + 1.373 +Set-returning function that returns the polygons of an `ecluster` as `epoint[]` 1.374 +rows. 1.375 + 1.376 +#### `empty_ebox`() 1.377 + 1.378 +Returns the empty `ebox`. 1.379 +See "1. Types", subsection `ebox` for details. 1.380 + 1.381 +#### `epoint(`latitude `float8,` longitude `float8)` 1.382 + 1.383 +Returns an `epoint` with the given latitude and longitude. 1.384 + 1.385 +#### `epoint_latlon(`latitude `float8,` longitude `float8)` 1.386 + 1.387 +Alias for `epoint(float8, float8)`. 1.388 + 1.389 +#### `epoint_lonlat(`longitude `float8,` latitude `float8)` 1.390 + 1.391 +Same as `epoint(float8, float8)` but with arguments reversed. 1.392 + 1.393 +#### `GeoJSON_to_epoint(jsonb, text)` 1.394 + 1.395 +Maps a GeoJSON object of type "Point" or "Feature" (which contains a 1.396 +"Point") to an `epoint` datum. For any other JSON objects, NULL is returned. 1.397 + 1.398 +The second parameter (which defaults to `epoint_lonlat`) may be set to a name 1.399 +of a conversion function that transforms two coordinates (two `float8` 1.400 +parameters) to an `epoint`. 1.401 + 1.402 +#### `GeoJSON_to_ecluster(jsonb, text)` 1.403 + 1.404 +Maps a (valid) GeoJSON object to an `ecluster`. Note that this function 1.405 +does not check whether the JSONB object is a valid GeoJSON object. 1.406 + 1.407 +The second parameter (which defaults to `epoint_lonlat`) may be set to a name 1.408 +of a conversion function that transforms two coordinates (two `float8` 1.409 +parameters) to an `epoint`. 1.410 + 1.411 +#### `max_latitude(ebox)` 1.412 + 1.413 +Returns the northern boundary of a given `ebox` in degrees between -90 and +90. 1.414 + 1.415 +#### `max_longitude(ebox)` 1.416 + 1.417 +Returns the eastern boundary of a given `ebox` in degrees between -180 and +180 1.418 +(both inclusive). 1.419 + 1.420 +#### `min_latitude(ebox)` 1.421 + 1.422 +Returns the southern boundary of a given `ebox` in degrees between -90 and +90. 1.423 + 1.424 +#### `min_longitude(ebox)` 1.425 + 1.426 +Returns the western boundary of a given `ebox` in degrees between -180 and +180 1.427 +(both inclusive). 1.428 + 1.429 +#### `latitude(epoint)` 1.430 + 1.431 +Returns the latitude value of an `epoint` in degrees between -90 and +90. 1.432 + 1.433 +#### `longitude(epoint)` 1.434 + 1.435 +Returns the longitude value of an `epoint` in degrees between -180 and +180 1.436 +(both inclusive). 1.437 + 1.438 +#### `radius(ecircle)` 1.439 + 1.440 +Returns the radius of an `ecircle` in meters. 1.441 +