pgLatLon

annotate README.html @ 51:133626ff7cb2

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

Impressum / About Us