| rev | line source | 
| jbe@74 | 1 pgLatLon v0.15 documentation | 
| jbe@65 | 2 ============================ | 
| jbe@0 | 3 | 
| jbe@0 | 4 pgLatLon is a spatial database extension for the PostgreSQL object-relational | 
| jbe@0 | 5 database management system providing geographic data types and spatial indexing | 
| jbe@0 | 6 for the WGS-84 spheroid. | 
| jbe@0 | 7 | 
| jbe@32 | 8 While many other spatial databases still use imprecise bounding boxes for | 
| jbe@32 | 9 many operations, pgLatLon aims to support more precise calculations for all | 
| jbe@32 | 10 implemented geographic operators. Efficient indexing of geographic objects | 
| jbe@32 | 11 is provided using space-filling fractal curves. Optimizations on bit level | 
| jbe@32 | 12 (including logarithmic compression) allow for a highly memory-efficient | 
| jbe@32 | 13 non-overlapping index suitable for huge datasets. | 
| jbe@0 | 14 | 
| jbe@10 | 15 pgLatLon is a lightweight solution as it only depends on PostgreSQL itself (and | 
| jbe@10 | 16 a C compiler for building). | 
| jbe@10 | 17 | 
| jbe@0 | 18 Unlike competing spatial extensions for PostgreSQL, pgLatLon is available under | 
| jbe@0 | 19 the permissive MIT/X11 license to avoid problems with viral licenses like the | 
| jbe@0 | 20 GPLv2/v3. | 
| jbe@0 | 21 | 
| jbe@0 | 22 | 
| jbe@0 | 23 Installation | 
| jbe@0 | 24 ------------ | 
| jbe@0 | 25 | 
| jbe@0 | 26 ### Automatic installation | 
| jbe@0 | 27 | 
| jbe@0 | 28 Prerequisites: | 
| jbe@0 | 29 | 
| jbe@0 | 30 * Ensure that the `pg_config` binary is in your path (shipped with PostgreSQL). | 
| jbe@0 | 31 * Ensure that GNU Make is available (either as `make` or `gmake`). | 
| jbe@0 | 32 | 
| jbe@0 | 33 Then simply type: | 
| jbe@0 | 34 | 
| jbe@0 | 35     make install | 
| jbe@0 | 36 | 
| jbe@0 | 37 ### Manual installation | 
| jbe@0 | 38 | 
| jbe@0 | 39 It is also possible to compile and install the extension without GNU Make as | 
| jbe@0 | 40 follows: | 
| jbe@0 | 41 | 
| jbe@74 | 42     cc -Wall -O2 -fPIC -shared -I `pg_config --includedir-server` -o latlon-v0010.so latlon-v0010.c | 
| jbe@74 | 43     cp latlon-v0010.so `pg_config --pkglibdir` | 
| jbe@0 | 44     cp latlon.control `pg_config --sharedir`/extension/ | 
| jbe@13 | 45     cp latlon--*.sql `pg_config --sharedir`/extension/ | 
| jbe@0 | 46 | 
| jbe@0 | 47 ### Loading the extension | 
| jbe@0 | 48 | 
| jbe@0 | 49 After installation, you can create a database and load the extension as | 
| jbe@0 | 50 follows: | 
| jbe@0 | 51 | 
| jbe@0 | 52     % createdb test_database | 
| jbe@0 | 53     % psql test_database | 
| jbe@0 | 54     psql (9.5.4) | 
| jbe@0 | 55     Type "help" for help. | 
| jbe@0 | 56 | 
| jbe@0 | 57     test_database=# CREATE EXTENSION latlon; | 
| jbe@0 | 58 | 
| jbe@16 | 59 ### Updating | 
| jbe@16 | 60 | 
| jbe@16 | 61 Before updating your database cluster to a new version of pgLatLon, you may | 
| jbe@16 | 62 want to uninstall the old by calling "`make uninstall`" in the unpacked source | 
| jbe@16 | 63 code directory of your old pgLatLon version. You may also manually delete the | 
| jbe@16 | 64 `latlon-v????.so` files from your PostgreSQL library directory and the | 
| jbe@16 | 65 `latlon.control` and `latlon--*.sql` files from your PostgreSQL extension | 
| jbe@16 | 66 directory. | 
| jbe@16 | 67 | 
| jbe@16 | 68 The new version can be installed as described above. For altering an existing | 
| jbe@16 | 69 database to use the installed new version (mandatory if you removed the old | 
| jbe@16 | 70 version), execute the following SQL command in the respective databases: | 
| jbe@16 | 71 | 
| jbe@16 | 72     ALTER EXTENSION latlon UPDATE; | 
| jbe@16 | 73 | 
| jbe@16 | 74 If the update contains modifications to operator classes, it may be necessary | 
| jbe@16 | 75 to drop all indices on geographic data types first (you will get an error | 
| jbe@16 | 76 message in this case). These indices can be re-created after the update. | 
| jbe@16 | 77 | 
| jbe@16 | 78 Note that taking several update steps at once (e.g. updating from version 0.2 | 
| jbe@16 | 79 directly to version 0.4) requires the intermediate versions to be installed | 
| jbe@16 | 80 (i.e. in this example version 0.3 would need to be installed). Whenever you | 
| jbe@16 | 81 install or uninstall an intermediate or old version, make sure to afterwards | 
| jbe@16 | 82 re-install the latest pgLatLon version to ensure that the `latlon.control` file | 
| jbe@16 | 83 is available and points to the latest version. | 
| jbe@16 | 84 | 
| jbe@16 | 85 If the update contains modifications to the internal data representation | 
| jbe@16 | 86 format, an update path might not be available. In this case, create a dump of | 
| jbe@16 | 87 your database, delete your database, and restore it from your dump. | 
| jbe@16 | 88 | 
| jbe@16 | 89 Be sure to always keep backups of all your data before attempting to update. | 
| jbe@16 | 90 | 
| jbe@0 | 91 | 
| jbe@0 | 92 Reference | 
| jbe@0 | 93 --------- | 
| jbe@0 | 94 | 
| jbe@0 | 95 ### 1. Types | 
| jbe@0 | 96 | 
| jbe@0 | 97 pgLatLon provides four geographic types: `epoint`, `ebox`, `ecircle`, and | 
| jbe@0 | 98 `ecluster`. | 
| jbe@0 | 99 | 
| jbe@0 | 100 #### `epoint` | 
| jbe@0 | 101 | 
| jbe@33 | 102 A point on the Earth spheroid (WGS-84). | 
| jbe@0 | 103 | 
| jbe@0 | 104 The text input format is `'[N|S]<float> [E|W]<float>'`, where each float is in | 
| jbe@0 | 105 degrees. Note the required white space between the latitude and longitude | 
| jbe@0 | 106 components.  Each floating point number may have a sign, in which case `N`/`S` | 
| jbe@0 | 107 or `E`/`W` are switched respectively (e.g. `E-5` is the same as `W5`). | 
| jbe@0 | 108 | 
| jbe@0 | 109 An `epoint` may also be created from two floating point numbers by calling | 
| jbe@0 | 110 `epoint(latitude, longitude)`, where positive latitudes are used for the | 
| jbe@0 | 111 northern hemisphere, negative latitudes are used for the southern hemisphere, | 
| jbe@0 | 112 positive longitudes indicate positions east of the prime meridian, and negative | 
| jbe@0 | 113 longitudes indicate positions west of the prime meridian. | 
| jbe@0 | 114 | 
| jbe@0 | 115 Latitudes exceeding -90 or +90 degrees are truncated to -90 or +90 | 
| jbe@0 | 116 respectively, in which case a warning will be issued. Longitudes exceeding -180 | 
| jbe@0 | 117 or +180 degrees will be converted to values between -180 and +180 (both | 
| jbe@0 | 118 inclusive) by adding or substracting a multiple of 360 degrees, in which case a | 
| jbe@0 | 119 notice will be issued. | 
| jbe@0 | 120 | 
| jbe@0 | 121 If the latitude is -90 or +90 (south pole or north pole), a longitude value is | 
| jbe@0 | 122 still stored in the datum, and if a point is on the prime meridian or the | 
| jbe@0 | 123 180th meridian, the east/west bit is also stored in the datum. In case of the | 
| jbe@0 | 124 prime meridian, this is done by storing a floating point value of -0 for | 
| jbe@0 | 125 0 degrees west and a value of +0 for 0 degrees east. In case of the | 
| jbe@0 | 126 180th meridian, this is done by storing -180 or +180 respectively. The equality | 
| jbe@33 | 127 operator, however, returns true when the same points on Earth are described, | 
| jbe@0 | 128 i.e. the longitude is ignored for the poles, and 180 degrees west is considered | 
| jbe@0 | 129 to be equal to 180 degrees east. | 
| jbe@0 | 130 | 
| jbe@0 | 131 #### `ebox` | 
| jbe@0 | 132 | 
| jbe@33 | 133 An area on Earth demarcated by a southern and northern latitude, and a western | 
| jbe@0 | 134 and eastern longitude (all given in WGS-84). | 
| jbe@0 | 135 | 
| jbe@0 | 136 The text input format is | 
| jbe@0 | 137 `'{N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float>'`, where each float is in | 
| jbe@0 | 138 degrees. The ordering of the four white-space separated blocks is not | 
| jbe@0 | 139 significant. To include the 180th meridian, one longitude boundary must be | 
| jbe@0 | 140 equal to or exceed `W180` or `E180`, e.g. `'N10 N20 E170 E190'`. | 
| jbe@0 | 141 | 
| jbe@0 | 142 A special value is the empty area, denoted by the text represenation `'empty'`. | 
| jbe@0 | 143 Such an `ebox` does not contain any point. | 
| jbe@0 | 144 | 
| jbe@0 | 145 An `ebox` may also be created from four floating point numbers by calling | 
| jbe@0 | 146 `ebox(min_latitude, max_latitude, min_longitude, max_longitude)`, where | 
| jbe@0 | 147 positive values are used for north and east, and negative values are used for | 
| jbe@0 | 148 south and west. If `min_latitude` is strictly greater than `max_latitude`, an | 
| jbe@0 | 149 empty `ebox` is created. If `min_longitude` is greater than `max_longitude` and | 
| jbe@0 | 150 if both longitudes are between -180 and +180 degrees, then the area oriented in | 
| jbe@0 | 151 such way that the 180th meridian is included. | 
| jbe@0 | 152 | 
| jbe@0 | 153 If the longitude span is less than 120 degrees, an `ebox` may be alternatively | 
| jbe@0 | 154 created from two `epoints` in the following way: `ebox(epoint(lat1, lon1), | 
| jbe@0 | 155 epoint(lat2, lon2))`. In this case `lat1` and `lat2` as well as `lon1` and | 
| jbe@0 | 156 `lon2` can be swapped without any impact. | 
| jbe@0 | 157 | 
| jbe@0 | 158 #### `ecircle` | 
| jbe@0 | 159 | 
| jbe@0 | 160 An area containing all points not farther away from a given center point | 
| jbe@0 | 161 (WGS-84) than a given radius. | 
| jbe@0 | 162 | 
| jbe@0 | 163 The text input format is `'{N|S}<float> {E|W}<float> <float>'`, where the first | 
| jbe@0 | 164 two floats denote the center point in degrees and the third float denotes the | 
| jbe@0 | 165 radius in meters. A radius equal to minus infinity denotes an empty circle | 
| jbe@0 | 166 which contains no point at all (despite having a center), while a radius equal | 
| jbe@0 | 167 to zero denotes a circle that includes a single point. | 
| jbe@0 | 168 | 
| jbe@0 | 169 An `ecircle` may also be created by calling `ecircle(epoint(...), radius)` or | 
| jbe@0 | 170 from three floating point numbers by calling `ecircle(latitude, longitude, | 
| jbe@0 | 171 radius)`. | 
| jbe@0 | 172 | 
| jbe@0 | 173 #### `ecluster` | 
| jbe@0 | 174 | 
| jbe@0 | 175 A collection of points, paths, polygons, and outlines on the WGS-84 spheroid. | 
| jbe@0 | 176 Each path, polygon, or outline must cover a longitude range of less than | 
| jbe@0 | 177 180 degrees to avoid ambiguities. | 
| jbe@0 | 178 | 
| jbe@0 | 179 The text input format is a white-space separated list of the following items: | 
| jbe@0 | 180 | 
| jbe@0 | 181 * `point   ({N|S}<float> {E|W}<float>)` | 
| jbe@0 | 182 * `path    ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` | 
| jbe@0 | 183 * `outline ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` | 
| jbe@0 | 184 * `polygon ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)` | 
| jbe@0 | 185 | 
| jbe@0 | 186 Paths are open by default (i.e. there is no connection from the last point in | 
| jbe@0 | 187 the list to the first point in the list). Outlines and polygons, in contrast, | 
| jbe@0 | 188 are automatically closed (i.e. there is a line segment from the last point in | 
| jbe@0 | 189 the list to the first point in the list) which means the first point should not | 
| jbe@0 | 190 be repeated as last point in the list. Polygons are filled, outlines are not. | 
| jbe@0 | 191 | 
| jbe@0 | 192 ### 2. Indices | 
| jbe@0 | 193 | 
| jbe@0 | 194 Two kinds of indices are supported: B-tree and GiST indices. | 
| jbe@0 | 195 | 
| jbe@0 | 196 #### B-tree indices | 
| jbe@0 | 197 | 
| jbe@0 | 198 A B-tree index can be used for simple equality searches and is supported by the | 
| jbe@0 | 199 `epoint`, `ebox`, and `ecircle` data types. B-tree indices can not be used for | 
| jbe@0 | 200 geographic searches. | 
| jbe@0 | 201 | 
| jbe@0 | 202 #### GiST indices | 
| jbe@0 | 203 | 
| jbe@0 | 204 For geographic searches, GiST indices must be used. The `epoint`, `ecircle`, | 
| jbe@0 | 205 and `ecluster` data types support GiST indexing. A GiST index for geographic | 
| jbe@0 | 206 searches can be created as follows: | 
| jbe@0 | 207 | 
| jbe@0 | 208     CREATE TABLE tbl ( | 
| jbe@0 | 209             id              serial4         PRIMARY KEY, | 
| jbe@0 | 210             loc             epoint          NOT NULL ); | 
| jbe@0 | 211 | 
| jbe@0 | 212     CREATE INDEX name_of_index ON tbl USING gist (loc); | 
| jbe@0 | 213 | 
| jbe@0 | 214 GiST indices also support nearest neighbor searches when using the distance | 
| jbe@0 | 215 operator (`<->`) in the ORDER BY clause. | 
| jbe@0 | 216 | 
| jbe@0 | 217 #### Indices on other data types (e.g. GeoJSON) | 
| jbe@0 | 218 | 
| jbe@0 | 219 Note that further types can be indexed by using an index on an expression with | 
| jbe@0 | 220 a conversion function. One conversion function provided by pgLatLon is the | 
| jbe@49 | 221 `GeoJSON_to_ecluster(jsonb, text)` function: | 
| jbe@0 | 222 | 
| jbe@0 | 223     CREATE TABLE tbl ( | 
| jbe@0 | 224             id              serial4         PRIMARY KEY, | 
| jbe@0 | 225             loc             jsonb           NOT NULL ); | 
| jbe@0 | 226 | 
| jbe@58 | 227     CREATE INDEX name_of_index ON tbl USING gist ((GeoJSON_to_ecluster("loc"))); | 
| jbe@0 | 228 | 
| jbe@0 | 229 When using the conversion function in an expression, the index will be used | 
| jbe@0 | 230 automatically: | 
| jbe@0 | 231 | 
| jbe@0 | 232     SELECT * FROM tbl WHERE GeoJSON_to_ecluster("loc") && 'N50 E10 10000'::ecircle; | 
| jbe@0 | 233 | 
| jbe@0 | 234 ### 3. Operators | 
| jbe@0 | 235 | 
| jbe@0 | 236 #### Equality operator `=` | 
| jbe@0 | 237 | 
| jbe@0 | 238 Tests if two geographic objects are equal. | 
| jbe@0 | 239 | 
| jbe@0 | 240 The longitude is ignored for the poles, and 180 degrees west is considered to | 
| jbe@0 | 241 be equal to 180 degrees east. | 
| jbe@0 | 242 | 
| jbe@0 | 243 For boxes and circles, two empty objects are considered equal. (Note that a | 
| jbe@0 | 244 circle is not empty if the radius is zero but only if it is negative infinity, | 
| jbe@0 | 245 i.e. smaller than zero.) Two circles with a positive infinite radius are also | 
| jbe@0 | 246 considered equal. | 
| jbe@0 | 247 | 
| jbe@0 | 248 Implemented for: | 
| jbe@0 | 249 | 
| jbe@0 | 250 * `epoint = epoint` | 
| jbe@0 | 251 * `ebox = ebox` | 
| jbe@0 | 252 * `ecircle = ecircle` | 
| jbe@0 | 253 | 
| jbe@0 | 254 The negation is the inequality operator (`<>` or `!=`). | 
| jbe@0 | 255 | 
| jbe@0 | 256 #### Linear ordering operators `<<<`, `<<<=`, `>>>=`, `>>>` | 
| jbe@0 | 257 | 
| jbe@0 | 258 These operators create an arbitrary (but well-defined) linear ordering of | 
| jbe@0 | 259 geographic objects, which is used internally for B-tree indexing and merge | 
| jbe@0 | 260 joins. These operators will usually not be used by an application programmer. | 
| jbe@0 | 261 | 
| jbe@0 | 262 #### Overlap operator `&&` | 
| jbe@0 | 263 | 
| jbe@0 | 264 Tests if two geographic objects have at least one point in common. Currently | 
| jbe@0 | 265 implemented for: | 
| jbe@0 | 266 | 
| jbe@0 | 267 * `epoint && ebox` | 
| jbe@0 | 268 * `epoint && ecircle` | 
| jbe@0 | 269 * `epoint && ecluster` | 
| jbe@0 | 270 * `ebox && ebox` | 
| jbe@16 | 271 * `ebox && ecircle` | 
| jbe@16 | 272 * `ebox && ecluster` | 
| jbe@0 | 273 * `ecircle && ecircle` | 
| jbe@0 | 274 * `ecircle && ecluster` | 
| jbe@16 | 275 * `ecluster && ecluster` | 
| jbe@0 | 276 | 
| jbe@20 | 277 The `&&` operator is commutative, i.e. "`a && b`" is the same as "`b && a`". | 
| jbe@20 | 278 Each commutation is supported as well. | 
| jbe@0 | 279 | 
| jbe@10 | 280 #### Lossy overlap operator `&&+` | 
| jbe@10 | 281 | 
| jbe@10 | 282 Tests if two geographic objects may have at least one point in common. Opposed | 
| jbe@10 | 283 to the `&&` operator, the `&&+` operator may return false positives and is | 
| jbe@10 | 284 currently implemented for: | 
| jbe@10 | 285 | 
| jbe@10 | 286 * `epoint &&+ ecluster` | 
| jbe@10 | 287 * `ebox &&+ ecircle` | 
| jbe@10 | 288 * `ebox &&+ ecluster` | 
| jbe@10 | 289 * `ecircle &&+ ecluster` | 
| jbe@10 | 290 * `ecluster &&+ ecluster` | 
| jbe@10 | 291 | 
| jbe@20 | 292 The `&&+` operator is commutative, i.e. "`a &&+ b`" is the same as "`b &&+ a`". | 
| jbe@16 | 293 Each commutation is supported as well. | 
| jbe@10 | 294 | 
| jbe@10 | 295 Where two data types support both the `&&` and the `&&+` operator, the `&&+` | 
| jbe@10 | 296 operator computes faster. | 
| jbe@10 | 297 | 
| jbe@16 | 298 #### Contains operator `@>` | 
| jbe@16 | 299 | 
| jbe@16 | 300 Tests if the object right of the operator is contained in the object left of | 
| jbe@16 | 301 the operator. Currently implemented for: | 
| jbe@16 | 302 | 
| jbe@16 | 303 * `ebox @> epoint` (alias for `&&`) | 
| jbe@20 | 304 * `ebox @> ebox` | 
| jbe@16 | 305 * `ebox @> ecluster` | 
| jbe@16 | 306 * `ecluster @> epoint` (alias for `&&`) | 
| jbe@16 | 307 * `ecluster @> ebox` | 
| jbe@16 | 308 * `ecluster @> ecluster` | 
| jbe@16 | 309 | 
| jbe@20 | 310 The commutator of `@>` ("contains") is `<@` ("is contained in"), i.e. | 
| jbe@20 | 311 "`a @> b`" is the same as "`b <@ a`". | 
| jbe@20 | 312 | 
| jbe@20 | 313 Whether the perimeter of an object is taken into account is undefined and may | 
| jbe@20 | 314 differ between the left and the right hand side of the operator. The current | 
| jbe@65 | 315 implementation (where not an alias for `&&`) returns true only if an object is | 
| jbe@65 | 316 contained completely within the other object, not touching its perimeter, | 
| jbe@65 | 317 paths, outlines, or any singular points. | 
| jbe@16 | 318 | 
| jbe@0 | 319 #### Distance operator `<->` | 
| jbe@0 | 320 | 
| jbe@0 | 321 Calculates the shortest distance between two geographic objects in meters (zero | 
| jbe@0 | 322 if the objects are overlapping). Currently implemented for: | 
| jbe@0 | 323 | 
| jbe@0 | 324 * `epoint <-> epoint` | 
| jbe@16 | 325 * `epoint <-> ebox` | 
| jbe@0 | 326 * `epoint <-> ecircle` | 
| jbe@0 | 327 * `epoint <-> ecluster` | 
| jbe@16 | 328 * `ebox <-> ebox` | 
| jbe@16 | 329 * `ebox <-> ecircle` | 
| jbe@16 | 330 * `ebox <-> ecluster` | 
| jbe@0 | 331 * `ecircle <-> ecircle` | 
| jbe@0 | 332 * `ecircle <-> ecluster` | 
| jbe@16 | 333 * `ecluster <-> ecluster` | 
| jbe@0 | 334 | 
| jbe@20 | 335 The `<->` operator is commutative, i.e. "`a <-> b`" is the same as "`b <-> a`". | 
| jbe@0 | 336 Each commutation is supported as well. | 
| jbe@0 | 337 | 
| jbe@0 | 338 For short distances, the result is very accurate (i.e. respects the dimensions | 
| jbe@0 | 339 of the WGS-84 spheroid). For longer distances in the order of magnitude of | 
| jbe@33 | 340 Earth's radius or greater, the value is only approximate (but the error is | 
| jbe@0 | 341 still less than 0.2% as long as no polygons with very long edges are involved). | 
| jbe@0 | 342 | 
| jbe@0 | 343 The functions `distance(epoint, epoint)` and `distance(ecluster, epoint)` can | 
| jbe@0 | 344 be used as an alias for this operator. | 
| jbe@0 | 345 | 
| jbe@0 | 346 Note: In case of radial searches with a fixed radius, this operator should | 
| jbe@0 | 347 not be used. Instead, an `ecircle` should be created and used in combination | 
| jbe@0 | 348 with the overlap operator (`&&`). Alternatively, the functions | 
| jbe@0 | 349 `distance_within(epoint, epoint, float8)` or `distance_within(ecluster, epoint, | 
| jbe@0 | 350 float8)` can be used for fixed-radius searches. | 
| jbe@0 | 351 | 
| jbe@0 | 352 ### 4. Functions | 
| jbe@0 | 353 | 
| jbe@0 | 354 #### `center(circle)` | 
| jbe@0 | 355 | 
| jbe@0 | 356 Returns the center of an `ecircle` as an `epoint`. | 
| jbe@0 | 357 | 
| jbe@0 | 358 #### `distance(epoint, epoint)` | 
| jbe@0 | 359 | 
| jbe@0 | 360 Calculates the distance between two `epoint` datums in meters. This function is | 
| jbe@0 | 361 an alias for the distance operator `<->`. | 
| jbe@0 | 362 | 
| jbe@0 | 363 Note: In case of radial searches with a fixed radius, this function should not be | 
| jbe@0 | 364 used. Use `distance_within(epoint, epoint, float8)` instead. | 
| jbe@0 | 365 | 
| jbe@0 | 366 #### `distance(ecluster, epoint)` | 
| jbe@0 | 367 | 
| jbe@0 | 368 Calculates the distance from an `ecluster` to an `epoint` in meters. This | 
| jbe@0 | 369 function is an alias for the distance operator `<->`. | 
| jbe@0 | 370 | 
| jbe@0 | 371 Note: In case of radial searches with a fixed radius, this function should not be | 
| jbe@0 | 372 used. Use `distance_within(epoint, epoint, float8)` instead. | 
| jbe@0 | 373 | 
| jbe@0 | 374 #### `distance_within(`variable `epoint,` fixed `epoint,` radius `float8)` | 
| jbe@0 | 375 | 
| jbe@0 | 376 Checks if the distance between two `epoint` datums is not greater than a given | 
| jbe@0 | 377 value (search radius). | 
| jbe@0 | 378 | 
| jbe@0 | 379 Note: In case of radial searches with a fixed radius, the first argument must | 
| jbe@0 | 380 be used for the table column, while the second argument must be used for the | 
| jbe@0 | 381 search center. Otherwise an existing index cannot be used. | 
| jbe@0 | 382 | 
| jbe@0 | 383 #### `distance_within(`variable `ecluster,` fixed `epoint,` radius `float8)` | 
| jbe@0 | 384 | 
| jbe@0 | 385 Checks if the distance from an `ecluster` to an `epoint` is not greater than a | 
| jbe@0 | 386 given value (search radius). | 
| jbe@0 | 387 | 
| jbe@0 | 388 #### `ebox(`latmin `float8,` latmax `float8,` lonmin `float8,` lonmax `float8)` | 
| jbe@0 | 389 | 
| jbe@0 | 390 Creates a new `ebox` with the given boundaries. | 
| jbe@0 | 391 See "1. Types", subsection `ebox` for details. | 
| jbe@0 | 392 | 
| jbe@0 | 393 #### `ebox(epoint, epoint)` | 
| jbe@0 | 394 | 
| jbe@0 | 395 Creates a new `ebox`. This function may only be used if the longitude | 
| jbe@0 | 396 difference is less than or equal to 120 degrees. | 
| jbe@0 | 397 See "1. Types", subsection `ebox` for details. | 
| jbe@0 | 398 | 
| jbe@0 | 399 #### `ecircle(epoint, float8)` | 
| jbe@0 | 400 | 
| jbe@0 | 401 Creates an `ecircle` with the given center point and radius. | 
| jbe@0 | 402 | 
| jbe@0 | 403 #### `ecircle(`latitude `float8,` longitude `float8,` radius `float8)` | 
| jbe@0 | 404 | 
| jbe@0 | 405 Creates an `ecircle` with the given center point and radius. | 
| jbe@0 | 406 | 
| jbe@0 | 407 #### `ecluster_concat(ecluster, ecluster)` | 
| jbe@0 | 408 | 
| jbe@0 | 409 Combines two clusters to form a new `ecluster` by uniting all entries of both | 
| jbe@0 | 410 clusters. Note that two overlapping areas of polygons annihilate each other | 
| jbe@0 | 411 (which may be used to create polygons with holes). | 
| jbe@0 | 412 | 
| jbe@0 | 413 #### `ecluster_concat(ecluster[])` | 
| jbe@0 | 414 | 
| jbe@0 | 415 Creates a new `ecluster` that unites all entries of all clusters in the passed | 
| jbe@0 | 416 array. Note that two overlapping areas of polygons annihilate each other (which | 
| jbe@0 | 417 may be used to create polygons with holes). | 
| jbe@0 | 418 | 
| jbe@0 | 419 #### `ecluster_create_multipoint(epoint[])` | 
| jbe@0 | 420 | 
| jbe@0 | 421 Creates a new `ecluster` which contains multiple points. | 
| jbe@0 | 422 | 
| jbe@0 | 423 #### `ecluster_create_outline(epoint[])` | 
| jbe@0 | 424 | 
| jbe@0 | 425 Creates a new `ecluster` that is an outline given by the passed points. | 
| jbe@0 | 426 | 
| jbe@0 | 427 #### `ecluster_create_path(epoint[])` | 
| jbe@0 | 428 | 
| jbe@0 | 429 Creates a new `ecluster` that is a path given by the passed points. | 
| jbe@0 | 430 | 
| jbe@0 | 431 #### `ecluster_create_polygon(epoint[])` | 
| jbe@0 | 432 | 
| jbe@0 | 433 Creates a new `ecluster` that is a polygon given by the passed points. | 
| jbe@0 | 434 | 
| jbe@0 | 435 #### `ecluster_extract_outlines(ecluster)` | 
| jbe@0 | 436 | 
| jbe@0 | 437 Set-returning function that returns the outlines of an `ecluster` as `epoint[]` | 
| jbe@0 | 438 rows. | 
| jbe@0 | 439 | 
| jbe@0 | 440 #### `ecluster_extract_paths(ecluster)` | 
| jbe@0 | 441 | 
| jbe@0 | 442 Set-returning function that returns the paths of an `ecluster` as `epoint[]` | 
| jbe@0 | 443 rows. | 
| jbe@0 | 444 | 
| jbe@0 | 445 #### `ecluster_extract_points(ecluster)` | 
| jbe@0 | 446 | 
| jbe@0 | 447 Set-returning function that returns the points of an `ecluster` as `epoint` | 
| jbe@0 | 448 rows. | 
| jbe@0 | 449 | 
| jbe@0 | 450 #### `ecluster_extract_polygons(ecluster)` | 
| jbe@0 | 451 | 
| jbe@0 | 452 Set-returning function that returns the polygons of an `ecluster` as `epoint[]` | 
| jbe@0 | 453 rows. | 
| jbe@0 | 454 | 
| jbe@0 | 455 #### `empty_ebox`() | 
| jbe@0 | 456 | 
| jbe@0 | 457 Returns the empty `ebox`. | 
| jbe@0 | 458 See "1. Types", subsection `ebox` for details. | 
| jbe@0 | 459 | 
| jbe@0 | 460 #### `epoint(`latitude `float8,` longitude `float8)` | 
| jbe@0 | 461 | 
| jbe@0 | 462 Returns an `epoint` with the given latitude and longitude. | 
| jbe@0 | 463 | 
| jbe@0 | 464 #### `epoint_latlon(`latitude `float8,` longitude `float8)` | 
| jbe@0 | 465 | 
| jbe@0 | 466 Alias for `epoint(float8, float8)`. | 
| jbe@0 | 467 | 
| jbe@0 | 468 #### `epoint_lonlat(`longitude `float8,` latitude `float8)` | 
| jbe@0 | 469 | 
| jbe@0 | 470 Same as `epoint(float8, float8)` but with arguments reversed. | 
| jbe@0 | 471 | 
| jbe@42 | 472 #### `fair_distance(ecluster, epoint,` samples `int4 = 10000)` | 
| jbe@42 | 473 | 
| jbe@42 | 474 When working with user-generated content, users may be tempted to create | 
| jbe@42 | 475 intentionally oversized objects in order to optimize search results in an | 
| jbe@42 | 476 unfair manner. The `fair_distance` function aims to handle this by returning an | 
| jbe@42 | 477 adjusted distance (i.e. distance increased by a penalty) if a geographic object | 
| jbe@42 | 478 (the `ecluster`) consists of more than one point. | 
| jbe@42 | 479 | 
| jbe@42 | 480 The first argument to this function is an `ecluster`, the second argument is a | 
| jbe@42 | 481 search point (`epoint`), and the third argument is an interger related to the | 
| jbe@42 | 482 precision (higher precision will require more computation time). | 
| jbe@42 | 483 | 
| jbe@42 | 484 The penalty by which the returned distance is increased fulfills (at least) the | 
| jbe@42 | 485 following properties: | 
| jbe@42 | 486 | 
| jbe@46 | 487 * The penalty function is continuous (except noise created by numerical | 
| jbe@46 | 488   integration, see paragraph after this list) as long as no objects are added | 
| jbe@46 | 489   to or removed from the `ecluster`. That particularly means: small changes in | 
| jbe@46 | 490   the search point (second argument) cause only small changes in the result. | 
| jbe@46 | 491 * For search points far away from the `ecluster` (i.e. large distances compared | 
| jbe@46 | 492   to the dimensions of the `ecluster`), the penalty approaches zero, i.e. the | 
| jbe@46 | 493   behavior of the `fair_distance` function approaches the behavior of the | 
| jbe@46 | 494   `distance` function. | 
| jbe@42 | 495 * If the `ecluster` consists of a set of points, the penalty for a search point | 
| jbe@46 | 496   close to one of those points (closer than half of the minimum distance | 
| jbe@46 | 497   between each pair of points in the `ecluster`) is chosen in such a way that | 
| jbe@46 | 498   the adjusted distance is equal to the distance from the search point to the | 
| jbe@42 | 499   closest point in the `ecluster` multiplied by the square root of the count of | 
| jbe@42 | 500   points in the `ecluster`. | 
| jbe@46 | 501 * If the `ecluster` does not cover any area (i.e. only consists of points, | 
| jbe@46 | 502   paths, and/or outlines), and if the search point (second argument) overlaps | 
| jbe@46 | 503   with the `ecluster`, then the penalty (and thus the result) is zero. | 
| jbe@46 | 504 * The integral (or average) of the square of the fair distance value (result of | 
| jbe@46 | 505   this function) over all possible search points is independent of the | 
| jbe@46 | 506   `ecluster` as long as the `ecluster` does not cover more than a half of | 
| jbe@46 | 507   earth's surface. | 
| jbe@42 | 508 | 
| jbe@46 | 509 The function uses numerical integration to compute the result. The third | 
| jbe@46 | 510 parameter (which defaults to 10000) can be used to adjust the number of samples | 
| jbe@46 | 511 taken. A higher sample count increases precision as well as execution time of | 
| jbe@46 | 512 the function. Because this function internally uses a spherical model of earth | 
| jbe@46 | 513 for certain steps of the calculation, the precision cannot be increased | 
| jbe@46 | 514 unboundedly. | 
| jbe@46 | 515 | 
| jbe@46 | 516 Despite the limitations explained above, it is ensured that the penalty is | 
| jbe@46 | 517 always positive, i.e. results returned by the `fair_distance` function are | 
| jbe@46 | 518 always equal to or greater than the results returned by the `distance` | 
| jbe@46 | 519 function regardless of stochastic effects.  Furthermore, all results are | 
| jbe@46 | 520 deterministic and reproducible with the same version of pgLatLon. | 
| jbe@42 | 521 | 
| jbe@0 | 522 #### `GeoJSON_to_epoint(jsonb, text)` | 
| jbe@0 | 523 | 
| jbe@0 | 524 Maps a GeoJSON object of type "Point" or "Feature" (which contains a | 
| jbe@0 | 525 "Point") to an `epoint` datum. For any other JSON objects, NULL is returned. | 
| jbe@0 | 526 | 
| jbe@0 | 527 The second parameter (which defaults to `epoint_lonlat`) may be set to a name | 
| jbe@0 | 528 of a conversion function that transforms two coordinates (two `float8` | 
| jbe@0 | 529 parameters) to an `epoint`. | 
| jbe@0 | 530 | 
| jbe@0 | 531 #### `GeoJSON_to_ecluster(jsonb, text)` | 
| jbe@0 | 532 | 
| jbe@0 | 533 Maps a (valid) GeoJSON object to an `ecluster`. Note that this function | 
| jbe@0 | 534 does not check whether the JSONB object is a valid GeoJSON object. | 
| jbe@0 | 535 | 
| jbe@0 | 536 The second parameter (which defaults to `epoint_lonlat`) may be set to a name | 
| jbe@0 | 537 of a conversion function that transforms two coordinates (two `float8` | 
| jbe@0 | 538 parameters) to an `epoint`. | 
| jbe@0 | 539 | 
| jbe@0 | 540 #### `max_latitude(ebox)` | 
| jbe@0 | 541 | 
| jbe@0 | 542 Returns the northern boundary of a given `ebox` in degrees between -90 and +90. | 
| jbe@0 | 543 | 
| jbe@0 | 544 #### `max_longitude(ebox)` | 
| jbe@0 | 545 | 
| jbe@0 | 546 Returns the eastern boundary of a given `ebox` in degrees between -180 and +180 | 
| jbe@0 | 547 (both inclusive). | 
| jbe@0 | 548 | 
| jbe@0 | 549 #### `min_latitude(ebox)` | 
| jbe@0 | 550 | 
| jbe@0 | 551 Returns the southern boundary of a given `ebox` in degrees between -90 and +90. | 
| jbe@0 | 552 | 
| jbe@0 | 553 #### `min_longitude(ebox)` | 
| jbe@0 | 554 | 
| jbe@0 | 555 Returns the western boundary of a given `ebox` in degrees between -180 and +180 | 
| jbe@0 | 556 (both inclusive). | 
| jbe@0 | 557 | 
| jbe@0 | 558 #### `latitude(epoint)` | 
| jbe@0 | 559 | 
| jbe@0 | 560 Returns the latitude value of an `epoint` in degrees between -90 and +90. | 
| jbe@0 | 561 | 
| jbe@0 | 562 #### `longitude(epoint)` | 
| jbe@0 | 563 | 
| jbe@0 | 564 Returns the longitude value of an `epoint` in degrees between -180 and +180 | 
| jbe@0 | 565 (both inclusive). | 
| jbe@0 | 566 | 
| jbe@0 | 567 #### `radius(ecircle)` | 
| jbe@0 | 568 | 
| jbe@0 | 569 Returns the radius of an `ecircle` in meters. | 
| jbe@0 | 570 |