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