liquid_feedback_core

annotate pgLatLon/README.mkd @ 529:96ee2db56bec

New PostgreSQL extension "pgLatLon" for geospatial operations and indexing in LiquidFeedback
author jbe
date Thu Aug 18 20:19:58 2016 +0200 (2016-08-18)
parents
children 6bc81898fd3b
rev   line source
jbe@529 1 pgLatLon v0.1 documentation
jbe@529 2 ===========================
jbe@529 3
jbe@529 4 pgLatLon is a spatial database extension for the PostgreSQL object-relational
jbe@529 5 database management system providing geographic data types and spatial indexing
jbe@529 6 for the WGS-84 spheroid.
jbe@529 7
jbe@529 8 While many other spatial databases still use imprecise bounding boxes for many
jbe@529 9 operations, pgLatLon supports more precise geometric calculations for all
jbe@529 10 implemented operators. Efficient indexing of geometric objects is provided
jbe@529 11 using fractal indicies. Optimizations on bit level (including logarithmic
jbe@529 12 compression) allow for a highly memory-efficient non-overlapping index suitable
jbe@529 13 for huge datasets.
jbe@529 14
jbe@529 15 Unlike competing spatial extensions for PostgreSQL, pgLatLon is available under
jbe@529 16 the permissive MIT/X11 license to avoid problems with viral licenses like the
jbe@529 17 GPLv2/v3.
jbe@529 18
jbe@529 19
jbe@529 20 Installation
jbe@529 21 ------------
jbe@529 22
jbe@529 23 ### Automatic installation
jbe@529 24
jbe@529 25 Prerequisites:
jbe@529 26
jbe@529 27 * Ensure that the `pg_config` binary is in your path (shipped with PostgreSQL).
jbe@529 28 * Ensure that GNU Make is available (either as `make` or `gmake`).
jbe@529 29
jbe@529 30 Then simply type:
jbe@529 31
jbe@529 32 make install
jbe@529 33
jbe@529 34 ### Manual installation
jbe@529 35
jbe@529 36 It is also possible to compile and install the extension without GNU Make as
jbe@529 37 follows:
jbe@529 38
jbe@529 39 cc -Wall -O2 -fPIC -shared -I `pg_config --includedir-server` -o latlon-v0001.so latlon-v0001.c
jbe@529 40 cp latlon-v0001.so `pg_config --pkglibdir`
jbe@529 41 cp latlon.control `pg_config --sharedir`/extension/
jbe@529 42 cp latlon--0.1.sql `pg_config --sharedir`/extension/
jbe@529 43
jbe@529 44 ### Loading the extension
jbe@529 45
jbe@529 46 After installation, you can create a database and load the extension as
jbe@529 47 follows:
jbe@529 48
jbe@529 49 % createdb test_database
jbe@529 50 % psql test_database
jbe@529 51 psql (9.5.4)
jbe@529 52 Type "help" for help.
jbe@529 53
jbe@529 54 test_database=# CREATE EXTENSION latlon;
jbe@529 55
jbe@529 56
jbe@529 57 Reference
jbe@529 58 ---------
jbe@529 59
jbe@529 60 ### 1. Types
jbe@529 61
jbe@529 62 pgLatLon provides four geographic types: `epoint`, `ebox`, `ecircle`, and
jbe@529 63 `ecluster`.
jbe@529 64
jbe@529 65 #### `epoint`
jbe@529 66
jbe@529 67 A point on the earth spheroid (WGS-84).
jbe@529 68
jbe@529 69 The text input format is `'[N|S]<float> [E|W]<float>'`, where each float is in
jbe@529 70 degrees. Note the required white space between the latitude and longitude
jbe@529 71 components. Each floating point number may have a sign, in which case `N`/`S`
jbe@529 72 or `E`/`W` are switched respectively (e.g. `E-5` is the same as `W5`).
jbe@529 73
jbe@529 74 An `epoint` may also be created from two floating point numbers by calling
jbe@529 75 `epoint(latitude, longitude)`, where positive latitudes are used for the
jbe@529 76 northern hemisphere, negative latitudes are used for the southern hemisphere,
jbe@529 77 positive longitudes indicate positions east of the prime meridian, and negative
jbe@529 78 longitudes indicate positions west of the prime meridian.
jbe@529 79
jbe@529 80 Latitudes exceeding -90 or +90 degrees are truncated to -90 or +90
jbe@529 81 respectively, in which case a warning will be issued. Longitudes exceeding -180
jbe@529 82 or +180 degrees will be converted to values between -180 and +180 (both
jbe@529 83 inclusive) by adding or substracting a multiple of 360 degrees, in which case a
jbe@529 84 notice will be issued.
jbe@529 85
jbe@529 86 If the latitude is -90 or +90 (south pole or north pole), a longitude value is
jbe@529 87 still stored in the datum, and if a point is on the prime meridian or the
jbe@529 88 180th meridian, the east/west bit is also stored in the datum. In case of the
jbe@529 89 prime meridian, this is done by storing a floating point value of -0 for
jbe@529 90 0 degrees west and a value of +0 for 0 degrees east. In case of the
jbe@529 91 180th meridian, this is done by storing -180 or +180 respectively. The equality
jbe@529 92 operator, however, returns true when the same points on earth are described,
jbe@529 93 i.e. the longitude is ignored for the poles, and 180 degrees west is considered
jbe@529 94 to be equal to 180 degrees east.
jbe@529 95
jbe@529 96 #### `ebox`
jbe@529 97
jbe@529 98 An area on earth demarcated by a southern and northern latitude, and a western
jbe@529 99 and eastern longitude (all given in WGS-84).
jbe@529 100
jbe@529 101 The text input format is
jbe@529 102 `'{N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float>'`, where each float is in
jbe@529 103 degrees. The ordering of the four white-space separated blocks is not
jbe@529 104 significant. To include the 180th meridian, one longitude boundary must be
jbe@529 105 equal to or exceed `W180` or `E180`, e.g. `'N10 N20 E170 E190'`.
jbe@529 106
jbe@529 107 A special value is the empty area, denoted by the text represenation `'empty'`.
jbe@529 108 Such an `ebox` does not contain any point.
jbe@529 109
jbe@529 110 An `ebox` may also be created from four floating point numbers by calling
jbe@529 111 `ebox(min_latitude, max_latitude, min_longitude, max_longitude)`, where
jbe@529 112 positive values are used for north and east, and negative values are used for
jbe@529 113 south and west. If `min_latitude` is strictly greater than `max_latitude`, an
jbe@529 114 empty `ebox` is created. If `min_longitude` is greater than `max_longitude` and
jbe@529 115 if both longitudes are between -180 and +180 degrees, then the area oriented in
jbe@529 116 such way that the 180th meridian is included.
jbe@529 117
jbe@529 118 If the longitude span is less than 120 degrees, an `ebox` may be alternatively
jbe@529 119 created from two `epoints` in the following way: `ebox(epoint(lat1, lon1),
jbe@529 120 epoint(lat2, lon2))`. In this case `lat1` and `lat2` as well as `lon1` and
jbe@529 121 `lon2` can be swapped without any impact.
jbe@529 122
jbe@529 123 #### `ecircle`
jbe@529 124
jbe@529 125 An area containing all points not farther away from a given center point
jbe@529 126 (WGS-84) than a given radius.
jbe@529 127
jbe@529 128 The text input format is `'{N|S}<float> {E|W}<float> <float>'`, where the first
jbe@529 129 two floats denote the center point in degrees and the third float denotes the
jbe@529 130 radius in meters. A radius equal to minus infinity denotes an empty circle
jbe@529 131 which contains no point at all (despite having a center), while a radius equal
jbe@529 132 to zero denotes a circle that includes a single point.
jbe@529 133
jbe@529 134 An `ecircle` may also be created by calling `ecircle(epoint(...), radius)` or
jbe@529 135 from three floating point numbers by calling `ecircle(latitude, longitude,
jbe@529 136 radius)`.
jbe@529 137
jbe@529 138 #### `ecluster`
jbe@529 139
jbe@529 140 A collection of points, paths, polygons, and outlines on the WGS-84 spheroid.
jbe@529 141 Each path, polygon, or outline must cover a longitude range of less than
jbe@529 142 180 degrees to avoid ambiguities.
jbe@529 143
jbe@529 144 The text input format is a white-space separated list of the following items:
jbe@529 145
jbe@529 146 * `point ({N|S}<float> {E|W}<float>)`
jbe@529 147 * `path ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
jbe@529 148 * `outline ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
jbe@529 149 * `polygon ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
jbe@529 150
jbe@529 151 Paths are open by default (i.e. there is no connection from the last point in
jbe@529 152 the list to the first point in the list). Outlines and polygons, in contrast,
jbe@529 153 are automatically closed (i.e. there is a line segment from the last point in
jbe@529 154 the list to the first point in the list) which means the first point should not
jbe@529 155 be repeated as last point in the list. Polygons are filled, outlines are not.
jbe@529 156
jbe@529 157 ### 2. Indices
jbe@529 158
jbe@529 159 Two kinds of indices are supported: B-tree and GiST indices.
jbe@529 160
jbe@529 161 #### B-tree indicies
jbe@529 162
jbe@529 163 A B-tree index can be used for simple equality searches and is supported by the
jbe@529 164 `epoint`, `ebox`, and `ecircle` data types. B-tree indices can not be used for
jbe@529 165 geographic searches.
jbe@529 166
jbe@529 167 #### GiST indicies
jbe@529 168
jbe@529 169 For geographic searches, GiST indices must be used. The `epoint`, `ecircle`,
jbe@529 170 and `ecluster` data types support GiST indexing. A GiST index for geographic
jbe@529 171 searches can be created as follows:
jbe@529 172
jbe@529 173 CREATE TABLE tbl (
jbe@529 174 id serial4 PRIMARY KEY,
jbe@529 175 loc epoint NOT NULL );
jbe@529 176
jbe@529 177 CREATE INDEX name_of_index ON tbl USING gist (loc);
jbe@529 178
jbe@529 179 GiST indicies also support nearest neighbor searches when using the distance
jbe@529 180 operator (`<->`) in the ORDER BY clause.
jbe@529 181
jbe@529 182 #### Indicies on other data types (e.g. GeoJSON)
jbe@529 183
jbe@529 184 Note that further types can be indexed by using an index on an expression with
jbe@529 185 a conversion function. One conversion function provided by pgLatLon is the
jbe@529 186 `GeoJSON_to_ecluster(float8, float8, text)` function:
jbe@529 187
jbe@529 188 CREATE TABLE tbl (
jbe@529 189 id serial4 PRIMARY KEY,
jbe@529 190 loc jsonb NOT NULL );
jbe@529 191
jbe@529 192 CREATE INDEX name_of_index ON tbl USING gist((GeoJSON_to_ecluster("loc")));
jbe@529 193
jbe@529 194 When using the conversion function in an expression, the index will be used
jbe@529 195 automatically:
jbe@529 196
jbe@529 197 SELECT * FROM tbl WHERE GeoJSON_to_ecluster("loc") && 'N50 E10 10000'::ecircle;
jbe@529 198
jbe@529 199 ### 3. Operators
jbe@529 200
jbe@529 201 #### Equality operator `=`
jbe@529 202
jbe@529 203 Tests if two geographic objects are equal.
jbe@529 204
jbe@529 205 The longitude is ignored for the poles, and 180 degrees west is considered to
jbe@529 206 be equal to 180 degrees east.
jbe@529 207
jbe@529 208 For boxes and circles, two empty objects are considered equal. (Note that a
jbe@529 209 circle is not empty if the radius is zero but only if it is negative infinity,
jbe@529 210 i.e. smaller than zero.) Two circles with a positive infinite radius are also
jbe@529 211 considered equal.
jbe@529 212
jbe@529 213 Implemented for:
jbe@529 214
jbe@529 215 * `epoint = epoint`
jbe@529 216 * `ebox = ebox`
jbe@529 217 * `ecircle = ecircle`
jbe@529 218
jbe@529 219 The negation is the inequality operator (`<>` or `!=`).
jbe@529 220
jbe@529 221 #### Linear ordering operators `<<<`, `<<<=`, `>>>=`, `>>>`
jbe@529 222
jbe@529 223 These operators create an arbitrary (but well-defined) linear ordering of
jbe@529 224 geographic objects, which is used internally for B-tree indexing and merge
jbe@529 225 joins. These operators will usually not be used by an application programmer.
jbe@529 226
jbe@529 227 #### Overlap operator `&&`
jbe@529 228
jbe@529 229 Tests if two geographic objects have at least one point in common. Currently
jbe@529 230 implemented for:
jbe@529 231
jbe@529 232 * `epoint && ebox`
jbe@529 233 * `epoint && ecircle`
jbe@529 234 * `epoint && ecluster`
jbe@529 235 * `ebox && ebox`
jbe@529 236 * `ecircle && ecircle`
jbe@529 237 * `ecircle && ecluster`
jbe@529 238
jbe@529 239 The `&&` operator is commutative, i.e. `a && b` is the same as `b && a`. Each
jbe@529 240 commutation is supported as well.
jbe@529 241
jbe@529 242 #### Distance operator `<->`
jbe@529 243
jbe@529 244 Calculates the shortest distance between two geographic objects in meters (zero
jbe@529 245 if the objects are overlapping). Currently implemented for:
jbe@529 246
jbe@529 247 * `epoint <-> epoint`
jbe@529 248 * `epoint <-> ecircle`
jbe@529 249 * `epoint <-> ecluster`
jbe@529 250 * `ecircle <-> ecircle`
jbe@529 251 * `ecircle <-> ecluster`
jbe@529 252
jbe@529 253 The `<->` operator is commutative, i.e. `a <-> b` is the same as `b <-> a`.
jbe@529 254 Each commutation is supported as well.
jbe@529 255
jbe@529 256 For short distances, the result is very accurate (i.e. respects the dimensions
jbe@529 257 of the WGS-84 spheroid). For longer distances in the order of magnitude of
jbe@529 258 earth's radius or greater, the value is only approximate (but the error is
jbe@529 259 still less than 0.2% as long as no polygons with very long edges are involved).
jbe@529 260
jbe@529 261 The functions `distance(epoint, epoint)` and `distance(ecluster, epoint)` can
jbe@529 262 be used as an alias for this operator.
jbe@529 263
jbe@529 264 Note: In case of radial searches with a fixed radius, this operator should
jbe@529 265 not be used. Instead, an `ecircle` should be created and used in combination
jbe@529 266 with the overlap operator (`&&`). Alternatively, the functions
jbe@529 267 `distance_within(epoint, epoint, float8)` or `distance_within(ecluster, epoint,
jbe@529 268 float8)` can be used for fixed-radius searches.
jbe@529 269
jbe@529 270 ### 4. Functions
jbe@529 271
jbe@529 272 #### `center(circle)`
jbe@529 273
jbe@529 274 Returns the center of an `ecircle` as an `epoint`.
jbe@529 275
jbe@529 276 #### `distance(epoint, epoint)`
jbe@529 277
jbe@529 278 Calculates the distance between two `epoint` datums in meters. This function is
jbe@529 279 an alias for the distance operator `<->`.
jbe@529 280
jbe@529 281 Note: In case of radial searches with a fixed radius, this function should not be
jbe@529 282 used. Use `distance_within(epoint, epoint, float8)` instead.
jbe@529 283
jbe@529 284 #### `distance(ecluster, epoint)`
jbe@529 285
jbe@529 286 Calculates the distance from an `ecluster` to an `epoint` in meters. This
jbe@529 287 function is an alias for the distance operator `<->`.
jbe@529 288
jbe@529 289 Note: In case of radial searches with a fixed radius, this function should not be
jbe@529 290 used. Use `distance_within(epoint, epoint, float8)` instead.
jbe@529 291
jbe@529 292 #### `distance_within(`variable `epoint,` fixed `epoint,` radius `float8)`
jbe@529 293
jbe@529 294 Checks if the distance between two `epoint` datums is not greater than a given
jbe@529 295 value (search radius).
jbe@529 296
jbe@529 297 Note: In case of radial searches with a fixed radius, the first argument must
jbe@529 298 be used for the table column, while the second argument must be used for the
jbe@529 299 search center. Otherwise an existing index cannot be used.
jbe@529 300
jbe@529 301 #### `distance_within(`variable `ecluster,` fixed `epoint,` radius `float8)`
jbe@529 302
jbe@529 303 Checks if the distance from an `ecluster` to an `epoint` is not greater than a
jbe@529 304 given value (search radius).
jbe@529 305
jbe@529 306 #### `ebox(`latmin `float8,` latmax `float8,` lonmin `float8,` lonmax `float8)`
jbe@529 307
jbe@529 308 Creates a new `ebox` with the given boundaries.
jbe@529 309 See "1. Types", subsection `ebox` for details.
jbe@529 310
jbe@529 311 #### `ebox(epoint, epoint)`
jbe@529 312
jbe@529 313 Creates a new `ebox`. This function may only be used if the longitude
jbe@529 314 difference is less than or equal to 120 degrees.
jbe@529 315 See "1. Types", subsection `ebox` for details.
jbe@529 316
jbe@529 317 #### `ecircle(epoint, float8)`
jbe@529 318
jbe@529 319 Creates an `ecircle` with the given center point and radius.
jbe@529 320
jbe@529 321 #### `ecircle(`latitude `float8,` longitude `float8,` radius `float8)`
jbe@529 322
jbe@529 323 Creates an `ecircle` with the given center point and radius.
jbe@529 324
jbe@529 325 #### `ecluster_concat(ecluster, ecluster)`
jbe@529 326
jbe@529 327 Combines two clusters to form a new `ecluster` by uniting all entries of both
jbe@529 328 clusters. Note that two overlapping areas of polygons annihilate each other
jbe@529 329 (which may be used to create polygons with holes).
jbe@529 330
jbe@529 331 #### `ecluster_concat(ecluster[])`
jbe@529 332
jbe@529 333 Creates a new `ecluster` that unites all entries of all clusters in the passed
jbe@529 334 array. Note that two overlapping areas of polygons annihilate each other (which
jbe@529 335 may be used to create polygons with holes).
jbe@529 336
jbe@529 337 #### `ecluster_create_multipoint(epoint[])`
jbe@529 338
jbe@529 339 Creates a new `ecluster` which contains multiple points.
jbe@529 340
jbe@529 341 #### `ecluster_create_outline(epoint[])`
jbe@529 342
jbe@529 343 Creates a new `ecluster` that is an outline given by the passed points.
jbe@529 344
jbe@529 345 #### `ecluster_create_path(epoint[])`
jbe@529 346
jbe@529 347 Creates a new `ecluster` that is a path given by the passed points.
jbe@529 348
jbe@529 349 #### `ecluster_create_polygon(epoint[])`
jbe@529 350
jbe@529 351 Creates a new `ecluster` that is a polygon given by the passed points.
jbe@529 352
jbe@529 353 #### `ecluster_extract_outlines(ecluster)`
jbe@529 354
jbe@529 355 Set-returning function that returns the outlines of an `ecluster` as `epoint[]`
jbe@529 356 rows.
jbe@529 357
jbe@529 358 #### `ecluster_extract_paths(ecluster)`
jbe@529 359
jbe@529 360 Set-returning function that returns the paths of an `ecluster` as `epoint[]`
jbe@529 361 rows.
jbe@529 362
jbe@529 363 #### `ecluster_extract_points(ecluster)`
jbe@529 364
jbe@529 365 Set-returning function that returns the points of an `ecluster` as `epoint`
jbe@529 366 rows.
jbe@529 367
jbe@529 368 #### `ecluster_extract_polygons(ecluster)`
jbe@529 369
jbe@529 370 Set-returning function that returns the polygons of an `ecluster` as `epoint[]`
jbe@529 371 rows.
jbe@529 372
jbe@529 373 #### `empty_ebox`()
jbe@529 374
jbe@529 375 Returns the empty `ebox`.
jbe@529 376 See "1. Types", subsection `ebox` for details.
jbe@529 377
jbe@529 378 #### `epoint(`latitude `float8,` longitude `float8)`
jbe@529 379
jbe@529 380 Returns an `epoint` with the given latitude and longitude.
jbe@529 381
jbe@529 382 #### `epoint_latlon(`latitude `float8,` longitude `float8)`
jbe@529 383
jbe@529 384 Alias for `epoint(float8, float8)`.
jbe@529 385
jbe@529 386 #### `epoint_lonlat(`longitude `float8,` latitude `float8)`
jbe@529 387
jbe@529 388 Same as `epoint(float8, float8)` but with arguments reversed.
jbe@529 389
jbe@529 390 #### `GeoJSON_to_epoint(jsonb, text)`
jbe@529 391
jbe@529 392 Maps a GeoJSON object of type "Point" or "Feature" (which contains a
jbe@529 393 "Point") to an `epoint` datum. For any other JSON objects, NULL is returned.
jbe@529 394
jbe@529 395 The second parameter (which defaults to `epoint_lonlat`) may be set to a name
jbe@529 396 of a conversion function that transforms two coordinates (two `float8`
jbe@529 397 parameters) to an `epoint`.
jbe@529 398
jbe@529 399 #### `GeoJSON_to_ecluster(jsonb, text)`
jbe@529 400
jbe@529 401 Maps a (valid) GeoJSON object to an `ecluster`. Note that this function
jbe@529 402 does not check whether the JSONB object is a valid GeoJSON object.
jbe@529 403
jbe@529 404 The second parameter (which defaults to `epoint_lonlat`) may be set to a name
jbe@529 405 of a conversion function that transforms two coordinates (two `float8`
jbe@529 406 parameters) to an `epoint`.
jbe@529 407
jbe@529 408 #### `max_latitude(ebox)`
jbe@529 409
jbe@529 410 Returns the northern boundary of a given `ebox` in degrees between -90 and +90.
jbe@529 411
jbe@529 412 #### `max_longitude(ebox)`
jbe@529 413
jbe@529 414 Returns the eastern boundary of a given `ebox` in degrees between -180 and +180
jbe@529 415 (both inclusive).
jbe@529 416
jbe@529 417 #### `min_latitude(ebox)`
jbe@529 418
jbe@529 419 Returns the southern boundary of a given `ebox` in degrees between -90 and +90.
jbe@529 420
jbe@529 421 #### `min_longitude(ebox)`
jbe@529 422
jbe@529 423 Returns the western boundary of a given `ebox` in degrees between -180 and +180
jbe@529 424 (both inclusive).
jbe@529 425
jbe@529 426 #### `latitude(epoint)`
jbe@529 427
jbe@529 428 Returns the latitude value of an `epoint` in degrees between -90 and +90.
jbe@529 429
jbe@529 430 #### `longitude(epoint)`
jbe@529 431
jbe@529 432 Returns the longitude value of an `epoint` in degrees between -180 and +180
jbe@529 433 (both inclusive).
jbe@529 434
jbe@529 435 #### `radius(ecircle)`
jbe@529 436
jbe@529 437 Returns the radius of an `ecircle` in meters.
jbe@529 438

Impressum / About Us