</varlistentry>
</variablelist>
</sect2>
- <sect2>
- <title>Using Minnesota 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>
- <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>
</sect1>
<sect1>
<title>Building Indexes</title>
that need to be done.
</para>
</sect2>
+ </sect1>
+ <sect1>
+ <title>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>Using Complex Queries in Mapserver</title>
- <para><emphasis>coming soon...</emphasis></para>
+ <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 road_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>
<sect1>
<title>Java Clients (JDBC)</title>
<para>Java clients can access PostGIS "geometry" objects in the