pgLatLon

diff README.md @ 81:b0e17a5a0258

Renamed README.mkd to README.md
author jbe
date Thu Oct 23 15:15:56 2025 +0200 (3 days ago)
parents README.mkd@76b3fd3293fc
children 037e28f426e7
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/README.md	Thu Oct 23 15:15:56 2025 +0200
     1.3 @@ -0,0 +1,570 @@
     1.4 +pgLatLon v0.15 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
    1.12 +many operations, pgLatLon aims to support more precise calculations for all
    1.13 +implemented geographic operators. Efficient indexing of geographic objects
    1.14 +is provided using space-filling fractal curves. Optimizations on bit level
    1.15 +(including logarithmic compression) allow for a highly memory-efficient
    1.16 +non-overlapping index suitable for huge datasets.
    1.17 +
    1.18 +pgLatLon is a lightweight solution as it only depends on PostgreSQL itself (and
    1.19 +a C compiler for building).
    1.20 +
    1.21 +Unlike competing spatial extensions for PostgreSQL, pgLatLon is available under
    1.22 +the permissive MIT/X11 license to avoid problems with viral licenses like the
    1.23 +GPLv2/v3.
    1.24 +
    1.25 +
    1.26 +Installation
    1.27 +------------
    1.28 +
    1.29 +### Automatic installation
    1.30 +
    1.31 +Prerequisites:
    1.32 +
    1.33 +* Ensure that the `pg_config` binary is in your path (shipped with PostgreSQL).
    1.34 +* Ensure that GNU Make is available (either as `make` or `gmake`).
    1.35 +
    1.36 +Then simply type:
    1.37 +
    1.38 +    make install
    1.39 +
    1.40 +### Manual installation    
    1.41 +
    1.42 +It is also possible to compile and install the extension without GNU Make as
    1.43 +follows:
    1.44 +
    1.45 +    cc -Wall -O2 -fPIC -shared -I `pg_config --includedir-server` -o latlon-v0010.so latlon-v0010.c
    1.46 +    cp latlon-v0010.so `pg_config --pkglibdir`
    1.47 +    cp latlon.control `pg_config --sharedir`/extension/
    1.48 +    cp latlon--*.sql `pg_config --sharedir`/extension/
    1.49 +
    1.50 +### Loading the extension
    1.51 +
    1.52 +After installation, you can create a database and load the extension as
    1.53 +follows:
    1.54 +
    1.55 +    % createdb test_database
    1.56 +    % psql test_database
    1.57 +    psql (9.5.4)
    1.58 +    Type "help" for help.
    1.59 +
    1.60 +    test_database=# CREATE EXTENSION latlon;
    1.61 +
    1.62 +### Updating
    1.63 +
    1.64 +Before updating your database cluster to a new version of pgLatLon, you may
    1.65 +want to uninstall the old by calling "`make uninstall`" in the unpacked source
    1.66 +code directory of your old pgLatLon version. You may also manually delete the
    1.67 +`latlon-v????.so` files from your PostgreSQL library directory and the
    1.68 +`latlon.control` and `latlon--*.sql` files from your PostgreSQL extension
    1.69 +directory.
    1.70 +
    1.71 +The new version can be installed as described above. For altering an existing
    1.72 +database to use the installed new version (mandatory if you removed the old
    1.73 +version), execute the following SQL command in the respective databases:
    1.74 +
    1.75 +    ALTER EXTENSION latlon UPDATE;
    1.76 +
    1.77 +If the update contains modifications to operator classes, it may be necessary
    1.78 +to drop all indices on geographic data types first (you will get an error
    1.79 +message in this case). These indices can be re-created after the update.
    1.80 +
    1.81 +Note that taking several update steps at once (e.g. updating from version 0.2
    1.82 +directly to version 0.4) requires the intermediate versions to be installed
    1.83 +(i.e. in this example version 0.3 would need to be installed). Whenever you
    1.84 +install or uninstall an intermediate or old version, make sure to afterwards
    1.85 +re-install the latest pgLatLon version to ensure that the `latlon.control` file
    1.86 +is available and points to the latest version.
    1.87 +
    1.88 +If the update contains modifications to the internal data representation
    1.89 +format, an update path might not be available. In this case, create a dump of
    1.90 +your database, delete your database, and restore it from your dump.
    1.91 +
    1.92 +Be sure to always keep backups of all your data before attempting to update.
    1.93 +
    1.94 +
    1.95 +Reference
    1.96 +---------
    1.97 +
    1.98 +### 1. Types
    1.99 +
   1.100 +pgLatLon provides four geographic types: `epoint`, `ebox`, `ecircle`, and
   1.101 +`ecluster`.
   1.102 +
   1.103 +#### `epoint`
   1.104 +
   1.105 +A point on the Earth spheroid (WGS-84).
   1.106 +
   1.107 +The text input format is `'[N|S]<float> [E|W]<float>'`, where each float is in
   1.108 +degrees. Note the required white space between the latitude and longitude
   1.109 +components.  Each floating point number may have a sign, in which case `N`/`S`
   1.110 +or `E`/`W` are switched respectively (e.g. `E-5` is the same as `W5`).
   1.111 +
   1.112 +An `epoint` may also be created from two floating point numbers by calling
   1.113 +`epoint(latitude, longitude)`, where positive latitudes are used for the
   1.114 +northern hemisphere, negative latitudes are used for the southern hemisphere,
   1.115 +positive longitudes indicate positions east of the prime meridian, and negative
   1.116 +longitudes indicate positions west of the prime meridian.
   1.117 +
   1.118 +Latitudes exceeding -90 or +90 degrees are truncated to -90 or +90
   1.119 +respectively, in which case a warning will be issued. Longitudes exceeding -180
   1.120 +or +180 degrees will be converted to values between -180 and +180 (both
   1.121 +inclusive) by adding or substracting a multiple of 360 degrees, in which case a
   1.122 +notice will be issued.
   1.123 +
   1.124 +If the latitude is -90 or +90 (south pole or north pole), a longitude value is
   1.125 +still stored in the datum, and if a point is on the prime meridian or the
   1.126 +180th meridian, the east/west bit is also stored in the datum. In case of the
   1.127 +prime meridian, this is done by storing a floating point value of -0 for
   1.128 +0 degrees west and a value of +0 for 0 degrees east. In case of the
   1.129 +180th meridian, this is done by storing -180 or +180 respectively. The equality
   1.130 +operator, however, returns true when the same points on Earth are described,
   1.131 +i.e. the longitude is ignored for the poles, and 180 degrees west is considered
   1.132 +to be equal to 180 degrees east.
   1.133 +
   1.134 +#### `ebox`
   1.135 +
   1.136 +An area on Earth demarcated by a southern and northern latitude, and a western
   1.137 +and eastern longitude (all given in WGS-84).
   1.138 +
   1.139 +The text input format is
   1.140 +`'{N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float>'`, where each float is in
   1.141 +degrees. The ordering of the four white-space separated blocks is not
   1.142 +significant. To include the 180th meridian, one longitude boundary must be
   1.143 +equal to or exceed `W180` or `E180`, e.g. `'N10 N20 E170 E190'`.
   1.144 +
   1.145 +A special value is the empty area, denoted by the text represenation `'empty'`.
   1.146 +Such an `ebox` does not contain any point.
   1.147 +
   1.148 +An `ebox` may also be created from four floating point numbers by calling
   1.149 +`ebox(min_latitude, max_latitude, min_longitude, max_longitude)`, where
   1.150 +positive values are used for north and east, and negative values are used for
   1.151 +south and west. If `min_latitude` is strictly greater than `max_latitude`, an
   1.152 +empty `ebox` is created. If `min_longitude` is greater than `max_longitude` and
   1.153 +if both longitudes are between -180 and +180 degrees, then the area oriented in
   1.154 +such way that the 180th meridian is included.
   1.155 +
   1.156 +If the longitude span is less than 120 degrees, an `ebox` may be alternatively
   1.157 +created from two `epoints` in the following way: `ebox(epoint(lat1, lon1),
   1.158 +epoint(lat2, lon2))`. In this case `lat1` and `lat2` as well as `lon1` and
   1.159 +`lon2` can be swapped without any impact.
   1.160 +
   1.161 +#### `ecircle`
   1.162 +
   1.163 +An area containing all points not farther away from a given center point
   1.164 +(WGS-84) than a given radius.
   1.165 +
   1.166 +The text input format is `'{N|S}<float> {E|W}<float> <float>'`, where the first
   1.167 +two floats denote the center point in degrees and the third float denotes the
   1.168 +radius in meters. A radius equal to minus infinity denotes an empty circle
   1.169 +which contains no point at all (despite having a center), while a radius equal
   1.170 +to zero denotes a circle that includes a single point.
   1.171 +
   1.172 +An `ecircle` may also be created by calling `ecircle(epoint(...), radius)` or
   1.173 +from three floating point numbers by calling `ecircle(latitude, longitude,
   1.174 +radius)`.
   1.175 +
   1.176 +#### `ecluster`
   1.177 +
   1.178 +A collection of points, paths, polygons, and outlines on the WGS-84 spheroid.
   1.179 +Each path, polygon, or outline must cover a longitude range of less than
   1.180 +180 degrees to avoid ambiguities.
   1.181 +
   1.182 +The text input format is a white-space separated list of the following items:
   1.183 +
   1.184 +* `point   ({N|S}<float> {E|W}<float>)`
   1.185 +* `path    ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
   1.186 +* `outline ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
   1.187 +* `polygon ({N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> {N|S}<float> {E|W}<float> ...)`
   1.188 +
   1.189 +Paths are open by default (i.e. there is no connection from the last point in
   1.190 +the list to the first point in the list). Outlines and polygons, in contrast,
   1.191 +are automatically closed (i.e. there is a line segment from the last point in
   1.192 +the list to the first point in the list) which means the first point should not
   1.193 +be repeated as last point in the list. Polygons are filled, outlines are not.
   1.194 +
   1.195 +### 2. Indices
   1.196 +
   1.197 +Two kinds of indices are supported: B-tree and GiST indices.
   1.198 +
   1.199 +#### B-tree indices
   1.200 +
   1.201 +A B-tree index can be used for simple equality searches and is supported by the
   1.202 +`epoint`, `ebox`, and `ecircle` data types. B-tree indices can not be used for
   1.203 +geographic searches.
   1.204 +
   1.205 +#### GiST indices
   1.206 +
   1.207 +For geographic searches, GiST indices must be used. The `epoint`, `ecircle`,
   1.208 +and `ecluster` data types support GiST indexing. A GiST index for geographic
   1.209 +searches can be created as follows:
   1.210 +
   1.211 +    CREATE TABLE tbl (
   1.212 +            id              serial4         PRIMARY KEY,
   1.213 +            loc             epoint          NOT NULL );
   1.214 +
   1.215 +    CREATE INDEX name_of_index ON tbl USING gist (loc);
   1.216 +
   1.217 +GiST indices also support nearest neighbor searches when using the distance
   1.218 +operator (`<->`) in the ORDER BY clause.
   1.219 +
   1.220 +#### Indices on other data types (e.g. GeoJSON)
   1.221 +
   1.222 +Note that further types can be indexed by using an index on an expression with
   1.223 +a conversion function. One conversion function provided by pgLatLon is the
   1.224 +`GeoJSON_to_ecluster(jsonb, text)` function:
   1.225 +
   1.226 +    CREATE TABLE tbl (
   1.227 +            id              serial4         PRIMARY KEY,
   1.228 +            loc             jsonb           NOT NULL );
   1.229 +
   1.230 +    CREATE INDEX name_of_index ON tbl USING gist ((GeoJSON_to_ecluster("loc")));
   1.231 +
   1.232 +When using the conversion function in an expression, the index will be used
   1.233 +automatically:
   1.234 +
   1.235 +    SELECT * FROM tbl WHERE GeoJSON_to_ecluster("loc") && 'N50 E10 10000'::ecircle;
   1.236 +
   1.237 +### 3. Operators
   1.238 +
   1.239 +#### Equality operator `=`
   1.240 +
   1.241 +Tests if two geographic objects are equal.
   1.242 +
   1.243 +The longitude is ignored for the poles, and 180 degrees west is considered to
   1.244 +be equal to 180 degrees east.
   1.245 +
   1.246 +For boxes and circles, two empty objects are considered equal. (Note that a
   1.247 +circle is not empty if the radius is zero but only if it is negative infinity,
   1.248 +i.e. smaller than zero.) Two circles with a positive infinite radius are also
   1.249 +considered equal.
   1.250 +
   1.251 +Implemented for:
   1.252 +
   1.253 +* `epoint = epoint`
   1.254 +* `ebox = ebox`
   1.255 +* `ecircle = ecircle`
   1.256 +
   1.257 +The negation is the inequality operator (`<>` or `!=`).
   1.258 +
   1.259 +#### Linear ordering operators `<<<`, `<<<=`, `>>>=`, `>>>`
   1.260 +
   1.261 +These operators create an arbitrary (but well-defined) linear ordering of
   1.262 +geographic objects, which is used internally for B-tree indexing and merge
   1.263 +joins. These operators will usually not be used by an application programmer.
   1.264 +
   1.265 +#### Overlap operator `&&`
   1.266 +
   1.267 +Tests if two geographic objects have at least one point in common. Currently
   1.268 +implemented for:
   1.269 +
   1.270 +* `epoint && ebox`
   1.271 +* `epoint && ecircle`
   1.272 +* `epoint && ecluster`
   1.273 +* `ebox && ebox`
   1.274 +* `ebox && ecircle`
   1.275 +* `ebox && ecluster`
   1.276 +* `ecircle && ecircle`
   1.277 +* `ecircle && ecluster`
   1.278 +* `ecluster && ecluster`
   1.279 +
   1.280 +The `&&` operator is commutative, i.e. "`a && b`" is the same as "`b && a`".
   1.281 +Each commutation is supported as well.
   1.282 +
   1.283 +#### Lossy overlap operator `&&+`
   1.284 +
   1.285 +Tests if two geographic objects may have at least one point in common. Opposed
   1.286 +to the `&&` operator, the `&&+` operator may return false positives and is
   1.287 +currently implemented for:
   1.288 +
   1.289 +* `epoint &&+ ecluster`
   1.290 +* `ebox &&+ ecircle`
   1.291 +* `ebox &&+ ecluster`
   1.292 +* `ecircle &&+ ecluster`
   1.293 +* `ecluster &&+ ecluster`
   1.294 +
   1.295 +The `&&+` operator is commutative, i.e. "`a &&+ b`" is the same as "`b &&+ a`".
   1.296 +Each commutation is supported as well.
   1.297 +
   1.298 +Where two data types support both the `&&` and the `&&+` operator, the `&&+`
   1.299 +operator computes faster.
   1.300 +
   1.301 +#### Contains operator `@>`
   1.302 +
   1.303 +Tests if the object right of the operator is contained in the object left of
   1.304 +the operator. Currently implemented for:
   1.305 +
   1.306 +* `ebox @> epoint` (alias for `&&`)
   1.307 +* `ebox @> ebox`
   1.308 +* `ebox @> ecluster`
   1.309 +* `ecluster @> epoint` (alias for `&&`)
   1.310 +* `ecluster @> ebox`
   1.311 +* `ecluster @> ecluster`
   1.312 +
   1.313 +The commutator of `@>` ("contains") is `<@` ("is contained in"), i.e.
   1.314 +"`a @> b`" is the same as "`b <@ a`".
   1.315 +
   1.316 +Whether the perimeter of an object is taken into account is undefined and may
   1.317 +differ between the left and the right hand side of the operator. The current
   1.318 +implementation (where not an alias for `&&`) returns true only if an object is
   1.319 +contained completely within the other object, not touching its perimeter,
   1.320 +paths, outlines, or any singular points.
   1.321 +
   1.322 +#### Distance operator `<->`
   1.323 +
   1.324 +Calculates the shortest distance between two geographic objects in meters (zero
   1.325 +if the objects are overlapping). Currently implemented for:
   1.326 +
   1.327 +* `epoint <-> epoint`
   1.328 +* `epoint <-> ebox`
   1.329 +* `epoint <-> ecircle`
   1.330 +* `epoint <-> ecluster`
   1.331 +* `ebox <-> ebox`
   1.332 +* `ebox <-> ecircle`
   1.333 +* `ebox <-> ecluster`
   1.334 +* `ecircle <-> ecircle`
   1.335 +* `ecircle <-> ecluster`
   1.336 +* `ecluster <-> ecluster`
   1.337 +
   1.338 +The `<->` operator is commutative, i.e. "`a <-> b`" is the same as "`b <-> a`".
   1.339 +Each commutation is supported as well.
   1.340 +
   1.341 +For short distances, the result is very accurate (i.e. respects the dimensions
   1.342 +of the WGS-84 spheroid). For longer distances in the order of magnitude of
   1.343 +Earth's radius or greater, the value is only approximate (but the error is
   1.344 +still less than 0.2% as long as no polygons with very long edges are involved).
   1.345 +
   1.346 +The functions `distance(epoint, epoint)` and `distance(ecluster, epoint)` can
   1.347 +be used as an alias for this operator.
   1.348 +
   1.349 +Note: In case of radial searches with a fixed radius, this operator should
   1.350 +not be used. Instead, an `ecircle` should be created and used in combination
   1.351 +with the overlap operator (`&&`). Alternatively, the functions
   1.352 +`distance_within(epoint, epoint, float8)` or `distance_within(ecluster, epoint,
   1.353 +float8)` can be used for fixed-radius searches.
   1.354 +
   1.355 +### 4. Functions
   1.356 +
   1.357 +#### `center(circle)`
   1.358 +
   1.359 +Returns the center of an `ecircle` as an `epoint`.
   1.360 +
   1.361 +#### `distance(epoint, epoint)`
   1.362 +
   1.363 +Calculates the distance between two `epoint` datums in meters. This function is
   1.364 +an alias for the distance operator `<->`.
   1.365 +
   1.366 +Note: In case of radial searches with a fixed radius, this function should not be
   1.367 +used. Use `distance_within(epoint, epoint, float8)` instead.
   1.368 +
   1.369 +#### `distance(ecluster, epoint)`
   1.370 +
   1.371 +Calculates the distance from an `ecluster` to an `epoint` in meters. This
   1.372 +function is an alias for the distance operator `<->`.
   1.373 +
   1.374 +Note: In case of radial searches with a fixed radius, this function should not be
   1.375 +used. Use `distance_within(epoint, epoint, float8)` instead.
   1.376 +
   1.377 +#### `distance_within(`variable `epoint,` fixed `epoint,` radius `float8)`
   1.378 +
   1.379 +Checks if the distance between two `epoint` datums is not greater than a given
   1.380 +value (search radius).
   1.381 +
   1.382 +Note: In case of radial searches with a fixed radius, the first argument must
   1.383 +be used for the table column, while the second argument must be used for the
   1.384 +search center. Otherwise an existing index cannot be used.
   1.385 +
   1.386 +#### `distance_within(`variable `ecluster,` fixed `epoint,` radius `float8)`
   1.387 +
   1.388 +Checks if the distance from an `ecluster` to an `epoint` is not greater than a
   1.389 +given value (search radius).
   1.390 +
   1.391 +#### `ebox(`latmin `float8,` latmax `float8,` lonmin `float8,` lonmax `float8)`
   1.392 +
   1.393 +Creates a new `ebox` with the given boundaries.
   1.394 +See "1. Types", subsection `ebox` for details.
   1.395 +
   1.396 +#### `ebox(epoint, epoint)`
   1.397 +
   1.398 +Creates a new `ebox`. This function may only be used if the longitude
   1.399 +difference is less than or equal to 120 degrees.
   1.400 +See "1. Types", subsection `ebox` for details.
   1.401 +
   1.402 +#### `ecircle(epoint, float8)`
   1.403 +
   1.404 +Creates an `ecircle` with the given center point and radius.
   1.405 +
   1.406 +#### `ecircle(`latitude `float8,` longitude `float8,` radius `float8)`
   1.407 +
   1.408 +Creates an `ecircle` with the given center point and radius.
   1.409 +
   1.410 +#### `ecluster_concat(ecluster, ecluster)`
   1.411 +
   1.412 +Combines two clusters to form a new `ecluster` by uniting all entries of both
   1.413 +clusters. Note that two overlapping areas of polygons annihilate each other
   1.414 +(which may be used to create polygons with holes).
   1.415 +
   1.416 +#### `ecluster_concat(ecluster[])`
   1.417 +
   1.418 +Creates a new `ecluster` that unites all entries of all clusters in the passed
   1.419 +array. Note that two overlapping areas of polygons annihilate each other (which
   1.420 +may be used to create polygons with holes).
   1.421 +
   1.422 +#### `ecluster_create_multipoint(epoint[])`
   1.423 +
   1.424 +Creates a new `ecluster` which contains multiple points.
   1.425 +
   1.426 +#### `ecluster_create_outline(epoint[])`
   1.427 +
   1.428 +Creates a new `ecluster` that is an outline given by the passed points.
   1.429 +
   1.430 +#### `ecluster_create_path(epoint[])`
   1.431 +
   1.432 +Creates a new `ecluster` that is a path given by the passed points.
   1.433 +
   1.434 +#### `ecluster_create_polygon(epoint[])`
   1.435 +
   1.436 +Creates a new `ecluster` that is a polygon given by the passed points.
   1.437 +
   1.438 +#### `ecluster_extract_outlines(ecluster)`
   1.439 +
   1.440 +Set-returning function that returns the outlines of an `ecluster` as `epoint[]`
   1.441 +rows.
   1.442 +
   1.443 +#### `ecluster_extract_paths(ecluster)`
   1.444 +
   1.445 +Set-returning function that returns the paths of an `ecluster` as `epoint[]`
   1.446 +rows.
   1.447 +
   1.448 +#### `ecluster_extract_points(ecluster)`
   1.449 +
   1.450 +Set-returning function that returns the points of an `ecluster` as `epoint`
   1.451 +rows.
   1.452 +
   1.453 +#### `ecluster_extract_polygons(ecluster)`
   1.454 +
   1.455 +Set-returning function that returns the polygons of an `ecluster` as `epoint[]`
   1.456 +rows.
   1.457 +
   1.458 +#### `empty_ebox`()
   1.459 +
   1.460 +Returns the empty `ebox`.
   1.461 +See "1. Types", subsection `ebox` for details.
   1.462 +
   1.463 +#### `epoint(`latitude `float8,` longitude `float8)`
   1.464 +
   1.465 +Returns an `epoint` with the given latitude and longitude.
   1.466 +
   1.467 +#### `epoint_latlon(`latitude `float8,` longitude `float8)`
   1.468 +
   1.469 +Alias for `epoint(float8, float8)`.
   1.470 +
   1.471 +#### `epoint_lonlat(`longitude `float8,` latitude `float8)`
   1.472 +
   1.473 +Same as `epoint(float8, float8)` but with arguments reversed.
   1.474 +
   1.475 +#### `fair_distance(ecluster, epoint,` samples `int4 = 10000)`
   1.476 +
   1.477 +When working with user-generated content, users may be tempted to create
   1.478 +intentionally oversized objects in order to optimize search results in an
   1.479 +unfair manner. The `fair_distance` function aims to handle this by returning an
   1.480 +adjusted distance (i.e. distance increased by a penalty) if a geographic object
   1.481 +(the `ecluster`) consists of more than one point.
   1.482 +
   1.483 +The first argument to this function is an `ecluster`, the second argument is a
   1.484 +search point (`epoint`), and the third argument is an interger related to the
   1.485 +precision (higher precision will require more computation time).
   1.486 +
   1.487 +The penalty by which the returned distance is increased fulfills (at least) the
   1.488 +following properties:
   1.489 +
   1.490 +* The penalty function is continuous (except noise created by numerical
   1.491 +  integration, see paragraph after this list) as long as no objects are added
   1.492 +  to or removed from the `ecluster`. That particularly means: small changes in
   1.493 +  the search point (second argument) cause only small changes in the result.
   1.494 +* For search points far away from the `ecluster` (i.e. large distances compared
   1.495 +  to the dimensions of the `ecluster`), the penalty approaches zero, i.e. the
   1.496 +  behavior of the `fair_distance` function approaches the behavior of the
   1.497 +  `distance` function.
   1.498 +* If the `ecluster` consists of a set of points, the penalty for a search point
   1.499 +  close to one of those points (closer than half of the minimum distance
   1.500 +  between each pair of points in the `ecluster`) is chosen in such a way that
   1.501 +  the adjusted distance is equal to the distance from the search point to the
   1.502 +  closest point in the `ecluster` multiplied by the square root of the count of
   1.503 +  points in the `ecluster`.
   1.504 +* If the `ecluster` does not cover any area (i.e. only consists of points,
   1.505 +  paths, and/or outlines), and if the search point (second argument) overlaps
   1.506 +  with the `ecluster`, then the penalty (and thus the result) is zero.
   1.507 +* The integral (or average) of the square of the fair distance value (result of
   1.508 +  this function) over all possible search points is independent of the
   1.509 +  `ecluster` as long as the `ecluster` does not cover more than a half of
   1.510 +  earth's surface.
   1.511 +
   1.512 +The function uses numerical integration to compute the result. The third
   1.513 +parameter (which defaults to 10000) can be used to adjust the number of samples
   1.514 +taken. A higher sample count increases precision as well as execution time of
   1.515 +the function. Because this function internally uses a spherical model of earth
   1.516 +for certain steps of the calculation, the precision cannot be increased
   1.517 +unboundedly.
   1.518 +
   1.519 +Despite the limitations explained above, it is ensured that the penalty is
   1.520 +always positive, i.e. results returned by the `fair_distance` function are
   1.521 +always equal to or greater than the results returned by the `distance`
   1.522 +function regardless of stochastic effects.  Furthermore, all results are
   1.523 +deterministic and reproducible with the same version of pgLatLon.
   1.524 +
   1.525 +#### `GeoJSON_to_epoint(jsonb, text)`
   1.526 +
   1.527 +Maps a GeoJSON object of type "Point" or "Feature" (which contains a
   1.528 +"Point") to an `epoint` datum. For any other JSON objects, NULL is returned.
   1.529 +
   1.530 +The second parameter (which defaults to `epoint_lonlat`) may be set to a name
   1.531 +of a conversion function that transforms two coordinates (two `float8`
   1.532 +parameters) to an `epoint`.
   1.533 +
   1.534 +#### `GeoJSON_to_ecluster(jsonb, text)`
   1.535 +
   1.536 +Maps a (valid) GeoJSON object to an `ecluster`. Note that this function
   1.537 +does not check whether the JSONB object is a valid GeoJSON object.
   1.538 +
   1.539 +The second parameter (which defaults to `epoint_lonlat`) may be set to a name
   1.540 +of a conversion function that transforms two coordinates (two `float8`
   1.541 +parameters) to an `epoint`.
   1.542 +
   1.543 +#### `max_latitude(ebox)`
   1.544 +
   1.545 +Returns the northern boundary of a given `ebox` in degrees between -90 and +90.
   1.546 +
   1.547 +#### `max_longitude(ebox)`
   1.548 +
   1.549 +Returns the eastern boundary of a given `ebox` in degrees between -180 and +180
   1.550 +(both inclusive).
   1.551 +
   1.552 +#### `min_latitude(ebox)`
   1.553 +
   1.554 +Returns the southern boundary of a given `ebox` in degrees between -90 and +90.
   1.555 +
   1.556 +#### `min_longitude(ebox)`
   1.557 +
   1.558 +Returns the western boundary of a given `ebox` in degrees between -180 and +180
   1.559 +(both inclusive).
   1.560 +
   1.561 +#### `latitude(epoint)`
   1.562 +
   1.563 +Returns the latitude value of an `epoint` in degrees between -90 and +90.
   1.564 +
   1.565 +#### `longitude(epoint)`
   1.566 +
   1.567 +Returns the longitude value of an `epoint` in degrees between -180 and +180
   1.568 +(both inclusive).
   1.569 +
   1.570 +#### `radius(ecircle)`
   1.571 +
   1.572 +Returns the radius of an `ecircle` in meters.
   1.573 +

Impressum / About Us