mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-24 09:02:37 +00:00
d3604edebc
git-svn-id: http://svn.osgeo.org/postgis/trunk@292 b70326c6-7e19-0410-871a-916f4a2858ee
2677 lines
106 KiB
XML
2677 lines
106 KiB
XML
<?xml version="1.0"?>
|
||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN">
|
||
<book>
|
||
<title>PostGIS Manual</title>
|
||
<bookinfo>
|
||
<editor>
|
||
<firstname>Paul</firstname>
|
||
<surname>Ramsey</surname>
|
||
<affiliation>
|
||
<orgname><ulink url="http://www.refractions.net">Refractions Research Inc</ulink></orgname>
|
||
<address>
|
||
<street>209 - 560 Johnson Street</street>
|
||
<city>Victoria</city>
|
||
<state>British Columbia</state>
|
||
<country>Canada</country>
|
||
<email>pramsey@refractions.net</email>
|
||
</address>
|
||
</affiliation>
|
||
</editor>
|
||
<abstract>
|
||
<para>PostGIS is an extension to the PostgreSQL object-relational database system
|
||
which allows GIS (Geographic Information Systems) objects to be stored in the
|
||
database. PostGIS includes support for GiST-based R-Tree spatial indexes, and
|
||
functions for basic analysis of GIS objects.
|
||
</para>
|
||
</abstract>
|
||
</bookinfo>
|
||
<chapter>
|
||
<title>Introduction</title>
|
||
<para>PostGIS is developed by Refractions Research Inc, as a spatial database
|
||
technology research project. Refractions is a GIS and database
|
||
consulting company in Victoria, British Columbia, Canada, specializing in data
|
||
integration and custom software development. We plan on supporting and
|
||
developing PostGIS to support a range of important GIS functionality, including
|
||
full OpenGIS support, advanced topological constructs (coverages, surfaces,
|
||
networks), desktop user interface tools for viewing and editing GIS data, and
|
||
web-based access tools.
|
||
</para>
|
||
<sect1>
|
||
<title>Credits</title>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>Dave Blasby <dblasby@refractions.net></term>
|
||
<listitem>
|
||
<para>The principal developer of PostGIS. Dave maintains the server
|
||
side objects and index support, the server side analytical
|
||
functions, and the Mapserver connectivity.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Chris Hodgson <chodgson@refractions.net></term>
|
||
<listitem>
|
||
<para>Maintains new functions and the 7.2 index bindings.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Paul Ramsey <pramsey@refractions.net></term>
|
||
<listitem>
|
||
<para>Maintains the JDBC objects and keeps track of the
|
||
documentation and packaging.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Jeff Lounsbury <jeffloun@refractions.net></term>
|
||
<listitem>
|
||
<para>Maintains the Shape loader/dumper.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect1>
|
||
<sect1>
|
||
<title>More Information</title>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The latest software, documentation and news items are available
|
||
at the PostGIS web site,
|
||
<ulink url="http://postgis.refractions.net">http://postgis.refractions.net</ulink>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>More information about the PostgreSQL database server is
|
||
available at the PostgreSQL main site
|
||
<ulink url="http://www.postgresql.org">http://www.postgresql.org</ulink>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>More information about GiST indexing is available at the GiST
|
||
development site,
|
||
<ulink url="http://www.sai.msu.su/~megera/postgres/gist">http://www.sai.msu.su/~megera/postgres/gist</ulink>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>More information about Mapserver internet map server is available at
|
||
<ulink url="http://mapserver.gis.umn.edu/">http://mapserver.gis.umn.edu</ulink>.</para></listitem><listitem><para>The "<ulink url="http://www.opengis.org/techno/specs/99-049.pdf">Simple Features for Specification for SQL</ulink>" is available at the OpenGIS Consortium web site: <ulink url="http://www.opengis.org">http://www.opengis.org</ulink>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</sect1>
|
||
</chapter>
|
||
<chapter>
|
||
<title>Installation</title>
|
||
<sect1>
|
||
<title>Requirements</title>
|
||
<para>PostGIS has the following requirements for building and usage:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>A complete configured and built PostgreSQL source code tree.
|
||
PostGIS uses definitions from the PostgreSQL configure/build process
|
||
to conform to the particular platform you are building on.
|
||
PostgreSQL is available from
|
||
<ulink url="http://www.postgresql.org">http://www.postgresql.org</ulink>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>GNU C compiler (<filename>gcc</filename>). Some other ANSI C
|
||
compilers can be used to compile PostGIS, but we find far fewer
|
||
problems when compiling with <filename>gcc</filename>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>GNU Make (<filename>gmake</filename> or <filename>make</filename>).
|
||
For many systems, GNU <filename>make</filename> is the default version
|
||
of make. Check the version by invoking <filename>make -v</filename>.
|
||
Other versions of <filename>make</filename> may not process the
|
||
PostGIS <filename>Makefile</filename> properly.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>(Optional) Proj4 reprojection library. The Proj4 library is used
|
||
to provide coordinate reprojection support within PostGIS. Proj4 is
|
||
available for download from
|
||
<ulink url="http://www.remotesensing.org/proj">http://www.remotesensing.org/proj</ulink>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</sect1>
|
||
<sect1 id="PGInstall">
|
||
<title>PostGIS</title>
|
||
<para>The PostGIS module is a extension to the PostgreSQL backend server.
|
||
As such, PostGIS 0.7 <emphasis>requires</emphasis> a full copy of the
|
||
PostgreSQL source tree in order to compile. The PostgreSQL source code
|
||
is available at
|
||
<ulink url="http://www.postgresql.org">http://www.postgresql.org</ulink>.
|
||
</para>
|
||
<para>PostGIS 0.7 can be built against PostgreSQL 7.1.x or PostgreSQL 7.2.x.
|
||
Earlier versions of PostgreSQL are <emphasis>not</emphasis> supported.
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Before you can compile the postgis server modules, you must
|
||
compile and install the PostgreSQL package.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Retrieve the PostGIS source archive from
|
||
<ulink url="http://postgis.refractions.net/postgis-0.7.3.tar.gz">http://postgis.refractions.net/postgis-0.7.3.tar.gz</ulink>.
|
||
Uncompress and untar the archive in the "contrib" directory of
|
||
the PostgreSQL source tree.
|
||
</para>
|
||
<programlisting># cd [postgresql source tree]/contrib
|
||
# gzip -d -c postgis-0.7.tar.gz | tar xvf -</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Once your PostgreSQL installation is up-to-date, enter the
|
||
"postgis" directory, and edit the <filename>Makefile</filename>.
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>If you are compiling PostGIS 0.7.2 or earlier
|
||
against PostgreSQL 7.2.x, you must set the
|
||
<varname>USE_PG72</varname> variable to
|
||
<emphasis>1</emphasis>. This is done automatically by
|
||
newer version of postgis.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If want support for coordinate reprojection you must
|
||
have the Proj4 library installed, and set the
|
||
<varname>USE_PROJ</varname> variable to <emphasis>1</emphasis>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Run the compile and install commands.</para>
|
||
<programlisting># make
|
||
# make install</programlisting>
|
||
<para>All files are installed relative to the PostgreSQL install
|
||
directory, <filename>[prefix]</filename>.
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Libraries are installed
|
||
<filename>[prefix]/lib/contrib</filename>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Important support files such as
|
||
<filename>postgis.sql</filename> are installed in
|
||
<filename>[prefix]/share/contrib</filename>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Loader and dumber binaries are installed in
|
||
<filename>[prefix]/bin</filename>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</listitem>
|
||
<listitem>
|
||
<para>PostGIS requires the PL/pgSQL procedural language extension.
|
||
Before loading the <filename>postgis.sql</filename> file,
|
||
you must first enable PL/pgSQL. You should use the
|
||
<filename>createlang</filename> command. The PostgreSQL 7.1
|
||
Programmer's Guide has the details if you want to this manually
|
||
for some reason.
|
||
</para>
|
||
<programlisting># createlang plpgsql [yourdatabase]</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Now load the PostGIS object and function definitions into
|
||
your database by loading the <filename>postgis.sql</filename>
|
||
definitions file.
|
||
</para>
|
||
<programlisting># psql -d [yourdatabase] -f postgis.sql</programlisting>
|
||
<para>The PostGIS server extensions are now loaded and ready to use.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>For a complete set of EPSG coordinate system definition
|
||
identifiers, you can also load the
|
||
<filename>spatial_ref_sys.sql</filename> definitions file and
|
||
populate the <varname>SPATIAL_REF_SYS</varname> table.
|
||
</para>
|
||
<programlisting># psql -d [yourdatabase] -f spatial_ref_sys.sql</programlisting>
|
||
</listitem>
|
||
</orderedlist>
|
||
<sect2>
|
||
<title>Upgrading</title>
|
||
<para>Upgrading PostGIS can be tricky, because the underlying C libraries
|
||
which support the object types and geometries may have changed between
|
||
versions. To avoid problems when upgrading, you will have to dump all
|
||
the tables in your database, destroy the database, create a new one,
|
||
execute the new <filename>postgis.sql</filename> file, then upload your
|
||
database dump:
|
||
</para>
|
||
<programlisting># pg_dump -t "*" -f dumpfile.sql yourdatabase
|
||
# dropdb yourdatabase
|
||
# createdb yourdatabase
|
||
# createlang plpgsql yourdatabse
|
||
# psql -f postgis.sql -d yourdatabase
|
||
# psql -f dumpfile.sql -d yourdatabase
|
||
# vacuumdb -z yourdatabase</programlisting>
|
||
<note>
|
||
<para>When upgrading from version 0.5 to 0.6+, all your geometries
|
||
will be created with an SRID of -1. To create valid OpenGIS
|
||
geometries, you will have to create a valid SRID in the
|
||
SPATIAL_REF_SYS table, and then update your geometries to
|
||
reference the SRID with the following SQL (with the appropriate
|
||
substitutions:
|
||
</para>
|
||
<programlisting>UPDATE TABLE <table> SET <geocolumn> = SetSRID(<geocolumn>,<SRID>);</programlisting>
|
||
</note>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Common Problems</title>
|
||
<para>There are several things to check when your installation or
|
||
upgrade doesn't go as you expected.
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>It is easiest if you untar the PostGIS
|
||
distribution into the contrib directory under the PostgreSQL
|
||
source tree. However, if this is not possible for some reason,
|
||
you can set the <filename>PGSQL_SRC</filename>environment
|
||
variable to the path to the PostgreSQL source directory. This
|
||
will allow you to compile PostGIS, but the
|
||
<filename>make install</filename> may not work, so be prepared
|
||
to copy the PostGIS library and executable files to the
|
||
appropriate locations yourself.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Check that you you have installed PostgreSQL 7.1 or newer,
|
||
and that you are compiling against the same version of the
|
||
PostgreSQL source as the version of PostgreSQL that is
|
||
running. Mix-ups can occur when your (Linux) distrubution has
|
||
already installed PostgreSQL, or you have otherwise installed
|
||
PostgreSQL before and forgotten about it. PostGIS will only
|
||
work with PostgreSQL 7.1 or newer, and strange, unexpected
|
||
error messages will result if you use an older version. To
|
||
check the version of PostgreSQL which is running, connect to
|
||
the database using psql and run this query:
|
||
</para>
|
||
<programlisting>SELECT version();</programlisting>
|
||
</listitem>
|
||
</orderedlist>
|
||
<para>Also check that you have made any necessary changes to the top
|
||
of the Makefile. This includes:
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Changing the <filename>USE_PG72=0</filename> line to
|
||
<filename>USE_PG72=1</filename> if you are using PostgreSQL
|
||
7.2 or newer. If this line is incorrect, it will result in
|
||
a large number of errors being generated either when compiling,
|
||
or when executing the sql statements in the postgis.sql file.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Also, if you want to be able to do coordinate
|
||
reprojections, you must install the Proj.4 library on your
|
||
system, and set the <filename>USE_PROJ</filename> variable
|
||
to 1 in the Makefile.
|
||
</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>JDBC</title>
|
||
<para>The JDBC extensions provide Java objects corresponding to the
|
||
internal PostGIS types. These objects can be used to write Java clients
|
||
which query the PostGIS database and draw or do calculations on the GIS
|
||
data in PostGIS.
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Enter the <filename>jdbc</filename> sub-directory of the
|
||
PostGIS distribution.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Edit the <filename>Makefile</filename> to provide the correct
|
||
paths of your java compiler (<varname>JAVAC</varname>) and
|
||
interpreter (<varname>JAVA</varname>).
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Run the <filename>make</filename> command. Copy the
|
||
<filename>postgis.jar</filename> file to wherever you keep your
|
||
java libraries.
|
||
</para>
|
||
</listitem>
|
||
</orderedlist>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Loader/Dumper</title>
|
||
<para>The data loader and dumper are built and installed automatically
|
||
as part of the PostGIS build. To build and install them manually:
|
||
</para>
|
||
<programlisting># cd postgis-0.7/loader
|
||
# make
|
||
# make install</programlisting>
|
||
<para>The loader is called <filename>shp2pgsql</filename> and converts
|
||
ESRI Shape files into SQL suitable for loading in PostGIS/PostgreSQL.
|
||
The dumper is called <filename>pgsql2shp</filename> and converts
|
||
PostGIS tables into ESRI shape files.
|
||
</para>
|
||
</sect1>
|
||
</chapter>
|
||
<chapter>
|
||
<title>Frequently Asked Questions</title>
|
||
<qandaset>
|
||
<qandaentry>
|
||
<question>
|
||
<para>What kind of geometric objects can I store?</para>
|
||
</question>
|
||
<answer>
|
||
<para>You can store point, line, polygon, multipoint, multiline,
|
||
multipolygon, and geometrycollections. These are specified in
|
||
the Open GIS Well Known Text Format (with 3d extentions).
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>How do I insert a GIS object into the database?</para>
|
||
</question>
|
||
<answer>
|
||
<para>First, you need to create a table with a column of type
|
||
"geometry" to hold your GIS data. Connect to your database with
|
||
<filename>psql</filename> and try the following SQL:
|
||
</para>
|
||
<programlisting>CREATE TABLE gtest ( ID int4, NAME varchar(20) );
|
||
SELECT AddGeometryColumn('dbname','gtest','geom',-1,'LINESTRING',2);</programlisting>
|
||
<para>If the geometry column addition fails, you probably have not
|
||
loaded the PostGIS functions and objects into this database. See the
|
||
<link linkend="PGInstall">installation instructions</link>.
|
||
</para>
|
||
<para>Then, you can insert a geometry into the table using a SQL
|
||
insert statement. The GIS object itself is formatted using the
|
||
OpenGIS Consortium "well-known text" format:
|
||
</para>
|
||
<programlisting>INSERT INTO gtest (ID, NAME, GEOM) VALUES (1, 'First Geometry', GeometryFromText('LINESTRING(2 3,4 5,6 5,7 8)', -1));</programlisting>
|
||
<para>For more information about other GIS objects, see the
|
||
<link linkend="RefObject">object reference</link>.
|
||
</para>
|
||
<para>To view your GIS data in the table:</para>
|
||
<programlisting>SELECT id, name, AsText(geom) AS geom FROM gtest;</programlisting>
|
||
<para>The return value should look something like this:</para>
|
||
<programlisting> id | name | geom
|
||
----+----------------+-----------------------------
|
||
1 | First Geometry | LINESTRING(2 3,4 5,6 5,7 8)
|
||
(1 row)</programlisting>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>How do I construct a spatial query?</para>
|
||
</question>
|
||
<answer>
|
||
<para>There are a number of spatial operators available to
|
||
PostgreSQL, and several of them have been implemented by PostGIS
|
||
in order to provide indexing support.
|
||
</para>
|
||
<para>In order to do a spatial query with index support, you must
|
||
use the "overlap operator" (&&) which uses the following
|
||
important simplifying assumption: <emphasis>all features shall be
|
||
represented by their bounding boxes</emphasis>.
|
||
</para>
|
||
<para>We recognize that using bounding boxes to proxy for features is
|
||
a limiting assumption, but it is an important one in providing
|
||
spatial indexing capabilities. Commercial spatial databases use
|
||
the same assumption -- bounding boxes are important to most
|
||
spatial indexing schemes.
|
||
</para>
|
||
<para>The most important spatial operator from a user's perspective
|
||
is the "&&" overlap operator, which tests whether one
|
||
feature's bounding box overlaps that of another. An example of a
|
||
spatial query using && is:
|
||
</para>
|
||
<programlisting>SELECT id,name FROM GTEST WHERE GEOM && 'BOX3D(3 4,4 5)'::box3d</programlisting>
|
||
<para>Note that the bounding box used for querying must be
|
||
explicitly declared as a <varname>box3d</varname> using the
|
||
"::box3d" casting operation.
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>How do I speed up spatial queries on large tables?</para>
|
||
</question>
|
||
<answer>
|
||
<para>Fast queries on large tables is the <emphasis>raison
|
||
d'etre</emphasis> of spatial databases (along with transaction
|
||
support) so having a good index in important.</para>
|
||
<para>To build a spatial index on a table with a
|
||
<varname>geometry</varname> column, use the "CREATE INDEX"
|
||
function as follows:
|
||
</para>
|
||
<programlisting>CREATE INDEX [indexname] ON [tablename]
|
||
USING GIST ( [geometrycolumn] gist_geometry_ops);</programlisting>
|
||
<para>The "USING GIST" option tells the server to use a GiST
|
||
(Generalized Search Tree) index. The reference to
|
||
"gist_geometry_ops" tells the server to use a particular set
|
||
of comparison operators for building the index: the
|
||
"gist_geometry_ops" are part of the PostGIS extension.
|
||
<note>
|
||
<para>For PostgreSQL version 7.1.x, you can specifically
|
||
request a "lossy" index by appending WITH (ISLOSSY) to
|
||
the index creation command. For PostgreSQL 7.2.x and
|
||
above all GiST indexes are assumed to be lossy. Lossy
|
||
indexes uses a proxy object (in the spatial case, a
|
||
bounding box) for building the index.
|
||
</para>
|
||
</note>
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>How can I get my search to return things that really are inside
|
||
the search box, not just overlapping bounding boxes?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>The '&&' operator only checks bounding box overlaps,
|
||
but you can use the "truly_inside()" function to get only those
|
||
features which <emphasis>actually</emphasis> intersect the search
|
||
box. For example, by combining the use of "&&" for a fast
|
||
index search and truly_inside() for an accurate final check of the
|
||
result set, you can get only those features inside the search box
|
||
(note that this <emphasis>only</emphasis> works for search boxes
|
||
right now, not any arbitrary geometry):
|
||
</para>
|
||
<programlisting>SELECT [COLUMN1],[COLUMN2],AsText([GEOMETRYCOLUMN])
|
||
FROM [TABLE] WHERE [GEOM_COLUMN] && [BOX3d]
|
||
AND truly_inside([GEOM_COLUMN],[BOX3d]);</programlisting>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>Why aren't PostgreSQL R-Tree indexes supported?</para>
|
||
</question>
|
||
<answer>
|
||
<para>Early versions of PostGIS used the PostgreSQL R-Tree
|
||
indexes. However, PostgreSQL R-Trees have been completely
|
||
discarded since version 0.6, and spatial indexing is provided
|
||
with an R-Tree-over-GiST scheme.
|
||
</para>
|
||
<para>Our tests have shown search speed for native R-Tree and
|
||
GiST to be comparable. Native PostgreSQL R-Trees have two
|
||
limitations which make them undesirable for use with GIS
|
||
features (note that these limitations are due to the current
|
||
PostgreSQL native R-Tree implementation, not the R-Tree
|
||
concept in general):
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>R-Tree indexes in PostgreSQL cannot handle features
|
||
which are larger than 8K in size. GiST indexes can, using
|
||
the "lossy" trick of substituting the bounding box for
|
||
the feature itself.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>R-Tree indexes in PostgreSQL are not "null safe", so
|
||
building an index on a geometry column which contains
|
||
null geometries will fail.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>Why should I use the <varname>AddGeometryColumn()</varname>
|
||
function and all the other OpenGIS stuff?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>If you do not want to use the OpenGIS support functions,
|
||
you do not have to. Simply create tables as in older versions,
|
||
defining your geometry columns in the CREATE statement. All
|
||
your geometries will have SRIDs of -1, and the OpenGIS meta-data
|
||
tables will <emphasis>not</emphasis> be filled in properly.
|
||
However, this will cause most applications based on PostGIS to
|
||
fail, and it is generally suggested that you do use
|
||
<varname>AddGeometryColumn()</varname> to create geometry tables.
|
||
</para>
|
||
<para>Mapserver is one application which makes use of the
|
||
<varname>geometry_columns</varname> meta-data. Specifically,
|
||
Mapserver can use the SRID of the geometry column to do on-the-fly
|
||
reprojection of features into the correct map projection.
|
||
</para>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>What is the best way to find all objects within a radius of
|
||
another object?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>To use the database most efficiently, it is best to do
|
||
radius queries which combine the radius test with a bounding
|
||
box test: the bounding box test uses the spatial index, giving
|
||
fast access to a subset of data which the radius test is then
|
||
applied to.
|
||
</para>
|
||
<para>For example, to find all objects with 100 meters of
|
||
POINT(1000 1000) the following query would work well:
|
||
</para>
|
||
<programlisting>SELECT *
|
||
FROM GEOTABLE
|
||
WHERE
|
||
GEOM && GeometryFromText('BOX3D(900 900,1100 1100)',-1)
|
||
AND
|
||
Distance(GeometryFromText('POINT(1000 1000)',-1),GEOM) < 100;</programlisting>
|
||
</answer>
|
||
</qandaentry>
|
||
<qandaentry>
|
||
<question>
|
||
<para>How do I perform a coordinate reprojection as part of
|
||
a query?
|
||
</para>
|
||
</question>
|
||
<answer>
|
||
<para>To perform a reprojection, both the source and
|
||
destination coordinate systems must be defined in the
|
||
SPATIAL_REF_SYS table, and the geometries being reprojected
|
||
must already have an SRID set on them. Once that is done, a
|
||
reprojection is as simple as referring to the desired
|
||
destination SRID.
|
||
</para>
|
||
<programlisting>SELECT Transform(GEOM,4269) FROM GEOTABLE;</programlisting>
|
||
</answer>
|
||
</qandaentry>
|
||
</qandaset>
|
||
</chapter>
|
||
<chapter>
|
||
<title>Using PostGIS</title>
|
||
<sect1 id="RefObject">
|
||
<title>GIS Objects</title>
|
||
<para>The GIS objects supported by PostGIS are the "Simple Features"
|
||
defined by the OpenGIS Consortium (OGC). Note that PostGIS currently supports
|
||
the features and the representation APIs, but not the various comparison and
|
||
convolution operators given in the OGC "Simple Features for SQL"
|
||
specification.</para>
|
||
<para>Examples of the text representations of the features are as
|
||
follows:
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>POINT(0 0 0)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>LINESTRING(0 0,1 1,1 2)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>POLYGON((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2 0,1 2 0,1 1 0))</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>MULTIPOINT(0 0 0,1 2 1)</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>MULTILINESTRING((0 0 0,1 1 0,1 2 1),(2 3 1,3 2 1,5 4 1))</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>MULTIPOLYGON(((0 0 0,4 0 0,4 4 0,0 4 0,0 0 0),(1 1 0,2 1 0,2 2
|
||
0,1 2 0,1 1 0)),((-1 -1 0,-1 -2 0,-2 -2 0,-2 -1 0,-1 -1 0)))</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>GEOMETRYCOLLECTION(POINT(2 3 9),LINESTRING((2 3 4,3 4 5)))</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>Note that in the examples above there are features with both
|
||
2-dimensional and 3-dimensional coordinates. PostGIS supports both 2d and 3d
|
||
coordinates -- if you describe a feature with 2D coordinates when you insert
|
||
it, the database will return that feature to you with 2D coordinates when you
|
||
extract it. See the sections on the <link linkend="force_2d">force_2d()</link>
|
||
and <link linkend="force_3d">force_3d()</link> functions for information on
|
||
converting features to a particular coordinate dimension representation.
|
||
</para>
|
||
<sect2>
|
||
<title>Standard versus Canonical Forms</title>
|
||
<para>The OpenGIS specification defines two standard ways of expressing
|
||
spatial objects: the Well-Known Text (WKT) form (shown in the previous
|
||
section) and the Well-Known Binary (WKB) form. Both WKT and WKB
|
||
include information about the type of the object and the coordinates
|
||
which form the object.
|
||
</para>
|
||
<para>However, the OpenGIS specification also requires that the
|
||
internal storage format of spatial objects include a spatial
|
||
referencing system identifier (SRID). The SRID is required when
|
||
creating spatial objects for insertion into the database. For
|
||
example, a valid insert statement to create and insert a spatial
|
||
object would be:
|
||
</para>
|
||
<programlisting>INSERT INTO SPATIALTABLE ( THE_GEOM, THE_NAME )
|
||
VALUES (
|
||
GeometryFromText('POINT(-126.4 45.32)', 312),
|
||
'A Place'
|
||
)</programlisting>
|
||
<para>Note that the "GeometryFromText" function requires an SRID
|
||
number.
|
||
</para>
|
||
<para>The "canonical form" of the spatial objects in PostgreSQL is a
|
||
text representation which includes all the information necessary
|
||
to construct the object. Unlike the OpenGIS standard forms, it
|
||
includes the type, coordinate, and SRID information. The canonical
|
||
form is the default form returned from a SELECT query. The example
|
||
below shows the difference between the OGC standard and PostGIS
|
||
canonical forms:
|
||
</para>
|
||
<programlisting>db=> SELECT AsText(geom) AS OGCGeom FROM thetable;
|
||
OGCGeom
|
||
-------------------------------------------------
|
||
LINESTRING(-123.741378393049 48.9124018962261,-123.741587115639 48.9123981907507)
|
||
(1 row)
|
||
|
||
db=> SELECT geom AS PostGISGeom FROM thetable;
|
||
PostGISGeom
|
||
-------------------------------------------------
|
||
SRID=123;LINESTRING(-123.741378393049 48.9124018962261,-123.741587115639 48.9123981907507)
|
||
(1 row)</programlisting>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Using OpenGIS Standards</title>
|
||
<para>The OpenGIS "Simple Features Specification for SQL" defines
|
||
standard GIS object types, the functions required to manipulate them,
|
||
and a set of meta-data tables. In order to ensure that meta-data
|
||
remain consistent, operations such as creating and removing a spatial
|
||
column are carried out through special procedures defined by OpenGIS.
|
||
</para>
|
||
<para>There are two OpenGIS meta-data tables: SPATIAL_REF_SYS and
|
||
GEOMETRY_COLUMNS. The SPATIAL_REF_SYS table holds the numeric IDs and textual
|
||
descriptions of coordinate systems used in the spatial database.
|
||
</para>
|
||
<sect2>
|
||
<title>The SPATIAL_REF_SYS Table</title>
|
||
<para>The SPATIAL_REF_SYS table definition is as follows:</para>
|
||
<programlisting>CREATE TABLE SPATIAL_REF_SYS (
|
||
SRID INTEGER NOT NULL PRIMARY KEY,
|
||
AUTH_NAME VARCHAR(256),
|
||
AUTH_SRID INTEGER,
|
||
SRTEXT VARCHAR(2048),
|
||
PROJ4TEXT VARCHAR(2048)
|
||
)</programlisting>
|
||
<para>The SPATIAL_REF_SYS columns are as follows:</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>SRID</term>
|
||
<listitem>
|
||
<para>An integer value that uniquely identifies the Spatial
|
||
Referencing System within the database.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>AUTH_NAME</term>
|
||
<listitem>
|
||
<para>The name of the standard or standards body that is being
|
||
cited for this reference system. For example, "EPSG" would
|
||
be a valid AUTH_NAME.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>AUTH_SRID</term>
|
||
<listitem>
|
||
<para>The ID of the Spatial Reference System as defined by the
|
||
Authority cited in the AUTH_NAME. In the case of EPSG, this
|
||
is where the EPSG projection code would go.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>SRTEXT</term>
|
||
<listitem>
|
||
<para>The Well-Known Text representation of the Spatial
|
||
Reference System. An example of a WKT SRS representation is:
|
||
</para>
|
||
<programlisting>PROJCS["NAD83 / UTM Zone 10N",
|
||
GEOGCS["NAD83",
|
||
DATUM["North_American_Datum_1983",
|
||
SPHEROID["GRS 1980",6378137,298.257222101]
|
||
],
|
||
PRIMEM["Greenwich",0],
|
||
UNIT["degree",0.0174532925199433]
|
||
],
|
||
PROJECTION["Transverse_Mercator"],
|
||
PARAMETER["latitude_of_origin",0],
|
||
PARAMETER["central_meridian",-123],
|
||
PARAMETER["scale_factor",0.9996],
|
||
PARAMETER["false_easting",500000],
|
||
PARAMETER["false_northing",0],
|
||
UNIT["metre",1]
|
||
]</programlisting>
|
||
<para>For a listing of EPSG projection codes and their
|
||
corresponding WKT representations, see
|
||
<ulink url="http://www.opengis.org/techno/interop/EPSG2WKT.TXT">http://www.opengis.org/techno/interop/EPSG2WKT.TXT</ulink>.
|
||
For a discussion of WKT in general, see the OpenGIS
|
||
"Coordinate Transformation Services Implementation
|
||
Specification" at
|
||
<ulink url="http://www.opengis.org/techno/specs.htm">http://www.opengis.org/techno/specs.htm</ulink>.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>PROJ4TEXT</term>
|
||
<listitem>
|
||
<para>PostGIS uses the Proj4 library to provide coordinate
|
||
transformation capabilities. The <varname>PROJ4TEXT</varname>
|
||
column contains the Proj4 coordinate definition string for
|
||
a particular SRID. For example:
|
||
</para>
|
||
<programlisting>+proj=utm +zone=10 +ellps=clrk66 +datum=NAD27 +units=m</programlisting>
|
||
<para>For more information about, see the Proj4 web site at
|
||
<ulink url="http://www.remotesensing.org/proj">http://www.remotesensing.org/proj</ulink>.
|
||
The <filename>spatial_ref_sys.sql</filename> file contains
|
||
both <varname>SRTEXT</varname> and <varname>PROJ4TEXT</varname>
|
||
definitions for all EPSG projections.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect2>
|
||
<sect2>
|
||
<title>The GEOMETRY_COLUMNS Table</title>
|
||
<para>The <varname>GEOMETRY_COLUMNS</varname> table definition is
|
||
as follows:
|
||
</para>
|
||
<programlisting>CREATE TABLE GEOMETRY_COLUMNS (
|
||
F_TABLE_CATALOG VARCHAR(256) NOT NULL,
|
||
F_TABLE_SCHEMA VARCHAR(256) NOT NULL,
|
||
F_TABLE_NAME VARCHAR(256) NOT NULL,
|
||
F_GEOMETRY_COLUMN VARCHAR(256) NOT NULL,
|
||
COORD_DIMENSION INTEGER NOT NULL,
|
||
SRID INTEGER NOT NULL,
|
||
TYPE VARCHAR(30) NOT NULL
|
||
)</programlisting>
|
||
<para>The columns are as follows:</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>F_TABLE_CATALOG, F_TABLE_SCHEMA, F_TABLE_NAME</term>
|
||
<listitem>
|
||
<para>The fully qualified name of the feature table containing
|
||
the geometry column. Note that the terms "catalog" and
|
||
"schema" are Oracle-ish. There is not PostgreSQL analogue of
|
||
"catalog" so that column is left blank -- for "schema" the
|
||
database name is used.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>F_GEOMETRY_COLUMN</term>
|
||
<listitem>
|
||
<para>The name of the geometry column in the feature
|
||
table.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>COORD_DIMENSION</term>
|
||
<listitem>
|
||
<para>The spatial dimension (2 or 3 dimensional) of the
|
||
column.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>SRID</term>
|
||
<listitem>
|
||
<para>The ID of the spatial reference system used for the
|
||
coordinate geometry in this table. It is a foreign key reference to the
|
||
SPATIAL_REF_SYS.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>TYPE</term>
|
||
<listitem>
|
||
<para>The type of the spatial object. To restrict the spatial
|
||
column to a single type, use one of: POINT, LINESTRING,
|
||
POLYGON, MULTPOINT, MULTILINESTRING, MULTIPOLYGON,
|
||
GEOMETRYCOLLECTION. For heterogeneous (mixed-type)
|
||
collections, you can use "GEOMETRY" as the type.
|
||
</para>
|
||
<note>
|
||
<para>This attribute is (probably) not part of the OpenGIS
|
||
specification, but is required for ensuring type
|
||
homogeneity.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Creating a Spatial Table</title>
|
||
<para>Creating a table with spatial data is done in two stages:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Create a normal non-spatial table.</para>
|
||
<para>For example: CREATE TABLE ROADS_GEOM ( ID int4, NAME
|
||
varchar(25) )
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Add a spatial column to the table using the OpenGIS
|
||
"AddGeometryColumn" function. The syntax is:
|
||
AddGeometryColumn(<db_name>, <table_name>,
|
||
<column_name>, <srid>, <type>,
|
||
<dimension>).
|
||
</para>
|
||
<para>For example: SELECT AddGeometryColumn('roads_db',
|
||
'roads_geom', 'geom', 423, 'LINESTRING', 2)
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>Here is an example of SQL used to create a table and add a
|
||
spatial column (assuming the db is 'parks_db' and that an SRID of 128 exists
|
||
already):
|
||
</para>
|
||
<programlisting>CREATE TABLE PARKS ( PARK_ID int4, PARK_NAME varchar(128), PARK_DATE date, PARK_TYPE varchar(2) );
|
||
SELECT AddGeometryColumn('parks_db', 'parks', 'park_geom', 128, 'MULTIPOLYGON', 2 );</programlisting>
|
||
<para>Here is another example, using the generic "geometry" type and
|
||
the undefined SRID value of -1:
|
||
</para>
|
||
<programlisting>CREATE TABLE ROADS ( ROAD_ID int4, ROAD_NAME varchar(128) );
|
||
SELECT AddGeometryColumn( 'roads_db', 'roads', 'roads_geom', -1, 'GEOMETRY', 3 );</programlisting>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Loading GIS Data</title>
|
||
<para>Once you have created a spatial table, you are ready to upload GIS
|
||
data to the database. Currently, there are two ways to get data into a
|
||
PostGIS/PostgreSQL database: using formatted SQL statements or using the Shape
|
||
file loader/dumper.
|
||
</para>
|
||
<sect2>
|
||
<title>Using SQL</title>
|
||
<para>If you can convert your data to a text representation, then using
|
||
formatted SQL might be the easiest way to get your data into PostGIS. As with
|
||
Oracle and other SQL databases, data can be bulk loaded by piping a large text
|
||
file full of SQL "INSERT" statements into the SQL terminal monitor.
|
||
</para>
|
||
<para>A data upload file (<filename>roads.sql</filename> for example)
|
||
might look like this:
|
||
</para>
|
||
<programlisting>BEGIN;
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (1,GeometryFromText('LINESTRING(191232 243118,191108 243242)',-1),'Jeff Rd');
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (2,GeometryFromText('LINESTRING(189141 244158,189265 244817)',-1),'Geordie Rd');
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (3,GeometryFromText('LINESTRING(192783 228138,192612 229814)',-1),'Paul St');
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (4,GeometryFromText('LINESTRING(189412 252431,189631 259122)',-1),'Graeme Ave');
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (5,GeometryFromText('LINESTRING(190131 224148,190871 228134)',-1),'Phil Tce');
|
||
INSERT INTO ROADS_GEOM (ID,GEOM,NAME ) VALUES (6,GeometryFromText('LINESTRING(198231 263418,198213 268322)',-1),'Dave Cres');
|
||
COMMIT;</programlisting>
|
||
<para>The data file can be piped into PostgreSQL very easily using the
|
||
"psql" SQL terminal monitor:
|
||
</para>
|
||
<programlisting>psql -d [database] -f roads.sql</programlisting>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Using the Loader</title>
|
||
<para>The <filename>shp2pgsql</filename> data loader converts ESRI Shape
|
||
files into SQL suitable for insertion into a PostGIS/PostgreSQL database.
|
||
The loader has several operating modes distinguished by command line flags:
|
||
</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>-d</term>
|
||
<listitem>
|
||
<para>Drops the database table before creating a new table with
|
||
the data in the Shape file.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-a</term>
|
||
<listitem>
|
||
<para>Appends data from the Shape file into the database table.
|
||
Note that to use this option to load multiple files, the
|
||
files must have the same attributes and same data types.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-c</term>
|
||
<listitem>
|
||
<para>Creates a new table and populates it from the Shape file.
|
||
<emphasis>This is the default mode.</emphasis>
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-D</term>
|
||
<listitem>
|
||
<para>Creates a new table and populates it from the Shape file.
|
||
This uses the PostgreSQL "dump" format for the output data
|
||
and is much faster to load than the default "insert" SQL format.
|
||
Use this for very large data sets.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-s <SRID></term>
|
||
<listitem>
|
||
<para>Creates and populates the geometry tables with the
|
||
specified SRID.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
<para>An example session using the loader to create an input file and
|
||
uploading it might look like this:
|
||
</para>
|
||
<programlisting># shp2pgsql shaperoads roadstable roadsdb > roads.sql
|
||
# psql -d roadsdb -f roads.sql</programlisting>
|
||
<para>A conversion and upload can be done all in one step using UNIX
|
||
pipes:
|
||
</para>
|
||
<programlisting># shp2pgsql shaperoads roadstable roadsdb | psql -d roadsdb</programlisting>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Retrieving GIS Data</title>
|
||
<para>Data can be extracted from the database using either SQL or the
|
||
Shape file loader/dumper. In the section on SQL we will discuss some of the
|
||
operators available to do comparisons and queries on spatial tables.
|
||
</para>
|
||
<sect2>
|
||
<title>Using SQL</title>
|
||
<para>The most straightforward means of pulling data out of the
|
||
database is to use a SQL select query and dump the resulting columns into a
|
||
parsable text file:
|
||
</para>
|
||
<programlisting>db=# SELECT id, AsText(geom) AS geom, name FROM ROADS_GEOM;
|
||
id | geom | name
|
||
---+-----------------------------------------+-----------
|
||
1 | LINESTRING(191232 243118,191108 243242) | Jeff Rd
|
||
2 | LINESTRING(189141 244158,189265 244817) | Geordie Rd
|
||
3 | LINESTRING(192783 228138,192612 229814) | Paul St
|
||
4 | LINESTRING(189412 252431,189631 259122) | Graeme Ave
|
||
5 | LINESTRING(190131 224148,190871 228134) | Phil Tce
|
||
6 | LINESTRING(198231 263418,198213 268322) | Dave Cres
|
||
7 | LINESTRING(218421 284121,224123 241231) | Chris Way
|
||
(6 rows)</programlisting>
|
||
<para>However, there will be times when some kind of restriction is
|
||
necessary to cut down the number of fields returned. In the case of
|
||
attribute-based restrictions, just use the same SQL syntax as normal
|
||
with a non-spatial table. In the case of spatial restrictions, the
|
||
following operators are available/useful:
|
||
</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>&&</term>
|
||
<listitem>
|
||
<para>This operator tells whether the bounding box of one
|
||
geometry overlaps the bounding box of another.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>~=</term>
|
||
<listitem>
|
||
<para>This operators tests whether two geometries are
|
||
geometrically identical. For example, if 'POLYGON((0 0,1 1,1 0,0 0))'
|
||
is the same as 'POLYGON((0 0,1 1,1 0,0 0))' (it is).
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>=</term>
|
||
<listitem>
|
||
<para>This operator is a little more naive, it only tests whether
|
||
the bounding boxes of to geometries are the same.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
<para>Next, you can use these operators in queries. Note that when
|
||
specifying geometries and boxes on the SQL command line, you must
|
||
explicitly turn the string representations into geometries by using
|
||
the "GeometryFromText()" function. So, for example:
|
||
</para>
|
||
<programlisting>SELECT
|
||
ID, NAME
|
||
FROM ROADS_GEOM
|
||
WHERE
|
||
GEOM ~= GeometryFromText('LINESTRING(191232 243118,191108 243242)',-1);</programlisting>
|
||
<para>The above query would return the single record from the
|
||
"ROADS_GEOM" table in which the geometry was equal to that value.
|
||
</para>
|
||
<para>When using the "&&" operator, you can specify either a
|
||
BOX3D as the comparison feature or a GEOMETRY. When you specify a GEOMETRY,
|
||
however, its bounding box will be used for the comparison.
|
||
</para>
|
||
<programlisting>SELECT
|
||
ID, NAME
|
||
FROM ROADS_GEOM
|
||
WHERE
|
||
GEOM && GeometryFromText('POLYGON((191232 243117,191232 243119,191234 243117,191232 243117))',-1);</programlisting>
|
||
<para>The above query will use the bounding box of the polygon for
|
||
comparison purposes.
|
||
</para>
|
||
<para>The most common spatial query will probably be a "frame-based"
|
||
query, used by client software, like data browsers and web mappers, to
|
||
grab a "map frame" worth of data for display. Using a "BOX3D" object
|
||
for the frame, such a query looks like this:
|
||
</para>
|
||
<programlisting>SELECT
|
||
AsText(GEOM) AS GEOM
|
||
FROM ROADS_GEOM
|
||
WHERE
|
||
GEOM && GeometryFromText('BOX3D(191232 243117,191232 243119)'::box3d,-1);</programlisting>
|
||
<para>Note the use of the SRID, to specify the projection of the BOX3D.
|
||
The value -1 is used to indicate no specified SRID.
|
||
</para>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Using the Dumper</title>
|
||
<para>The <filename>pgsql2shp</filename> table dumper connects directly
|
||
to the database and converts a table into a shape file. The basic
|
||
syntax is:
|
||
</para>
|
||
<programlisting>pgsql2shp [<options>] <database> <table></programlisting>
|
||
<para>The commandline options are:</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>-d</term>
|
||
<listitem>
|
||
<para>Write a 3-dimensional shape file. The default is to write a 2-dimensional shape file.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-f <filename></term>
|
||
<listitem>
|
||
<para>Write the output to a particular filename.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-h <host></term>
|
||
<listitem>
|
||
<para>The database host to connect to.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-p <port></term>
|
||
<listitem>
|
||
<para>The port to connect to on the database host.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-P <password></term>
|
||
<listitem>
|
||
<para>The password to use when connecting to the database.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-u <user></term>
|
||
<listitem>
|
||
<para>The username to use when connecting to the database.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>-g <geometry column></term>
|
||
<listitem>
|
||
<para>In the case of tables with multiple geometry columns, the geometry
|
||
column to use when writing the shape file.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Building Indexes</title>
|
||
<para>Indexes are what make using a spatial database for large databases
|
||
possible. Without indexing, any search for a feature would require a
|
||
"sequential scan" of every record in the database. Indexing speeds up searching
|
||
by organizing the data into a search tree which can be quickly traversed to
|
||
find a particular record. PostgreSQL supports three kinds of indexes by
|
||
default: B-Tree indexes, R-Tree indexes, and GiST indexes.
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>B-Trees are used for data which can be sorted along one axis;
|
||
for example, numbers, letters, dates. GIS data cannot be rationally sorted
|
||
along one axis (which is greater, (0,0) or (0,1) or (1,0)?) so B-Tree indexing
|
||
is of no use for us.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>R-Trees break up data into rectangles, and sub-rectangles, and
|
||
sub-sub rectangles, etc. R-Trees are used by some spatial databases to index GIS
|
||
data, but the PostgreSQL R-Tree implementation is not as robust as the GiST
|
||
implementation.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para> GiST (Generalized Search Trees) indexes break up data into
|
||
"things to one side", "things which overlap", "things which are inside" and can
|
||
be used on a wide range of data-types, including GIS data. PostGIS uses an
|
||
R-Tree index implemented on top of GiST to index GIS data.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<sect2>
|
||
<title>GiST Indexes</title>
|
||
<para>GiST stands for "Generalized Search Tree" and is a generalized
|
||
form of indexing. In addition to GIS indexing, GiST is used to speed up
|
||
searches on all kinds of irregular data structures (integer arrays, spectral
|
||
data, etc) which are not amenable to normal B-Tree indexing.
|
||
</para>
|
||
<para>Once a GIS data table exceeds a few thousand rows, you will want
|
||
to build an index to speed up spatial searches of the data (unless all your
|
||
searches are based on attributes, in which case you'll want to build a normal
|
||
index on the attribute fields).
|
||
</para>
|
||
<para>The syntax for building a GiST index on a "geometry" column is as
|
||
follows:
|
||
</para>
|
||
<programlisting>CREATE INDEX [indexname] ON [tablename]
|
||
USING GIST ( [geometryfield] GIST_GEOMETRY_OPS ); </programlisting>
|
||
<para>Building a spatial index is a computationally intensive exercise:
|
||
on tables of around 1 million rows, on a 300MHz Solaris machine, we have found
|
||
building a GiST index takes about 1 hour. After building an index, it is
|
||
important to force PostgreSQL to collect table statistics, which are
|
||
used to optimize query plans:
|
||
</para>
|
||
<programlisting>VACUUM ANALYZE;</programlisting>
|
||
<para>GiST indexes have two advantages over R-Tree indexes in
|
||
PostgreSQL. Firstly, GiST indexes are "null safe", meaning
|
||
they can index columns which include null values. Secondly, GiST
|
||
indexes support the concept of "lossiness" which is important
|
||
when dealing with GIS objects larger than the PostgreSQL 8K
|
||
page size. Lossiness allows PostgreSQL to store only the
|
||
"important" part of an object in an index -- in the case of GIS
|
||
objects, just the bounding box. GIS objects larger than 8K will
|
||
cause R-Tree indexes to fail in the process of being built.
|
||
</para>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Using Indexes</title>
|
||
<para>Ordinarily, indexes invisibly speed up data access: once the
|
||
index is built, the query planner transparently decides when to use index
|
||
information to speed up a query plan. Unfortunately, the PostgreSQL query
|
||
planner does not optimize the use of GiST indexes well, so sometimes searches which should use a spatial index instead default to a sequence
|
||
scan of the whole table.
|
||
</para>
|
||
<para>If you find your spatial indexes are not being used (or your
|
||
attribute indexes, for that matter) there are a couple things you can
|
||
do:
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Firstly, make sure you run the "VACUUM ANALYZE [tablename]"
|
||
command on the tables you are having problems with. "VACUUM ANALYZE" gathers
|
||
statistics about the number and distributions of values in a table, to provide
|
||
the query planner with better information to make decisions around index
|
||
usage. You should regularly vacuum your databases anyways -- many PostgreSQL
|
||
DBAs have "VACUUM" run as an off-peak cron job on a regular basis.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If vacuuming does not work, you can force the planner to use the index
|
||
information by using the "SET =OFF" command. You should only use
|
||
this command sparingly, and only on spatially indexed queries: generally
|
||
speaking, the planner knows better than you do about when to use normal B-Tree
|
||
indexes. Once you have run your query, you should consider setting
|
||
"ENABLE_SEQSCAN" back on, so that other queries will utilize the planner as
|
||
normal.
|
||
</para>
|
||
<note>
|
||
<para>As of version 0.6, it should not be necessary to force the
|
||
planner to use the index with "ENABLE_SEQSCAN".
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Complex Queries</title>
|
||
<para>The <emphasis>raison d'etre</emphasis> of spatial database functionality
|
||
is performing queries inside the database which would ordinarily require
|
||
desktop GIS functionality. Using PostGIS effectively requires knowing what
|
||
spatial functions are available, and ensuring that appropriate indexes are
|
||
in place to provide good performance.
|
||
</para>
|
||
<sect2>
|
||
<title>Taking Advantage of Indexes</title>
|
||
<para>When constructing a query it is important to remember that only the
|
||
bounding-box-based operators such as && can take advatage of the
|
||
GiST spatial index. Functions such as <varname>distance()</varname>
|
||
cannot use the index to optimize their operation. For example, the
|
||
following query would be quite slow on a large table:
|
||
</para>
|
||
<programlisting>SELECT the_geom FROM geom_table
|
||
WHERE distance( the_geom, GeometryFromText( 'POINT(100000 200000)', -1 ) ) < 100</programlisting>
|
||
<para>This query is selecting all the geometries in geom_table which are within
|
||
100 units of the point (100000, 200000). It will be slow because it is
|
||
calculating the distance between each point in the table and our specified
|
||
point, ie. one <varname>distance()</varname> calculation for each row in
|
||
the table. We can avoid this by using the && operator to reduce
|
||
the number of distance calculations required:
|
||
</para>
|
||
<programlisting>SELECT the_geom FROM geom_table
|
||
WHERE the_geom && 'BOX3D(90900 190900, 100100 200100)'::box3d
|
||
AND distance( the_geom, GeometryFromText( 'POINT(100000 200000)', -1 ) ) < 100</programlisting>
|
||
<para>This query selects the same geometries, but it does it in a more efficient way.
|
||
Assuming there is a GiST index on the_geom, the query planner will recognize that
|
||
it can use the index to reduce the number of rows before calculating the result
|
||
of the <varname>distance()</varname> function. Notice that the
|
||
<varname>BOX3D</varname> geometry which is used in the && operation is a 200 unit
|
||
square box centered on the original point - this is our "query box". The
|
||
&& operator uses the index to quickly reduce the result set down to
|
||
only those geometries which have bounding boxes that overlap the "query box".
|
||
Assuming that our query box is much smaller than the extents of the entire
|
||
geometry table, this will drastically reduce the number of distance calculations
|
||
that need to be done.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Using Mapserver</title>
|
||
<para>The Minnesota Mapserver is an internet web-mapping server which conforms
|
||
to the OpenGIS Web Mapping Server specification.
|
||
</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>The Mapserver homepage is at
|
||
<ulink url="http://mapserver.gis.umn.edu">http://mapserver.gis.umn.edu</ulink>.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>The OpenGIS Web Map Specification is at
|
||
<ulink url="http://www.opengis.org/techno/specs/01-047r2.pdf">http://www.opengis.org/techno/specs/01-047r2.pdf</ulink>.
|
||
</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<sect2>
|
||
<title> Basic Usage</title>
|
||
<para>To use PostGIS with Mapserver, you will need to know about how to
|
||
configure Mapserver, which is beyond the scope of this documentation.
|
||
This section will cover specific PostGIS issues and configuration details.
|
||
</para>
|
||
<para>To use PostGIS with Mapserver, you will need:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>Version 0.6 or newer of PostGIS.</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Version 3.5 or newer of Mapserver.</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>Mapserver accesses PostGIS/PostgreSQL data like any other
|
||
PostgreSQL client -- using <filename>libpq</filename>. This
|
||
means that Mapserver can be installed on any machine with
|
||
network access to the PostGIS server, as long as the system
|
||
has the <filename>libpq</filename> PostgreSQL client libraries.
|
||
</para>
|
||
<orderedlist>
|
||
<listitem>
|
||
<para>Compile and install Mapserver, with whatever
|
||
options you desire, including the "--with-postgis"
|
||
configuration option.
|
||
</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>In your Mapserver map file, add a PostGIS layer.
|
||
For example:
|
||
</para>
|
||
<programlisting>LAYER
|
||
CONNECTIONTYPE postgis
|
||
NAME "widehighways"
|
||
# Connect to a remote spatial database
|
||
CONNECTION "user=dbuser dbname=gisdatabase host=bigserver"
|
||
# Get the lines from the 'geom' column of the 'roads' table
|
||
DATA "geom from roads"
|
||
STATUS ON
|
||
TYPE LINE
|
||
# Of the lines in the extents, only render the wide highways
|
||
FILTER "type = 'highway' and numlanes >= 4"
|
||
CLASS
|
||
# Make the superhighways brighter and 2 pixels wide
|
||
EXPRESSION ([numlanes] >= 6)
|
||
COLOR 255 22 22
|
||
SYMBOL "solid"
|
||
SIZE 2
|
||
END
|
||
CLASS
|
||
# All the rest are darker and only 1 pixel wide
|
||
EXPRESSION ([numlanes] < 6)
|
||
COLOR 205 92 82
|
||
END
|
||
END</programlisting>
|
||
<para>In the example above, the PostGIS-specific
|
||
directives are as follows:
|
||
</para>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>CONNECTIONTYPE</term>
|
||
<listitem>
|
||
<para>For PostGIS layers, this is always
|
||
"postgis".
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>CONNECTION</term>
|
||
<listitem>
|
||
<para>The database connection is governed
|
||
by the a 'connection string' which is a
|
||
standard set of keys and values like this
|
||
(with the default values in <>):
|
||
</para>
|
||
<para>user=<username> password=<password>
|
||
dbname=<username> hostname=<server>
|
||
port=<5432>
|
||
</para>
|
||
<para>An empty connection string is still valid, and
|
||
any of the key/value pairs can be omitted. At a
|
||
minimum you will generally supply the database
|
||
name and username to connect with.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>DATA</term>
|
||
<listitem>
|
||
<para>The form of this parameter is "<column>
|
||
from <tablename>" where the column is the
|
||
spatial column to be rendered to the map.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>FILTER</term>
|
||
<listitem>
|
||
<para>The filter must be a valid SQL string
|
||
corresponding to the logic normally following
|
||
the "WHERE" keyword in a SQL query. So, for
|
||
example, to render only roads with 6 or more lanes,
|
||
use a filter of "num_lanes >= 6".
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</listitem>
|
||
<listitem>
|
||
<para>In your spatial database, ensure you have spatial (GiST)
|
||
indexes built for any the layers you will be drawing.
|
||
</para>
|
||
<programlisting>CREATE INDEX [indexname]
|
||
ON [tablename]
|
||
USING GIST ( [geometrycolumn] GIST_GEOMETRY_OPS );</programlisting>
|
||
</listitem>
|
||
<listitem>
|
||
<para>If you will be querying your layers using Mapserver you
|
||
will also need an "oid index".
|
||
</para>
|
||
<para>Mapserver requires unique identifiers for each spatial
|
||
record when doing queries, and the PostGIS module of Mapserver
|
||
uses the PostgreSQL <varname>oid</varname> value to provide
|
||
these unique identifiers. A side-effect of this is that in
|
||
order to do fast random access of records during queries, an
|
||
index on the <varname>oid</varname> is needed.
|
||
</para>
|
||
<para>To build an "oid index", use the following SQL:</para>
|
||
<programlisting>CREATE INDEX [indexname] ON [tablename] ( oid );</programlisting>
|
||
</listitem>
|
||
</orderedlist>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Advanced Usage</title>
|
||
<para>The <varname>USING</varname> pseudo-SQL clause is used to add some
|
||
information to help mapserver understand the results of more complex queries.
|
||
More specifically, when either a view or a subselect is used as the source table
|
||
(the thing to the right of "FROM" in a <varname>DATA</varname> definition)
|
||
it is more difficult for mapserver to automatically determine a unique identifier
|
||
for each row and also the SRID for the table. The <varname>USING</varname> clause
|
||
can provide mapserver with these two pieces of information as follows:
|
||
</para>
|
||
<programlisting>DATA "the_geom FROM (SELECT table1.the_geom AS the_geom, table1.oid AS oid, table2.data AS data
|
||
FROM table1 LEFT JOIN table2 ON table1.id = table2.id) AS new_table USING UNIQUE oid USING SRID=-1"</programlisting>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>USING UNIQUE <uniqueid></term>
|
||
<listitem>
|
||
<para>Mapserver requires a unique id for each row in order to identify
|
||
the row when doing map queries. Normally, it would use the oid as the
|
||
unique identifier, but views and subselects don't automatically have an
|
||
oid column. If you want to use Mapserver's query functionality,
|
||
you need to add a unique column to your view or subselect, and declare
|
||
it with <varname>USING UNIQUE</varname>.
|
||
For example, you could explicitly select one of the table's oid values
|
||
for this purpose, or any other column which is guaranteed to be
|
||
unique for the result set.
|
||
</para>
|
||
<para>
|
||
The <varname>USING</varname> statement can also be useful even for simple
|
||
<varname>DATA</varname> statements, if you are doing map queries.
|
||
It was previously recommended to add an index on the oid column of tables
|
||
used in query-able layers, in order to speed up the performance of map
|
||
queries. However, with the <varname>USING</varname> clause, it is possible
|
||
to tell mapserver to use your table's primary key as the identifier for
|
||
map queries, and then it is no longer necessary to have an additional index.
|
||
</para>
|
||
<note>
|
||
<para>"Querying a Map" is the action of clicking on a map to ask for
|
||
information about the map features in that location. Don't confuse
|
||
"map queries" with the SQL query in a <varname>DATA</varname> definition.
|
||
</para>
|
||
</note>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>USING SRID=<srid></term>
|
||
<listitem>
|
||
<para>PostGIS needs to know which spatial referencing system is being used by
|
||
the geometries in order to return the correct data back to mapserver.
|
||
Normally it is possible to find this information in the "geometry_columns"
|
||
table in the PostGIS database, however, this is not possible for tables
|
||
which are created on the fly such as subselects and views.
|
||
So the <varname>USING SRID=</varname> option allows the correct SRID to be
|
||
specified in the <varname>DATA</varname> definition.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Examples</title>
|
||
<para>Lets start with a simple example and work our way up. Consider the following
|
||
Mapserver layer definition:
|
||
</para>
|
||
<programlisting>LAYER
|
||
CONNECTIONTYPE postgis
|
||
NAME "roads"
|
||
CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
|
||
DATA "the_geom FROM roads"
|
||
STATUS ON
|
||
TYPE LINE
|
||
CLASS
|
||
COLOR 0 0 0
|
||
END
|
||
END</programlisting>
|
||
<para>This layer will display all the road geometries in the roads table
|
||
as black lines.
|
||
</para>
|
||
<para>Now lets say we want to show only the highways until
|
||
we get zoomed in to at least a 1:100000 scale - the next two layers will
|
||
acheive this effect:
|
||
</para>
|
||
<programlisting>LAYER
|
||
CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
|
||
DATA "the_geom FROM roads"
|
||
MINSCALE 100000
|
||
STATUS ON
|
||
TYPE LINE
|
||
FILTER "road_type = 'highway'"
|
||
CLASS
|
||
COLOR 0 0 0
|
||
END
|
||
END
|
||
|
||
LAYER
|
||
CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
|
||
DATA "the_geom FROM roads"
|
||
MAXSCALE 100000
|
||
STATUS ON
|
||
TYPE LINE
|
||
CLASSITEM road_type
|
||
CLASS
|
||
EXPRESSION "highway"
|
||
SIZE 2
|
||
COLOR 255 0 0
|
||
END
|
||
CLASS
|
||
COLOR 0 0 0
|
||
END
|
||
END</programlisting>
|
||
<para>The first layer is used when the scale is greater than 1:100000, and
|
||
displays only the roads of type "highway" as black lines. The
|
||
<varname>FILTER</varname> option causes only roads of type "highway" to
|
||
be displayed.
|
||
</para>
|
||
<para>The second layer is used when the scale is less than 1:100000, and
|
||
will display highways as double-thick red lines, and other roads as
|
||
regular black lines.
|
||
</para>
|
||
<para>So, we have done a couple of interesting things using only mapserver
|
||
functionality, but our <varname>DATA</varname> SQL statement has remained
|
||
simple. Suppose that the name of the road is stored in another table (for
|
||
whatever reason) and we need to do a join to get it and label our roads.
|
||
</para>
|
||
<programlisting>LAYER
|
||
CONNECTION "user=theuser password=thepass dbname=thedb host=theserver"
|
||
DATA "the_geom FROM (SELECT roads.oid AS oid, roads.the_geom AS the_geom, road_names.name as name
|
||
FROM roads LEFT JOIN road_names ON roads.road_name_id = road_names.road_name_id) AS named_roads
|
||
USING UNIQUE oid USING SRID=-1"
|
||
MAXSCALE 20000
|
||
STATUS ON
|
||
TYPE ANNOTATION
|
||
LABELITEM name
|
||
CLASS
|
||
LABEL
|
||
ANGLE auto
|
||
SIZE 8
|
||
COLOR 0 192 0
|
||
TYPE truetype
|
||
FONT arial
|
||
END
|
||
END
|
||
END</programlisting>
|
||
<para>This annotation layer adds green labels to all the roads when
|
||
the scale gets down to 1:20000 or less. It also demonstrates how to
|
||
use an SQL join in a <varname>DATA</varname> definition.
|
||
</para>
|
||
</sect2>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Java Clients (JDBC)</title>
|
||
<para>Java clients can access PostGIS "geometry" objects in the
|
||
PostgreSQL database either directly as text representations or using the JDBC
|
||
extension objects bundled with PostGIS. In order to use the extension objects,
|
||
the "postgis.jar" file must be in your CLASSPATH along with the
|
||
"postgresql.jar" JDBC driver package.</para>
|
||
<programlisting>import java.sql.*;
|
||
import java.util.*;
|
||
import java.lang.*;
|
||
import org.postgis.*;
|
||
|
||
public class JavaGIS {
|
||
public static void main(String[] args)
|
||
{
|
||
java.sql.Connection conn;
|
||
try
|
||
{
|
||
/*
|
||
* Load the JDBC driver and establish a connection.
|
||
*/
|
||
Class.forName("org.postgresql.Driver");
|
||
String url = "jdbc:postgresql://localhost:5432/database";
|
||
conn = DriverManager.getConnection(url, "postgres", "");
|
||
|
||
/*
|
||
* Add the geometry types to the connection. Note that you
|
||
* must cast the connection to the pgsql-specific connection * implementation before calling the addDataType() method.
|
||
*/
|
||
((org.postgresql.Connection)conn).addDataType("geometry","org.postgis.PGgeometry");
|
||
((org.postgresql.Connection)conn).addDataType("box3d","org.postgis.PGbox3d");
|
||
|
||
/*
|
||
* Create a statement and execute a select query.
|
||
*/
|
||
Statement s = conn.createStatement();
|
||
ResultSet r = s.executeQuery("select AsText(geom) as geom,id from geomtable");
|
||
while( r.next() )
|
||
{
|
||
/*
|
||
* Retrieve the geometry as an object then cast it to the geometry type.
|
||
* Print things out.
|
||
*/
|
||
PGgeometry geom = (PGgeometry)r.getObject(1);
|
||
int id = r.getInt(2);
|
||
System.out.println("Row " + id + ":");
|
||
System.out.println(geom.toString());
|
||
}
|
||
s.close();
|
||
conn.close();
|
||
}
|
||
catch( Exception e )
|
||
{
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}</programlisting>
|
||
<para>The "PGgeometry" object is a wrapper object which contains a
|
||
specific topological geometry object (subclasses of the abstract class
|
||
"Geometry") depending on the type: Point, LineString, Polygon, MultiPoint,
|
||
MultiLineString, MultiPolygon.</para>
|
||
<programlisting>PGgeometry geom = (PGgeometry)r.getObject(1);
|
||
if( geom.getType() = Geometry.POLYGON )
|
||
{
|
||
Polygon pl = (Polygon)geom.getGeometry();
|
||
for( int r = 0; r < pl.numRings(); r++ )
|
||
{
|
||
LinearRing rng = pl.getRing(r);
|
||
System.out.println("Ring: " + r);
|
||
for( int p = 0; p < rng.numPoints(); p++ )
|
||
{
|
||
Point pt = rng.getPoint(p);
|
||
System.out.println("Point: " + p);
|
||
System.out.println(pt.toString());
|
||
}
|
||
}
|
||
}</programlisting>
|
||
<para>The JavaDoc for the extension objects provides a reference for the
|
||
various data accessor functions in the geometric objects.
|
||
</para>
|
||
</sect1>
|
||
<sect1>
|
||
<title> C Clients (libpq)</title>
|
||
<para>...</para>
|
||
<sect2>
|
||
<title>Text Cursors</title>
|
||
<para>...</para>
|
||
</sect2>
|
||
<sect2>
|
||
<title>Binary Cursors</title>
|
||
<para>...</para>
|
||
</sect2>
|
||
</sect1>
|
||
</chapter>
|
||
<chapter>
|
||
<title>PostGIS Reference</title>
|
||
<para>The functions given below are the ones which a user of PostGIS is
|
||
likely to need. There are other functions which are required support functions
|
||
to the PostGIS objects which are not of use to a general user.
|
||
</para>
|
||
<sect1>
|
||
<title>OpenGIS Functions</title>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>AddGeometryColumn(varchar, varchar, varchar, integer, varchar, integer)</term>
|
||
<listitem>
|
||
<para>Syntax: AddGeometryColumn(<db_name>,
|
||
<table_name>, <column_name>, <srid>, <type>,
|
||
<dimension>). Adds a geometry column to an existing table of attributes.
|
||
The <varname>dbname</varname> is the name of the database instance.
|
||
The <varname>srid</varname> must be an integer value reference to an
|
||
entry in the SPATIAL_REF_SYS table. The <varname>type</varname> must
|
||
be an uppercase string corresponding to the geometry type, eg, 'POLYGON'
|
||
or 'MULTILINESTRING'.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>DropGeometryColumn(varchar, varchar, varchar)</term>
|
||
<listitem>
|
||
<para>Syntax: DropGeometryColumn(<db_name>, <table_name>,
|
||
<column_name>). Remove a geometry column from a spatial table.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>AsBinary(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the geometry in the OGC "well-known-binary" format,
|
||
using the endian encoding of the server on which the database is
|
||
running. This is useful in binary cursors to pull data out of
|
||
the database without converting it to a string representation.
|
||
</para>
|
||
<para>OGC SPEC s2.1.1.1 - also see asBinary(<geometry>,'XDR') and asBinary(<geometry>,'NDR')
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Dimension(geometry)</term>
|
||
<listitem>
|
||
<para>The inherent dimension of this Geometry object, which must be less than or equal
|
||
to the coordinate dimension. OGC SPEC s2.1.1.1 - returns 0 for points, 1 for lines, 2 for polygons, and the largest dimension of the components of a GEOMETRYCOLLECTION.
|
||
</para>
|
||
<programlisting>select dimension('GEOMETRYCOLLECTION(LINESTRING(1 1,0 0),POINT(0 0)');
|
||
dimension
|
||
-----------
|
||
1</programlisting>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>isEmpty(geometry)</term>
|
||
<listitem>
|
||
<para>
|
||
Returns 1 (TRUE) if this Geometry is the empty geometry . If true, then this
|
||
Geometry represents the empty point set - i.e. GEOMETRYCOLLECTION(EMPTY).
|
||
</para>
|
||
<para>OGC SPEC s2.1.1.1 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>isSimple(geometry)</term>
|
||
<listitem>
|
||
<para>
|
||
Returns 1 (TRUE) if this Geometry has no anomalous geometric points, such as self
|
||
intersection or self tangency.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
|
||
<para>OGC SPEC s2.1.1.1 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>boundary(geometry)</term>
|
||
<listitem>
|
||
<para>
|
||
Returns the closure of the combinatorial boundary of this Geometry. The
|
||
combinatorial boundary is defined as described in section 3.12.3.2 of the OGC SPEC. Because the result of this function
|
||
is a closure, and hence topologically closed, the resulting boundary can be represented using
|
||
representational geometry primitives as discussed in the OGC SPEC, section 3.12.2.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>OGC SPEC s2.1.1.1 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>equals(geometry)</term>
|
||
<listitem>
|
||
<para>
|
||
Returns 1 (TRUE) if this Geometry is <20>spatially equal<61> to
|
||
anotherGeometry. Use this for a 'better' answer than '='. equals ('LINESTRING(0 0, 10 10)','LINESTRING(0 0, 5 5, 10 10)') is true.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>OGC SPEC s2.1.1.1 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>disjoint(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry is <20>spatially disjoint<6E> from anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 //s2.1.13.3 - a.Relate(b, <20>FF*FF****<2A>) </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>intersects(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry <20>spatially intersects<74> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 //s2.1.13.3 - Intersects(g1, g2 ) --> Not (Disjoint(g1, g2 )) </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>touches(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry <20>spatially touches<65> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3- a.Touches(b) -> (I(a) intersection I(b) = {empty set} ) and (a intersection b) not empty </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>crosses(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry <20>spatially crosses<65> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 - a.Relate(b, <20>T*T******<2A>) </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>within(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry is <20>spatially within<69> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 - a.Relate(b, <20>T*F**F***<2A>) </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>overlaps(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry is <20>spatially overlapping<6E> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>contains(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry is <20>spatially contains<6E> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 - same as within(geometry,geometry)</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>intersects(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Geometry is <20>spatially intersects<74> anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 - NOT disjoint(geometry,geometry)</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>relate(geometry,geometry, intersectionPatternMatrix)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this
|
||
Geometry is spatially related to anotherGeometry, by testing for intersections between the Interior,
|
||
Boundary and Exterior of the two geometries as specified by the values in the intersectionPatternMatrix.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para> NOTE: this is the "allowable" version that returns a boolean, not an integer.
|
||
<para>OGC SPEC s2.1.1.1 // s2.1.13.3 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>relate(geometry,geometry)</term>
|
||
<listitem>
|
||
<para> returns the DE-9IM (dimensionally extended nine-intersection matrix)
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>not in OGC spec, but implied. see s2.1.13.2 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>buffer(geometry,double)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents all points whose distance from
|
||
this Geometry is less than or equal to distance. Calculations are in the Spatial Reference System of this
|
||
Geometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>convexhull(geometry)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents the convex hull of this Geometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>intersection(geometry,geometry)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents the point set
|
||
intersection of this Geometry with anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>geomunion(geometry,geometry)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents the point set union of
|
||
this Geometry with anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>NOTE: this is renamed from "union" because union is an SQL reserved word</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>difference(geometry,geometry)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents the point set
|
||
difference of this Geometry with anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>difference(geometry,geometry)</term>
|
||
<listitem>
|
||
<para> Returns a geometry that represents the point set
|
||
symmetric difference of this Geometry with anotherGeometry.
|
||
</para>
|
||
<para>Performed by the GEOS module</para>
|
||
<para>Do not call with a GeometryCollection as an argument</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Envelope(geometry)</term>
|
||
<listitem>
|
||
<para>Returns a POLYGON representing the bounding box of the
|
||
geometry.
|
||
</para>
|
||
<para> OGC SPEC s2.1.1.1 - The minimum bounding box for this Geometry, returned as a Geometry. The
|
||
polygon is defined by the corner points of the bounding box ((MINX, MINY), (MAXX, MINY), (MAXX,
|
||
MAXY), (MINX, MAXY), (MINX, MINY)). </para><para>NOTE:PostGIS will add a Zmin/Zmax coordinate as well.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>GeometryType(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the type of the geometry as a string. Eg: 'LINESTRING',
|
||
'POLYGON', 'MULTIPOINT', etc.
|
||
</para>
|
||
<para>
|
||
OGC SPEC s2.1.1.1 - Returns the name of the instantiable subtype of Geometry of which this
|
||
Geometry instance is a member. The name of the instantiable subtype of Geometry is returned as a string.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>X(geometry)</term>
|
||
<listitem>
|
||
<para>Find and return the X coordinate of the first point in the
|
||
geometry. Return NULL if there is no point in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Y(geometry)</term>
|
||
<listitem>
|
||
<para>Find and return the Y coordinate of the first point in the
|
||
geometry. Return NULL if there is no point in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Z(geometry)</term>
|
||
<listitem>
|
||
<para>Find and return the Z coordinate of the first point in the
|
||
geometry. Return NULL if there is no point in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>NumPoints(geometry)</term>
|
||
<listitem>
|
||
<para>Find and return the number of points in the first linestring
|
||
in the geometry. Return NULL if there is no linestring in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>PointN(geometry,integer)</term>
|
||
<listitem>
|
||
<para>Return the N'th point in the first linestring in the
|
||
geometry. Return NULL if there is no linestring in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>ExteriorRing(geometry)</term>
|
||
<listitem>
|
||
<para>Return the exterior ring of the first polygon in the
|
||
geometry. Return NULL if there is no polygon in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>NumInteriorRings(geometry)</term>
|
||
<listitem>
|
||
<para>Return the number of interior rings of the first polygon in
|
||
the geometry. Return NULL if there is no polygon in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>InteriorRingN(geometry,integer)</term>
|
||
<listitem>
|
||
<para>Return the N'th interior ring of the first polygon in the
|
||
geometry. Return NULL if there is no polygon in the geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>IsClosed(geometry)</term>
|
||
<listitem>
|
||
<para>Returns true of the geometry start and
|
||
end points are coincident.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>IsRing(geometry)</term>
|
||
<listitem>
|
||
<para>Returns 1 (TRUE) if this Curve is closed (StartPoint ( ) = EndPoint ( )) and this Curve
|
||
is simple (does not pass through the same point more than once).
|
||
|
||
</para>
|
||
<para>performed by GEOS</para>
|
||
<para> OGC spec 2.1.5.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>NumGeometries(geometry)</term>
|
||
<listitem>
|
||
<para>If geometry is a GEOMETRYCOLLECTION (or MULTI*) return the number of
|
||
geometries, otherwise return NULL.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>GeometryN(geometry,int)</term>
|
||
<listitem>
|
||
<para>Return the N'th geometry if the geometry is a
|
||
GEOMETRYCOLLECTION, MULTIPOINT, MULTILINESTRING or
|
||
MULTIPOLYGON. Otherwise, return NULL.
|
||
</para>
|
||
<para>0 is 1st geometry</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Distance(geometry,geometry)</term>
|
||
<listitem>
|
||
<para>Return the cartesian distance between two geometries
|
||
in projected units.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>AsText(geometry)</term>
|
||
<listitem>
|
||
<para>Return the Well-Known Text representation of the
|
||
geometry. For example: POLYGON(0 0,0 1,1 1,1 0,0 0)
|
||
</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>SRID(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the integer SRID number of the spatial
|
||
reference system of the geometry.
|
||
</para>
|
||
<para>OGC SPEC s2.1.1.1</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>GeometryFromText(varchar, integer)</term>
|
||
<listitem>
|
||
<para>Syntax: GeometryFromText(<geometry>,<SRID>)
|
||
Convert a Well-Known Text representation of a geometry
|
||
into a geometry object.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>GeomFromText(varchar, integer)</term>
|
||
<listitem>
|
||
<para>As above. A synonym for GeometryFromText.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>SetSRID(geometry)</term>
|
||
<listitem>
|
||
<para>Set the SRID on a geometry to a particular integer
|
||
value. Useful in constructing bounding boxes for queries.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>EndPoint(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the last point of the geometry as a point.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>StartPoint(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the first point of the geometry as a point.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>Centroid(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the centroid of the geometry as a point.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect1>
|
||
<sect1>
|
||
<title>Other Functions</title>
|
||
<variablelist>
|
||
<varlistentry>
|
||
<term>A &< B</term>
|
||
<listitem>
|
||
<para>The "&<" operator returns true if A's bounding box
|
||
overlaps or is to the left of B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A &> B</term>
|
||
<listitem>
|
||
<para>The "&>" operator returns true if A's bounding box
|
||
overlaps or is to the right of B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A << B</term>
|
||
<listitem>
|
||
<para>The "<<" operator returns true if A's bounding box is
|
||
strictly to the left of B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A >> B</term>
|
||
<listitem>
|
||
<para>The ">>" operator returns true if A's bounding box is
|
||
strictly to the right of B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A ~= B</term>
|
||
<listitem>
|
||
<para>The "~=" operator is the "same as" operator. It tests actual
|
||
geometric equality of two features. So if A and B are the same feature,
|
||
vertex-by-vertex, the operator returns true.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A @ B</term>
|
||
<listitem>
|
||
<para>The "@" operator returns true if A's bounding box is
|
||
completely contained by B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A ~ B</term>
|
||
<listitem>
|
||
<para>The "~" operator returns true if A's bounding box
|
||
completely contains B's bounding box.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>A && B</term>
|
||
<listitem>
|
||
<para>The "&&" operator is the "overlaps" operator. If A's
|
||
bounding boux overlaps B's bounding box the operator returns true.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>area2d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the area of the geometry if it is a polygon or
|
||
multi-polygon.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>area(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the area of the geometry if it is a polygon or
|
||
multi-polygon. (same as area2(<polygon|multipolygon>)
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>asbinary(geometry,'NDR')</term>
|
||
<listitem>
|
||
<para>Returns the geometry in the OGC "well-known-binary" format,
|
||
using little-endian encoding. This is useful in binary cursors to pull data out
|
||
of the database without converting it to a string representation.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>isvalid(geometry)</term>
|
||
<listitem>
|
||
<para>returns true if this geometry is valid.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>asbinary(geometry,'XDR')</term>
|
||
<listitem>
|
||
<para>Returns the geometry in the OGC "well-known-binary" format,
|
||
using big-endian encoding. This is useful in binary cursors to pull data out of
|
||
the database without converting it to a string representation.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>GeomFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>GeometryFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PointFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a Point</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>LineFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a Line</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>LinestringFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a Line</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
|
||
<varlistentry>
|
||
<term>PolyFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a Polygon</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PolygonFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a Polygon</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MPointFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a MULTIPOINT</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MLineFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a MULTILINESTRING</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MPolyFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a MULTIPOLYGON</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>GeomCollFromText(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> Throws an error if the WKT is not a GEOMETRYCOLLECTION</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>GeomFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>GeometryFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PointFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a POINT </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>LineFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a LINESTRING </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>LinestringFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> from the conformance suite</para>
|
||
<para> throws an error if WKB is not a LINESTRING </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PolyFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a POLYGON </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PolygonFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> from the conformance suite</para>
|
||
<para> throws an error if WKB is not a POLYGON </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MPointFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a MULTIPOINT </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MLineFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a MULTILINESTRING </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>MPolyFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a MULTIPOLYGON </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>GeomCollFromWKB(text,[<srid>])</term>
|
||
<listitem>
|
||
<para>Makes a Geometry from WKB with the given SRID. If SRID is not give, it defaults to -1.</para>
|
||
<para> OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
|
||
<para> throws an error if WKB is not a GEOMETRYCOLLECTION </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
<varlistentry>
|
||
<term>PointOnSurface(geometry)</term>
|
||
<listitem>
|
||
<para>Return a Point guaranteed to lie on the surface</para>
|
||
<para>Implemented using GEOS</para>
|
||
<para> OGC SPEC 3.2.14.2 and 3.2.18.2 - </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
|
||
|
||
<varlistentry>
|
||
<term>box3d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns a BOX3D representing the maximum extents of the
|
||
geometry.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>collect(geometry)</term>
|
||
<listitem>
|
||
<para>This function returns a GEOMETRYCOLLECTION object from a set
|
||
of geometries. The collect() function is an "aggregate" function in
|
||
the terminology of PostgreSQL. That means that it operators on
|
||
lists of data, in the same way the sum() and mean() functions do.
|
||
For example, "SELECT COLLECT(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN"
|
||
will return a separate GEOMETRYCOLLECTION for each distinct value
|
||
of ATTRCOLUMN.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>distance_spheroid(point, point, spheroid)</term>
|
||
<listitem>
|
||
<para>Returns linear distance between two lat/lon points given a
|
||
particular spheroid. See the explanation of spheroids given for
|
||
<link linkend="length_spheroid">length_spheroid()</link>.
|
||
Currently only implemented for points.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>extent(geometry)</term>
|
||
<listitem>
|
||
<para>The extent() function is an "aggregate" function in the
|
||
terminology of PostgreSQL. That means that it operators on lists of data, in
|
||
the same way the sum() and mean() functions do. For example, "SELECT
|
||
EXTENT(GEOM) FROM GEOMTABLE" will return a BOX3D giving the maximum extend of
|
||
all features in the table. Similarly, "SELECT EXTENT(GEOM) FROM GEOMTABLE GROUP
|
||
BY CATEGORY" will return one extent result for each category.</para>
|
||
</listitem>
|
||
</varlistentry><varlistentry><term>find_srid(varchar,varchar,varchar)</term><listitem><para>The syntax is find_srid(<db/schema>, <table>, <column>) and the function returns the integer SRID of the specified column by searching through the GEOMETRY_COLUMNS table. If the geometry column has not been properly added with the AddGeometryColumns() function, this function will not work either.</para></listitem></varlistentry>
|
||
<varlistentry>
|
||
<term>force_collection(geometry)</term>
|
||
<listitem>
|
||
<para>Converts the geometry into a GEOMETRYCOLLECTION. This is
|
||
useful for simplifying the WKB representation.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry id="force_2d">
|
||
<term>force_2d(geometry)</term>
|
||
<listitem>
|
||
<para>Forces the geometries into a "2-dimensional mode" so that all
|
||
output representations will only have the X and Y coordinates. This is useful
|
||
for force OGC-compliant output (since OGC only specifies 2-D
|
||
geometries).</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry id="force_3d">
|
||
<term>force_3d(geometry)</term>
|
||
<listitem>
|
||
<para>Forces the geometries into a "3-dimensional mode" so that all
|
||
output representations will have the X, Y and Z coordinates.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>length2d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the 2-dimensional length of the geometry if it is a
|
||
linestring or multi-linestring.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>length(geometry)</term>
|
||
<listitem>
|
||
<para>The length of this Curve in its associated spatial reference.</para>
|
||
<para>synonym for length2d()</para>
|
||
<para>OGC SPEC 2.1.5.1 </para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>length3d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the 3-dimensional length of the geometry if it is a
|
||
linestring or multi-linestring.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry id="length_spheroid">
|
||
<term>length_spheroid(geometry,spheroid)</term>
|
||
<listitem>
|
||
<para>Calculates the length of of a geometry on an elipsoid. This
|
||
is useful if the coordinates of the geometry are in latitude/longitude and a
|
||
length is desired without reprojection. The elipsoid is a separate database
|
||
type and can be constructed as follows:
|
||
</para>
|
||
<literallayout>SPHEROID[<NAME>,<SEMI-MAJOR AXIS>,<INVERSE FLATTENING>]</literallayout>
|
||
<para>Eg:</para>
|
||
<literallayout>SPHEROID["GRS_1980",6378137,298.257222101]</literallayout>
|
||
<para>An example calculation might look like this: </para>
|
||
<literallayout>SELECT
|
||
length_spheroid(
|
||
geometry_column,
|
||
'SPHEROID["GRS_1980",6378137,298.257222101]'
|
||
)
|
||
FROM geometry_table;</literallayout>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>length3d_spheroid(geometry,spheroid)</term>
|
||
<listitem>
|
||
<para>Calculates the length of of a geometry on an elipsoid, taking
|
||
the elevation into account. This is just like length_spheroid except vertical
|
||
coordinates (expressed in the same units as the spheroid axes) are used to
|
||
calculate the extra distance vertical displacement adds.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>max_distance(linestring,linestring)</term>
|
||
<listitem>
|
||
<para>Returns the largest distance between two line strings.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>mem_size(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the amount of space (in bytes) the geometry
|
||
takes.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>npoints(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the number of points in the geometry.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>nrings(geometry)</term>
|
||
<listitem>
|
||
<para>If the geometry is a polygon or multi-polygon returns the
|
||
number of rings.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>numb_sub_objects(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the number of objects stored in the geometry. This is
|
||
useful for MULTI-geometries and GEOMETRYCOLLECTIONs.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>perimeter2d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the 2-dimensional perimeter of the geometry, if it is
|
||
a polygon or multi-polygon.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>perimeter3d(geometry)</term>
|
||
<listitem>
|
||
<para>Returns the 3-dimensional perimeter of the geometry, if it is
|
||
a polygon or multi-polygon.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>point_inside_circle(geometry,float,float,float)</term>
|
||
<listitem>
|
||
<para>The syntax for this functions is
|
||
point_inside_circle(<geometry>,<circle_center_x>,<circle_center_y>,<radius>).
|
||
Returns the true if the geometry is a point and is inside the circle. Returns
|
||
false otherwise.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>postgis_version()</term>
|
||
<listitem>
|
||
<para>Returns the version number of the PostGIS functions
|
||
installed in this database.
|
||
</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>summary(geometry)</term>
|
||
<listitem>
|
||
<para>Returns a text summary of the contents of the
|
||
geometry.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>transform(geometry,integer)</term>
|
||
<listitem>
|
||
<para>Returns a new geometry with its coordinates transformed to the SRID referenced by the integer parameter. The destination SRID must exist in the SPATIAL_REF_SYS table.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>translate(geometry,float8,float8,float8)</term>
|
||
<listitem>
|
||
<para>Translates the geometry to a new location using the numeric
|
||
parameters as offsets. Ie: translate(geom,X,Y,Z).</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>truly_inside(geometryA,geometryB)</term>
|
||
<listitem>
|
||
<para>Returns true if any part of B is within the bounding box of
|
||
A.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
<varlistentry>
|
||
<term>xmin(box3d) ymin(box3d) zmin(box3d)</term>
|
||
<listitem>
|
||
<para>Returns the requested minima of a bounding box.</para>
|
||
</listitem>
|
||
</varlistentry><varlistentry>
|
||
<term>xmax(box3d) ymax(box3d) zmax(box3d)</term>
|
||
<listitem>
|
||
<para>Returns the requested maxima of a bounding box.</para>
|
||
</listitem>
|
||
</varlistentry>
|
||
</variablelist>
|
||
</sect1>
|
||
</chapter>
|
||
</book>
|