pgLatLon

annotate README.mkd @ 2:4f07a22f4d45

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

Impressum / About Us