[Git][debian-gis-team/postgis][upstream] New upstream version 3.1.0~beta2+dfsg

Bas Couwenberg gitlab at salsa.debian.org
Fri Dec 11 19:01:53 GMT 2020



Bas Couwenberg pushed to branch upstream at Debian GIS Project / postgis


Commits:
705f41a1 by Bas Couwenberg at 2020-12-11T19:36:55+01:00
New upstream version 3.1.0~beta2+dfsg
- - - - -


25 changed files:

- ChangeLog
- NEWS
- Version.config
- ci/winnie/build_postgis.sh
- ci/winnie/regress_postgis.sh
- doc/.tx/config
- doc/Makefile.in
- doc/postgis.xml
- doc/reference_relationship.xml
- doc/reference_validation.xml
- doc/usage.xml
- doc/using_postgis_dataman.xml
- + doc/using_postgis_query.xml
- extensions/address_standardizer/Makefile
- extensions/postgis_raster/Makefile
- liblwgeom/cunit/cu_geos.c
- liblwgeom/lwgeom_geos.c
- liblwgeom/lwgeom_geos_clean.c
- postgis/lwgeom_geos_clean.c
- postgis/sqldefines.h
- postgis_revision.h
- regress/core/clean.sql
- regress/core/clean_expected
- + regress/core/geos_noop.sql
- + regress/core/geos_noop_expected


Changes:

=====================================
ChangeLog
=====================================
@@ -1,3 +1,63 @@
+2020-12-11  Martin Davis <mtnclimb at gmail.com>
+
+	* doc/using_postgis_query.xml: Improve doc usage spatial rel section
+
+2020-12-08  Sandro Santilli <strk at kbt.io>
+
+	* NEWS, doc/reference_validation.xml,
+	liblwgeom/lwgeom_geos_clean.c, postgis/lwgeom_geos_clean.c,
+	regress/core/clean.sql, regress/core/clean_expected: Have
+	ST_MakeValid remove coordinates with NaN values Closes #4813
+
+2020-12-10  Martin Davis <mtnclimb at gmail.com>
+
+	* doc/using_postgis_dataman.xml: Improve doc Data Management
+	sections
+
+2020-12-10  Martin Davis <mtnclimb at gmail.com>
+
+	* doc/reference_relationship.xml: Fix doc distance function
+	descriptions
+
+2020-12-10  Regina Obe <lr at pcorp.us>
+
+	* ci/winnie/build_postgis.sh, ci/winnie/regress_postgis.sh: Get rid
+	of winnie's with --with-library-minor-version before release in prep
+	for real packaging
+
+2020-12-10  Martin Davis <mtnclimb at gmail.com>
+
+	* doc/.tx/config, doc/Makefile.in, doc/postgis.xml,
+	doc/reference_relationship.xml, doc/usage.xml,
+	doc/using_postgis_dataman.xml, doc/using_postgis_query.xml: Add doc
+	Spatial Query section
+
+2020-12-10  Martin Davis <mtnclimb at gmail.com>
+
+	* doc/using_postgis_dataman.xml: Improve doc SRS section
+
+2020-12-10  Sandro Santilli <strk at kbt.io>
+
+	* NEWS, Version.config: Target 3.1.0beta2, add NEWS item of last
+	commits
+
+2020-12-10  Sandro Santilli <strk at kbt.io>
+
+	* liblwgeom/cunit/cu_geos.c: Update unit test of geos_noop after
+	previous commit References #4814 in master branch (3.1.0dev)
+
+2020-12-10  Sandro Santilli <strk at kbt.io>
+
+	* liblwgeom/lwgeom_geos.c, regress/core/geos_noop.sql,
+	regress/core/geos_noop_expected: Do not drop empty geometry
+	components when converting to GEOS References #4814 in master branch (3.1.0dev)
+
+2020-12-10  Sandro Santilli <strk at kbt.io>
+
+	* liblwgeom/lwgeom_geos.c, regress/core/geos_noop.sql,
+	regress/core/geos_noop_expected: Fix GEOS conversion of POINT EMPTY
+	to retain type References #4815 in master branch
+
 2020-12-09  Paul Ramsey <pramsey at cleverelephant.ca>
 
 	* NEWS, README.postgis, Version.config, doc/release_notes.xml: 
@@ -38,65 +98,5 @@
 
 2020-12-07  Martin Davis <mtnclimb at gmail.com>
 
-	* doc/using_postgis_app.xml, doc/using_postgis_dataman.xml: Improve
-	Doc data management section
-
-2020-12-07  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/performance_tips.xml, doc/reference_relationship.xml,
-	doc/usage.xml, doc/using_postgis_app.xml: Misc Doc Usage changes
-
-2020-12-07  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/using_postgis_app.xml: Make Doc Using PG titles consistent
-
-2020-12-07  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/reference_relationship.xml, doc/using_postgis_dataman.xml: 
-	Improve doc for DE-9IM and relate
-
-2020-12-07  Paul Ramsey <pramsey at cleverelephant.ca>
-
-	* regress/core/in_gml.sql: Add EPSG:8857 to set of missing SRS for
-	GML test, Closes #4810w
-
-2020-12-07  Paul Ramsey <pramsey at cleverelephant.ca>
-
-	* liblwgeom/lwin_wkt.c, regress/core/tickets.sql,
-	regress/core/tickets_expected: Handle SRID=999999 consistently with
-	other high SRID numbers. Closes #4812
-
-2020-12-07  Paul Ramsey <pramsey at cleverelephant.ca>
-
-	* : commit 22cebe4b3c762ba13574e48b00c79779dcf3b190 Author: Paul
-	Ramsey <pramsey at cleverelephant.ca> Date:   Mon Dec 7 10:08:03 2020
-	-0800
-
-2020-12-07  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/database_tuning.xml: Improve Doc tuning section
-
-2020-12-07  Sandro Santilli <strk at kbt.io>
-
-	* extensions/upgradeable_versions.mk: Add support for upgrading from
-	2.5.5
-
-2020-12-06  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/reference_processing.xml: Improve Doc Ref for processing
-	functions
-
-2020-12-06  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/reference_processing.xml, doc/reference_relationship.xml: 
-	Improve Doc Ref descriptions
-
-2020-12-06  Martin Davis <mtnclimb at gmail.com>
-
-	* doc/reference_processing.xml: Improve Doc Ref for processing
-	functions
-
-2020-12-06  Martin Davis <mtnclimb at gmail.com>
-
-	* Move Doc Ref functions to better sections
+	* Improve Doc data management section
 


=====================================
NEWS
=====================================
@@ -1,6 +1,17 @@
+PostGIS 3.1.0beta2
+2020/12/DD
+Only tickets not included in 3.1.0beta1
+
+ * Enhancements *
+  - #4814, Do not drop empty geometry components when converting
+           to GEOS (Sandro Santilli)
+  - #4815, Fix GEOS conversion of POINT EMPTY to retain type
+           (Sandro Santilli)
+  - #4813, ST_MakeValid removing NaN coordinates (Sandro Santilli)
+
 PostGIS 3.1.0beta1
 2020/12/09
-Only tickets not included in 3.1.0beta1
+Only tickets not included in 3.1.0alpha3
 
  * Breaking changes *
   - #4214, Deprecated ST_Count(tablename,...), ST_ApproxCount(tablename, ...)
@@ -21,6 +32,7 @@ Only tickets not included in 3.1.0beta1
   - Fix axis order issue with urn:ogc:def:crs:EPSG in ST_GeomFromGML()
            (Even Roualt)
 
+
 PostGIS 3.1.0alpha3
 2020/11/19
 Only tickets not included in 3.1.0alpha2


=====================================
Version.config
=====================================
@@ -5,7 +5,7 @@
 
 POSTGIS_MAJOR_VERSION=3
 POSTGIS_MINOR_VERSION=1
-POSTGIS_MICRO_VERSION=0beta1
+POSTGIS_MICRO_VERSION=0beta2
 
 # Liblwgeom interface versioning, reset to 0:0:0 (cur:age:rev)
 # when changing POSTGIS_MINOR_VERSION


=====================================
ci/winnie/build_postgis.sh
=====================================
@@ -167,7 +167,7 @@ LDFLAGS="-L${PGPATH}/lib -L${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYP
   --with-libiconv=${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE} \
   --with-xsldir=${PROJECTS}/docbook/docbook-xsl-1.76.1 \
   --without-interrupt-tests \
-  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE} --with-library-minor-version
+  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE}
 fi;
 
 make clean


=====================================
ci/winnie/regress_postgis.sh
=====================================
@@ -156,7 +156,7 @@ LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${PROJECTS}/rel-libiconv-${I
   --with-gui --with-gettext=no \
   --with-sfcgal=${PROJECTS}/CGAL/rel-sfcgal-${SFCGAL_VER}w${OS_BUILD}${GCC_TYPE}/bin/sfcgal-config \
   --without-interrupt-tests \
-  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE} --with-library-minor-version
+  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE}
   #exit
 else
 CPPFLAGS="-I${PGPATH}/include -I${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/include" \
@@ -169,7 +169,7 @@ LDFLAGS="-L${PGPATH}/lib -L${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYP
   --with-libiconv=${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE} \
   --with-xsldir=${PROJECTS}/docbook/docbook-xsl-1.76.1 \
   --without-interrupt-tests \
-  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE} --with-library-minor-version
+  --prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE}
 fi;
 
 


=====================================
doc/.tx/config
=====================================
@@ -161,6 +161,11 @@ file_filter = po/<lang>/using_postgis_dataman.xml.po
 source_file = po/templates/using_postgis_dataman.xml.pot
 source_lang = en
 
+[postgis.using_postgis_querypot]
+file_filter = po/<lang>/using_postgis_query.xml.po
+source_file = po/templates/using_postgis_query.xml.pot
+source_lang = en
+
 [postgis.using_raster_datamanxmlpot]
 file_filter = po/<lang>/using_raster_dataman.xml.po
 source_file = po/templates/using_raster_dataman.xml.pot
@@ -220,4 +225,3 @@ source_lang = en
 file_filter = po/<lang>/administration.xml.po
 source_file = po/templates/administration.xml.pot
 source_lang = en
-


=====================================
doc/Makefile.in
=====================================
@@ -155,6 +155,7 @@ XML_SOURCES = \
 	reporting.xml \
 	using_postgis_app.xml \
 	using_postgis_dataman.xml \
+	using_postgis_query.xml \
 	using_raster_dataman.xml
 
 XML_GENERATED_SOURCES = \


=====================================
doc/postgis.xml
=====================================
@@ -20,6 +20,7 @@
 <!ENTITY administration SYSTEM "administration.xml">
 <!ENTITY usage SYSTEM "usage.xml">
 <!ENTITY using_postgis_dataman SYSTEM "using_postgis_dataman.xml">
+<!ENTITY using_postgis_query SYSTEM "using_postgis_query.xml">
 <!ENTITY using_raster_dataman SYSTEM "using_raster_dataman.xml">
 <!ENTITY using_postgis_app SYSTEM "using_postgis_app.xml">
 <!ENTITY performance_tips SYSTEM "performance_tips.xml">


=====================================
doc/reference_relationship.xml
=====================================
@@ -1403,7 +1403,7 @@ FROM (SELECT ST_Buffer(ST_GeomFromText('POINT(1 0.5)'), 3)  As a,
             which is not evaluated by any named predicate.
             </para>
             <para>
-             For more information refer to <xref linkend="DE-9IM" />.
+             For more information refer to <xref linkend="eval_spatial_rel" />.
             </para>
 
 			<para><emphasis role="bold">Variant 1:</emphasis> Tests if two geometries are spatially related
@@ -1498,7 +1498,7 @@ FF1FF0102
 		<title>See Also</title>
 
 		<para>
-            <xref linkend="DE-9IM" />, <xref linkend="ST_RelateMatch" />,
+            <xref linkend="eval_spatial_rel" />, <xref linkend="ST_RelateMatch" />,
             <xref linkend="ST_Contains" />, <xref linkend="ST_ContainsProperly" />,
             <xref linkend="ST_Covers" />, <xref linkend="ST_CoveredBy" />,
             <xref linkend="ST_Crosses" />, <xref linkend="ST_Disjoint" />, <xref linkend="ST_Equals" />,
@@ -1536,7 +1536,7 @@ FF1FF0102
         Intersection matrix values can be computed by <xref linkend="ST_Relate" />.
         </para>
         <para>
-        For more information refer to <xref linkend="DE-9IM" />.
+        For more information refer to <xref linkend="eval_spatial_rel" />.
         </para>
 		<para>Performed by the GEOS module</para>
 
@@ -1587,7 +1587,7 @@ SELECT pat.name AS relationship, pat.val AS pattern,
 	<!-- Optionally add a "See Also" section -->
 	<refsection>
 		<title>See Also</title>
-		<para><xref linkend="DE-9IM" />, <xref linkend="ST_Relate" /></para>
+		<para><xref linkend="eval_spatial_rel" />, <xref linkend="ST_Relate" /></para>
 	</refsection>
 </refentry>
 
@@ -2073,7 +2073,7 @@ ST_DWithin(
 				<parameter>distance_meters</parameter></paramdef>
 
 				<paramdef choice="opt"><type>boolean </type>
-				<parameter>use_spheroid</parameter></paramdef>
+				<parameter>use_spheroid = true</parameter></paramdef>
 		  </funcprototype>
 		</funcsynopsis>
 	  </refsynopsisdiv>
@@ -2085,28 +2085,28 @@ ST_DWithin(
 
 		<para>For <type>geometry</type>: The distance is specified in units defined by the
 		spatial reference system of the geometries.  For this function to make
-		sense, the source geometries must both be of the same coordinate projection,
-		having the same SRID.</para>
+		sense, the source geometries must be in the same coordinate system
+		(have the same SRID).</para>
 
-		<para>For <type>geography</type> units are in meters and measurement is
-		defaulted to <varname>use_spheroid</varname>=true, for faster check, <varname>use_spheroid</varname>=false to measure along sphere.
+		<para>For <type>geography</type>: units are in meters and distance measurement
+		defaults to <varname>use_spheroid</varname>=true.
+        For faster evaluation use <varname>use_spheroid</varname>=false to measure on the sphere.
 		</para>
 
+		<note><para>Use <xref linkend="ST_3DDWithin"/> for 3D geometries.</para></note>
+
 		<note>
-		  <para>This function call will automatically include a bounding box
-		  comparison that will make use of any indexes that are available on
+		  <para>This function call includes a bounding box
+		  comparison that makes use of any indexes that are available on
 		  the geometries.</para>
 		</note>
 
 		<note>
 		  <para>Prior to 1.3, ST_Expand was commonly used in conjunction with && and ST_Distance to
-		  achieve the same effect and in pre-1.3.4 this function was basically short-hand for that construct.
-		  From 1.3.4, ST_DWithin uses a more short-circuit distance function which should make it more efficient
-		  than prior versions for larger buffer regions.</para>
+		  test for distance, and in pre-1.3.4 this function used that logic.
+		  From 1.3.4, ST_DWithin uses a faster short-circuit distance function.</para>
 		</note>
 
-		<note><para>Use ST_3DDWithin if you have 3D geometries.</para></note>
-
 		<para>&sfs_compliant;</para>
 		<para>Availability: 1.5.0 support for geography was introduced</para>
 		<para>Enhanced: 2.1.0 improved speed for geography. See <ulink url="http://blog.opengeo.org/2012/07/12/making-geography-faster/">Making Geography faster</ulink> for details.</para>
@@ -2186,10 +2186,10 @@ SELECT b.tower_id, b.geom
 			circle with center <varname>center_x</varname>,<varname>center_y</varname>
             and radius <varname>radius</varname>.
         </para>
-		<warning><para>Does use spatial indexes. Use <xref linkend="ST_DWithin" /> instead.</para></warning>
+		<warning><para>Does not use spatial indexes. Use <xref linkend="ST_DWithin" /> instead.</para></warning>
 
 		<para>Availability: 1.2</para>
-		<para>Changed: 2.2.0 In prior versions this used to be called ST_Point_Inside_Circle</para>
+		<para>Changed: 2.2.0 In prior versions this was called ST_Point_Inside_Circle</para>
 	  </refsection>
 
 


=====================================
doc/reference_validation.xml
=====================================
@@ -320,6 +320,7 @@ SELECT ST_IsValidReason('LINESTRING(220227 150406,2220227 150407,222020 150410)'
     <para>Availability: 2.0.0</para>
     <para>Enhanced: 2.0.1, speed improvements</para>
     <para>Enhanced: 2.1.0, added support for GEOMETRYCOLLECTION and MULTIPOINT.</para>
+    <para>Enhanced: 3.1.0, added removal of Coordinates with NaN values.</para>
 
     <para>&Z_support;</para>
 


=====================================
doc/usage.xml
=====================================
@@ -3,6 +3,7 @@
   <title>PostGIS Usage</title>
 
   &using_postgis_dataman;
+  &using_postgis_query;
   &performance_tips;
   &using_postgis_app;
   &using_raster_dataman;


=====================================
doc/using_postgis_dataman.xml
=====================================
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <sect1 id="using_postgis_dbmanagement">
-  <title>Data Management and Queries</title>
+  <title>Data Management</title>
 
   <sect2 id="RefObject">
 	<title>GIS Objects</title>
@@ -524,11 +524,11 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 </sect2>
 
   <sect2>
-	<title>Using OpenGIS Standards</title>
+	<title>Spatial Metadata Tables</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,
+	<para>The OpenGIS "Simple Features Specification for SQL" defines some
+	metadata tables to describe geometry table structure and coordinate systems.
+    In order to ensure that metadata remains consistent,
 	operations such as creating and removing a spatial column are carried out
 	through special procedures defined by OpenGIS.</para>
 
@@ -541,30 +541,42 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 	<sect3 id="spatial_ref_sys">
 	  <title>The SPATIAL_REF_SYS Table and Spatial Reference Systems</title>
 
-	  <para>The spatial_ref_sys table is a PostGIS included and OGC compliant database table that lists over 3000
-			known <ulink url="http://www.sharpgis.net/post/2007/05/Spatial-references2c-coordinate-systems2c-projections2c-datums2c-ellipsoids-e28093-confusing.aspx">spatial reference systems</ulink>
-			and details needed to transform/reproject between them.</para>
+	<para>The <varname>SPATIAL_REF_SYS</varname> table used by PostGIS
+    is an OGC-compliant database table that lists over 3000
+	known <ulink url="https://en.wikipedia.org/wiki/Spatial_reference_system">spatial reference systems</ulink>
+	and details needed to transform (reproject) between them.</para>
 
-	  <para>Although the PostGIS spatial_ref_sys table contains over 3000 of the more commonly used spatial reference system definitions that can be handled by the proj library, it does not contain all known to man and you can define your own custom projection if you are familiar with proj4 constructs.  Keep in mind that most spatial reference systems are regional and have no meaning when used outside of the bounds they were intended for.</para>
+    <para>The PostGIS <varname>SPATIAL_REF_SYS</varname> table contains over 3000 of
+    the most common spatial reference system definitions that are handled by the
+    <ulink url="https://proj.org">PROJ</ulink> projection library.
+    But there are many coordinate systems that it does not contain.
+    You can define your own custom spatial reference system if you are familiar with PROJ constructs.
+    Keep in mind that most spatial reference systems are regional
+    and have no meaning when used outside of the bounds they were intended for.</para>
 
-	  <para>An excellent resource for finding spatial reference systems not defined in the core set is <ulink url="http://spatialreference.org/">http://spatialreference.org/</ulink></para>
+    <para>A resource for finding spatial reference systems not defined in the core set is <ulink url="http://spatialreference.org/">http://spatialreference.org/</ulink></para>
 
-	  <para>Some of the more commonly used spatial reference systems are: <ulink url="http://spatialreference.org/ref/epsg/4326/">4326 - WGS 84 Long Lat</ulink>,
+	  <para>Some commonly used spatial reference systems are:
+            <ulink url="http://spatialreference.org/ref/epsg/4326/">4326 - WGS 84 Long Lat</ulink>,
 			<ulink url="http://spatialreference.org/ref/epsg/4269/">4269 - NAD 83 Long Lat</ulink>,
 			<ulink url="http://spatialreference.org/ref/epsg/3395/">3395 - WGS 84 World Mercator</ulink>,
 			<ulink url="http://spatialreference.org/ref/epsg/2163/">2163 - US National Atlas Equal Area</ulink>,
-			Spatial reference systems for each NAD 83, WGS 84 UTM zone - UTM zones are one of the most ideal for measurement, but only cover 6-degree regions.
+        and the 60 WGS84 UTM zones.
+		UTM zones are one of the most ideal for measurement, but only cover 6-degree regions.
+        (To determine which UTM zone to use for your area of interest, see the <ulink url="http://trac.osgeo.org/postgis/wiki/UsersWikiplpgsqlfunctionsDistance">utmzone PostGIS plpgsql helper function</ulink>.)
 	</para>
 	<para>
-		Various US state plane spatial reference systems (meter or feet based) - usually one or 2 exists per US state.  Most of the meter ones are in the core set, but many of the
-		feet based ones or ESRI created ones you will need to pull from <ulink url="http://spatialreference.org">spatialreference.org</ulink>.
-	</para>
-	<para>
-		For details on determining which UTM zone to use for your area of interest, check out the <ulink url="http://trac.osgeo.org/postgis/wiki/UsersWikiplpgsqlfunctionsDistance">utmzone PostGIS plpgsql helper function</ulink>.
+		US states use State Plane spatial reference systems (meter or feet based) - usually one or 2 exists per state.
+        Most of the meter-based ones are in the core set, but many of the
+		feet-based ones or ESRI created ones will need to be copied from <ulink url="http://spatialreference.org">spatialreference.org</ulink>.
 	</para>
 
-	  <para>The <varname>SPATIAL_REF_SYS</varname> table definition is as
-	  follows:</para>
+	<para>You can even define non-Earth-based coordinate systems,
+    such as <ulink url="http://spatialreference.org/ref/iau2000/mars-2000/">Mars 2000</ulink>
+ This Mars coordinate system is non-planar (it's in degrees spheroidal),
+ but you can use it with the <varname>geography</varname> type to obtain length and proximity measurements in meters instead of degrees.</para>
+
+	  <para>The <varname>SPATIAL_REF_SYS</varname> table definition is:</para>
 
 	  <programlisting>CREATE TABLE spatial_ref_sys (
   srid       INTEGER NOT NULL PRIMARY KEY,
@@ -574,16 +586,15 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
   proj4text  VARCHAR(2048)
 )</programlisting>
 
-	  <para>The <varname>SPATIAL_REF_SYS</varname> columns are as
-	  follows:</para>
+	  <para>The columns are:</para>
 
 	  <variablelist>
 		<varlistentry>
-		  <term><ulink url="http://en.wikipedia.org/wiki/SRID">SRID</ulink></term>
+		  <term>SRID</term>
 
 		  <listitem>
-			<para>An integer value that uniquely identifies the Spatial
-			Referencing System (SRS) within the database.</para>
+			<para>An integer code that uniquely identifies the <ulink url="http://en.wikipedia.org/wiki/SRID">Spatial
+			Reference System</ulink> (SRS) within the database.</para>
 		  </listitem>
 		</varlistentry>
 
@@ -592,7 +603,7 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 
 		  <listitem>
 			<para>The name of the standard or standards body that is being
-			cited for this reference system. For example, "EPSG" would be a
+			cited for this reference system. For example, "EPSG" is a
 			valid <varname>AUTH_NAME</varname>.</para>
 		  </listitem>
 		</varlistentry>
@@ -634,7 +645,7 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 			<para>For a listing of EPSG projection codes and their
 			corresponding WKT representations, see <ulink
 			url="http://www.opengeospatial.org/">http://www.opengeospatial.org/</ulink>.
-			For a discussion of WKT in general, see the OpenGIS "Coordinate
+			For a discussion of SRS WKT in general, see the OpenGIS "Coordinate
 			Transformation Services Implementation Specification" at <ulink
 			url="http://www.opengeospatial.org/standards">http://www.opengeospatial.org/standards</ulink>.
 			For information on the European Petroleum Survey Group (EPSG) and
@@ -647,15 +658,15 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 		  <term>PROJ4TEXT</term>
 
 		  <listitem>
-			<para>PostGIS uses the Proj4 library to provide coordinate
+			<para>PostGIS uses the PROJ 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://trac.osgeo.org/proj/">http://trac.osgeo.org/proj/</ulink>.
+			<para>For more information see the
+            <ulink url="https://proj.org/">Proj4 web site</ulink>.
 			The <filename>spatial_ref_sys.sql</filename> file contains both
 			<varname>SRTEXT</varname> and <varname>PROJ4TEXT</varname>
 			definitions for all EPSG projections.</para>
@@ -668,7 +679,7 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
 	  <title>The GEOMETRY_COLUMNS View</title>
 
 	  <para><varname>GEOMETRY_COLUMNS</varname> is a view reading from database system catalog tables.
-	  Its structure is as follows:</para>
+	  Its structure is:</para>
 
 	  <programlisting>\d geometry_columns</programlisting>
 <screen>             View "public.geometry_columns"
@@ -682,7 +693,7 @@ The GEOMETRY type calculates a meaningless cartesian distance between Reykjavik
  srid              | integer                |
  type              | character varying(30)  |</screen>
 
-	  <para>The column meanings are:</para>
+	  <para>The columns are:</para>
 
 	  <variablelist>
 		<varlistentry>
@@ -872,10 +883,11 @@ SELECT f_table_name, f_geometry_column, srid, type
 ------------------+-------------------+------+-------
  vw_pois_ny_parks | geom              | 4326 | POINT
  vw_pois_ny_parks | geom_2160         | 2160 | POINT</screen>
- </sect3>
-
-	<sect3 id="OGC_Validity">
-	  <title>Ensuring Geometry is OpenGIS Compliant</title>
+    </sect3>
+</sect2>
+<!-- ==============================================================  -->
+<sect2 id="OGC_Validity">
+	  <title>Geometry Validation</title>
 
 	  <para>PostGIS is compliant with the Open Geospatial Consortium’s (OGC)
 	  OpenGIS Specifications.  As such, many PostGIS methods require, or more
@@ -1208,430 +1220,7 @@ gisdb=# SELECT
 		constraint checking geometry dimensions, so it is enough to specify 2
 		there.</para>
 	  </note>
-	</sect3>
-
-      <sect3 id="DE-9IM">
-        <title>Evaluating Spatial Relationships with the DE-9IM</title>
-
-        <para>
-        The OGC SFS defines a set of <emphasis>named spatial relationship predicates</emphasis> to evaluate the
-        spatial relationship between pairs of geometries.
-        PostGIS provides these as the functions
-            <xref linkend="ST_Contains" />,
-            <xref linkend="ST_Crosses" />, <xref linkend="ST_Disjoint" />, <xref linkend="ST_Equals" />,
-            <xref linkend="ST_Intersects" />, <xref linkend="ST_Overlaps" />,
-            <xref linkend="ST_Touches" />, <xref linkend="ST_Within" />.
-        It also defines the non-standard relationship predicates
-            <xref linkend="ST_Covers" />, <xref linkend="ST_CoveredBy" />,
-            and <xref linkend="ST_ContainsProperly" />.
-        </para>
-
-        <para>In some cases the named spatial relationships
-        are insufficient to  provide a desired spatial filter.
-        </para>
-
-        <informaltable frame="none" border="0">
-          <tgroup cols="1">
-            <tbody>
-              <row>
-                <entry><para><informalfigure float="1" floatstyle="left">
-                    <graphic align="left" fileref="images/de9im01.png" />
-                  </informalfigure></para><para>For example, consider a linear
-                dataset representing a road network. It may be required
-                to identify all road segments that cross
-                each other, not at a point, but in a line (perhaps to validate some business rule).
-                In this case <xref linkend="ST_Crosses" /> does not
-                provide the necessary spatial filter, since for
-                linear features it returns <varname>true</varname> only where they cross at a point.
-                </para>
-                <para>A two-step solution
-                would be to first compute the actual intersection
-                (<xref linkend="ST_Intersection" />) of pairs of road lines that spatially
-                intersect (<xref linkend="ST_Intersects" />), and then check if the intersection's
-                <xref linkend="ST_GeometryType" /> is '<varname>LINESTRING</varname>' (properly
-                dealing with cases that return
-                <varname>GEOMETRYCOLLECTION</varname>s of
-                <varname>[MULTI]POINT</varname>s,
-                <varname>[MULTI]LINESTRING</varname>s, etc.).</para>
-                <para>Clearly, a simpler and faster solution is desirable.</para></entry>
-              </row>
-            </tbody>
-          </tgroup>
-        </informaltable>
-
-        <informaltable frame="none" border="0">
-          <tgroup cols="1">
-            <tbody>
-              <row>
-                <entry><para> <informalfigure float="1" floatstyle="right">
-                    <graphic align="right" fileref="images/de9im02.png" />
-                  </informalfigure></para> <para>A second
-                example is locating
-                wharves that intersect a lake's boundary on a line and
-                where one end of the wharf is up on shore. In other
-                words, where a wharf is within but not completely contained by a
-                lake, intersects the boundary of a lake on a line, and where
-                exactly one of the wharf's endpoints is within or on the
-                boundary of the lake. It is possible to use a
-                combination of spatial predicates to find the required
-                features:</para> <itemizedlist>
-                    <listitem>
-                      <para><xref linkend="ST_Contains" />(lake, wharf) = TRUE</para>
-                    </listitem>
-
-                    <listitem>
-                      <para><xref linkend="ST_ContainsProperly" />(lake, wharf) = FALSE</para>
-                    </listitem>
-
-                    <listitem>
-                      <para><xref linkend="ST_GeometryType" />(<xref linkend="ST_Intersection" />(wharf, lake)) =
-                      'LINESTRING'</para>
-                    </listitem>
-
-                    <listitem>
-                      <para><xref linkend="ST_NumGeometries" />(<xref linkend="ST_Multi" />(<xref linkend="ST_Intersection" />(<xref linkend="ST_Boundary" />(wharf),
-                      <xref linkend="ST_Boundary" />(lake)))) = 1</para>
-
-                      <para>... but needless to say, this is quite complicated.</para>
-                    </listitem>
-                  </itemizedlist></entry>
-              </row>
-            </tbody>
-          </tgroup>
-        </informaltable>
-
-        <para>These requirements can be met by using the
-        Dimensionally Extended 9-Intersection Model (DE-9IM for short).</para>
-
-        <sect4>
-          <title>Theory</title>
-
-          <para>According to the <ulink
-          url="http://www.opengeospatial.org/standards/sfs">OpenGIS Simple
-          Features Implementation Specification for SQL</ulink>, "the basic
-          approach to comparing two geometries is to make pair-wise tests of
-          the intersections between the Interiors, Boundaries and Exteriors of
-          the two geometries and to classify the relationship between the two
-          geometries based on the entries in the resulting 'intersection'
-          matrix."</para>
-
-        <para>In the theory of point-set topology,
-        the points in a geometry embedded in 2-dimensional space
-        can be categorized into the following sets:
-        </para>
-
-          <glosslist>
-            <glossentry>
-              <glossterm>Boundary</glossterm>
-
-              <glossdef>
-                <para>The boundary of a geometry is the set of geometries of
-                the next lower dimension. For <varname>POINT</varname>s, which
-                have a dimension of 0, the boundary is the empty set. The
-                boundary of a <varname>LINESTRING</varname> is the two
-                endpoints. For <varname>POLYGON</varname>s, the boundary is
-                the linework of the exterior and interior
-                rings.</para>
-              </glossdef>
-            </glossentry>
-
-            <glossentry>
-              <glossterm>Interior</glossterm>
-
-              <glossdef>
-                <para>The interior of a geometry are those points of a
-                geometry that are not in the boundary. For
-                <varname>POINT</varname>s, the interior is the
-                point itself. The interior of a
-                <varname>LINESTRING</varname> is the set of points
-                between the endpoints. For <varname>POLYGON</varname>s, the
-                interior is the areal surface inside the polygon.</para>
-              </glossdef>
-            </glossentry>
-
-            <glossentry>
-              <glossterm>Exterior</glossterm>
-
-              <glossdef>
-                <para>The exterior of a geometry is the rest of the space
-                in which the geometry is embedded;
-                in other words, all points not in the interior or on the boundary of the geometry.
-                It is a 2-dimensional non-closed surface.
-                </para>
-              </glossdef>
-            </glossentry>
-          </glosslist>
-
-        <para>The <ulink url="http://en.wikipedia.org/wiki/DE-9IM">Dimensionally Extended 9-Intersection Model</ulink>
-        (DE-9IM) describes the spatial relationship between two geometries
-        by specifying the dimensions of the 9 intersections between the above sets for each geometry.
-        The intersection dimensions can be formally represented
-        in a 3x3 <emphasis role="bold">intersection matrix</emphasis>.
-        </para>
-
-        <para>For a geometry <emphasis>g</emphasis>
-            the <emphasis>Interior</emphasis>, <emphasis>Boundary</emphasis>, and <emphasis>Exterior</emphasis>
-            are denoted using the notation
-          <emphasis>I(g)</emphasis>, <emphasis>B(g)</emphasis>, and
-          <emphasis>E(g)</emphasis>.
-          Also, <emphasis>dim(g)</emphasis> denotes the dimension of
-          <emphasis>g</emphasis> with the domain of
-          <literal>{0,1,2,F}</literal>
-          (as computed by <xref linkend="ST_Dimension" />)
-        </para>
-
-        <itemizedlist spacing="compact">
-        <listitem>
-            <para><literal>0</literal> => point</para>
-        </listitem>
-
-        <listitem>
-            <para><literal>1</literal> => line</para>
-        </listitem>
-
-        <listitem>
-            <para><literal>2</literal> => area</para>
-        </listitem>
-
-        <listitem>
-            <para><literal>F</literal> => empty set</para>
-        </listitem>
-
-        </itemizedlist>
-
-        <para>
-          Using this notation, the intersection matrix
-          for two geometries <emphasis>a</emphasis> and <emphasis>b</emphasis> is:</para>
-
-          <informaltable tabstyle="styledtable">
-            <tgroup align="center" cols="4">
-              <thead>
-                <row>
-                  <entry></entry>
-                  <entry><emphasis role="bold">Interior</emphasis></entry>
-                  <entry><emphasis role="bold">Boundary</emphasis></entry>
-                  <entry><emphasis role="bold">Exterior</emphasis></entry>
-                </row>
-              </thead>
-
-              <tbody>
-                <row>
-                  <entry><emphasis role="bold">Interior</emphasis></entry>
-                  <entry><emphasis>dim( I(a) ∩ I(b) )</emphasis></entry>
-                  <entry><emphasis>dim( I(a) ∩ B(b) )</emphasis></entry>
-                  <entry><emphasis>dim( I(a) ∩ E(b) )</emphasis></entry>
-                </row>
-                <row>
-                  <entry><emphasis role="bold">Boundary</emphasis></entry>
-                  <entry><emphasis>dim( B(a) ∩ I(b) )</emphasis></entry>
-                  <entry><emphasis>dim( B(a) ∩ B(b) )</emphasis></entry>
-                  <entry><emphasis>dim( B(a) ∩ E(b) )</emphasis></entry>
-                </row>
-                <row>
-                  <entry><emphasis role="bold">Exterior</emphasis></entry>
-                  <entry><emphasis>dim( E(a) ∩ I(b) )</emphasis></entry>
-                  <entry><emphasis>dim( E(a) ∩ B(b) )</emphasis></entry>
-                  <entry><emphasis>dim( E(a) ∩ E(b) )</emphasis></entry>
-                </row>
-              </tbody>
-
-            </tgroup>
-          </informaltable>
-
-         <para>Visually, for two overlapping polygonal geometries, this looks like:</para>
-
-          <informaltable frame="none" border="0">
-            <tgroup cols="2">
-              <colspec colwidth="80pt" />
-
-              <tbody>
-                <row>
-                  <entry></entry>
-
-                  <entry align="center"><para><informalfigure>
-                      <graphic align="center" fileref="images/de9im04.png"
-                               valign="middle" />
-                    </informalfigure></para></entry>
-                </row>
-
-                <row>
-                  <entry align="center" valign="middle"><para><informalfigure>
-                      <graphic align="center" fileref="images/de9im03.png"
-                               valign="middle" />
-                    </informalfigure></para></entry>
-
-                  <entry><para> <informaltable tabstyle="styledtable">
-                      <tgroup align="center" cols="4">
-                        <thead valign="middle">
-                          <row>
-                            <entry></entry>
-
-                            <entry><emphasis
-                            role="bold">Interior</emphasis></entry>
-
-                            <entry><emphasis
-                            role="bold">Boundary</emphasis></entry>
-
-                            <entry><emphasis
-                            role="bold">Exterior</emphasis></entry>
-                          </row>
-                        </thead>
-
-                        <tbody valign="middle">
-                          <row>
-                            <entry spanname="de9im_a" style=""><emphasis
-                            role="bold">Interior</emphasis></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im05.png" />
-                              </informalfigure></para><para><emphasis>dim( I(a) ∩ I(b) ) =
-                            </emphasis><emphasis
-                            role="bold">2</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im06.png" />
-                              </informalfigure></para><para><emphasis>dim( I(a) ∩ B(b)  =
-                            </emphasis><emphasis
-                            role="bold">1</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im07.png" />
-                              </informalfigure></para><para><emphasis>dim( I(a) ∩ E(b) ) =
-                            </emphasis><emphasis
-                            role="bold">2</emphasis></para></entry>
-                          </row>
-
-                          <row>
-                            <entry><emphasis
-                            role="bold">Boundary</emphasis></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im08.png" />
-                              </informalfigure></para><para><emphasis>dim( B(a) ∩ I(b) ) =
-                            </emphasis><emphasis
-                            role="bold">1</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im09.png" />
-                              </informalfigure></para><para><emphasis>dim( B(a) ∩ B(b) ) =
-                            </emphasis><emphasis
-                            role="bold">0</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im10.png" />
-                              </informalfigure></para><para><emphasis>dim( B(a) ∩ E(b) ) =
-                            </emphasis><emphasis
-                            role="bold">1</emphasis></para></entry>
-                          </row>
-
-                          <row>
-                            <entry><emphasis
-                            role="bold">Exterior</emphasis></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im11.png" />
-                              </informalfigure></para><para><emphasis>dim( E(a) ∩ I(b) ) =
-                            </emphasis><emphasis
-                            role="bold">2</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im12.png" />
-                              </informalfigure></para><para><emphasis>dim( E(a) ∩ B(b) ) =
-                            </emphasis><emphasis
-                            role="bold">1</emphasis></para></entry>
-
-                            <entry><para><informalfigure>
-                                <graphic fileref="images/de9im13.png" />
-                              </informalfigure></para><para><emphasis>dim( E(a) ∩ E(b)  =
-                            </emphasis><emphasis
-                            role="bold">2</emphasis></para></entry>
-                          </row>
-                        </tbody>
-                      </tgroup>
-                    </informaltable></para></entry>
-                </row>
-              </tbody>
-            </tgroup>
-          </informaltable>
-
-          <para>Reading from left to right and top to bottom, the intersection matrix is
-          represented as the text string '<emphasis role="bold">212101212</emphasis>'.</para>
-
-          <para>
-          PostGIS provides the <xref linkend="ST_Relate" /> function
-          to compute the intersection matrix:
-          </para>
-
-          <programlisting>
-SELECT ST_Relate( 'LINESTRING (1 1, 5 5)',
-                  'POLYGON ((3 3, 3 7, 7 7, 7 3, 3 3))' );
-st_relate
------------
-1010F0212
-</programlisting>
-
-          <para>
-          To specify fully general spatial relationships,
-          an <emphasis role="bold">intersection matrix pattern</emphasis> is used.
-          This is a matrix representation augmented with the additional symbols
-          <literal>{T,*}</literal>:
-            </para>
-
-          <itemizedlist spacing="compact">
-            <listitem>
-              <para><literal>T</literal> =>
-              intersection dimension is non-empty; i.e. is in <literal>{0,1,2}</literal></para>
-            </listitem>
-
-            <listitem>
-              <para><literal>*</literal> => don't care</para>
-            </listitem>
-          </itemizedlist>
-
-          <para>Using intersection matrix patterns and the 3-parameter variant of <xref linkend="ST_Relate" />,
-          specific spatial relationships can be evaluated in a more succinct way.
-          For the first example above, the intersection matrix pattern specifying
-          two lines intersecting in a line is
-          '<emphasis role="bold">1*1***1**</emphasis>':</para>
-
-          <programlisting>-- Find road segments that intersect in a line
-SELECT a.id
-FROM roads a, roads b
-WHERE a.id != b.id
-      AND a.geom && b.geom
-      AND ST_Relate(a.geom, b.geom, '1*1***1**');</programlisting>
-
-          <para>For the second example, the intersection matrix pattern
-          specifying a line partly inside and partly outside a polygon is
-          '<emphasis role="bold">102101FF2</emphasis>':</para>
-
-          <programlisting>-- Find wharves partly on a lake's shoreline
-SELECT a.lake_id, b.wharf_id
-FROM lakes a, wharfs b
-WHERE a.geom && b.geom
-      AND ST_Relate(a.geom, b.geom, '102101FF2');</programlisting>
-
-          <para>For more information, refer to:</para>
-
-          <itemizedlist spacing="compact">
-            <listitem>
-              <para><ulink url="http://www.opengeospatial.org/standards/sfs">OpenGIS Simple
-          Features Implementation Specification for SQL</ulink> (version 1.1, section 2.1.13.2)</para>
-            </listitem>
-
-            <listitem>
-                <para><ulink url="https://en.wikipedia.org/wiki/DE-9IM">Dimensionally
-              Extended Nine-Intersection Model (DE-9IM)</ulink></para>
-            </listitem>
-            <listitem>
-              <para><ulink url="http://docs.geotools.org/latest/userguide/library/jts/dim9.html">GeoTools: Point Set Theory and the DE-9IM Matrix</ulink></para>
-            </listitem>
-          </itemizedlist>
-
-        </sect4>
-      </sect3>
-
-  </sect2>
+</sect2>
 
   <sect2 id="loading-data">
 	<title>Loading Spatial Data</title>
@@ -2398,26 +1987,24 @@ CREATE INDEX [indexname] ON [tablename]
 	  <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 sometimes does not optimize the use of GiST indexes well, so
-	  sometimes searches which should use a spatial index instead may perform a
-	  sequential scan of the whole table.</para>
+	  is built, the PostgreSQL query planner automatically decides when to use index
+	  information to speed up a query plan. Unfortunately, the
+	  query planner sometimes does not optimize the use of GiST indexes,
+      so queries end up using slow sequential scans instead of a spatial index.</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>
+	  <para>If you find your spatial indexes are not being used,
+      there are a couple things you can do:</para>
 
 	  <itemizedlist>
 		<listitem>
-		  <para>Firstly, read query plan and check your query actually tries to compute the
-			thing you need. A runaway JOIN condition, either forgotten or to the wrong table,
-			can unexpectedly bring you all of your table multiple times. To get query plan,
-			add EXPLAIN keyword in front of your query.</para>
+		  <para>Examine the query plan and check your query actually computes the
+			thing you need. An erroneous JOIN, either forgotten or to the wrong table,
+			can unexpectedly retrieve table records multiple times.
+            To get the query plan, execute with <code>EXPLAIN</code> in front of the query.</para>
 		</listitem>
 
 		<listitem>
-		  <para>Second, make sure statistics are gathered about the number
+		  <para>Make sure statistics are gathered about the number
 		  and distributions of values in a table, to provide the query planner
 		  with better information to make decisions around index usage.
 			<command>VACUUM ANALYZE</command> will compute both.</para>
@@ -2450,286 +2037,14 @@ CREATE INDEX [indexname] ON [tablename]
 
 		<listitem>
 		  <para>If <command>set enable_seqscan to off;</command> does not help your query,
-			it may happen you use a construction Postgres is not yet able to untangle.
-			A subquery with inline select is one example - you need to rewrite it to the form
-			planner can optimize, say, a LATERAL JOIN.</para>
+			the query may be using a SQL construct that the Postgres planner is not yet able to optimize.
+            It may be possible to rewrite the query in a way that the planner is able to handle.
+			For example, a subquery with an inline SELECT may not produce an efficient plan,
+            but could possibly be rewritten using a LATERAL JOIN.</para>
 		</listitem>
 
 	  </itemizedlist>
 	</sect3>
   </sect2>
 
-  <sect2>
-	<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. The SRID of 312 used in these
-	examples is purely for demonstration.  You should be using a REAL SRID listed in the the spatial_ref_sys table
-	and one that matches the projection of your data.  If your data has no spatial reference system
-	specified, you should be THINKING very thoughtfully why it doesn't and maybe it should.</para>
-	<para>If your reason is because you are modeling something that doesn't have a geographic spatial reference system defined such as the internals of a molecule
-	or the floorplan of a not yet built amusement park then that's fine.  If the location of the amusement park has been planned however, then it would make
-	sense to use a suitable planar coordinate system for that location if nothing more than to ensure the amusement part is not trespassing on already existing
-	structures.</para>
-	<para>Even in the case where you are planning a Mars expedition to transport the human race in the event of a nuclear holocaust
-and you want to map out the Mars planet for rehabitation,  you can use a non-earthly coordinate system such as <ulink url="http://spatialreference.org/ref/iau2000/mars-2000/">Mars 2000</ulink>
- make one up and insert it in the <varname>spatial_ref_sys</varname> table. Though this Mars coordinate system is a non-planar one (it's in degrees spheroidal),
- you can use it with the geography type to have your length and proximity measurements in meters instead of degrees.</para>
-
-	<sect3>
-	  <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 advantage
-	  of the GiST spatial index. Functions such as
-	  <varname>ST_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 ST_Distance(the_geom, 'SRID=312;POINT(100000 200000)') < 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>ST_Distance()</varname> calculation
-	  for each row in the table. We can avoid this by using the single step
-		index accelerated function ST_DWithin to reduce the number of distance
-		calculations required:</para>
-
-	  <programlisting>SELECT the_geom
-FROM geom_table
-WHERE ST_DWithin(the_geom, 'SRID=312;POINT(100000 200000)', 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>ST_Distance()</varname>
-	  function. Notice that the <varname>ST_MakeEnvelope</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>
-	</sect3>
-
-	<sect3 id="examples_spatial_sql">
-	  <title>Examples of Spatial SQL</title>
-
-	  <para>The examples in this section will make use of two tables, a table
-	  of linear roads, and a table of polygonal municipality boundaries. The
-	  table definitions for the <varname>bc_roads</varname> table is:</para>
-
-	  <programlisting>Column      | Type              | Description
-------------+-------------------+-------------------
-gid         | integer           | Unique ID
-name        | character varying | Road Name
-the_geom    | geometry          | Location Geometry (Linestring)</programlisting>
-
-	  <para>The table definition for the <varname>bc_municipality</varname>
-	  table is:</para>
-
-	  <programlisting>Column     | Type              | Description
------------+-------------------+-------------------
-gid        | integer           | Unique ID
-code       | integer           | Unique ID
-name       | character varying | City / Town Name
-the_geom   | geometry          | Location Geometry (Polygon)</programlisting>
-
-	  <qandaset>
-		<qandaentry id="qa_total_length_roads">
-		  <question>
-			<para>What is the total length of all roads, expressed in
-			kilometers?</para>
-		  </question>
-
-		  <answer>
-			<para>You can answer this question with a very simple piece of
-			SQL:</para>
-
-			<programlisting>SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM bc_roads;
-
-km_roads
-------------------
-70842.1243039643
-(1 row)</programlisting>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>How large is the city of Prince George, in hectares?</para>
-		  </question>
-
-		  <answer>
-			<para>This query combines an attribute condition (on the
-			municipality name) with a spatial calculation (of the
-			area):</para>
-
-			<programlisting>SELECT
-  ST_Area(the_geom)/10000 AS hectares
-FROM bc_municipality
-WHERE name = 'PRINCE GEORGE';
-
-hectares
-------------------
-32657.9103824927
-(1 row)</programlisting>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>What is the largest municipality in the province, by
-			area?</para>
-		  </question>
-
-		  <answer>
-			<para>This query brings a spatial measurement into the query
-			condition. There are several ways of approaching this problem, but
-			the most efficient is below:</para>
-
-			<programlisting>SELECT
-  name,
-  ST_Area(the_geom)/10000 AS hectares
-FROM
-  bc_municipality
-ORDER BY hectares DESC
-LIMIT 1;
-
-name           | hectares
----------------+-----------------
-TUMBLER RIDGE  | 155020.02556131
-(1 row)</programlisting>
-
-			<para>Note that in order to answer this query we have to calculate
-			the area of every polygon. If we were doing this a lot it would
-			make sense to add an area column to the table that we could
-			separately index for performance. By ordering the results in a
-			descending direction, and them using the PostgreSQL "LIMIT"
-			command we can easily pick off the largest value without using an
-			aggregate function like max().</para>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>What is the length of roads fully contained within each
-			municipality?</para>
-		  </question>
-
-		  <answer>
-			<para>This is an example of a "spatial join", because we are
-			bringing together data from two tables (doing a join) but using a
-			spatial interaction condition ("contained") as the join condition
-			rather than the usual relational approach of joining on a common
-			key:</para>
-
-			<programlisting>SELECT
-  m.name,
-  sum(ST_Length(r.the_geom))/1000 as roads_km
-FROM
-  bc_roads AS r,
-  bc_municipality AS m
-WHERE
-  ST_Contains(m.the_geom, r.the_geom)
-GROUP BY m.name
-ORDER BY roads_km;
-
-name                        | roads_km
-----------------------------+------------------
-SURREY                      | 1539.47553551242
-VANCOUVER                   | 1450.33093486576
-LANGLEY DISTRICT            | 833.793392535662
-BURNABY                     | 773.769091404338
-PRINCE GEORGE               | 694.37554369147
-...</programlisting>
-
-			<para>This query takes a while, because every road in the table is
-			summarized into the final result (about 250K roads for our
-			particular example table). For smaller overlays (several thousand
-			records on several hundred) the response can be very fast.</para>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>Create a new table with all the roads within the city of
-			Prince George.</para>
-		  </question>
-
-		  <answer>
-			<para>This is an example of an "overlay", which takes in two
-			tables and outputs a new table that consists of spatially clipped
-			or cut resultants. Unlike the "spatial join" demonstrated above,
-			this query actually creates new geometries. An overlay is like a
-			turbo-charged spatial join, and is useful for more exact analysis
-			work:</para>
-
-			<programlisting>CREATE TABLE pg_roads as
-SELECT
-  ST_Intersection(r.the_geom, m.the_geom) AS intersection_geom,
-  ST_Length(r.the_geom) AS rd_orig_length,
-  r.*
-FROM
-  bc_roads AS r,
-  bc_municipality AS m
-WHERE
-  m.name = 'PRINCE GEORGE'
-	AND ST_Intersects(r.the_geom, m.the_geom);</programlisting>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>What is the length in kilometers of "Douglas St" in
-			Victoria?</para>
-		  </question>
-
-		  <answer>
-			<programlisting>SELECT
-  sum(ST_Length(r.the_geom))/1000 AS kilometers
-FROM
-  bc_roads r,
-  bc_municipality m
-WHERE
-	r.name = 'Douglas St'
-	AND m.name = 'VICTORIA'
-	AND ST_Intersects(m.the_geom, r.the_geom);
-
-kilometers
-------------------
-4.89151904172838
-(1 row)</programlisting>
-		  </answer>
-		</qandaentry>
-
-		<qandaentry>
-		  <question>
-			<para>What is the largest municipality polygon that has a
-			hole?</para>
-		  </question>
-
-		  <answer>
-			<programlisting>SELECT gid, name, ST_Area(the_geom) AS area
-FROM bc_municipality
-WHERE ST_NRings(the_geom) > 1
-ORDER BY area DESC LIMIT 1;
-
-gid  | name         | area
------+--------------+------------------
-12   | SPALLUMCHEEN | 257374619.430216
-(1 row)</programlisting>
-		  </answer>
-		</qandaentry>
-	  </qandaset>
-	</sect3>
-  </sect2>
 </sect1>


=====================================
doc/using_postgis_query.xml
=====================================
@@ -0,0 +1,709 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sect1 id="using_postgis_query">
+  <title>Spatial 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,
+    how to use them in queries, and ensuring that
+	appropriate indexes are in place to provide good performance.
+    </para>
+
+    <sect2 id="eval_spatial_rel">
+        <title>Determining Spatial Relationships</title>
+
+        <para>Spatial relationships indicate how two geometries interact with one another.
+        They are a fundamental capability for querying geometry.
+        </para>
+
+        <sect3>
+          <title>Dimensionally Extended 9-Intersection Model</title>
+
+         <para>According to the <ulink
+          url="http://www.opengeospatial.org/standards/sfs">OpenGIS Simple
+          Features Implementation Specification for SQL</ulink>, "the basic
+          approach to comparing two geometries is to make pair-wise tests of
+          the intersections between the Interiors, Boundaries and Exteriors of
+          the two geometries and to classify the relationship between the two
+          geometries based on the entries in the resulting 'intersection'
+          matrix."</para>
+
+        <para>In the theory of point-set topology,
+        the points in a geometry embedded in 2-dimensional space are categorized into three sets:
+        </para>
+
+          <glosslist>
+            <glossentry>
+              <glossterm>Boundary</glossterm>
+
+              <glossdef>
+                <para>The boundary of a geometry is the set of geometries of
+                the next lower dimension. For <varname>POINT</varname>s, which
+                have a dimension of 0, the boundary is the empty set. The
+                boundary of a <varname>LINESTRING</varname> is the two
+                endpoints. For <varname>POLYGON</varname>s, the boundary is
+                the linework of the exterior and interior
+                rings.</para>
+              </glossdef>
+            </glossentry>
+
+            <glossentry>
+              <glossterm>Interior</glossterm>
+
+              <glossdef>
+                <para>The interior of a geometry are those points of a
+                geometry that are not in the boundary. For
+                <varname>POINT</varname>s, the interior is the
+                point itself. The interior of a
+                <varname>LINESTRING</varname> is the set of points
+                between the endpoints. For <varname>POLYGON</varname>s, the
+                interior is the areal surface inside the polygon.</para>
+              </glossdef>
+            </glossentry>
+
+            <glossentry>
+              <glossterm>Exterior</glossterm>
+
+              <glossdef>
+                <para>The exterior of a geometry is the rest of the space
+                in which the geometry is embedded;
+                in other words, all points not in the interior or on the boundary of the geometry.
+                It is a 2-dimensional non-closed surface.
+                </para>
+              </glossdef>
+            </glossentry>
+          </glosslist>
+
+        <para>The <ulink url="http://en.wikipedia.org/wiki/DE-9IM">Dimensionally Extended 9-Intersection Model</ulink>
+        (DE-9IM) describes the spatial relationship between two geometries
+        by specifying the dimensions of the 9 intersections between the above sets for each geometry.
+        The intersection dimensions can be formally represented
+        in a 3x3 <emphasis role="bold">intersection matrix</emphasis>.
+        </para>
+
+        <para>For a geometry <emphasis>g</emphasis>
+            the <emphasis>Interior</emphasis>, <emphasis>Boundary</emphasis>, and <emphasis>Exterior</emphasis>
+            are denoted using the notation
+          <emphasis>I(g)</emphasis>, <emphasis>B(g)</emphasis>, and
+          <emphasis>E(g)</emphasis>.
+          Also, <emphasis>dim(s)</emphasis> denotes the dimension of
+          a set <emphasis>s</emphasis> with the domain of
+          <literal>{0,1,2,F}</literal>:
+        </para>
+
+        <itemizedlist spacing="compact">
+        <listitem>
+            <para><literal>0</literal> => point</para>
+        </listitem>
+
+        <listitem>
+            <para><literal>1</literal> => line</para>
+        </listitem>
+
+        <listitem>
+            <para><literal>2</literal> => area</para>
+        </listitem>
+
+        <listitem>
+            <para><literal>F</literal> => empty set</para>
+        </listitem>
+
+        </itemizedlist>
+
+        <para>
+          Using this notation, the intersection matrix
+          for two geometries <emphasis>a</emphasis> and <emphasis>b</emphasis> is:</para>
+
+          <informaltable tabstyle="styledtable">
+            <tgroup align="center" cols="4">
+              <thead>
+                <row>
+                  <entry></entry>
+                  <entry><emphasis role="bold">Interior</emphasis></entry>
+                  <entry><emphasis role="bold">Boundary</emphasis></entry>
+                  <entry><emphasis role="bold">Exterior</emphasis></entry>
+                </row>
+              </thead>
+
+              <tbody>
+                <row>
+                  <entry><emphasis role="bold">Interior</emphasis></entry>
+                  <entry><emphasis>dim( I(a) ∩ I(b) )</emphasis></entry>
+                  <entry><emphasis>dim( I(a) ∩ B(b) )</emphasis></entry>
+                  <entry><emphasis>dim( I(a) ∩ E(b) )</emphasis></entry>
+                </row>
+                <row>
+                  <entry><emphasis role="bold">Boundary</emphasis></entry>
+                  <entry><emphasis>dim( B(a) ∩ I(b) )</emphasis></entry>
+                  <entry><emphasis>dim( B(a) ∩ B(b) )</emphasis></entry>
+                  <entry><emphasis>dim( B(a) ∩ E(b) )</emphasis></entry>
+                </row>
+                <row>
+                  <entry><emphasis role="bold">Exterior</emphasis></entry>
+                  <entry><emphasis>dim( E(a) ∩ I(b) )</emphasis></entry>
+                  <entry><emphasis>dim( E(a) ∩ B(b) )</emphasis></entry>
+                  <entry><emphasis>dim( E(a) ∩ E(b) )</emphasis></entry>
+                </row>
+              </tbody>
+
+            </tgroup>
+          </informaltable>
+
+         <para>Visually, for two overlapping polygonal geometries, this looks like:</para>
+
+          <informaltable frame="none" border="0">
+            <tgroup cols="2">
+              <colspec colwidth="80pt" />
+
+              <tbody>
+                <row>
+                  <entry></entry>
+
+                  <entry align="center"><para><informalfigure>
+                      <graphic align="center" fileref="images/de9im04.png"
+                               valign="middle" />
+                    </informalfigure></para></entry>
+                </row>
+
+                <row>
+                  <entry align="center" valign="middle"><para><informalfigure>
+                      <graphic align="center" fileref="images/de9im03.png"
+                               valign="middle" />
+                    </informalfigure></para></entry>
+
+                  <entry><para> <informaltable tabstyle="styledtable">
+                      <tgroup align="center" cols="4">
+                        <thead valign="middle">
+                          <row>
+                            <entry></entry>
+
+                            <entry><emphasis
+                            role="bold">Interior</emphasis></entry>
+
+                            <entry><emphasis
+                            role="bold">Boundary</emphasis></entry>
+
+                            <entry><emphasis
+                            role="bold">Exterior</emphasis></entry>
+                          </row>
+                        </thead>
+
+                        <tbody valign="middle">
+                          <row>
+                            <entry spanname="de9im_a" style=""><emphasis
+                            role="bold">Interior</emphasis></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im05.png" />
+                              </informalfigure></para><para><emphasis>dim( I(a) ∩ I(b) ) =
+                            </emphasis><emphasis
+                            role="bold">2</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im06.png" />
+                              </informalfigure></para><para><emphasis>dim( I(a) ∩ B(b)  =
+                            </emphasis><emphasis
+                            role="bold">1</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im07.png" />
+                              </informalfigure></para><para><emphasis>dim( I(a) ∩ E(b) ) =
+                            </emphasis><emphasis
+                            role="bold">2</emphasis></para></entry>
+                          </row>
+
+                          <row>
+                            <entry><emphasis
+                            role="bold">Boundary</emphasis></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im08.png" />
+                              </informalfigure></para><para><emphasis>dim( B(a) ∩ I(b) ) =
+                            </emphasis><emphasis
+                            role="bold">1</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im09.png" />
+                              </informalfigure></para><para><emphasis>dim( B(a) ∩ B(b) ) =
+                            </emphasis><emphasis
+                            role="bold">0</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im10.png" />
+                              </informalfigure></para><para><emphasis>dim( B(a) ∩ E(b) ) =
+                            </emphasis><emphasis
+                            role="bold">1</emphasis></para></entry>
+                          </row>
+
+                          <row>
+                            <entry><emphasis
+                            role="bold">Exterior</emphasis></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im11.png" />
+                              </informalfigure></para><para><emphasis>dim( E(a) ∩ I(b) ) =
+                            </emphasis><emphasis
+                            role="bold">2</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im12.png" />
+                              </informalfigure></para><para><emphasis>dim( E(a) ∩ B(b) ) =
+                            </emphasis><emphasis
+                            role="bold">1</emphasis></para></entry>
+
+                            <entry><para><informalfigure>
+                                <graphic fileref="images/de9im13.png" />
+                              </informalfigure></para><para><emphasis>dim( E(a) ∩ E(b)  =
+                            </emphasis><emphasis
+                            role="bold">2</emphasis></para></entry>
+                          </row>
+                        </tbody>
+                      </tgroup>
+                    </informaltable></para></entry>
+                </row>
+              </tbody>
+            </tgroup>
+          </informaltable>
+
+          <para>Reading from left to right and top to bottom, the intersection matrix is
+          represented as the text string '<emphasis role="bold">212101212</emphasis>'.</para>
+
+          <para>For more information, refer to:</para>
+
+          <itemizedlist spacing="compact">
+            <listitem>
+              <para><ulink url="http://www.opengeospatial.org/standards/sfs">OpenGIS Simple
+          Features Implementation Specification for SQL</ulink> (version 1.1, section 2.1.13.2)</para>
+            </listitem>
+
+            <listitem>
+                <para><ulink url="https://en.wikipedia.org/wiki/DE-9IM">Wikipedia: Dimensionally
+              Extended Nine-Intersection Model (DE-9IM)</ulink></para>
+            </listitem>
+            <listitem>
+              <para><ulink url="http://docs.geotools.org/latest/userguide/library/jts/dim9.html">GeoTools: Point Set Theory and the DE-9IM Matrix</ulink></para>
+            </listitem>
+          </itemizedlist>
+
+        </sect3>
+
+        <sect3>
+          <title>Named Spatial Relationships</title>
+
+        <para>To make it easy to determine common spatial relationships,
+        the OGC SFS defines a set of <emphasis>named spatial relationship predicates</emphasis>.
+        PostGIS provides these as the functions
+            <xref linkend="ST_Contains" />,
+            <xref linkend="ST_Crosses" />, <xref linkend="ST_Disjoint" />, <xref linkend="ST_Equals" />,
+            <xref linkend="ST_Intersects" />, <xref linkend="ST_Overlaps" />,
+            <xref linkend="ST_Touches" />, <xref linkend="ST_Within" />.
+        It also defines the non-standard relationship predicates
+            <xref linkend="ST_Covers" />, <xref linkend="ST_CoveredBy" />,
+            and <xref linkend="ST_ContainsProperly" />.
+        </para>
+        <para>Spatial predicates are usually used as conditions in SQL <code>WHERE</code> or <code>JOIN</code> clauses.
+        The named spatial predicates automatically use a spatial index if one is available,
+        so there is no need to use the bounding box operator <code>&&</code> as well.
+        For example:
+        </para>
+
+		<programlisting>
+SELECT city.name, state.name, city.geom
+FROM city JOIN state ON ST_Intersects(city.geom, state.geom);
+</programlisting>
+
+        <para>For more details and illustrations, see the
+        <ulink url="https://postgis.net/workshops/postgis-intro/spatial_relationships.html">PostGIS Workshop.</ulink></para>
+
+        </sect3>
+
+        <sect3>
+          <title>General Spatial Relationships</title>
+
+        <para>In some cases the named spatial relationships
+        are insufficient to  provide a desired spatial filter condition.
+        </para>
+
+        <informaltable frame="none" border="0">
+          <tgroup cols="1">
+            <tbody>
+              <row>
+                <entry><para><informalfigure float="1" floatstyle="left">
+                    <graphic align="left" fileref="images/de9im01.png" />
+                  </informalfigure></para><para>For example, consider a linear
+                dataset representing a road network. It may be required
+                to identify all road segments that cross
+                each other, not at a point, but in a line (perhaps to validate some business rule).
+                In this case <xref linkend="ST_Crosses" /> does not
+                provide the necessary spatial filter, since for
+                linear features it returns <varname>true</varname> only where they cross at a point.
+                </para>
+                <para>A two-step solution
+                would be to first compute the actual intersection
+                (<xref linkend="ST_Intersection" />) of pairs of road lines that spatially
+                intersect (<xref linkend="ST_Intersects" />), and then check if the intersection's
+                <xref linkend="ST_GeometryType" /> is '<varname>LINESTRING</varname>' (properly
+                dealing with cases that return
+                <varname>GEOMETRYCOLLECTION</varname>s of
+                <varname>[MULTI]POINT</varname>s,
+                <varname>[MULTI]LINESTRING</varname>s, etc.).</para>
+                <para>Clearly, a simpler and faster solution is desirable.</para></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <informaltable frame="none" border="0">
+          <tgroup cols="1">
+            <tbody>
+              <row>
+                <entry><para> <informalfigure float="1" floatstyle="right">
+                    <graphic align="right" fileref="images/de9im02.png" />
+                  </informalfigure></para> <para>A second
+                example is locating
+                wharves that intersect a lake's boundary on a line and
+                where one end of the wharf is up on shore. In other
+                words, where a wharf is within but not completely contained by a
+                lake, intersects the boundary of a lake on a line, and where
+                exactly one of the wharf's endpoints is within or on the
+                boundary of the lake. It is possible to use a
+                combination of spatial predicates to find the required
+                features:</para> <itemizedlist>
+                    <listitem>
+                      <para><xref linkend="ST_Contains" />(lake, wharf) = TRUE</para>
+                    </listitem>
+
+                    <listitem>
+                      <para><xref linkend="ST_ContainsProperly" />(lake, wharf) = FALSE</para>
+                    </listitem>
+
+                    <listitem>
+                      <para><xref linkend="ST_GeometryType" />(<xref linkend="ST_Intersection" />(wharf, lake)) =
+                      'LINESTRING'</para>
+                    </listitem>
+
+                    <listitem>
+                      <para><xref linkend="ST_NumGeometries" />(<xref linkend="ST_Multi" />(<xref linkend="ST_Intersection" />(<xref linkend="ST_Boundary" />(wharf),
+                      <xref linkend="ST_Boundary" />(lake)))) = 1</para>
+
+                      <para>... but needless to say, this is quite complicated.</para>
+                    </listitem>
+                  </itemizedlist></entry>
+              </row>
+            </tbody>
+          </tgroup>
+        </informaltable>
+
+        <para>These requirements can be met by computing the full DE-9IM intersection matrix.
+          PostGIS provides the <xref linkend="ST_Relate" /> function
+          to do this:
+          </para>
+
+          <programlisting>
+SELECT ST_Relate( 'LINESTRING (1 1, 5 5)',
+                  'POLYGON ((3 3, 3 7, 7 7, 7 3, 3 3))' );
+st_relate
+-----------
+1010F0212
+</programlisting>
+
+        <para>To test a particular spatial relationship,
+          an <emphasis role="bold">intersection matrix pattern</emphasis> is used.
+          This is the matrix representation augmented with the additional symbols
+          <literal>{T,*}</literal>:
+            </para>
+
+          <itemizedlist spacing="compact">
+            <listitem>
+              <para><literal>T</literal> =>
+              intersection dimension is non-empty; i.e. is in <literal>{0,1,2}</literal></para>
+            </listitem>
+
+            <listitem>
+              <para><literal>*</literal> => don't care</para>
+            </listitem>
+          </itemizedlist>
+
+          <para>Using intersection matrix patterns,
+          specific spatial relationships can be evaluated in a more succinct way.
+          The <xref linkend="ST_Relate" /> and the <xref linkend="ST_RelateMatch" />
+          functions can be used to test intersection matrix patterns.
+          For the first example above, the intersection matrix pattern specifying
+          two lines intersecting in a line is
+          '<emphasis role="bold">1*1***1**</emphasis>':</para>
+
+          <programlisting>-- Find road segments that intersect in a line
+SELECT a.id
+FROM roads a, roads b
+WHERE a.id != b.id
+      AND a.geom && b.geom
+      AND ST_Relate(a.geom, b.geom, '1*1***1**');</programlisting>
+
+          <para>For the second example, the intersection matrix pattern
+          specifying a line partly inside and partly outside a polygon is
+          '<emphasis role="bold">102101FF2</emphasis>':</para>
+
+          <programlisting>-- Find wharves partly on a lake's shoreline
+SELECT a.lake_id, b.wharf_id
+FROM lakes a, wharfs b
+WHERE a.geom && b.geom
+      AND ST_Relate(a.geom, b.geom, '102101FF2');</programlisting>
+
+        </sect3>
+    </sect2>
+
+	<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 advantage
+	  of the GiST spatial index. Functions such as
+	  <varname>ST_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 ST_Distance(the_geom, 'SRID=312;POINT(100000 200000)') < 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>ST_Distance()</varname> calculation
+	  for each row in the table. We can avoid this by using the single step
+		index accelerated function ST_DWithin to reduce the number of distance
+		calculations required:</para>
+
+	  <programlisting>SELECT the_geom
+FROM geom_table
+WHERE ST_DWithin(the_geom, 'SRID=312;POINT(100000 200000)', 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>ST_Distance()</varname>
+	  function. Notice that the <varname>ST_MakeEnvelope</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>
+
+	<sect2 id="examples_spatial_sql">
+	  <title>Examples of Spatial SQL</title>
+
+	  <para>The examples in this section will make use of two tables, a table
+	  of linear roads, and a table of polygonal municipality boundaries. The
+	  table definitions for the <varname>bc_roads</varname> table is:</para>
+
+	  <programlisting>Column      | Type              | Description
+------------+-------------------+-------------------
+gid         | integer           | Unique ID
+name        | character varying | Road Name
+the_geom    | geometry          | Location Geometry (Linestring)</programlisting>
+
+	  <para>The table definition for the <varname>bc_municipality</varname>
+	  table is:</para>
+
+	  <programlisting>Column     | Type              | Description
+-----------+-------------------+-------------------
+gid        | integer           | Unique ID
+code       | integer           | Unique ID
+name       | character varying | City / Town Name
+the_geom   | geometry          | Location Geometry (Polygon)</programlisting>
+
+	  <qandaset>
+		<qandaentry id="qa_total_length_roads">
+		  <question>
+			<para>What is the total length of all roads, expressed in
+			kilometers?</para>
+		  </question>
+
+		  <answer>
+			<para>You can answer this question with a very simple piece of
+			SQL:</para>
+
+			<programlisting>SELECT sum(ST_Length(the_geom))/1000 AS km_roads FROM bc_roads;
+
+km_roads
+------------------
+70842.1243039643
+(1 row)</programlisting>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>How large is the city of Prince George, in hectares?</para>
+		  </question>
+
+		  <answer>
+			<para>This query combines an attribute condition (on the
+			municipality name) with a spatial calculation (of the
+			area):</para>
+
+			<programlisting>SELECT
+  ST_Area(the_geom)/10000 AS hectares
+FROM bc_municipality
+WHERE name = 'PRINCE GEORGE';
+
+hectares
+------------------
+32657.9103824927
+(1 row)</programlisting>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>What is the largest municipality in the province, by
+			area?</para>
+		  </question>
+
+		  <answer>
+			<para>This query brings a spatial measurement into the query
+			condition. There are several ways of approaching this problem, but
+			the most efficient is below:</para>
+
+			<programlisting>SELECT
+  name,
+  ST_Area(the_geom)/10000 AS hectares
+FROM
+  bc_municipality
+ORDER BY hectares DESC
+LIMIT 1;
+
+name           | hectares
+---------------+-----------------
+TUMBLER RIDGE  | 155020.02556131
+(1 row)</programlisting>
+
+			<para>Note that in order to answer this query we have to calculate
+			the area of every polygon. If we were doing this a lot it would
+			make sense to add an area column to the table that we could
+			separately index for performance. By ordering the results in a
+			descending direction, and them using the PostgreSQL "LIMIT"
+			command we can easily pick off the largest value without using an
+			aggregate function like max().</para>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>What is the length of roads fully contained within each
+			municipality?</para>
+		  </question>
+
+		  <answer>
+			<para>This is an example of a "spatial join", because we are
+			bringing together data from two tables (doing a join) but using a
+			spatial interaction condition ("contained") as the join condition
+			rather than the usual relational approach of joining on a common
+			key:</para>
+
+			<programlisting>SELECT
+  m.name,
+  sum(ST_Length(r.the_geom))/1000 as roads_km
+FROM
+  bc_roads AS r,
+  bc_municipality AS m
+WHERE
+  ST_Contains(m.the_geom, r.the_geom)
+GROUP BY m.name
+ORDER BY roads_km;
+
+name                        | roads_km
+----------------------------+------------------
+SURREY                      | 1539.47553551242
+VANCOUVER                   | 1450.33093486576
+LANGLEY DISTRICT            | 833.793392535662
+BURNABY                     | 773.769091404338
+PRINCE GEORGE               | 694.37554369147
+...</programlisting>
+
+			<para>This query takes a while, because every road in the table is
+			summarized into the final result (about 250K roads for our
+			particular example table). For smaller overlays (several thousand
+			records on several hundred) the response can be very fast.</para>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>Create a new table with all the roads within the city of
+			Prince George.</para>
+		  </question>
+
+		  <answer>
+			<para>This is an example of an "overlay", which takes in two
+			tables and outputs a new table that consists of spatially clipped
+			or cut resultants. Unlike the "spatial join" demonstrated above,
+			this query actually creates new geometries. An overlay is like a
+			turbo-charged spatial join, and is useful for more exact analysis
+			work:</para>
+
+			<programlisting>CREATE TABLE pg_roads as
+SELECT
+  ST_Intersection(r.the_geom, m.the_geom) AS intersection_geom,
+  ST_Length(r.the_geom) AS rd_orig_length,
+  r.*
+FROM
+  bc_roads AS r,
+  bc_municipality AS m
+WHERE
+  m.name = 'PRINCE GEORGE'
+	AND ST_Intersects(r.the_geom, m.the_geom);</programlisting>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>What is the length in kilometers of "Douglas St" in
+			Victoria?</para>
+		  </question>
+
+		  <answer>
+			<programlisting>SELECT
+  sum(ST_Length(r.the_geom))/1000 AS kilometers
+FROM
+  bc_roads r,
+  bc_municipality m
+WHERE
+	r.name = 'Douglas St'
+	AND m.name = 'VICTORIA'
+	AND ST_Intersects(m.the_geom, r.the_geom);
+
+kilometers
+------------------
+4.89151904172838
+(1 row)</programlisting>
+		  </answer>
+		</qandaentry>
+
+		<qandaentry>
+		  <question>
+			<para>What is the largest municipality polygon that has a
+			hole?</para>
+		  </question>
+
+		  <answer>
+			<programlisting>SELECT gid, name, ST_Area(the_geom) AS area
+FROM bc_municipality
+WHERE ST_NRings(the_geom) > 1
+ORDER BY area DESC LIMIT 1;
+
+gid  | name         | area
+-----+--------------+------------------
+12   | SPALLUMCHEEN | 257374619.430216
+(1 row)</programlisting>
+		  </answer>
+		</qandaentry>
+	  </qandaset>
+
+  </sect2>
+</sect1>


=====================================
extensions/address_standardizer/Makefile
=====================================
@@ -30,7 +30,7 @@ POSTGIS_PGSQL_VERSION=96
 # SQL preprocessor
 SQLPP = /usr/bin/cpp -traditional-cpp -w -P
 GREP=/bin/grep
-EXTVERSION = 3.1.0beta1
+EXTVERSION = 3.1.0beta2
 MODULE_big = address_standardizer-3
 MODULEPATH    = $$libdir/address_standardizer-3
 ifeq (no,yes)
@@ -46,7 +46,7 @@ DATA_built = \
 	$(NULL)
 
 all:  sql/address_standardizer.sql sql/address_standardizer--1.0--$(EXTVERSION).sql sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--ANY--$(EXTVERSION).sql \
- sql/$(EXTENSION)_data_us.sql sql/address_standardizer--3.1.0beta1.sql sql/$(EXTENSION)_data_us--3.1.0beta1.sql  sql/$(EXTENSION)_data_us--$(EXTVERSION)--$(EXTVERSION)next.sql \
+ sql/$(EXTENSION)_data_us.sql sql/address_standardizer--3.1.0beta2.sql sql/$(EXTENSION)_data_us--3.1.0beta2.sql  sql/$(EXTENSION)_data_us--$(EXTVERSION)--$(EXTVERSION)next.sql \
 sql/$(EXTENSION)_data_us--$(EXTVERSION)next--$(EXTVERSION).sql \
 sql/test-init-extensions.sql sql/test-parseaddress.sql sql/test-standardize_address_1.sql sql/test-standardize_address_2.sql
 
@@ -74,7 +74,7 @@ sql/%.sql: %.sql.in
 		| sed -e 's|@EXTVERSION@|$(EXTVERSION)|g' \
 		> $@
 
-sql/address_standardizer--3.1.0beta1.sql: sql/address_standardizer_types.sql \
+sql/address_standardizer--3.1.0beta2.sql: sql/address_standardizer_types.sql \
     sql/address_standardizer_functions.sql
 	mkdir -p sql
 	cat $^ > $@


=====================================
extensions/postgis_raster/Makefile
=====================================
@@ -1,7 +1,7 @@
 include ../upgradeable_versions.mk
 
 EXTENSION     = postgis_raster
-EXTVERSION    = 3.1.0beta1
+EXTVERSION    = 3.1.0beta2
 MINORVERSION  = 3.1
 MODULEPATH    = $$libdir/$(EXTENSION)-3
 


=====================================
liblwgeom/cunit/cu_geos.c
=====================================
@@ -71,7 +71,7 @@ test_geos_noop(void)
 	geom_in = lwgeom_from_wkt(in_ewkt, LW_PARSER_CHECK_NONE);
 	geom_out = lwgeom_geos_noop(geom_in);
 	out_ewkt = lwgeom_to_ewkt(geom_out);
-	ASSERT_STRING_EQUAL(out_ewkt, "GEOMETRYCOLLECTION(LINESTRING(1 1,2 2),POLYGON((0 0,1 0,1 1,0 0)))");
+	ASSERT_STRING_EQUAL(out_ewkt, "GEOMETRYCOLLECTION(LINESTRING(1 1,2 2),POINT EMPTY,POLYGON((0 0,1 0,1 1,0 0)))");
 	lwfree(out_ewkt);
 	lwgeom_free(geom_in);
 	lwgeom_free(geom_out);


=====================================
liblwgeom/lwgeom_geos.c
=====================================
@@ -426,7 +426,7 @@ LWGEOM2GEOS(const LWGEOM* lwgeom, uint8_t autofix)
 		lwp = (LWPOINT*)lwgeom;
 
 		if (lwgeom_is_empty(lwgeom))
-			g = GEOSGeom_createEmptyPolygon();
+			g = GEOSGeom_createEmptyPoint();
 		else
 		{
 #if POSTGIS_GEOS_VERSION < 38
@@ -532,7 +532,7 @@ LWGEOM2GEOS(const LWGEOM* lwgeom, uint8_t autofix)
 		{
 			GEOSGeometry* g;
 
-			if (lwgeom_is_empty(lwc->geoms[i])) continue;
+			/* if (lwgeom_is_empty(lwc->geoms[i])) continue; */
 
 			g = LWGEOM2GEOS(lwc->geoms[i], 0);
 			if (!g)


=====================================
liblwgeom/lwgeom_geos_clean.c
=====================================
@@ -22,6 +22,9 @@
  *
  **********************************************************************/
 
+#include "../postgis_config.h"
+/*#define POSTGIS_DEBUG_LEVEL 4*/
+
 #include "liblwgeom.h"
 #include "lwgeom_geos.h"
 #include "liblwgeom_internal.h"
@@ -31,7 +34,6 @@
 #include <stdlib.h>
 #include <assert.h>
 
-/* #define POSTGIS_DEBUG_LEVEL 4 */
 /* #define PARANOIA_LEVEL 2 */
 #undef LWGEOM_PROFILE_MAKEVALID
 
@@ -116,6 +118,36 @@ LWGEOM* lwline_make_geos_friendly(LWLINE* line);
 LWGEOM* lwpoly_make_geos_friendly(LWPOLY* poly);
 POINTARRAY* ring_make_geos_friendly(POINTARRAY* ring);
 
+static void
+ptarray_strip_nan_coords_in_place(POINTARRAY *pa)
+{
+	uint32_t i, j = 0;
+	POINT4D *p, *np;
+	int ndims = FLAGS_NDIMS(pa->flags);
+	for ( i = 0; i < pa->npoints; i++ )
+	{
+		int isnan = 0;
+		p = (POINT4D *)(getPoint_internal(pa, i));
+		if ( isnan(p->x) || isnan(p->y) ) isnan = 1;
+		else if (ndims > 2 && isnan(p->z) ) isnan = 1;
+		else if (ndims > 3 && isnan(p->m) ) isnan = 1;
+		if ( isnan ) continue;
+
+		np = (POINT4D *)(getPoint_internal(pa, j++));
+		if ( np != p ) {
+			np->x = p->x;
+			np->y = p->y;
+			if (ndims > 2)
+				np->z = p->z;
+			if (ndims > 3)
+				np->m = p->m;
+		}
+	}
+	pa->npoints = j;
+}
+
+
+
 /*
  * Ensure the geometry is "structurally" valid
  * (enough for GEOS to accept it)
@@ -129,10 +161,8 @@ lwgeom_make_geos_friendly(LWGEOM* geom)
 	switch (geom->type)
 	{
 	case POINTTYPE:
-	case MULTIPOINTTYPE:
-		/* a point is always valid */
+		ptarray_strip_nan_coords_in_place(((LWPOINT*)geom)->point);
 		return geom;
-		break;
 
 	case LINETYPE:
 		/* lines need at least 2 points */
@@ -147,6 +177,7 @@ lwgeom_make_geos_friendly(LWGEOM* geom)
 	case MULTILINETYPE:
 	case MULTIPOLYGONTYPE:
 	case COLLECTIONTYPE:
+	case MULTIPOINTTYPE:
 		return lwcollection_make_geos_friendly((LWCOLLECTION*)geom);
 		break;
 
@@ -170,8 +201,7 @@ lwgeom_make_geos_friendly(LWGEOM* geom)
  * constructed POINTARRAY.
  * TODO: move in ptarray.c
  */
-POINTARRAY* ptarray_close2d(POINTARRAY* ring);
-POINTARRAY*
+static POINTARRAY*
 ptarray_close2d(POINTARRAY* ring)
 {
 	POINTARRAY* newring;
@@ -193,6 +223,8 @@ ring_make_geos_friendly(POINTARRAY* ring)
 	POINTARRAY* closedring;
 	POINTARRAY* ring_in = ring;
 
+	ptarray_strip_nan_coords_in_place(ring_in);
+
 	/* close the ring if not already closed (2d only) */
 	closedring = ptarray_close2d(ring);
 	if (closedring != ring) ring = closedring;
@@ -259,6 +291,8 @@ lwline_make_geos_friendly(LWLINE* line)
 {
 	LWGEOM* ret;
 
+	ptarray_strip_nan_coords_in_place(line->points);
+
 	if (line->points->npoints == 1) /* 0 is fine, 2 is fine */
 	{
 #if 1
@@ -858,6 +892,8 @@ lwgeom_make_valid(LWGEOM* lwgeom_in)
 	GEOSGeometry* geosout;
 	LWGEOM* lwgeom_out;
 
+	LWDEBUG(1, "lwgeom_make_valid enter");
+
 	is3d = FLAGS_GET_Z(lwgeom_in->flags);
 
 	/*
@@ -867,7 +903,9 @@ lwgeom_make_valid(LWGEOM* lwgeom_in)
 
 	initGEOS(lwgeom_geos_error, lwgeom_geos_error);
 
-	lwgeom_out = lwgeom_in;
+	lwgeom_out = lwgeom_make_geos_friendly(lwgeom_in);
+	if (!lwgeom_out) lwerror("Could not make a geos friendly geometry out of input");
+
 	geosgeom = LWGEOM2GEOS(lwgeom_out, 1);
 	if (!geosgeom)
 	{
@@ -876,8 +914,6 @@ lwgeom_make_valid(LWGEOM* lwgeom_in)
 			 " - will try cleaning that up first",
 			 lwgeom_geos_errmsg);
 
-		lwgeom_out = lwgeom_make_geos_friendly(lwgeom_out);
-		if (!lwgeom_out) lwerror("Could not make a valid geometry out of input");
 
 		/* try again as we did cleanup now */
 		/* TODO: invoke LWGEOM2GEOS directly with autoclean ? */


=====================================
postgis/lwgeom_geos_clean.c
=====================================
@@ -27,7 +27,10 @@
 #include "fmgr.h"
 #include "funcapi.h"
 
+
 #include "../postgis_config.h"
+/*#define POSTGIS_DEBUG_LEVEL 4*/
+
 #include "lwgeom_geos.h"
 #include "liblwgeom.h"
 #include "lwgeom_pg.h"
@@ -35,8 +38,6 @@
 #include <string.h>
 #include <assert.h>
 
-/* #define POSTGIS_DEBUG_LEVEL 4 */
-
 Datum ST_MakeValid(PG_FUNCTION_ARGS);
 PG_FUNCTION_INFO_V1(ST_MakeValid);
 Datum ST_MakeValid(PG_FUNCTION_ARGS)
@@ -47,6 +48,8 @@ Datum ST_MakeValid(PG_FUNCTION_ARGS)
 	in = PG_GETARG_GSERIALIZED_P(0);
 	lwgeom_in = lwgeom_from_gserialized(in);
 
+	POSTGIS_DEBUG(1, "ST_MakeValid enter");
+
 	switch ( lwgeom_in->type )
 	{
 	case POINTTYPE:


=====================================
postgis/sqldefines.h
=====================================
@@ -10,7 +10,7 @@
 #define POSTGIS_PGSQL_HR_VERSION 9.6
 #define POSTGIS_GEOS_VERSION 36
 #define POSTGIS_PROJ_VERSION 72
-#define POSTGIS_LIB_VERSION '3.1.0beta1'
+#define POSTGIS_LIB_VERSION '3.1.0beta2'
 #define POSTGIS_LIBXML2_VERSION 2.9.10
 #define POSTGIS_SFCGAL_VERSION 10308
 
@@ -40,7 +40,7 @@
  * won't substitute within apostrophes)
  */
 #define _POSTGIS_SQL_SELECT_POSTGIS_VERSION 'SELECT ''3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1''::text AS version'
-#define _POSTGIS_SQL_SELECT_POSTGIS_BUILD_DATE 'SELECT ''2020-12-10 00:05:53''::text AS version'
+#define _POSTGIS_SQL_SELECT_POSTGIS_BUILD_DATE 'SELECT ''2020-12-11 17:45:04''::text AS version'
 #define _POSTGIS_SQL_SELECT_POSTGIS_PGSQL_VERSION 'SELECT ''96''::text AS version'
 
 #ifdef POSTGIS_REVISION
@@ -50,9 +50,9 @@
 * which means we need to then trim it to get rid of the extra spaces we added.
 * Maybe someone smarter can come up with a less goofy solution that makes all OS happy
 */
-#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT trim('3.1.0beta1'::text || $rev$ POSTGIS_REVISION $rev$) AS version $$
+#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT trim('3.1.0beta2'::text || $rev$ POSTGIS_REVISION $rev$) AS version $$
 #else
-#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '3.1.0beta1'::text AS version $$
+#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '3.1.0beta2'::text AS version $$
 #endif
 
 #define SRID_USR_MAX 998999


=====================================
postgis_revision.h
=====================================
@@ -1 +1 @@
-#define POSTGIS_REVISION 721a0b7
+#define POSTGIS_REVISION f3e3eb8


=====================================
regress/core/clean.sql
=====================================
@@ -49,4 +49,46 @@ SELECT '#1719.1', ST_AsEWKT(ST_MakeValid('POINT(0 0)'));
 SELECT '#1719.2', ST_AsEWKT(ST_Normalize(ST_MakeValid('GEOMETRYCOLLECTION(POINT(0 0),MULTIPOINT(3 4,5 2),LINESTRING(4 4, 4 4),POLYGON((0 0,10 10,0 10,10 0,0 0)))')));
 SELECT '#1719.3', ST_AsEWKT(ST_MakeValid('MULTIPOINT(3 4,5 2)'));
 
+
+SELECT '#4813.0', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakePoint('NaN', 'NaN'), 4326)));
+SELECT '#4813.1', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_Collect(p), 4326))) FROM (
+		SELECT ST_MakePoint('NaN', 'NaN') as p UNION ALL
+		SELECT ST_MakePoint(1, 0) as p UNION ALL
+		SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+		SELECT ST_MakePoint(10, 10) UNION ALL
+		SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+		SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+		SELECT ST_MakePoint('NaN', 'NaN')
+) foo;
+SELECT '#4813.10', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakeLine(p), 4326))) FROM (
+	SELECT ST_MakePoint('NaN', 'NaN') as p
+) foo;
+SELECT '#4813.11', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakeLine(p), 4326))) FROM (
+	SELECT ST_MakePoint(1, 0) as p UNION ALL
+	SELECT ST_MakePoint('NaN', 'NaN')
+) foo;
+SELECT '#4813.12', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakeLine(p), 4326))) FROM (
+	SELECT ST_MakePoint(1, 0) as p UNION ALL
+	SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+	SELECT ST_MakePoint(2, 0)
+) foo;
+SELECT '#4813.13', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakeLine(p), 4326))) FROM (
+	SELECT ST_MakePoint(1, 0) as p UNION ALL
+	SELECT ST_MakePoint(2, 0) UNION ALL
+	SELECT ST_MakePoint('NaN', 'NaN')
+) foo;
+SELECT '#4813.20', ST_AsEWKT(ST_MakeValid(ST_SetSRID(ST_MakePolygon(r), 4326))) FROM (
+	SELECT ST_MakeLine(p) as r FROM (
+			SELECT ST_MakePoint(1, 0) as p UNION ALL
+			SELECT ST_MakePoint(10, 0) UNION ALL
+			SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+			SELECT ST_MakePoint(10, 10) UNION ALL
+			SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+			SELECT ST_MakePoint(0, 10) UNION ALL
+			SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+			SELECT ST_MakePoint('NaN', 'NaN') UNION ALL
+			SELECT ST_MakePoint(1, 0)
+	) foo
+) bar;
+
 DROP TABLE clean_cases;


=====================================
regress/core/clean_expected
=====================================
@@ -29,3 +29,10 @@ RT|17.1|t|t|f
 #1719.1|POINT(0 0)
 #1719.2|GEOMETRYCOLLECTION(MULTIPOLYGON(((0 10,10 10,5 5,0 10)),((0 0,5 5,10 0,0 0))),MULTIPOINT(5 2,3 4),POINT(4 4),POINT(0 0))
 #1719.3|MULTIPOINT(3 4,5 2)
+#4813.0|SRID=4326;POINT EMPTY
+#4813.1|SRID=4326;MULTIPOINT(EMPTY,1 0,EMPTY,10 10,EMPTY,EMPTY,EMPTY)
+#4813.10|SRID=4326;LINESTRING EMPTY
+#4813.11|SRID=4326;POINT(1 0)
+#4813.12|SRID=4326;LINESTRING(1 0,2 0)
+#4813.13|SRID=4326;LINESTRING(1 0,2 0)
+#4813.20|SRID=4326;POLYGON((1 0,10 0,10 10,0 10,1 0))


=====================================
regress/core/geos_noop.sql
=====================================
@@ -0,0 +1,12 @@
+SELECT
+	--ST_AsEWKT(g),
+	ST_AsEWKT(postgis_geos_noop(g)) FROM ( VALUES
+('SRID=4326;POINT EMPTY'),
+('SRID=4326;MULTIPOINT EMPTY'),
+('SRID=4326;LINESTRING EMPTY'),
+('SRID=4326;MULTILINESTRING EMPTY'),
+('SRID=4326;POLYGON EMPTY'),
+('SRID=4326;MULTIPOLYGON EMPTY'),
+('SRID=4326;GEOMETRYCOLLECTION EMPTY'),
+('SRID=4326;GEOMETRYCOLLECTION(POINT EMPTY, LINESTRING EMPTY, POLYGON EMPTY, GEOMETRYCOLLECTION EMPTY)')
+) as foo(g);


=====================================
regress/core/geos_noop_expected
=====================================
@@ -0,0 +1,8 @@
+SRID=4326;POINT EMPTY
+SRID=4326;MULTIPOINT EMPTY
+SRID=4326;LINESTRING EMPTY
+SRID=4326;MULTILINESTRING EMPTY
+SRID=4326;POLYGON EMPTY
+SRID=4326;MULTIPOLYGON EMPTY
+SRID=4326;GEOMETRYCOLLECTION EMPTY
+SRID=4326;GEOMETRYCOLLECTION(POINT EMPTY,LINESTRING EMPTY,POLYGON EMPTY,GEOMETRYCOLLECTION EMPTY)



View it on GitLab: https://salsa.debian.org/debian-gis-team/postgis/-/commit/705f41a1820a3c3ee035cb2d3fea34aabbd4d4a2

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/postgis/-/commit/705f41a1820a3c3ee035cb2d3fea34aabbd4d4a2
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20201211/26e51c5b/attachment-0001.html>


More information about the Pkg-grass-devel mailing list