[postgis] 01/02: Import upstream version 2.1.2.

Markus Wanner markus_wanner-guest at moszumanska.debian.org
Mon Mar 31 07:41:00 UTC 2014


This is an automated email from the git hooks/post-receive script.

markus_wanner-guest pushed a commit to branch master
in repository postgis.

commit e0c5fb3c590cfef8ad03407673628c39039a1ee3
Author: Markus Wanner <markus at bluegap.ch>
Date:   Mon Mar 31 09:39:30 2014 +0200

    Import upstream version 2.1.2.
---
 .travis.yml                                        |  27 +-
 ChangeLog                                          | 523 +++++++++++++++++++++
 NEWS                                               |  40 ++
 README.postgis                                     |   4 +-
 Version.config                                     |   2 +-
 aclocal.m4                                         |   2 +-
 configure                                          |  20 +-
 configure.ac                                       |  11 +-
 doc/Makefile                                       |  24 +-
 doc/Makefile.comments                              |   4 +-
 doc/Makefile.in                                    |  10 +-
 doc/extras_topology.xml                            | 118 ++++-
 doc/faq.xml                                        |  11 +-
 doc/html/image_src/Makefile                        |   4 +-
 doc/postgis.xml                                    |   4 +-
 doc/postgis_comments.sql                           |  20 +-
 doc/reference_constructor.xml                      |  32 +-
 doc/reference_measure.xml                          |   2 +-
 doc/release_notes.xml                              |  36 ++
 doc/topology_comments.sql                          |   4 +
 doc/using_postgis_dataman.xml                      |  25 +-
 doc/using_raster_dataman.xml                       |   5 +-
 extensions/postgis/META.json                       |   2 +-
 extensions/postgis/Makefile.in                     |  38 +-
 extensions/postgis/doc/postgis.md                  |   5 +-
 extensions/postgis/postgis.control                 |   2 +-
 .../postgis/sql_bits/postgis--unpackaged.sql.in    |   1 +
 .../postgis/sql_bits/remove_from_extension.sql.in  |   4 +-
 extensions/postgis_extension_helper.sql            |   4 +-
 extensions/postgis_extension_helper_uninstall.sql  |   4 +-
 extensions/postgis_tiger_geocoder/META.json        |   2 +-
 extensions/postgis_tiger_geocoder/Makefile.in      |   6 +
 .../doc/postgis_tiger_geocoder.md                  |   5 +-
 .../postgis_tiger_geocoder.control                 |   2 +-
 .../sql_bits/remove_from_extension.sql.in          |   2 +-
 .../sql_bits/tiger_geocoder--unpackaged.sql.in     |   1 +
 extensions/postgis_topology/META.json              |   2 +-
 extensions/postgis_topology/doc/postgis.md         |   5 +-
 .../postgis_topology/postgis_topology.control      |   2 +-
 .../sql_bits/remove_from_extension.sql.in          |   4 +-
 .../sql_bits/topology--unpackaged.sql.in           |   1 +
 extensions/upgradeable_versions.mk                 |  17 +-
 java/jdbc/Makefile                                 |   2 +-
 java/jdbc/jtssrc/pom.xml                           |   2 +-
 java/jdbc/pom.xml                                  |   2 +-
 java/jdbc/src/org/postgis/GeometryCollection.java  |   8 +-
 liblwgeom/cunit/cu_geodetic.c                      |  42 +-
 liblwgeom/cunit/cu_tree.c                          |  18 +
 liblwgeom/g_box.c                                  |  19 +-
 liblwgeom/lwgeodetic.c                             |  47 +-
 liblwgeom/lwgeodetic.h                             |  15 +-
 liblwgeom/lwgeodetic_tree.c                        | 383 ++++++++++-----
 liblwgeom/lwgeodetic_tree.h                        |   3 +
 liblwgeom/lwin_geojson.c                           |  88 ++--
 libtool                                            |  20 +-
 postgis/geography_measurement_trees.c              | 197 ++++----
 postgis/gserialized_estimate.c                     |  12 +-
 postgis/gserialized_gist_2d.c                      |  10 +-
 postgis/lwgeom_in_gml.c                            |   6 +-
 postgis/postgis.sql.in                             |  22 +-
 postgis/sqldefines.h                               |   8 +-
 postgis_svn_revision.h                             |   2 +-
 raster/doc/RFC1-SerializedFormat                   |   2 +-
 raster/doc/RFC2-WellKnownBinaryFormat              |   2 +-
 raster/rt_core/rt_api.c                            |  41 +-
 raster/rt_core/rt_api.h                            |   4 +-
 raster/rt_pg/Makefile.in                           |  12 +-
 raster/rt_pg/rt_pg.c                               |  30 +-
 raster/rt_pg/rtpostgis.sql.in                      |  36 +-
 raster/test/regress/rt_asjpeg.sql                  |   1 +
 raster/test/regress/rt_asjpeg_expected             |   1 +
 raster/test/regress/rt_aspng.sql                   |   1 +
 raster/test/regress/rt_aspng_expected              |   1 +
 raster/test/regress/rt_astiff.sql                  |   2 +
 raster/test/regress/rt_astiff_expected             |   2 +
 raster/test/regress/rt_reclass.sql                 |  25 +
 raster/test/regress/rt_reclass_expected            |   1 +
 regress/empty.sql                                  |   6 +-
 regress/in_geojson.sql                             |   3 +
 regress/in_geojson_expected                        |   1 +
 regress/in_gml.sql                                 |   2 +
 regress/in_gml_expected                            |   1 +
 regress/legacy.sql                                 |   6 +-
 regress/loader/ReprojectPts-pre.sql                |   2 +
 regress/regress_ogc.sql                            | 128 ++---
 regress/regress_proj.sql                           |   2 +-
 regress/run_test.pl                                |  67 ++-
 regress/sql-mm-curvepoly.sql                       |   6 +-
 regress/sql-mm-curvepoly_expected                  |   4 +-
 regress/tickets.sql                                |  13 +-
 regress/tickets_expected                           |   2 +
 topology/sql/export/TopoJSON.sql.in                |   2 +-
 topology/sql/populate.sql.in                       |   8 +-
 topology/sql/sqlmm.sql.in                          |  29 +-
 topology/sql/topoelement/topoelement_agg.sql.in    |   1 +
 topology/sql/topogeometry/simplify.sql.in          |   2 +-
 topology/test/Makefile                             |   2 +-
 topology/test/regress/st_createtopogeo.sql         |   1 +
 topology/test/regress/st_simplify.sql              |  32 +-
 topology/test/regress/st_simplify_expected         |   3 +
 utils/postgis_proc_upgrade.pl                      |  76 ++-
 101 files changed, 1889 insertions(+), 614 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 027f17c..31b46d6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,29 +2,15 @@
 env:
   global:
     - PGUSER=postgres
-  matrix:
-    #- GEOS_VERSION=3.4.1 
-    #- GEOS_VERSION=3.3.8
-    #- GDAL_VERSION=1.10.0
+    - RUNTESTFLAGS=-v
 before_install:
   - rm .travis.yml
-  - sudo apt-add-repository -y ppa:ubuntugis/ubuntugis-unstable
   - sudo apt-get update
-  - sudo apt-get install -qq build-essential flex autoconf libtool gfortran postgresql-server-dev-all xsltproc libjson0-dev libproj-dev dblatex xsltproc libcunit1-dev libcunit1 docbook-xsl docbook-mathml libgdal-dev libgeos-dev
+  - apt-cache search libgdal
+  - sudo apt-get install -q build-essential flex autoconf libtool gfortran postgresql-server-dev-9.1 xsltproc libjson0-dev libproj-dev dblatex xsltproc libcunit1-dev libcunit1 docbook-xsl docbook-mathml libgdal-dev libgeos-dev
   - git config --global user.name "PostGIS Travis CI"
   - git config --global user.email $HOSTNAME":not-for-mail at travis-ci.org"
-install:
-  - export LSB_RELEASE=$( lsb_release -rs )
-  #- wget -q http://stardestroyer.de/travis/geos-$GEOS_VERSION.travis.$LSB_RELEASE.tar.gz
-  #- tar xvzf geos-$GEOS_VERSION.travis.$LSB_RELEASE.tar.gz -C / 
-  #- sudo ln -s /home/travis/geos-$GEOS_VERSION/lib/libgeos_c.so.1.8.0 /usr/lib/libgeos_c.so.1
-  #- wget -q http://stardestroyer.de/travis/gdal-$GDAL_VERSION.travis.$LSB_RELEASE.tar.gz
-  #- tar xvzf gdal-$GDAL_VERSION.travis.$LSB_RELEASE.tar.gz -C / 
-  #- LD_LIBRARY_PATH="/home/travis/geos-$GEOS_VERSION/lib:/home/travis/gdal-$GDAL_VERSION/lib"
-  #- LD_RUN_PATH="/home/travis/geos-$GEOS_VERSION/lib:/home/travis/gdal-$GDAL_VERSION/lib"
   - ./autogen.sh
-  # - ./configure --with-geosconfig=/home/travis/geos-$GEOS_VERSION/bin/geos-config --with-gdalconfig=/home/travis/gdal-$GDAL_VERSION/bin/gdal-config
-  - ./configure
 language: c
 compiler:
   - gcc
@@ -36,8 +22,5 @@ notifications:
     on_success: change
     on_failure: always
     use_notice: true
-script:
-  - make
-  - make check RUNTESTFLAGS=-v
-after_failure:
-  - cat /tmp/pgis_reg/*
+#after_failure:
+#  - cat /tmp/pgis_reg/*
diff --git a/ChangeLog b/ChangeLog
index e8b9442..b625b48 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,526 @@
+2014-03-28 22:10  strk
+
+	* regress/run_test.pl: Fix extension upgrade call for topology in
+	  run_test.pl
+
+2014-03-28 20:11  strk
+
+	* regress/legacy.sql: Also find uninstall_legacy.sql in :scriptdir,
+	  use \cd for 9.1 support
+
+2014-03-28 19:56  robe
+
+	* NEWS, doc/release_notes.xml: #2690 copy news to doc release
+	  notes. Be optimistic we'll release 3/31/2014
+
+2014-03-28 19:21  strk
+
+	* topology/test/regress/st_createtopogeo.sql: More spatial_ref_sys
+	  truncation during test
+
+2014-03-28 19:04  strk
+
+	* regress/legacy.sql: Have regress/legacy.sql truncate
+	  spatial_ref_sys
+
+2014-03-28 19:04  strk
+
+	* regress/legacy.sql, regress/run_test.pl: Allow using :scriptdir
+	  variable in regress tests
+	  
+	  Have legacy.sql use it to find legacy.sql.
+	  The run_test.pl script sets it using pg_config when --extensions
+	  switch is given.
+
+2014-03-28 13:04  pramsey
+
+	* regress/loader/ReprojectPts-pre.sql, regress/regress_ogc.sql,
+	  regress/regress_proj.sql: #2687, pass tests when raster/vector
+	  are co-loaded
+
+2014-03-28 12:53  strk
+
+	* extensions/postgis/Makefile.in: Extension "next" is patch-level
+	  away (#2684)
+
+2014-03-28 12:34  pramsey
+
+	* extensions/postgis/Makefile.in,
+	  extensions/upgradeable_versions.mk: #2684, upgrade extensions at
+	  the patch level
+
+2014-03-26 15:04  pramsey
+
+	* liblwgeom/lwgeodetic_tree.c: CircNode compare function needs to
+	  deference inputs
+
+2014-03-26 10:20  colivier
+
+	* postgis/lwgeom_in_gml.c, regress/in_gml.sql,
+	  regress/in_gml_expected: #2681 fix for 2.1 branch
+
+2014-03-26 10:06  pramsey
+
+	* NEWS: Add #2619
+
+2014-03-26 09:37  pramsey
+
+	* liblwgeom/lwgeodetic.c, liblwgeom/lwin_geojson.c: Quiet a pair of
+	  llvm warnings
+
+2014-03-26 09:22  pramsey
+
+	* configure.ac, liblwgeom/lwin_geojson.c, regress/in_geojson.sql,
+	  regress/in_geojson_expected: #2619, SIGSEGV in ST_GeomFromGeoJSON
+	  with empty list of coordinates
+
+2014-03-25 20:02  bergun
+
+	* java/jdbc/jtssrc/pom.xml, java/jdbc/pom.xml: #2625 updating
+	  pom.xml for 2.1.2 release
+
+2014-03-25 13:35  strk
+
+	* raster/rt_pg/Makefile.in: rtpostgis_upgrade_21_minor.sql is _not_
+	  same as 20_21
+	  
+	  Should fix make check w/out re-breaking #2674
+
+2014-03-25 12:31  pramsey
+
+	* NEWS: Update with latest changes
+
+2014-03-25 12:26  pramsey
+
+	* configure.ac: #2539, Check for json-c/json.h presence/usability
+	  before json/json.h
+
+2014-03-25 08:34  pramsey
+
+	* liblwgeom/cunit/cu_tree.c: Remove noise from test
+
+2014-03-25 08:17  pramsey
+
+	* liblwgeom/cunit/cu_tree.c, liblwgeom/lwgeodetic.c,
+	  liblwgeom/lwgeodetic.h, liblwgeom/lwgeodetic_tree.c,
+	  liblwgeom/lwgeodetic_tree.h,
+	  postgis/geography_measurement_trees.c: #2675, bad handling of
+	  multi-geometries in geography tree distance
+
+2014-03-24 17:49  strk
+
+	* NEWS, utils/postgis_proc_upgrade.pl: Fix missing operator = and
+	  hash_raster_ops opclass on raster
+	  
+	  Closes #2674
+
+2014-03-22 05:29  robe
+
+	* raster/rt_core/rt_api.h: #2620 allow kFreeBSD to be treated as
+	  FreeBSD
+
+2014-03-22 04:29  robe
+
+	* raster/rt_pg/rtpostgis.sql.in: #2674 missed the operator class
+	  hash_raster_ops in last commit
+
+2014-03-22 04:28  robe
+
+	* raster/rt_pg/rtpostgis.sql.in: #2674 raster missing availability
+	  info for some operators and functions used in equality operator
+
+2014-03-18 16:36  strk
+
+	* .travis.yml: Fix travis build by only installing postgresql 9.1
+	  (#2678)
+
+2014-03-13 21:11  robe
+
+	* doc/Makefile.in: #2609 topogeo_AddPolygon unnecessary use of
+	  DISTINCT
+
+2014-03-10 18:46  robe
+
+	* topology/sql/populate.sql.in: #2609 topogeo_AddPolygon
+	  unnecessary use of DISTINCT
+
+2014-03-09 23:16  robe
+
+	* doc/using_postgis_dataman.xml: #2558: WKT form(s) of MULTIPOINT
+	  documentation make OGC compliant
+
+2014-03-09 18:55  strk
+
+	* NEWS, configure.ac: Error out at configure time if no SQL
+	  preprocessor can be found
+	  
+	  Closes #2666
+
+2014-03-08 00:51  pramsey
+
+	* NEWS, liblwgeom/cunit/cu_geodetic.c, liblwgeom/lwgeodetic.c:
+	  #2534, st_distance is returning incorrect results for large
+	  geographies
+
+2014-03-08 00:43  pramsey
+
+	* liblwgeom/lwgeodetic.c, liblwgeom/lwgeodetic_tree.c: #2636,
+	  Regress ST_Distance_Sphere between 2.1.2dev and 2.0.4 with 2D
+
+2014-03-07 23:58  pramsey
+
+	* NEWS, liblwgeom/lwgeodetic.c: #2634, regression in sphere
+	  distance code
+
+2014-03-07 23:20  pramsey
+
+	* NEWS, liblwgeom/lwin_geojson.c: #2546, GeoJSON with string
+	  coordinates parses incorrectly
+
+2014-03-07 13:27  pramsey
+
+	* NEWS: Update for #2638
+
+2014-03-06 05:53  pramsey
+
+	* liblwgeom/cunit/cu_geodetic.c, liblwgeom/g_box.c: #2638,
+	  geography ST_Intersects bugginess with Polygon/multilinestring M
+
+2014-03-03 03:01  robe
+
+	* extensions/postgis/META.json, extensions/postgis/doc/postgis.md,
+	  extensions/postgis/sql_bits/remove_from_extension.sql.in,
+	  extensions/postgis_extension_helper.sql,
+	  extensions/postgis_extension_helper_uninstall.sql,
+	  extensions/postgis_tiger_geocoder/META.json,
+	  extensions/postgis_tiger_geocoder/doc/postgis_tiger_geocoder.md,
+	  extensions/postgis_tiger_geocoder/sql_bits/remove_from_extension.sql.in,
+	  extensions/postgis_topology/META.json,
+	  extensions/postgis_topology/doc/postgis.md,
+	  extensions/postgis_topology/sql_bits/remove_from_extension.sql.in:
+	  fix website links to go to postgis.net
+
+2014-02-25 17:54  pramsey
+
+	* postgis/geography_measurement_trees.c,
+	  postgis/gserialized_estimate.c: Fix variable decls in debugs,
+	  closes #2650
+
+2014-02-24 10:25  strk
+
+	* NEWS, postgis/postgis.sql.in: Let users without topology
+	  privileges call postgis_full_version()
+	  
+	  Closes #2655
+
+2014-02-24 07:08  strk
+
+	* NEWS, topology/sql/sqlmm.sql.in: Drop deprecated calls from
+	  topology (#2654)
+
+2014-02-24 06:41  strk
+
+	* NEWS, topology/sql/export/TopoJSON.sql.in,
+	  topology/sql/populate.sql.in, topology/sql/sqlmm.sql.in: Fully
+	  qualify calls to topology methods (#2653)
+
+2014-02-23 16:32  strk
+
+	* utils/postgis_proc_upgrade.pl: Fix AGG signatures with multi-word
+	  typenames
+	  
+	  For example... "double precision".
+	  This fixes upgrades involving drop/recreate of aggregates
+
+2014-02-23 16:32  strk
+
+	* regress/run_test.pl: Fix --extension --upgrade handling
+
+2014-02-23 16:32  strk
+
+	* regress/tickets.sql: Fix ambiguous query in tickets.sql when
+	  raster support is loaded
+	  
+	  See #2651
+
+2014-02-23 16:09  strk
+
+	* regress/run_test.pl: Add support for --extension --upgrade in
+	  run_test.pl
+
+2014-02-23 15:27  strk
+
+	* extensions/postgis/Makefile.in: Do not force extension-specific
+	  removal of objects on upgrade
+	  
+	  It should be taken care of by the upgrade scripts themselves
+
+2014-02-22 14:57  strk
+
+	* raster/rt_pg/Makefile.in, raster/rt_pg/rtpostgis.sql.in: Generate
+	  raster upgrade script using postgis_proc_upgrade
+
+2014-02-22 14:57  strk
+
+	* utils/postgis_proc_upgrade.pl: Make postgis_proc_upgrade ready to
+	  deal with rtpostgis.sql
+
+2014-02-22 09:13  strk
+
+	* NEWS, utils/postgis_proc_upgrade.pl: Soft upgrade: avoid
+	  drop/recreate of aggregates that hadn't changed
+	  
+	  Closes #2560
+
+2014-02-22 09:13  strk
+
+	* topology/sql/topoelement/topoelement_agg.sql.in: Encode
+	  availability of topology aggregates
+	  
+	  See #2560
+
+2014-02-22 09:13  strk
+
+	* raster/rt_pg/rtpostgis.sql.in: Encode availability and last
+	  change in raster aggregates
+	  
+	  See #2560
+
+2014-02-22 08:32  strk
+
+	* NEWS, topology/sql/sqlmm.sql.in: Fully qualify topology.topology
+	  (#2648)
+
+2014-02-20 05:46  robe
+
+	* doc/reference_measure.xml: #2646 typo arithmetric -> arithmetric
+	  in ST_Centroid
+
+2014-02-14 03:30  robe
+
+	* doc/using_raster_dataman.xml: #2576 Error in manual wrt
+	  using_raster RT_PLPython
+
+2014-02-14 03:23  robe
+
+	* doc/reference_constructor.xml: #2582 fix all references to -1 in
+	  constructors and change to 0 (SRID Unknown)
+
+2014-02-05 05:25  pramsey
+
+	* regress/empty.sql, regress/sql-mm-curvepoly.sql,
+	  regress/sql-mm-curvepoly_expected: #2396, wrap wkb outputting
+	  tests in explicit endianness
+
+2014-02-04 23:17  pramsey
+
+	* NEWS, postgis/gserialized_estimate.c: #2615, EstimatedExtent (and
+	  hence, underlying stats) gathering wrong bbox
+
+2014-02-04 22:43  pramsey
+
+	* NEWS, postgis/gserialized_estimate.c: #2543, invalid join
+	  selectivity error from simple query
+
+2014-02-04 19:44  pramsey
+
+	* NEWS: #2556 news entry
+
+2014-02-04 19:31  pramsey
+
+	* regress/tickets.sql, regress/tickets_expected: #2556, regression
+	  test
+
+2014-02-04 08:36  strk
+
+	* doc/extras_topology.xml: Fix ST_ModEdgeSplit documentation
+	  (#2633)
+
+2014-02-04 06:30  pramsey
+
+	* postgis/geography_measurement_trees.c: #2422, geography
+	  regression difference ST_DWithin
+	  "Fix" actually just removes tolerance-stop from the distance
+	  calculation
+	  Question of why tolerance stop fails, remains open.
+
+2014-02-04 06:05  pramsey
+
+	* postgis/geography_measurement_trees.c: Free tree on short circuit
+
+2014-02-04 06:01  pramsey
+
+	* liblwgeom/lwgeodetic_tree.c, liblwgeom/lwgeodetic_tree.h: Add
+	  circtree get point signature
+
+2014-02-04 05:56  pramsey
+
+	* doc/faq.xml, doc/using_postgis_dataman.xml: Update docs on WKB
+
+2014-02-04 05:56  pramsey
+
+	* HOWTO_RELEASE: Update SVN urls for osgeo https
+
+2014-02-04 05:47  pramsey
+
+	* postgis/geography_measurement_trees.c: #2556, ST_Intersects
+	  results depending on insert order
+
+2014-01-30 19:17  pramsey
+
+	* java/jdbc/src/org/postgis/GeometryCollection.java: #2588,
+	  GeometryCollection constructor parse defect for sub geometries
+	  (POINTM,POLYGONM,...) of GEOMETRYCOLLECTIONM (From bergun)
+
+2014-01-22 16:21  strk
+
+	* NEWS: Add notice about 2.0.0 having drop the SRID check in
+	  operator &&
+
+2014-01-17 03:46  dustymugs
+
+	* NEWS, raster/rt_core/rt_api.c: Fix the inability to open more
+	  than ~1024 unique out-db files in one process
+
+2014-01-13 22:49  strk
+
+	* NEWS, topology/sql/sqlmm.sql.in: Ensure face splitting algorithm
+	  uses the edge index (#2610)
+
+2014-01-04 17:45  dustymugs
+
+	* NEWS, raster/rt_core/rt_api.c: Remove use of void pointers in
+	  rt_raster_from_gdal_dataset to prevent void point arithemetics.
+	  Ticket #2589
+
+2014-01-01 02:18  robe
+
+	* doc/extras_topology.xml: #2593: document topology relationship
+	  functions intersects and equals.
+
+2013-12-19 17:29  strk
+
+	* extensions/postgis_tiger_geocoder/Makefile.in: Ensure output dir
+	  is created before attempting to write to it
+	  
+	  See https://travis-ci.org/postgis/postgis/builds/15654853#L1357
+
+2013-12-18 15:54  strk
+
+	* NEWS, postgis/postgis.sql.in: Do not allow installing postgis
+	  twice in the same database (#2580)
+	  
+	  Checks for the presence of a "postgis_version" function,
+	  and if found raises an exception with a message with
+	  the schema containing it.
+
+2013-12-07 14:41  dustymugs
+
+	* NEWS, raster/rt_pg/rt_pg.c, raster/test/regress/rt_reclass.sql,
+	  raster/test/regress/rt_reclass_expected: fix parsing issue of
+	  range arguments of ST_Reclass. Ticket #2555
+
+2013-11-27 16:03  dustymugs
+
+	* NEWS, raster/rt_pg/rtpostgis.sql.in,
+	  raster/test/regress/rt_asjpeg.sql,
+	  raster/test/regress/rt_asjpeg_expected,
+	  raster/test/regress/rt_aspng.sql,
+	  raster/test/regress/rt_aspng_expected,
+	  raster/test/regress/rt_astiff.sql,
+	  raster/test/regress/rt_astiff_expected: fix NULL raster handling
+	  in ST_AsPNG, ST_AsJPEG and ST_AsTIFF
+
+2013-11-21 17:24  strk
+
+	* NEWS, topology/sql/topogeometry/simplify.sql.in,
+	  topology/test/regress/st_simplify.sql,
+	  topology/test/regress/st_simplify_expected: Fix
+	  ST_Simplify(TopoGeometry) for hierarchical topogeoms (#2547)
+
+2013-11-21 16:52  strk
+
+	* doc/extras_topology.xml: Add link from TopoElement to
+	  TopoElementArray
+
+2013-11-21 16:52  strk
+
+	* raster/rt_pg/rtpostgis.sql.in: Fix dangling commutator for
+	  raster/geometry OPERATOR ~ (#2532)
+
+2013-11-20 00:17  pramsey
+
+	* NEWS, postgis/gserialized_gist_2d.c: #2494, Avoid unnecessary
+	  memory copy in gserialized_datum_get_box2df_p
+
+2013-11-16 22:35  robe
+
+	* HOWTO_RELEASE: minor tweaks to how to release
+
+2013-11-16 21:57  robe
+
+	* extensions/upgradeable_versions.mk: #2544: fix extension script
+	  (made a booboo last commit)
+
+2013-11-16 20:01  robe
+
+	* HOWTO_RELEASE, Version.config,
+	  extensions/upgradeable_versions.mk: #2544: change micro from svn
+	  to devand clarify how to release docs
+
+2013-11-12 21:40  pramsey
+
+	* liblwgeom/g_box.c: #2542, build on Centos/ RHEL 5
+
+2013-11-08 19:46  pramsey
+
+	* NEWS, Version.config: Set for next release
+
+2013-11-08 19:37  pramsey
+
+	* NEWS, README.postgis, Version.config,
+	  extensions/postgis/sql_bits/postgis--unpackaged.sql.in,
+	  extensions/postgis_tiger_geocoder/sql_bits/tiger_geocoder--unpackaged.sql.in,
+	  extensions/postgis_topology/sql_bits/topology--unpackaged.sql.in:
+	  Update all manual bits for 2.1.1 release
+
+2013-11-07 14:57  dustymugs
+
+	* NEWS, raster/rt_pg/rtpostgis.sql.in,
+	  raster/rt_pg/rtpostgis_upgrade_cleanup.sql.in,
+	  raster/test/regress/tickets.sql: Add missing operators for
+	  raster. Ticket #2532
+
+2013-11-06 16:32  strk
+
+	* NEWS, postgis/postgis.sql.in: Remove duplicated signatures
+
+2013-11-06 09:46  strk
+
+	* NEWS, liblwgeom/cunit/cu_split.c, liblwgeom/lwgeom_geos_split.c:
+	  Fix small memory leak in lwline_split_by_line (#2528)
+	  
+	  Thanks Alessandro Furieri for the report and test
+
+2013-11-06 09:42  strk
+
+	* NEWS: tab to space
+
+2013-11-06 05:12  dustymugs
+
+	* NEWS, raster/loader/raster2pgsql.c, raster/loader/raster2pgsql.h:
+	  added -k to raster2pgsql for skipping band is NODATA check
+
+2013-11-05 19:57  pramsey
+
+	* postgis/lwgeom_functions_basic.c: #2529, inconsistent behaviour
+	  in ST_FlipCoordinates
+
+2013-11-05 18:25  pramsey
+
+	* ChangeLog, NEWS, README.postgis, doc/release_notes.xml: Update
+	  doco for 2.1.1 release
+
 2013-11-05 17:58  pramsey
 
 	* extensions/postgis_tiger_geocoder/sql_bits, install-sh, postgis,
diff --git a/NEWS b/NEWS
index 5e70482..8b3cca4 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,42 @@
+
+PostGIS 2.1.2
+2014/03/31
+
+ * Important Changes *
+
+ * Bug Fixes *
+
+  - #2666, Error out at configure time if no SQL preprocessor can be found
+  - #2534, st_distance returning incorrect results for large geographies
+  - #2539, Check for json-c/json.h presence/usability before json/json.h
+  - #2543, invalid join selectivity error from simple query
+  - #2546, GeoJSON with string coordinates parses incorrectly 
+  - #2547, Fix ST_Simplify(TopoGeometry) for hierarchical topogeoms
+  - #2552, Fix NULL raster handling in ST_AsPNG, ST_AsTIFF and
+           ST_AsJPEG
+  - #2555, Fix parsing issue of range arguments of ST_Reclass
+  - #2556, geography ST_Intersects results depending on insert order
+  - #2580, Do not allow installing postgis twice in the same database
+  - #2589, Remove use of unnecessary void pointers
+  - #2607, Cannot open more than 1024 out-db files in one process
+  - #2610, Ensure face splitting algorithm uses the edge index
+  - #2615, EstimatedExtent (and hence, underlying stats) gathering wrong bbox
+  - #2619, Empty rings array in GeoJSON polygon causes crash
+  - #2634, regression in sphere distance code
+  - #2638, Geography distance on M geometries sometimes wrong
+  - #2648, #2653, Fix topology functions when "topology" is not in search_path
+  - #2654, Drop deprecated calls from topology
+  - #2655, Let users without topology privileges call postgis_full_version()
+  - #2674, Fix missing operator = and hash_raster_ops opclass on raster
+  - #2675, #2534, #2636, #2634, #2638, Geography distance issues with tree optimization
+  
+ * Enhancements *
+
+  - #2494, avoid memcopy in GiST index (hayamiz)
+  - #2560, soft upgrade: avoid drop/recreate of aggregates that hadn't changed
+
+
+
 PostGIS 2.1.1
 2013/11/08
 
@@ -448,6 +487,7 @@ PostGIS 2.0.0
     is now a view.
   - 3D analysis functions are now named with "3D" as a prefix 
     instead of a suffix (eg ST_Length3D has become ST_3DLength)
+  - Operator && does not check for SRID mismatch anymore
 
 * New Features *
   
diff --git a/README.postgis b/README.postgis
index 73068b5..68c4223 100644
--- a/README.postgis
+++ b/README.postgis
@@ -1,8 +1,8 @@
 PostGIS - Geographic Information Systems Extensions to PostgreSQL
 =================================================================
 
-:Version: 2.1.1
-:Date: 2013-11-08
+:Version: 2.1.2
+:Date: 2014-03-31
 :Website: http://postgis.net
 
 This distribution contains a module which implements GIS simple features, ties
diff --git a/Version.config b/Version.config
index 91c4a91..5fe989a 100644
--- a/Version.config
+++ b/Version.config
@@ -5,5 +5,5 @@
 
 POSTGIS_MAJOR_VERSION=2
 POSTGIS_MINOR_VERSION=1
-POSTGIS_MICRO_VERSION=1
+POSTGIS_MICRO_VERSION=2
 
diff --git a/aclocal.m4 b/aclocal.m4
index 8119f30..cc18be7 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,4 +1,4 @@
-# generated automatically by aclocal 1.13.3 -*- Autoconf -*-
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
 
 # Copyright (C) 1996-2013 Free Software Foundation, Inc.
 
diff --git a/configure b/configure
index f102512..0859da5 100755
--- a/configure
+++ b/configure
@@ -666,9 +666,9 @@ IGE_MAC_CFLAGS
 GTK_LIBS
 GTK_CFLAGS
 PKG_CONFIG
+HAVE_JSON
 JSON_LDFLAGS
 JSON_CPPFLAGS
-HAVE_JSON
 PROJ_LDFLAGS
 PROJ_CPPFLAGS
 POSTGIS_PROJ_VERSION
@@ -15230,7 +15230,11 @@ fi
 
   if test "x$GPP" != "x"; then
     SQLPP="${GPP} -C -s \'"   else
-    SQLPP="${CPP} -w -traditional-cpp"
+    if test "x${CPP}" != "x"; then
+      SQLPP="${CPP} -w -traditional-cpp"
+    else
+      as_fn_error $? "Required \"cpp\" command not found" "$LINENO" 5
+    fi
   fi
 fi
 
@@ -19180,7 +19184,6 @@ CHECK_JSON=yes
 HAVE_JSON=no
 
 
-
 # Check whether --with-json was given.
 if test "${with_json+set}" = set; then :
   withval=$with_json; CHECK_JSON="$withval"
@@ -19220,12 +19223,20 @@ fi
 
 CPPFLAGS_SAVE="$CPPFLAGS"
 CPPFLAGS="$JSON_CPPFLAGS"
-ac_fn_c_check_header_mongrel "$LINENO" "json/json.h" "ac_cv_header_json_json_h" "$ac_includes_default"
+ac_fn_c_check_header_mongrel "$LINENO" "json-c/json.h" "ac_cv_header_json_c_json_h" "$ac_includes_default"
+if test "x$ac_cv_header_json_c_json_h" = xyes; then :
+  HAVE_JSON=yes
+else
+
+  ac_fn_c_check_header_mongrel "$LINENO" "json/json.h" "ac_cv_header_json_json_h" "$ac_includes_default"
 if test "x$ac_cv_header_json_json_h" = xyes; then :
   HAVE_JSON=yes
 fi
 
 
+fi
+
+
 CPPFLAGS="$CPPFLAGS_SAVE"
 
 LIBS_SAVE="$LIBS"
@@ -19324,6 +19335,7 @@ fi
 
 
 
+
 fi
 
 
diff --git a/configure.ac b/configure.ac
index 67ad482..87946d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,7 +40,11 @@ else
   if test "x$GPP" != "x"; then
     SQLPP="${GPP} -C -s \'" dnl Use better string support
   else
-    SQLPP="${CPP} -w -traditional-cpp"
+    if test "x${CPP}" != "x"; then
+      SQLPP="${CPP} -w -traditional-cpp"
+    else
+      AC_MSG_ERROR([Required "cpp" command not found])
+    fi
   fi
 fi
 AC_SUBST([SQLPP])
@@ -747,7 +751,6 @@ dnl ===========================================================================
 
 CHECK_JSON=yes
 HAVE_JSON=no
-AC_SUBST([HAVE_JSON])
 
 AC_ARG_WITH([json],
 	[AS_HELP_STRING([--without-json], [build without json-c support])],
@@ -785,7 +788,8 @@ fi
 dnl Check that we can find the json/json.h header file
 CPPFLAGS_SAVE="$CPPFLAGS"
 CPPFLAGS="$JSON_CPPFLAGS"
-AC_CHECK_HEADER([json/json.h], [HAVE_JSON=yes], [])	
+AC_CHECK_HEADER([json-c/json.h], [HAVE_JSON=yes], [
+  AC_CHECK_HEADER([json/json.h], [HAVE_JSON=yes], [])])	
 CPPFLAGS="$CPPFLAGS_SAVE"
 
 dnl Ensure we can link against libjson
@@ -802,6 +806,7 @@ fi
 
 AC_SUBST([JSON_CPPFLAGS])
 AC_SUBST([JSON_LDFLAGS])
+AC_SUBST([HAVE_JSON])
 
 fi dnl }
 
diff --git a/doc/Makefile b/doc/Makefile
index f327120..673bf74 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -25,13 +25,13 @@ translations = it_IT pt_BR
 
 POSTGIS_MAJOR_VERSION=2
 POSTGIS_MINOR_VERSION=1
-POSTGIS_MICRO_VERSION=1
+POSTGIS_MICRO_VERSION=2
 
-INSTALL=/opt/local/bin/ginstall -c
+INSTALL=/usr/bin/install -c
 INSTALL_DATA=${INSTALL} -m 644
 
 XSLTPROC=/opt/local/bin/xsltproc
-XSLBASE=/opt/local/share/xsl/docbook-xsl
+XSLBASE=
 XMLLINT=/opt/local/bin/xmllint
 PERL=/opt/local/bin/perl
 
@@ -63,7 +63,7 @@ HTML_DOCBOOK_XSL=$(XSLBASE)/html/docbook.xsl
 CHUNK_HTML_DOCBOOK_XSL=$(XSLBASE)/html/chunk.xsl
 
 # DBLatex's dblatex script for PDF generation from DocBook
-DBLATEX=/opt/local/bin/dblatex
+DBLATEX=
 
 # Imagemagick's convert utility program for generated images used in the documentation
 IMAGEMAGICK=/opt/local/bin/convert
@@ -78,9 +78,9 @@ XML2POT=xml2pot
 DBTOEPUB=dbtoepub
 
 # Directories for postgresql subdirectories
-PGSQL_DOCDIR=/usr/local/pgsql/9.2/share/doc
-PGSQL_MANDIR=/usr/local/pgsql/9.2/share/man
-PGSQL_SHAREDIR=/usr/local/pgsql/9.2/share
+PGSQL_DOCDIR=/opt/pgsql/9.2/share/doc
+PGSQL_MANDIR=/opt/pgsql/9.2/share/man
+PGSQL_SHAREDIR=/opt/pgsql/9.2/share
 
 # If XSLTPROC or XSLBASE were not found during configure, we cannot
 # build the documentation
@@ -318,13 +318,17 @@ man-uninstall:
 	rm -f $(DESTDIR)$(PGSQL_MANDIR)/man1/shp2pgsql.1
 	rm -f $(DESTDIR)$(PGSQL_MANDIR)/man1/pgsql2shp.1
 
-docs-install: html/postgis.html
-	mkdir -p $(DESTDIR)$(PGSQL_DOCDIR)/postgis
-	$(INSTALL_DATA) html/postgis.html $(DESTDIR)$(PGSQL_DOCDIR)/postgis/postgis.html
+docs-install: html/postgis.html html/style.css
+	mkdir -p $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images
+	$(INSTALL_DATA) html/postgis.html $(DESTDIR)$(PGSQL_DOCDIR)/postgis/
+	$(INSTALL_DATA) html/style.css $(DESTDIR)$(PGSQL_DOCDIR)/postgis/
+	$(INSTALL_DATA) html/images/* $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images/
 	$(INSTALL_DATA) ../README.postgis $(DESTDIR)$(PGSQL_DOCDIR)/postgis/README.postgis
 
 docs-uninstall: 
 	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/postgis.html
+	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/style.css
+	rm -rf $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images
 	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/README.postgis
 
 install: comments-install
diff --git a/doc/Makefile.comments b/doc/Makefile.comments
index 4fbf34c..856c447 100644
--- a/doc/Makefile.comments
+++ b/doc/Makefile.comments
@@ -21,8 +21,8 @@ MODULEDIR=contrib/$(MODULE_doc)
 DATA_built=postgis_comments.sql raster_comments.sql topology_comments.sql
 
 # PGXS information
-PG_CONFIG = /usr/local/pgsql/9.2/bin/pg_config 
-PGXS := /usr/local/pgsql/9.2/lib/pgxs/src/makefiles/pgxs.mk
+PG_CONFIG = /opt/pgsql/9.2/bin/pg_config 
+PGXS := /opt/pgsql/9.2/lib/pgxs/src/makefiles/pgxs.mk
 include $(PGXS)
 
 # PGXS override feature. The ability to allow PostGIS to install itself
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 9264d46..b0f06b7 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -318,13 +318,17 @@ man-uninstall:
 	rm -f $(DESTDIR)$(PGSQL_MANDIR)/man1/shp2pgsql.1
 	rm -f $(DESTDIR)$(PGSQL_MANDIR)/man1/pgsql2shp.1
 
-docs-install: html/postgis.html
-	mkdir -p $(DESTDIR)$(PGSQL_DOCDIR)/postgis
-	$(INSTALL_DATA) html/postgis.html $(DESTDIR)$(PGSQL_DOCDIR)/postgis/postgis.html
+docs-install: html/postgis.html html/style.css
+	mkdir -p $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images
+	$(INSTALL_DATA) html/postgis.html $(DESTDIR)$(PGSQL_DOCDIR)/postgis/
+	$(INSTALL_DATA) html/style.css $(DESTDIR)$(PGSQL_DOCDIR)/postgis/
+	$(INSTALL_DATA) html/images/* $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images/
 	$(INSTALL_DATA) ../README.postgis $(DESTDIR)$(PGSQL_DOCDIR)/postgis/README.postgis
 
 docs-uninstall: 
 	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/postgis.html
+	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/style.css
+	rm -rf $(DESTDIR)$(PGSQL_DOCDIR)/postgis/images
 	rm -f $(DESTDIR)$(PGSQL_DOCDIR)/postgis/README.postgis
 
 install: comments-install
diff --git a/doc/extras_topology.xml b/doc/extras_topology.xml
index d09f38c..c7aa9fd 100644
--- a/doc/extras_topology.xml
+++ b/doc/extras_topology.xml
@@ -162,7 +162,10 @@ ERROR:  value for domain topology.topoelement violates check constraint "dimensi
             <!-- Optionally add a "See Also" section -->
             <refsection>
                 <title>See Also</title>
-                <para><xref linkend="GetTopoGeomElements"/></para>
+                <para>
+                  <xref linkend="GetTopoGeomElements"/>,
+                  <xref linkend="topoelementarray" />
+                </para>
             </refsection>
 		</refentry>
 		
@@ -1305,7 +1308,7 @@ an error is thrown.
 			<refsynopsisdiv>
 				<funcsynopsis>
 					<funcprototype>
-					<funcdef>text <function>ST_ModEdgeSplit</function></funcdef>
+					<funcdef>integer <function>ST_ModEdgeSplit</function></funcdef>
 					<paramdef><type>varchar </type> <parameter>atopology</parameter></paramdef>
 					<paramdef><type>integer </type> <parameter>anedge</parameter></paramdef>
 					<paramdef><type>geometry </type> <parameter>apoint</parameter></paramdef>
@@ -1320,6 +1323,7 @@ an error is thrown.
 Split an edge by creating a new node along an existing edge,
 modifying the original edge and adding a new edge.
 Updates all existing joined edges and relationships accordingly.
+Returns the identifier of the newly added node.
 		</para>
 
                 <!-- use this format if new function -->
@@ -1340,8 +1344,8 @@ Updates all existing joined edges and relationships accordingly.
 
 
 -- Split the edge  --
-SELECT topology.ST_ModEdgeSplit('ma_topo',  3, ST_SetSRID(ST_Point(227594,893910),26986)  ) As result;
-         result
+SELECT topology.ST_ModEdgeSplit('ma_topo',  3, ST_SetSRID(ST_Point(227594,893910),26986)  ) As node_id;
+        node_id
 -------------------------
 7
 </programlisting>
@@ -3206,4 +3210,110 @@ SELECT ']}'::text as t
             </refsection>
 	  </refentry>
 </sect1>
+<sect1 id="Topology_Relationships">
+	     <sect1info>
+            <abstract>
+                <para>This section lists the Topology functions used to check relationships between topogeometries and topology primitives</para>
+            </abstract>
+        </sect1info>
+	    <title>Topology Spatial Relationships</title>
+	    <refentry id="TG_Equals">
+        <refnamediv>
+          <refname>Equals</refname>
+      
+          <refpurpose>Returns true if two topogeometries are composed of the same topology primitives.</refpurpose>
+        </refnamediv>
+      
+        <refsynopsisdiv>
+          <funcsynopsis>
+            <funcprototype>
+              <funcdef>boolean <function>Equals</function></funcdef>
+              <paramdef><type>topogeometry </type> <parameter>tg1</parameter></paramdef>
+              <paramdef><type>topogeometry </type> <parameter>tg2</parameter></paramdef>
+            </funcprototype>
+          </funcsynopsis>
+        </refsynopsisdiv>
+      
+        <refsection>
+          <title>Description</title>
+      
+          <para>Returns true if two topogeometries are composed of the same topology primitives: faces, edges, nodes.</para>
+      
+          <!-- optionally mention that this function uses indexes if appropriate -->
+          <note>
+            <para>This function not supported for topogeometries that are geometry collections.  It also can not compare topogeometries from different topologies.</para>
+          </note>
+          <!-- use this format if new function -->
+        <para>Availability: 1.? </para>
+        
+       
+        <!-- Optionally mention 3d support -->
+        <para>&Z_support;</para>
+        </refsection>
+      
+      
+        <refsection>
+          <title>Examples</title>
+      
+          <programlisting><!--TODO: Need example --></programlisting>
+        </refsection>
+      
+        <!-- Optionally add a "See Also" section -->
+        <refsection>
+          <title>See Also</title>
+      
+          <para><xref linkend="GetTopoGeomElements" />, <xref linkend="ST_Equals" /></para>
+        </refsection>
+      </refentry>
+      
+      <refentry id="TG_Intersects">
+        <refnamediv>
+          <refname>Intersects</refname>
+      
+          <refpurpose>Returns true if two topogeometries are composed of the same topology primitives.</refpurpose>
+        </refnamediv>
+      
+        <refsynopsisdiv>
+          <funcsynopsis>
+            <funcprototype>
+              <funcdef>boolean <function>Equals</function></funcdef>
+              <paramdef><type>topogeometry </type> <parameter>tg1</parameter></paramdef>
+              <paramdef><type>topogeometry </type> <parameter>tg2</parameter></paramdef>
+            </funcprototype>
+          </funcsynopsis>
+        </refsynopsisdiv>
+      
+        <refsection>
+          <title>Description</title>
+      
+          <para>Returns true if two topogeometries share primitives or primitives intersect</para>
+      
+          <!-- optionally mention that this function uses indexes if appropriate -->
+          <note>
+            <para>This function not supported for topogeometries that are geometry collections.  It also can not compare topogeometries from different topologies.
+            Also not currently supported for hierarchichal topogeometries (topogeometries composed of other topogeometries).</para>
+          </note>
+          <!-- use this format if new function -->
+        <para>Availability: 1.? </para>
+        
+       
+        <!-- Optionally mention 3d support -->
+        <para>&Z_support;</para>
+        </refsection>
+      
+      
+        <refsection>
+          <title>Examples</title>
+      
+          <programlisting><!--TODO: Need example --></programlisting>
+        </refsection>
+      
+        <!-- Optionally add a "See Also" section -->
+        <refsection>
+          <title>See Also</title>
+      
+          <para><xref linkend="ST_Intersects" /></para>
+        </refsection>
+      </refentry>
+</sect1>
 </chapter>
diff --git a/doc/faq.xml b/doc/faq.xml
index 73ff240..097a177 100644
--- a/doc/faq.xml
+++ b/doc/faq.xml
@@ -97,14 +97,9 @@ SELECT MAX(ST_NPoints(geom)) FROM sometable;</programlisting>
       </question>
 
       <answer>
-        <para>You can store point, line, polygon, multipoint, multiline,
-        multipolygon, and geometrycollections. In PostGIS 2.0 and above you can also store TINS and Polyhedral Surfaces in the basic geometry type.
-        These are specified in the Open
-        GIS Well Known Text Format (with XYZ,XYM,XYZM extensions).  There are three data types currently supported.
-		The standard OGC geometry data type which uses a planar coordinate system for measurement, the 
-		geography data type which uses a geodetic coordinate system (not OGC, but you'll find a similar type in Microsoft SQL Server 2008+).  Only WGS 84 long lat (SRID:4326) is supported
-		by the geography data type.  The newest family member of the PostGIS spatial type family is raster for storing and analyzing raster data. Raster has its very own FAQ. Refer to <xref linkend="RT_FAQ"/>
-		and <xref linkend="RT_reference" /> for more details.</para>
+        <para>You can store Points, Linestrings, Polygons, CircularStrings, CompoundCurves, CurvePolygons, Triangles, PolyhedralSurfaces, TINs, Rasters, and collections of all the above. The most commonly used types used are Points, Linestrings and Polygons, and their collections.</para>
+        <para>Points, Linestrings and Polygons can be stored either as "geometry" or "geography". "Geometry" are cartesian representations of features in a 2D space. The shortest distance between two "geometry" points is a straight line. "Geography" are representations of objects on a spherical surface. The shortest distance between two "geography" points is a great circle.</para>
+        <para>The "raster" type has a distinct set of functions for manipulation and analysis. Refer to <xref linkend="RT_FAQ"/> and <xref linkend="RT_reference" /> for more details.</para>
       </answer>
     </qandaentry>
 	
diff --git a/doc/html/image_src/Makefile b/doc/html/image_src/Makefile
index 6494769..1b3d271 100644
--- a/doc/html/image_src/Makefile
+++ b/doc/html/image_src/Makefile
@@ -11,9 +11,9 @@
 # **********************************************************************
 
 CC=gcc
-CFLAGS=-g -O2  -Wall -Wmissing-prototypes 
+CFLAGS=-g -O2  -Wall -Wmissing-prototypes -I/usr/local/include
 
-CUNIT_LDFLAGS= -lcunit
+CUNIT_LDFLAGS=
 CUNIT_CPPFLAGS= -I../../../liblwgeom
 
 IMAGES= \
diff --git a/doc/postgis.xml b/doc/postgis.xml
index d0eedf9..f7128ba 100644
--- a/doc/postgis.xml
+++ b/doc/postgis.xml
@@ -3,12 +3,12 @@
                     "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
 
 <!-- This value is automatically generated by the Makefile -->
-<!ENTITY last_release_version "2.1.1">
+<!ENTITY last_release_version "@@LAST_RELEASE_VERSION@@">
 <!ENTITY last_minor_version "2.1">
 
 <!-- ONCE Tagged, this need to change to http://download.osgeo.org/postgis/source/postgis-@@LAST_RELEASE_VERSION@@.tar.gz -->
 <!-- In dev should be, this need to change to http://postgis.net/stuff/postgis-@@LAST_RELEASE_VERSION@@.tar.gz -->
-<!ENTITY postgis_download_url "http://download.osgeo.org/postgis/source/postgis-2.1.1.tar.gz">
+<!ENTITY postgis_download_url "http://download.osgeo.org/postgis/source/postgis-@@LAST_RELEASE_VERSION@@.tar.gz">
 
 <!-- Change these values to update the version numbers referenced within the documentation -->
 <!ENTITY last_proj_release_version "4.8.0">
diff --git a/doc/postgis_comments.sql b/doc/postgis_comments.sql
index 92deeee..2adc54f 100644
--- a/doc/postgis_comments.sql
+++ b/doc/postgis_comments.sql
@@ -69,9 +69,9 @@ COMMENT ON FUNCTION ST_GeographyFromText(text ) IS 'args: EWKT - Return a specif
 			
 COMMENT ON FUNCTION ST_GeogFromWKB(bytea ) IS 'args: geom - Creates a geography instance from a Well-Known Binary geometry representation (WKB) or extended Well Known Binary (EWKB).';
 			
-COMMENT ON FUNCTION ST_GeomCollFromText(text , integer ) IS 'args: WKT, srid - Makes a collection Geometry from collection WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_GeomCollFromText(text , integer ) IS 'args: WKT, srid - Makes a collection Geometry from collection WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_GeomCollFromText(text ) IS 'args: WKT - Makes a collection Geometry from collection WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_GeomCollFromText(text ) IS 'args: WKT - Makes a collection Geometry from collection WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
 COMMENT ON FUNCTION ST_GeomFromEWKB(bytea ) IS 'args: EWKB - Return a specified ST_Geometry value from Extended Well-Known Binary representation (EWKB).';
 			
@@ -105,9 +105,9 @@ COMMENT ON FUNCTION ST_GeomFromWKB(bytea , integer ) IS 'args: geom, srid - Crea
 			
 COMMENT ON FUNCTION ST_LineFromMultiPoint(geometry ) IS 'args: aMultiPoint - Creates a LineString from a MultiPoint geometry.';
 			
-COMMENT ON FUNCTION ST_LineFromText(text ) IS 'args: WKT - Makes a Geometry from WKT representation with the given SRID. If SRID is not given, it defaults to -1.';
+COMMENT ON FUNCTION ST_LineFromText(text ) IS 'args: WKT - Makes a Geometry from WKT representation with the given SRID. If SRID is not given, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_LineFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT representation with the given SRID. If SRID is not given, it defaults to -1.';
+COMMENT ON FUNCTION ST_LineFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT representation with the given SRID. If SRID is not given, it defaults to 0.';
 			
 COMMENT ON FUNCTION ST_LineFromWKB(bytea ) IS 'args: WKB - Makes a LINESTRING from WKB with the given SRID';
 			
@@ -145,13 +145,13 @@ COMMENT ON FUNCTION ST_MLineFromText(text , integer ) IS 'args: WKT, srid - Retu
 			
 COMMENT ON FUNCTION ST_MLineFromText(text ) IS 'args: WKT - Return a specified ST_MultiLineString value from WKT representation.';
 			
-COMMENT ON FUNCTION ST_MPointFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_MPointFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_MPointFromText(text ) IS 'args: WKT - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_MPointFromText(text ) IS 'args: WKT - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_MPolyFromText(text , integer ) IS 'args: WKT, srid - Makes a MultiPolygon Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_MPolyFromText(text , integer ) IS 'args: WKT, srid - Makes a MultiPolygon Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_MPolyFromText(text ) IS 'args: WKT - Makes a MultiPolygon Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_MPolyFromText(text ) IS 'args: WKT - Makes a MultiPolygon Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
 COMMENT ON FUNCTION ST_Point(float , float ) IS 'args: x_lon, y_lat - Returns an ST_Point with the given coordinate values. OGC alias for ST_MakePoint.';
 			
@@ -167,9 +167,9 @@ COMMENT ON FUNCTION ST_GeomFromWKB(bytea , integer ) IS 'args: geom, srid - Make
 			
 COMMENT ON FUNCTION ST_Polygon(geometry , integer ) IS 'args: aLineString, srid - Returns a polygon built from the specified linestring and SRID.';
 			
-COMMENT ON FUNCTION ST_PolygonFromText(text ) IS 'args: WKT - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_PolygonFromText(text ) IS 'args: WKT - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
-COMMENT ON FUNCTION ST_PolygonFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to -1.';
+COMMENT ON FUNCTION ST_PolygonFromText(text , integer ) IS 'args: WKT, srid - Makes a Geometry from WKT with the given SRID. If SRID is not give, it defaults to 0.';
 			
 COMMENT ON FUNCTION ST_WKBToSQL(bytea ) IS 'args: WKB - Return a specified ST_Geometry value from Well-Known Binary representation (WKB). This is an alias name for ST_GeomFromWKB that takes no srid';
 			
diff --git a/doc/reference_constructor.xml b/doc/reference_constructor.xml
index 5e36421..8aabdb4 100644
--- a/doc/reference_constructor.xml
+++ b/doc/reference_constructor.xml
@@ -274,7 +274,7 @@ ST_GeogFromWKB(E'\\001\\002\\000\\000\\000\\002\\000\\000\\000\\037\\205\\353Q\\
 		<refname>ST_GeomCollFromText</refname>
 
 		<refpurpose>Makes a collection Geometry from collection WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</refpurpose>
+			not give, it defaults to 0.</refpurpose>
 	  </refnamediv>
 
 	  <refsynopsisdiv>
@@ -297,7 +297,7 @@ ST_GeogFromWKB(E'\\001\\002\\000\\000\\000\\002\\000\\000\\000\\037\\205\\353Q\\
 		<title>Description</title>
 
 		  <para>Makes a collection Geometry from the Well-Known-Text (WKT) representation with the given SRID. If SRID is
-			not give, it defaults to -1.</para>
+			not give, it defaults to 0.</para>
 
 		  <para>OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
 
@@ -942,7 +942,7 @@ SELECT ST_GeomFromText('CIRCULARSTRING(220268 150415,220227 150505,220227 150406
 		geometry type. This function plays the role of the Geometry Factory in
 		SQL. This is an alternate name for ST_WKBToSQL.</para>
 
-		<para>If SRID is not specified, it defaults to -1 (Unknown).</para>
+		<para>If SRID is not specified, it defaults to 0 (Unknown).</para>
 		<para>&sfs_compliant; s3.2.7.2 - the optional SRID is from the conformance suite</para>
 		<para>&sqlmm_compliant; SQL-MM 3: 5.1.41</para>
 		<para>&curve_support;</para>
@@ -1030,7 +1030,7 @@ LINESTRING(1 2 3,4 5 6,7 8 9)
 		<refname>ST_LineFromText</refname>
 
 		<refpurpose>Makes a Geometry from WKT representation with the given SRID. If SRID is
-				not given, it defaults to -1.</refpurpose>
+				not given, it defaults to 0.</refpurpose>
 	  </refnamediv>
 
 	  <refsynopsisdiv>
@@ -1052,7 +1052,7 @@ LINESTRING(1 2 3,4 5 6,7 8 9)
 		<title>Description</title>
 
 		<para>Makes a Geometry from WKT with the given SRID. If SRID is
-				not give, it defaults to -1.  If WKT passed in is not a LINESTRING, then null is returned.  </para>
+				not give, it defaults to 0.  If WKT passed in is not a LINESTRING, then null is returned.  </para>
 
 		<note>
 		  <para>OGC SPEC 3.2.6.2 - option SRID is from the conformance
@@ -1120,7 +1120,7 @@ aline                            | null_return
 		<varname>LINESTRING</varname> geometry. This function plays the role of the Geometry
 		Factory in SQL.</para>
 
-	  <para>If an SRID is not specified, it defaults to -1. <varname>NULL</varname> is
+	  <para>If an SRID is not specified, it defaults to 0. <varname>NULL</varname> is
 		returned if the input <varname>bytea</varname>
 		does not represent a <varname>LINESTRING</varname>.</para>
 
@@ -1193,7 +1193,7 @@ aline                            | null_return
 		<varname>LINESTRING</varname> geometry. This function plays the role of the Geometry
 		Factory in SQL.</para>
 
-	  <para>If an SRID is not specified, it defaults to -1.  <varname>NULL</varname> is
+	  <para>If an SRID is not specified, it defaults to 0.  <varname>NULL</varname> is
 		returned if the input <varname>bytea</varname> does not represent a
 		<varname>LINESTRING</varname> geometry. This an alias for <xref linkend="ST_LineFromWKB" />.</para>
 
@@ -1785,7 +1785,7 @@ result
 		<title>Description</title>
 
 		 <para>Makes a Geometry from  Well-Known-Text (WKT) with the given SRID. If SRID is
-			not give, it defaults to -1.</para>
+			not give, it defaults to 0.</para>
 
 		 <para>OGC SPEC 3.2.6.2 - option SRID is from the conformance
 			suite</para>
@@ -1823,7 +1823,7 @@ result
 		<refname>ST_MPointFromText</refname>
 
 		<refpurpose>Makes a Geometry from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</refpurpose>
+			not give, it defaults to 0.</refpurpose>
 	  </refnamediv>
 
 	  <refsynopsisdiv>
@@ -1846,7 +1846,7 @@ result
 		<title>Description</title>
 
 		 <para>Makes a Geometry from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</para>
+			not give, it defaults to 0.</para>
 
 		 <para>OGC SPEC 3.2.6.2 - option SRID is from the conformance
 			suite</para>
@@ -1885,7 +1885,7 @@ SELECT ST_MPointFromText('MULTIPOINT(-70.9590 42.1180, -70.9611 42.1223)', 4326)
 		<refname>ST_MPolyFromText</refname>
 
 		<refpurpose>Makes a MultiPolygon Geometry from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</refpurpose>
+			not give, it defaults to 0.</refpurpose>
 	  </refnamediv>
 
 	  <refsynopsisdiv>
@@ -1908,7 +1908,7 @@ SELECT ST_MPointFromText('MULTIPOINT(-70.9590 42.1180, -70.9611 42.1223)', 4326)
 		<title>Description</title>
 
 		 <para>Makes a MultiPolygon from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</para>
+			not give, it defaults to 0.</para>
 
 		 <para>OGC SPEC 3.2.6.2 - option SRID is from the conformance suite</para>
 
@@ -2077,7 +2077,7 @@ SELECT ST_AsText(ST_PointFromGeoHash('9qqj7nmxncgyy4d0dbxqz0', 10));
 			<title>Description</title>
 
 			<para>Constructs a PostGIS ST_Geometry point object from the OGC Well-Known text representation. If SRID is
-			not give, it defaults to unknown (currently -1).  If geometry is not a WKT point representation, returns null.
+			not give, it defaults to unknown (currently 0).  If geometry is not a WKT point representation, returns null.
 			If completely invalid WKT, then throws an error.</para>
 
 			<!-- optionally mention that this function uses indexes if appropriate -->
@@ -2141,7 +2141,7 @@ SELECT ST_PointFromText('POINT(-71.064544 42.28787)', 4326);
 			<varname>POINT</varname> geometry. This function plays the role of the Geometry
 			Factory in SQL.</para>
 
-		<para>If an SRID is not specified, it defaults to -1.  <varname>NULL</varname> is
+		<para>If an SRID is not specified, it defaults to 0.  <varname>NULL</varname> is
 		returned if the input <varname>bytea</varname> does not represent a
 		<varname>POINT</varname> geometry.</para>
 		<para>&sfs_compliant; s3.2.7.2</para>
@@ -2250,7 +2250,7 @@ SRID=4326;POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))
 		<refname>ST_PolygonFromText</refname>
 
 		<refpurpose>Makes a Geometry from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.</refpurpose>
+			not give, it defaults to 0.</refpurpose>
 	  </refnamediv>
 
 	  <refsynopsisdiv>
@@ -2271,7 +2271,7 @@ SRID=4326;POLYGON((75.15 29.53 1,77 29 1,77.6 29.5 1,75.15 29.53 1))
 		<title>Description</title>
 
 		<para>Makes a Geometry from WKT with the given SRID. If SRID is
-			not give, it defaults to -1.  Returns null if WKT is not a polygon.</para>
+			not give, it defaults to 0.  Returns null if WKT is not a polygon.</para>
 
 
 		<para>OGC SPEC 3.2.6.2 - option SRID is from the conformance
diff --git a/doc/reference_measure.xml b/doc/reference_measure.xml
index dca8ff9..daf944b 100644
--- a/doc/reference_measure.xml
+++ b/doc/reference_measure.xml
@@ -831,7 +831,7 @@ SELECT degrees( ST_Azimuth(ST_Point(25,45), ST_Point(75,100)) ) as degA_B,
 	  <para>Computes the geometric center of a geometry, or equivalently,
 	  the center of mass of the geometry as a <varname>POINT</varname>. For
 	  [<varname>MULTI</varname>]<varname>POINT</varname>s, this is computed
-	  as the arithmetric mean of the input coordinates. For
+	  as the arithmetic mean of the input coordinates. For
 	  [<varname>MULTI</varname>]<varname>LINESTRING</varname>s, this is
 	  computed as the weighted length of each line segment. For
 	  [<varname>MULTI</varname>]<varname>POLYGON</varname>s, "weight" is
diff --git a/doc/release_notes.xml b/doc/release_notes.xml
index d139ae7..870d630 100644
--- a/doc/release_notes.xml
+++ b/doc/release_notes.xml
@@ -3,6 +3,42 @@
   <title>Appendix</title>
     <subtitle>Release Notes</subtitle>
     <sect1>
+      <title>Release 2.1.2</title>
+      <para>Release date: 2014/03/31</para>
+      <para>This is a bug fix release, addressing issues that have been filed since the 2.1.1 release.</para>
+      <simplesect>
+        <title>Bug Fixes</title>
+            <para>#2666, Error out at configure time if no SQL preprocessor can be found</para>
+            <para>#2534, st_distance returning incorrect results for large geographies</para>
+            <para>#2539, Check for json-c/json.h presence/usability before json/json.h</para>
+            <para>#2543, invalid join selectivity error from simple query</para>
+            <para>#2546, GeoJSON with string coordinates parses incorrectly </para>
+            <para>#2547, Fix ST_Simplify(TopoGeometry) for hierarchical topogeoms</para>
+            <para>#2552, Fix NULL raster handling in ST_AsPNG, ST_AsTIFF and
+                       ST_AsJPEG</para>
+            <para>#2555, Fix parsing issue of range arguments of ST_Reclass</para>
+            <para>#2556, geography ST_Intersects results depending on insert order</para>
+            <para>#2580, Do not allow installing postgis twice in the same database</para>
+            <para>#2589, Remove use of unnecessary void pointers</para>
+            <para>#2607, Cannot open more than 1024 out-db files in one process</para>
+            <para>#2610, Ensure face splitting algorithm uses the edge index</para>
+            <para>#2615, EstimatedExtent (and hence, underlying stats) gathering wrong bbox</para>
+            <para>#2619, Empty rings array in GeoJSON polygon causes crash</para>
+            <para>#2634, regression in sphere distance code</para>
+            <para>#2638, Geography distance on M geometries sometimes wrong</para>
+            <para>#2648, #2653, Fix topology functions when "topology" is not in search_path</para>
+            <para>#2654, Drop deprecated calls from topology</para>
+            <para>#2655, Let users without topology privileges call postgis_full_version()</para>
+            <para>#2674, Fix missing operator = and hash_raster_ops opclass on raster</para>
+            <para>#2675, #2534, #2636, #2634, #2638, Geography distance issues with tree optimization</para>
+      </simplesect>
+      <simplesect>
+        <title>Enhancements</title>
+          <para>#2494, avoid memcopy in GiST index (hayamiz)</para>
+          <para>#2560, soft upgrade: avoid drop/recreate of aggregates that hadn't changed</para>
+      </simplesect>
+    </sect1>
+    <sect1>
       <title>Release 2.1.1</title>
       <para>Release date: 2013/11/06</para>
       <para>This is a bug fix release, addressing issues that have been filed since the 2.1.0 release.</para>
diff --git a/doc/topology_comments.sql b/doc/topology_comments.sql
index 70b3def..722715a 100644
--- a/doc/topology_comments.sql
+++ b/doc/topology_comments.sql
@@ -134,4 +134,8 @@ COMMENT ON FUNCTION topology.AsGML(topogeometry , text , integer , integer , reg
 COMMENT ON FUNCTION topology.AsGML(topogeometry , text , integer , integer , regclass , text , int ) IS 'args: tg, nsprefix_in, precision, options, visitedTable, idprefix, gmlversion - Returns the GML representation of a topogeometry.';
 			
 COMMENT ON FUNCTION topology.AsTopoJSON(topogeometry , regclass ) IS 'args: tg, edgeMapTable - Returns the TopoJSON representation of a topogeometry.';
+			
+COMMENT ON FUNCTION topology.Equals(topogeometry , topogeometry ) IS 'args: tg1, tg2 - Returns true if two topogeometries are composed of the same topology primitives.';
+			
+COMMENT ON FUNCTION topology.Equals(topogeometry , topogeometry ) IS 'args: tg1, tg2 - Returns true if two topogeometries are composed of the same topology primitives.';
 			
\ No newline at end of file
diff --git a/doc/using_postgis_dataman.xml b/doc/using_postgis_dataman.xml
index 2b5c89c..b773b10 100644
--- a/doc/using_postgis_dataman.xml
+++ b/doc/using_postgis_dataman.xml
@@ -5,21 +5,22 @@
   <sect1 id="RefObject">
 	<title>GIS Objects</title>
 
-	<para>The GIS objects supported by PostGIS are a superset of the "Simple
-	Features" defined by the OpenGIS Consortium (OGC). As of version 0.9,
-	PostGIS supports all the objects and functions specified in the OGC
-	"Simple Features for SQL" specification.</para>
+	<para>The GIS objects supported by PostGIS are all the vector types defined
+  in the "Simple Features for SQL 1.2.1" standard defined by the OpenGIS Consortium (OGC),
+  and the ISO "SQL/MM Part 3: Spatial" document. In addition, PostGIS supports a raster
+  type (no standards exist to follow), and a topology model (following an early
+  draft ISO standard for topology that has not been published as yet).</para>
 
-	<para>PostGIS extends the standard with support for 3DZ,3DM and 4D
-	coordinates.</para>
+	<para>The OGC and ISO standards define 2D (x/y), 3D (x/y/z, x/y/m) and 4D (x/y/z/m) 
+  variants of points, lines, polygons, curved features, polyhedra, and TINS.</para>
 
 	<sect2 id="OpenGISWKBWKT">
-	  <title>OpenGIS WKB and WKT</title>
+	  <title>Well-Known Binary (WKB) and Well-Known Text (WKT) Representations</title>
 
-	  <para>The OpenGIS specification defines two standard ways of expressing
-	  spatial objects: the Well-Known Text (WKT) form and the Well-Known
-	  Binary (WKB) form. Both WKT and WKB include information about the type
-	  of the object and the coordinates which form the object.</para>
+	  <para>The OGC and ISO specifications define both text and binary 
+    representations for geometry objects, WKT and WKB. Both representations
+    include information about the type
+	  of the object and the coordinates that form the object.</para>
 
 	  <para>Examples of the text representations (WKT) of the spatial objects
 	  of the features are as follows:</para>
@@ -38,7 +39,7 @@
 		</listitem>
 
 		<listitem>
-		  <para>MULTIPOINT(0 0,1 2)</para>
+		  <para>MULTIPOINT((0 0),(1 2))</para>
 		</listitem>
 
 		<listitem>
diff --git a/doc/using_raster_dataman.xml b/doc/using_raster_dataman.xml
index 98ee86b..a01bbdf 100644
--- a/doc/using_raster_dataman.xml
+++ b/doc/using_raster_dataman.xml
@@ -728,8 +728,9 @@ public class SaveQueryImage {
    		
    		<sect2 id="RT_PLPython">
    			<title>Use PLPython to dump out images via SQL</title>
-   			<para>This is a plpython stored function that creates a file in the server directory for each record.</para>
-   			<programlisting>//plpython postgresql stored proc.  Requires you have plpython installed
+   			<para>This is a plpython stored function that creates a file in the server directory for each record.  
+   			plpython postgresql stored proc.  Requires you have plpython installed.  Should work fine with both plpythonu and plpython3u.</para>
+   			<programlisting>
 <![CDATA[CREATE OR REPLACE FUNCTION write_file (param_bytes bytea, param_filepath text)
 RETURNS text
 AS $$
diff --git a/extensions/postgis/META.json b/extensions/postgis/META.json
index 9c0800b..46a44b1 100644
--- a/extensions/postgis/META.json
+++ b/extensions/postgis/META.json
@@ -39,7 +39,7 @@
 		},
 		"repository": {
 			"url": "svn://svn.osgeo.org/postgis/",
-			"web": "http://www.postgis.org",
+			"web": "http://postgis.net",
 			"type": "svn"
 		}
 	},
diff --git a/extensions/postgis/Makefile.in b/extensions/postgis/Makefile.in
index 1da2460..3b81918 100644
--- a/extensions/postgis/Makefile.in
+++ b/extensions/postgis/Makefile.in
@@ -33,7 +33,7 @@ sql/$(EXTENSION).sql: sql_bits/postgis.sql sql_bits/postgis_comments.sql sql_bit
 	mkdir -p sql
 	cat $^ > $@
 	
-all: sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql sql_minor_upgrade
+all: sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql sql_minor_upgrade sql_patch_upgrade
 
 sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
 	mkdir -p sql
@@ -44,9 +44,9 @@ sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql: sql_bits/postgis--unpackaged.sq
 	cp $< $@
 	
 #this is a cludge to allow upgrading from same SVN to same SVN
-sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql: sql_bits/postgis_raster_upgrade_minor.sql
+sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql: sql_bits/extension_upgrade_patch.sql
 	cp $< $@
-sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql: sql_bits/postgis_raster_upgrade_minor.sql
+sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql: sql_bits/extension_upgrade_patch.sql
 	cp $< $@
 
 #strip BEGIN/COMMIT since these are not allowed in extensions
@@ -78,6 +78,14 @@ sql_bits/rtpostgis_upgrade_20_21.sql: ../../raster/rt_pg/rtpostgis_upgrade_20_21
 		-e 's/DROP CAST\(.*\)/SELECT postgis_extension_drop_if_exists('\''$(EXTENSION)'\'', '\''DROP CAST \1'\'');DROP CAST \1/' \
 	$< > $@
 
+sql_bits/rtpostgis_upgrade_21_minor.sql: ../../raster/rt_pg/rtpostgis_upgrade_21_minor.sql
+	sed -e 's/BEGIN;//g' -e 's/COMMIT;//g' \
+		-e 's/DROP FUNCTION _rename_raster_tables();/ALTER EXTENSION ${EXTENSION} DROP FUNCTION _rename_raster_tables();DROP FUNCTION _rename_raster_tables();/g' \
+		-e 's/DROP FUNCTION _drop_st_samealignment();/ALTER EXTENSION ${EXTENSION} DROP FUNCTION _drop_st_samealignment();DROP FUNCTION _drop_st_samealignment();/g' \
+		-e 's/DROP CAST\(.*\)/SELECT postgis_extension_drop_if_exists('\''$(EXTENSION)'\'', '\''DROP CAST \1'\'');DROP CAST \1/' \
+	$< > $@
+
+
 #don't drop casts just yet since we don't have provision to remove from extension yet
 #need to also drop temporary functions from extenions since it gets auto-added
 sql_bits/postgis_upgrade_20_21.sql: ../../postgis/postgis_upgrade_20_21.sql 
@@ -87,6 +95,13 @@ sql_bits/postgis_upgrade_20_21.sql: ../../postgis/postgis_upgrade_20_21.sql
 		 -e 's/DROP FUNCTION postgis_major_version_check();/ALTER EXTENSION ${EXTENSION} DROP FUNCTION postgis_major_version_check();DROP FUNCTION postgis_major_version_check();/g' \
 	 	 $< > $@
 
+sql_bits/postgis_upgrade_21_minor.sql: ../../postgis/postgis_upgrade_21_minor.sql 
+		 sed -e 's/BEGIN;//g' -e 's/COMMIT;//g' \
+		 -e '/^\(DROP\|CREATE\) \(CAST\).*;/d' \
+		 -e '/^\(DROP\|CREATE\) \(CAST\)/,/\;/d' \
+		 -e 's/DROP FUNCTION postgis_major_version_check();/ALTER EXTENSION ${EXTENSION} DROP FUNCTION postgis_major_version_check();DROP FUNCTION postgis_major_version_check();/g' \
+	 	 $< > $@
+
 
 ../../doc/raster_comments.sql:
 	$(MAKE) -C ../../doc comments
@@ -94,10 +109,12 @@ sql_bits/postgis_upgrade_20_21.sql: ../../postgis/postgis_upgrade_20_21.sql
 sql_bits/raster_comments.sql: ../../doc/raster_comments.sql
 	cp $< $@
 
-#postgis_raster_upgrade_minor.sql is the one that contains both postgis AND raster
-#TODO: come up with a better name
+#extension_upgrade_minor.sql is the one that contains both postgis AND raster
 #TODO: what about postgis_drop_after.sql ? where does it fit ??
-sql_bits/postgis_raster_upgrade_minor.sql: ../postgis_extension_helper.sql sql_bits/remove_from_extension.sql.in sql_bits/postgis_upgrade_20_21.sql sql_bits/rtpostgis_upgrade_20_21.sql ../../doc/raster_comments.sql ../../doc/postgis_comments.sql ../postgis_extension_helper_uninstall.sql
+sql_bits/extension_upgrade_minor.sql: ../postgis_extension_helper.sql sql_bits/postgis_upgrade_20_21.sql sql_bits/rtpostgis_upgrade_20_21.sql ../../doc/raster_comments.sql ../../doc/postgis_comments.sql ../postgis_extension_helper_uninstall.sql
+	cat $^ > $@
+
+sql_bits/extension_upgrade_patch.sql: ../postgis_extension_helper.sql sql_bits/postgis_upgrade_21_minor.sql sql_bits/rtpostgis_upgrade_21_minor.sql ../../doc/raster_comments.sql ../../doc/postgis_comments.sql ../postgis_extension_helper_uninstall.sql
 	cat $^ > $@
 
 # sql_bits/rtpostgis--unpackaged.sql:  ../../raster/rt_pg/rtpostgis.sql	 
@@ -139,8 +156,13 @@ sql_bits/rtpostgis-filtered.sql:  ../../raster/rt_pg/rtpostgis.sql
 
 sql/postgis--unpackaged--$(EXTVERSION).sql: sql_bits/postgis--unpackaged.sql.in
 
-sql_minor_upgrade: sql_bits/postgis_raster_upgrade_minor.sql
-	for OLD_VERSION in $(UPGRADEABLE_VERSIONS); do \
+sql_minor_upgrade: sql_bits/extension_upgrade_minor.sql
+	for OLD_VERSION in $(UPGRADEABLE_VERSIONS_MINOR); do \
+  	  cat $< > sql/$(EXTENSION)--$$OLD_VERSION--$(EXTVERSION).sql; \
+	done
+
+sql_patch_upgrade: sql_bits/extension_upgrade_patch.sql
+	for OLD_VERSION in $(UPGRADEABLE_VERSIONS_PATCH); do \
   	  cat $< > sql/$(EXTENSION)--$$OLD_VERSION--$(EXTVERSION).sql; \
 	done
 
diff --git a/extensions/postgis/doc/postgis.md b/extensions/postgis/doc/postgis.md
index ca68fc9..3e96c16 100644
--- a/extensions/postgis/doc/postgis.md
+++ b/extensions/postgis/doc/postgis.md
@@ -1,6 +1,5 @@
-PostGIS 2.0.0
+PostGIS
 ============
 
 Extensive documentation can be found at.
-HTML: http://www.postgis.org/documentation/manual-svn/
-PDF: http://www.postgis.org/download/postgis-2.0.0SVN.pdf
+http://postgis.net/documentation
diff --git a/extensions/postgis/postgis.control b/extensions/postgis/postgis.control
index a7626cb..9960cde 100644
--- a/extensions/postgis/postgis.control
+++ b/extensions/postgis/postgis.control
@@ -1,5 +1,5 @@
 # postgis extension
 comment = 'PostGIS geometry, geography, and raster spatial types and functions'
-default_version = '2.1.1'
+default_version = '2.1.2'
 module_pathname = '$libdir/postgis-2.1'
 relocatable = true
diff --git a/extensions/postgis/sql_bits/postgis--unpackaged.sql.in b/extensions/postgis/sql_bits/postgis--unpackaged.sql.in
index 42d7bf4..4cf3542 100644
--- a/extensions/postgis/sql_bits/postgis--unpackaged.sql.in
+++ b/extensions/postgis/sql_bits/postgis--unpackaged.sql.in
@@ -1170,3 +1170,4 @@
  ALTER EXTENSION postgis ADD view geometry_columns;
  ALTER EXTENSION postgis ADD view raster_columns;
  ALTER EXTENSION postgis ADD view raster_overviews;
+
diff --git a/extensions/postgis/sql_bits/remove_from_extension.sql.in b/extensions/postgis/sql_bits/remove_from_extension.sql.in
index b974389..6c411ca 100644
--- a/extensions/postgis/sql_bits/remove_from_extension.sql.in
+++ b/extensions/postgis/sql_bits/remove_from_extension.sql.in
@@ -1,9 +1,9 @@
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -- 
--- $Id: remove_from_extension.sql.in 10168 2012-08-06 16:21:04Z robe $
+-- $Id: remove_from_extension.sql.in 12288 2014-03-03 03:01:35Z robe $
 ----
 -- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http://postgis.net
 --
 -- Copyright (C) 2011 Regina Obe <lr at pcorp.us>
 --
diff --git a/extensions/postgis_extension_helper.sql b/extensions/postgis_extension_helper.sql
index 82a6fca..3b6dd42 100644
--- a/extensions/postgis_extension_helper.sql
+++ b/extensions/postgis_extension_helper.sql
@@ -1,9 +1,9 @@
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -- 
--- $Id: postgis_extension_helper.sql 10934 2012-12-26 13:44:51Z robe $
+-- $Id: postgis_extension_helper.sql 12288 2014-03-03 03:01:35Z robe $
 ----
 -- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http://postgis.net
 --
 -- Copyright (C) 2011 Regina Obe <lr at pcorp.us>
 -- Copyright (C) 2005 Refractions Research Inc.
diff --git a/extensions/postgis_extension_helper_uninstall.sql b/extensions/postgis_extension_helper_uninstall.sql
index 403f88e..74f9405 100644
--- a/extensions/postgis_extension_helper_uninstall.sql
+++ b/extensions/postgis_extension_helper_uninstall.sql
@@ -1,9 +1,9 @@
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -- 
--- $Id: postgis_extension_helper_uninstall.sql 10934 2012-12-26 13:44:51Z robe $
+-- $Id: postgis_extension_helper_uninstall.sql 12288 2014-03-03 03:01:35Z robe $
 ----
 -- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http://postgis.net
 --
 -- Copyright (C) 2011 Regina Obe <lr at pcorp.us>
 --
diff --git a/extensions/postgis_tiger_geocoder/META.json b/extensions/postgis_tiger_geocoder/META.json
index 0a80f0f..f5add01 100644
--- a/extensions/postgis_tiger_geocoder/META.json
+++ b/extensions/postgis_tiger_geocoder/META.json
@@ -30,7 +30,7 @@
 		},
 		"repository": {
 			"url": "svn://svn.osgeo.org/postgis/",
-			"web": "http://www.postgis.org",
+			"web": "http://postgis.net",
 			"type": "svn"
 		}
 	},
diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in
index bf2350c..decc331 100644
--- a/extensions/postgis_tiger_geocoder/Makefile.in
+++ b/extensions/postgis_tiger_geocoder/Makefile.in
@@ -30,15 +30,19 @@ ifeq ($(PG91),yes)
 all: sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql  sql_minor_upgrade
 
 sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql
+	mkdir -p sql
 	cp $< $@
 	
 sql/$(EXTENSION).sql: sql_bits/tiger_geocoder.sql  sql_bits/mark_editable_objects.sql.in sql_bits/tiger_geocoder_comments.sql
+	mkdir -p sql
 	cat $^ > $@
 	
 #this is a cludge to allow upgrading from same SVN to same SVN
 sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql: ../postgis_extension_helper.sql sql_bits/remove_from_extension.sql.in sql/tiger_geocoder_upgrade_minor.sql sql_bits/mark_editable_objects.sql.in sql_bits/tiger_geocoder_comments.sql ../postgis_extension_helper_uninstall.sql
+	mkdir -p sql
 	cat $^ > $@
 sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql: sql/$(EXTENSION)--$(EXTVERSION)--$(EXTVERSION)next.sql
+	mkdir -p sql
 	cp $< $@
 	
 #strip BEGIN/COMMIT since these are not allowed in extensions
@@ -144,6 +148,7 @@ sql_bits/tiger_geocoder_comments.sql: ../../doc/tiger_geocoder_comments.sql
 #hardcode for now using 
 #the extensions/make_unpackaged.sql script form an install
 sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql: sql_bits/tiger_geocoder--unpackaged.sql.in
+	mkdir -p sql
 	cp $< $@
 
 #upgrade script should have everything but table, schema, type creation/alter
@@ -155,6 +160,7 @@ sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql: sql_bits/tiger_geocoder--unpack
 #they can be dropped but we need to remove
 #them from the extension first
 sql/tiger_geocoder_upgrade_minor.sql:  sql_bits/tiger_geocoder_minor.sql.in 
+	mkdir -p sql
 	 sed -e '/^\(CREATE\|ALTER\) \(CAST\|TYPE\|TABLE\|SCHEMA\|DOMAIN\|TRIGGER\).*;/d' \
 	 	 -e '/^\(CREATE\|ALTER\) \(CAST\|TYPE\|TABLE\|SCHEMA\|DOMAIN\|TRIGGER\)/,/\;/d' \
 	 	 -e 's/BEGIN;//g' -e 's/COMMIT;//g' \
diff --git a/extensions/postgis_tiger_geocoder/doc/postgis_tiger_geocoder.md b/extensions/postgis_tiger_geocoder/doc/postgis_tiger_geocoder.md
index 14e6edc..3e96c16 100644
--- a/extensions/postgis_tiger_geocoder/doc/postgis_tiger_geocoder.md
+++ b/extensions/postgis_tiger_geocoder/doc/postgis_tiger_geocoder.md
@@ -1,6 +1,5 @@
-PostGIS 2.1.0
+PostGIS
 ============
 
 Extensive documentation can be found at.
-HTML: http://www.postgis.org/documentation/manual-svn/
-PDF: http://www.postgis.org/download/postgis-2.1.0SVN.pdf
+http://postgis.net/documentation
diff --git a/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control b/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control
index 46804fb..4869283 100644
--- a/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control
+++ b/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control
@@ -1,6 +1,6 @@
 # postgis tiger geocoder extension
 comment = 'PostGIS tiger geocoder and reverse geocoder'
-default_version = '2.1.1'
+default_version = '2.1.2'
 relocatable = false
 schema = tiger
 requires = 'postgis,fuzzystrmatch'
diff --git a/extensions/postgis_tiger_geocoder/sql_bits/remove_from_extension.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/remove_from_extension.sql.in
index c94313d..74990c2 100644
--- a/extensions/postgis_tiger_geocoder/sql_bits/remove_from_extension.sql.in
+++ b/extensions/postgis_tiger_geocoder/sql_bits/remove_from_extension.sql.in
@@ -3,7 +3,7 @@
 -- $Id: remove_from_extension.sql.in 9324 2012-02-27 22:08:12Z pramsey $
 ----
 -- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http://postgis.net
 --
 -- Copyright (C) 2011 Regina Obe <lr at pcorp.us>
 --
diff --git a/extensions/postgis_tiger_geocoder/sql_bits/tiger_geocoder--unpackaged.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/tiger_geocoder--unpackaged.sql.in
index c7efbc3..f80c896 100644
--- a/extensions/postgis_tiger_geocoder/sql_bits/tiger_geocoder--unpackaged.sql.in
+++ b/extensions/postgis_tiger_geocoder/sql_bits/tiger_geocoder--unpackaged.sql.in
@@ -100,3 +100,4 @@
  ALTER EXTENSION postgis_tiger_geocoder ADD table zip_state;
  ALTER EXTENSION postgis_tiger_geocoder ADD table zip_state_loc;
  ALTER EXTENSION postgis_tiger_geocoder ADD type norm_addy;
+
diff --git a/extensions/postgis_topology/META.json b/extensions/postgis_topology/META.json
index 122666a..ea28bd4 100644
--- a/extensions/postgis_topology/META.json
+++ b/extensions/postgis_topology/META.json
@@ -30,7 +30,7 @@
 		},
 		"repository": {
 			"url": "svn://svn.osgeo.org/postgis/",
-			"web": "http://www.postgis.org",
+			"web": "http://postgis.net",
 			"type": "svn"
 		}
 	},
diff --git a/extensions/postgis_topology/doc/postgis.md b/extensions/postgis_topology/doc/postgis.md
index ca68fc9..8feab14 100644
--- a/extensions/postgis_topology/doc/postgis.md
+++ b/extensions/postgis_topology/doc/postgis.md
@@ -1,6 +1,5 @@
-PostGIS 2.0.0
+PostGIS 
 ============
 
 Extensive documentation can be found at.
-HTML: http://www.postgis.org/documentation/manual-svn/
-PDF: http://www.postgis.org/download/postgis-2.0.0SVN.pdf
+HTML: http://postgis.net/documentation
diff --git a/extensions/postgis_topology/postgis_topology.control b/extensions/postgis_topology/postgis_topology.control
index 61b3c5e..6f6cd5f 100644
--- a/extensions/postgis_topology/postgis_topology.control
+++ b/extensions/postgis_topology/postgis_topology.control
@@ -1,6 +1,6 @@
 # postgis topology extension
 comment = 'PostGIS topology spatial types and functions'
-default_version = '2.1.1'
+default_version = '2.1.2'
 relocatable = false
 schema = topology
 requires = postgis
diff --git a/extensions/postgis_topology/sql_bits/remove_from_extension.sql.in b/extensions/postgis_topology/sql_bits/remove_from_extension.sql.in
index 5e557dd..d7a115a 100644
--- a/extensions/postgis_topology/sql_bits/remove_from_extension.sql.in
+++ b/extensions/postgis_topology/sql_bits/remove_from_extension.sql.in
@@ -1,9 +1,9 @@
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -- 
--- $Id: remove_from_extension.sql.in 9324 2012-02-27 22:08:12Z pramsey $
+-- $Id: remove_from_extension.sql.in 12288 2014-03-03 03:01:35Z robe $
 ----
 -- PostGIS - Spatial Types for PostgreSQL
--- http://www.postgis.org
+-- http://postgis.net
 --
 -- Copyright (C) 2011 Regina Obe <lr at pcorp.us>
 --
diff --git a/extensions/postgis_topology/sql_bits/topology--unpackaged.sql.in b/extensions/postgis_topology/sql_bits/topology--unpackaged.sql.in
index 99ba099..ea50f30 100644
--- a/extensions/postgis_topology/sql_bits/topology--unpackaged.sql.in
+++ b/extensions/postgis_topology/sql_bits/topology--unpackaged.sql.in
@@ -92,3 +92,4 @@
  ALTER EXTENSION postgis_topology ADD type topology.topoelementarray;
  ALTER EXTENSION postgis_topology ADD type topology.topogeometry;
  ALTER EXTENSION postgis_topology ADD type topology.validatetopology_returntype;
+
diff --git a/extensions/upgradeable_versions.mk b/extensions/upgradeable_versions.mk
index e786e14..c78e3bf 100644
--- a/extensions/upgradeable_versions.mk
+++ b/extensions/upgradeable_versions.mk
@@ -7,4 +7,19 @@ UPGRADEABLE_VERSIONS = \
 	2.1.0rc1 \
 	2.1.0rc2 \
 	2.1.0rc3 \
-	2.1.0
+	2.1.0 \
+	2.1.1
+    
+UPGRADEABLE_VERSIONS_MINOR = \
+	2.0.0 \
+    2.0.1 \
+    2.0.2 \
+    2.0.3 \
+    2.0.4 
+
+UPGRADEABLE_VERSIONS_PATCH = \
+	2.1.0rc1 \
+	2.1.0rc2 \
+	2.1.0rc3 \
+	2.1.0 \
+	2.1.1
diff --git a/java/jdbc/Makefile b/java/jdbc/Makefile
index dd4f5f9..9711a16 100644
--- a/java/jdbc/Makefile
+++ b/java/jdbc/Makefile
@@ -10,7 +10,7 @@
 # *
 # **********************************************************************
 
-ANT=/usr/bin/ant
+ANT=/opt/local/bin/ant
 
 all: build
 
diff --git a/java/jdbc/jtssrc/pom.xml b/java/jdbc/jtssrc/pom.xml
index 44f6627..2c2c837 100644
--- a/java/jdbc/jtssrc/pom.xml
+++ b/java/jdbc/jtssrc/pom.xml
@@ -5,7 +5,7 @@
 
 	<groupId>org.postgis</groupId>
 	<artifactId>postgis-jdbc-jtsparser</artifactId>
-	<version>2.0.0</version>
+	<version>2.1.2</version>
 	<packaging>jar</packaging>
 
 	<name>Postgis JDBC Driver JTS Parser</name>
diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml
index b885e74..e455d30 100644
--- a/java/jdbc/pom.xml
+++ b/java/jdbc/pom.xml
@@ -176,7 +176,7 @@
   <properties>
     <POSTGIS_MAJOR_VERSION>2</POSTGIS_MAJOR_VERSION>
     <POSTGIS_MINOR_VERSION>1</POSTGIS_MINOR_VERSION>
-    <POSTGIS_MICRO_VERSION>0SVN</POSTGIS_MICRO_VERSION>
+    <POSTGIS_MICRO_VERSION>2</POSTGIS_MICRO_VERSION>
   </properties>
 	
 </project>
diff --git a/java/jdbc/src/org/postgis/GeometryCollection.java b/java/jdbc/src/org/postgis/GeometryCollection.java
index f366dc2..2eaf968 100644
--- a/java/jdbc/src/org/postgis/GeometryCollection.java
+++ b/java/jdbc/src/org/postgis/GeometryCollection.java
@@ -21,7 +21,7 @@
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit the web at
  * http://www.gnu.org.
  * 
- * $Id: GeometryCollection.java 9324 2012-02-27 22:08:12Z pramsey $
+ * $Id: GeometryCollection.java 12202 2014-01-30 19:17:00Z pramsey $
  */
 
 package org.postgis;
@@ -34,7 +34,7 @@ import java.sql.SQLException;
  * 
  * @author markus.schaber at logix-tt.com
  * 
- * $Id: GeometryCollection.java 9324 2012-02-27 22:08:12Z pramsey $
+ * $Id: GeometryCollection.java 12202 2014-01-30 19:17:00Z pramsey $
  */
 
 public class GeometryCollection extends ComposedGeom {
@@ -68,10 +68,10 @@ public class GeometryCollection extends ComposedGeom {
     }
 
     protected void innerWKT(StringBuffer SB) {
-        subgeoms[0].outerWKT(SB, false);
+        subgeoms[0].outerWKT(SB, true);
         for (int i = 1; i < subgeoms.length; i++) {
             SB.append(',');
-            subgeoms[i].outerWKT(SB, false);
+            subgeoms[i].outerWKT(SB, true);
         }
     }
 
diff --git a/liblwgeom/cunit/cu_geodetic.c b/liblwgeom/cunit/cu_geodetic.c
index 5742375..2fbf061 100644
--- a/liblwgeom/cunit/cu_geodetic.c
+++ b/liblwgeom/cunit/cu_geodetic.c
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: cu_geodetic.c 11535 2013-06-07 17:39:43Z pramsey $
+ * $Id: cu_geodetic.c 12308 2014-03-08 00:51:28Z pramsey $
  *
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.refractions.net
@@ -674,6 +674,31 @@ static void test_edge_intersects(void)
 	line2pts("LINESTRING(90.0 80.0, -90.0 90.0)", &B1, &B2);
 	rv = edge_intersects(&A1, &A2, &B1, &B2);
 	CU_ASSERT(rv == (PIR_INTERSECTS|PIR_B_TOUCH_LEFT|PIR_A_TOUCH_RIGHT) );
+
+	/* Antipodal straddles. Great circles cross but at opposite */
+	/* sides of the globe */
+	/* #2534 */
+	/* http://www.gcmap.com/mapui?P=60N+90E-20S+90E%0D%0A0N+0E-90.04868865037885W+57.44011727050777S%0D%0A&MS=wls&DU=mi */
+	line2pts("LINESTRING(90.0 60.0, 90.0 -20.0)", &A1, &A2);
+	line2pts("LINESTRING(0.0 0.0, -90.04868865037885 -57.44011727050777)", &B1, &B2);
+	rv = edge_intersects(&A1, &A2, &B1, &B2);
+	CU_ASSERT(rv == 0);
+
+	line2pts("LINESTRING(-5 0, 5 0)", &A1, &A2);
+	line2pts("LINESTRING(179 -5, 179 5)", &B1, &B2);
+	rv = edge_intersects(&A1, &A2, &B1, &B2);
+	CU_ASSERT(rv == 0);
+
+	line2pts("LINESTRING(175 -85, 175 85)", &A1, &A2);
+	line2pts("LINESTRING(65 0, -105 0)", &B1, &B2);
+	rv = edge_intersects(&A1, &A2, &B1, &B2);
+	CU_ASSERT(rv == 0);
+	
+	line2pts("LINESTRING(175 -85, 175 85)", &A1, &A2);
+	line2pts("LINESTRING(45 0, -125 0)", &B1, &B2);
+	rv = edge_intersects(&A1, &A2, &B1, &B2);
+	CU_ASSERT(rv == 0);
+	
 }
 
 static void test_edge_distance_to_point(void)
@@ -1195,6 +1220,21 @@ static void test_lwgeom_distance_sphere(void)
 	lwgeom_free(lwg1);
 	lwgeom_free(lwg2);
 
+	/* Ticket #2638, no "M" */
+	lwg1 = lwgeom_from_wkt("LINESTRING (-41.0821 50.3036,50 -41)", LW_PARSER_CHECK_NONE);
+	lwg2 = lwgeom_from_wkt("POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))", LW_PARSER_CHECK_NONE);
+	d = lwgeom_distance_spheroid(lwg1, lwg2, &s, 0.0);
+	CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
+	lwgeom_free(lwg1);
+	lwgeom_free(lwg2);
+
+	/* Ticket #2638, with "M" */
+	lwg1 = lwgeom_from_wkt("LINESTRING M (-41.0821 50.3036 1,50 -41 1)", LW_PARSER_CHECK_NONE);
+	lwg2 = lwgeom_from_wkt("POLYGON M ((0 0 2,10 0 1,10 10 -2,0 10 -5,0 0 -5),(5 5 6,7 5 6,7 7 6,5 7 10,5 5 -2))", LW_PARSER_CHECK_NONE);
+	d = lwgeom_distance_spheroid(lwg1, lwg2, &s, 0.0);
+	CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
+	lwgeom_free(lwg1);
+	lwgeom_free(lwg2);
 }
 
 static void test_spheroid_distance(void)
diff --git a/liblwgeom/cunit/cu_tree.c b/liblwgeom/cunit/cu_tree.c
index da29fba..ddc23e8 100644
--- a/liblwgeom/cunit/cu_tree.c
+++ b/liblwgeom/cunit/cu_tree.c
@@ -283,6 +283,24 @@ static void test_tree_circ_distance(void)
 	lwgeom_free(lwg1);
 	lwgeom_free(lwg2);
 	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);
+	
+	/* Ticket #2634 */
+	lwg1 = lwgeom_from_wkt("MULTIPOINT (-10 40,-10 65,10 40,10 65,30 40,30 65,50 40,50 65)", LW_PARSER_CHECK_NONE);
+	lwg2 = lwgeom_from_wkt("POLYGON((-9.1111111 40,-9.14954053919354 39.6098193559677,-9.26335203497743 39.2346331352698,-9.4481718753949138.8888595339608,-9.6968975376269 38.5857864376269,-9.99997063396079 38.3370607753949,-10.3457442352698 38.1522409349774,-10.7209304559677 38.0384294391935,-11.1111111 38,-11.5012917440323 38.0384294391935,-11.8764779647302 38.1522409349774,-12.2222515660392 38.3370607753949,-12.5253246623731 38.5857864376269,-12.7740503246051 38.8888595339608,-12.9588701 [...]
+	c1 = lwgeom_calculate_circ_tree(lwg1);
+	c2 = lwgeom_calculate_circ_tree(lwg2);
+	d1 = circ_tree_distance_tree(c1, c2, &s, threshold);
+	d2 = lwgeom_distance_spheroid(lwg1, lwg2, &s, threshold);
+	// printf("d1 = %g   d2 = %g\n", d1 * WGS84_RADIUS, d2 * WGS84_RADIUS);
+	// printf("multipoint\n");
+	// circ_tree_print(c1, 0);
+	// printf("polygon\n");
+	// circ_tree_print(c2, 0);
+	circ_tree_free(c1);
+	circ_tree_free(c2);
+	lwgeom_free(lwg1);
+	lwgeom_free(lwg2);
+	CU_ASSERT_DOUBLE_EQUAL(d1, d2, 0.0000001);	
 }
 
 
diff --git a/liblwgeom/g_box.c b/liblwgeom/g_box.c
index ffcd8b9..f717262 100644
--- a/liblwgeom/g_box.c
+++ b/liblwgeom/g_box.c
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: g_box.c 12083 2013-11-04 23:17:11Z pramsey $
+ * $Id: g_box.c 12296 2014-03-06 05:53:39Z pramsey $
  *
  * PostGIS - Spatial Types for PostgreSQL
  * Copyright 2009 Paul Ramsey <pramsey at cleverelephant.ca>
@@ -9,6 +9,10 @@
  *
  **********************************************************************/
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include "liblwgeom_internal.h"
 #include "lwgeom_log.h"
 #include <stdlib.h>
@@ -240,10 +244,19 @@ int gbox_overlaps(const GBOX *g1, const GBOX *g2)
 	if ( g1->xmax < g2->xmin || g1->ymax < g2->ymin ||
 	     g1->xmin > g2->xmax || g1->ymin > g2->ymax )
 		return LW_FALSE;
+
+	/* Deal with the geodetic case special: we only compare the geodetic boxes (x/y/z) */
+	/* Never the M dimension */
+	if ( FLAGS_GET_GEODETIC(g1->flags) && FLAGS_GET_GEODETIC(g2->flags) )
+	{
+		if ( g1->zmax < g2->zmin || g1->zmin > g2->zmax )
+			return LW_FALSE;
+		else
+			return LW_TRUE;		
+	}
 		
 	/* If both geodetic or both have Z, check Z */
-	if ( (FLAGS_GET_Z(g1->flags) && FLAGS_GET_Z(g2->flags)) || 
-	     (FLAGS_GET_GEODETIC(g1->flags) && FLAGS_GET_GEODETIC(g2->flags)) )
+	if ( FLAGS_GET_Z(g1->flags) && FLAGS_GET_Z(g2->flags) )
 	{
 		if ( g1->zmax < g2->zmin || g1->zmin > g2->zmax )
 			return LW_FALSE;
diff --git a/liblwgeom/lwgeodetic.c b/liblwgeom/lwgeodetic.c
index 4632aee..4c96009 100644
--- a/liblwgeom/lwgeodetic.c
+++ b/liblwgeom/lwgeodetic.c
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: lwgeodetic.c 11535 2013-06-07 17:39:43Z pramsey $
+ * $Id: lwgeodetic.c 12358 2014-03-26 09:37:44Z pramsey $
  *
  * PostGIS - Spatial Types for PostgreSQL
  * Copyright 2009 Paul Ramsey <pramsey at cleverelephant.ca>
@@ -443,10 +443,10 @@ static void vector_scale(POINT3D *n, double scale)
 	return;
 }
 
-static inline double vector_magnitude(const POINT3D* v)
-{
-	return sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
-}
+// static inline double vector_magnitude(const POINT3D* v)
+// {
+// 	return sqrt(v->x*v->x + v->y*v->y + v->z*v->z);
+// }
 
 /**
 * Angle between two unit vectors
@@ -1419,7 +1419,22 @@ int edge_calculate_gbox(const POINT3D *A1, const POINT3D *A2, GBOX *gbox)
 	return LW_SUCCESS;
 }
 
-
+void lwpoly_pt_outside(const LWPOLY *poly, POINT2D *pt_outside)
+{	
+	/* Make sure we have boxes */
+	if ( poly->bbox )
+	{
+		gbox_pt_outside(poly->bbox, pt_outside);
+		return;
+	}
+	else
+	{
+		GBOX gbox;
+		lwgeom_calculate_gbox_geodetic((LWGEOM*)poly, &gbox);
+		gbox_pt_outside(&gbox, pt_outside);
+		return;
+	}
+}
 
 /**
 * Given a unit geocentric gbox, return a lon/lat (degrees) coordinate point point that is
@@ -1814,6 +1829,7 @@ static double ptarray_distance_spheroid(const POINTARRAY *pa1, const POINTARRAY
 			}
 			e1.start = e1.end;
 		}
+
 		/* On sphere, return answer */
 		if ( use_sphere )
 			return distance;
@@ -3078,7 +3094,7 @@ dot_product_side(const POINT3D *p, const POINT3D *q)
 int 
 edge_intersects(const POINT3D *A1, const POINT3D *A2, const POINT3D *B1, const POINT3D *B2)
 {
-	POINT3D AN, BN;  /* Normals to plane A and plane B */
+	POINT3D AN, BN, VN;  /* Normals to plane A and plane B */
 	double ab_dot;
 	int a1_side, a2_side, b1_side, b2_side;
 	int rv = PIR_NO_INTERACT;
@@ -3126,8 +3142,21 @@ edge_intersects(const POINT3D *A1, const POINT3D *A2, const POINT3D *B1, const P
 	if ( a1_side != a2_side && (a1_side + a2_side) == 0 &&
 	     b1_side != b2_side && (b1_side + b2_side) == 0 )
 	{
-		/* Mid-point intersection! */
-		return PIR_INTERSECTS;
+		/* Have to check if intersection point is inside both arcs */
+		unit_normal(&AN, &BN, &VN);
+		if ( point_in_cone(A1, A2, &VN) && point_in_cone(B1, B2, &VN) )
+		{
+			return PIR_INTERSECTS;
+		}
+
+		/* Have to check if intersection point is inside both arcs */
+		vector_scale(&VN, -1);
+		if ( point_in_cone(A1, A2, &VN) && point_in_cone(B1, B2, &VN) )
+		{
+			return PIR_INTERSECTS;
+		}
+		
+		return PIR_NO_INTERACT;
 	}
 
 	/* The rest are all intersects variants... */
diff --git a/liblwgeom/lwgeodetic.h b/liblwgeom/lwgeodetic.h
index b85fd5d..302213c 100644
--- a/liblwgeom/lwgeodetic.h
+++ b/liblwgeom/lwgeodetic.h
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: lwgeodetic.h 10566 2012-10-25 22:17:39Z pramsey $
+ * $Id: lwgeodetic.h 12343 2014-03-25 08:17:56Z pramsey $
  *
  * PostGIS - Spatial Types for PostgreSQL
  * Copyright 2009 Paul Ramsey <pramsey at cleverelephant.ca>
@@ -105,6 +105,7 @@ double edge_distance_to_edge(const GEOGRAPHIC_EDGE *e1, const GEOGRAPHIC_EDGE *e
 void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g);
 int ptarray_contains_point_sphere(const POINTARRAY *pa, const POINT2D *pt_outside, const POINT2D *pt_to_test);
 int lwpoly_covers_point2d(const LWPOLY *poly, const POINT2D *pt_to_test);
+void lwpoly_pt_outside(const LWPOLY *poly, POINT2D *pt_outside);
 int ptarray_point_in_ring(const POINTARRAY *pa, const POINT2D *pt_outside, const POINT2D *pt_to_test);
 double ptarray_area_sphere(const POINTARRAY *pa);
 double latitude_degrees_normalize(double lat);
@@ -130,4 +131,16 @@ double spheroid_distance(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b, c
 double spheroid_direction(const GEOGRAPHIC_POINT *r, const GEOGRAPHIC_POINT *s, const SPHEROID *spheroid);
 int spheroid_project(const GEOGRAPHIC_POINT *r, const SPHEROID *spheroid, double distance, double azimuth, GEOGRAPHIC_POINT *g);
 
+
 #endif /* _LWGEODETIC_H */
+
+
+
+/**
+* Notes for rewrite
+* 
+* Define separate POINT types for 2-d-points-in-radiands and 3-d-points-in-geocentric
+* Maintain consistent units (radians?) throughout all calculations
+* Put an index pointer onto LWGEOM itself, and cache the indexed LWGEOM instead of a bare tree
+* only primitive objects should get a tree
+*/
\ No newline at end of file
diff --git a/liblwgeom/lwgeodetic_tree.c b/liblwgeom/lwgeodetic_tree.c
index 1ab5960..c972fd6 100644
--- a/liblwgeom/lwgeodetic_tree.c
+++ b/liblwgeom/lwgeodetic_tree.c
@@ -80,6 +80,11 @@ circ_node_leaf_new(const POINTARRAY* pa, int i)
 	node->num_nodes = 0;
 	node->nodes = NULL;
 	node->edge_num = i;
+    
+    /* Zero out metadata */
+    node->pt_outside.x = 0.0;
+    node->pt_outside.y = 0.0;
+    node->geom_type = 0;
 	
 	return node;
 }
@@ -97,6 +102,9 @@ circ_node_leaf_point_new(const POINTARRAY* pa)
 	tree->nodes = NULL;
 	tree->num_nodes = 0;
 	tree->edge_num = 0;
+    tree->geom_type = POINTTYPE;
+    tree->pt_outside.x = 0.0;
+    tree->pt_outside.y = 0.0;
 	return tree;
 }
 
@@ -109,8 +117,8 @@ circ_node_compare(const void* v1, const void* v2)
 {
 	POINT2D p1, p2;
 	unsigned int u1, u2;
-	CIRC_NODE *c1 = (CIRC_NODE*)v1;
-	CIRC_NODE *c2 = (CIRC_NODE*)v2;
+	CIRC_NODE *c1 = *((CIRC_NODE**)v1);
+	CIRC_NODE *c2 = *((CIRC_NODE**)v2);
 	p1.x = rad2deg((c1->center).lon);
 	p1.y = rad2deg((c1->center).lat);
 	p2.x = rad2deg((c2->center).lon);
@@ -199,7 +207,7 @@ circ_node_internal_new(CIRC_NODE** c, int num_nodes)
 	GEOGRAPHIC_POINT new_center, c1;
 	double new_radius;
 	double offset1, dist, D, r1, ri;
-	int i;
+	int i, new_geom_type;
 
 	LWDEBUGF(3, "called with %d nodes --", num_nodes);
 
@@ -210,6 +218,7 @@ circ_node_internal_new(CIRC_NODE** c, int num_nodes)
 	/* Initialize calculation with values of the first circle */
 	new_center = c[0]->center;
 	new_radius = c[0]->radius;
+	new_geom_type = c[0]->geom_type;
 	
 	/* Merge each remaining circle into the new circle */
 	for ( i = 1; i < num_nodes; i++ )
@@ -220,6 +229,32 @@ circ_node_internal_new(CIRC_NODE** c, int num_nodes)
 		dist = sphere_distance(&c1, &(c[i]->center));
 		ri = c[i]->radius;
 
+		/* Promote geometry types up the tree, getting more and more collected */
+		/* Go until we find a value */
+		if ( ! new_geom_type )
+		{
+			new_geom_type = c[i]->geom_type;
+		}
+		/* Promote singleton to a multi-type */
+		else if ( ! lwtype_is_collection(new_geom_type) )
+		{
+			/* Anonymous collection if types differ */
+			if ( new_geom_type != c[i]->geom_type )
+			{
+				new_geom_type = COLLECTIONTYPE;
+			}
+			else
+			{
+				new_geom_type = lwtype_get_collectiontype(new_geom_type);				
+			}
+		}
+		/* If we can't add next feature to this collection cleanly, promote again to anonymous collection */
+		else if ( new_geom_type != lwtype_get_collectiontype(c[i]->geom_type) )
+		{
+			new_geom_type = COLLECTIONTYPE;
+		}
+
+
 		LWDEBUGF(3, "distance between new (%g %g) and %i (%g %g) is %g", c1.lon, c1.lat, i, c[i]->center.lon, c[i]->center.lat, dist);
 		
 		if ( FP_EQUALS(dist, 0) )
@@ -280,13 +315,14 @@ circ_node_internal_new(CIRC_NODE** c, int num_nodes)
 	node->num_nodes = num_nodes;
 	node->nodes = c;
 	node->edge_num = -1;
+    node->geom_type = new_geom_type;
+    node->pt_outside.x = 0.0;
+    node->pt_outside.y = 0.0;
 	return node;
 }
 
 /**
-* Build a tree of nodes from a point array, one node per edge, and each
-* with an associated measure range along a one-dimensional space. We
-* can then search that space as a range tree.
+* Build a tree of nodes from a point array, one node per edge.
 */
 CIRC_NODE* 
 circ_tree_new(const POINTARRAY* pa)
@@ -352,6 +388,9 @@ circ_nodes_merge(CIRC_NODE** nodes, int num_nodes)
 	int num_parents = 0;
 	int j;
 
+	// TODO, roll geom_type *up* as tree is built, changing to collection types as simple types are merged 
+	// TODO, change the distance algorithm to drive down to simple types first, test pip on poly/other cases, then test edges
+
 	while( num_children > 1 )
 	{
 		for ( j = 0; j < num_children; j++ )
@@ -389,6 +428,24 @@ circ_nodes_merge(CIRC_NODE** nodes, int num_nodes)
 
 
 /**
+* Returns a #POINT2D that is a vertex of the input shape
+*/
+int circ_tree_get_point(const CIRC_NODE* node, POINT2D* pt)
+{
+	if ( circ_node_is_leaf(node) )
+    {
+        pt->x = node->p1->x;
+        pt->y = node->p1->y;
+        return LW_SUCCESS;
+    }
+    else
+    {
+        return circ_tree_get_point(node->nodes[0], pt);
+    }
+}
+
+
+/**
 * Walk the tree and count intersections between the stab line and the edges.
 * odd => containment, even => no containment.
 * KNOWN PROBLEM: Grazings (think of a sharp point, just touching the
@@ -498,13 +555,19 @@ circ_tree_distance_tree(const CIRC_NODE* n1, const CIRC_NODE* n2, const SPHEROID
 	double min_dist = MAXFLOAT;
 	double max_dist = MAXFLOAT;
 	GEOGRAPHIC_POINT closest1, closest2;
-	double distance2;
 	double threshold_radians = threshold / spheroid->radius;
 	
 	circ_tree_distance_tree_internal(n1, n2, threshold_radians, &min_dist, &max_dist, &closest1, &closest2);
-	distance2 = spheroid_distance(&closest1, &closest2, spheroid);
 
-	return distance2;
+	/* Spherical case */
+	if ( spheroid->a == spheroid->b )
+	{
+		return spheroid->radius * sphere_distance(&closest1, &closest2);
+	}
+	else
+	{
+		return spheroid_distance(&closest1, &closest2, spheroid);		
+	}
 }
 
 static double 
@@ -514,12 +577,12 @@ circ_tree_distance_tree_internal(const CIRC_NODE* n1, const CIRC_NODE* n2, doubl
 	double d, d_min;
 	int i;
 	
-	LWDEBUGF(4, "entered, min_dist %.8g max_dist %.8g", *min_dist, *max_dist);
+	LWDEBUGF(4, "entered, min_dist=%.8g max_dist=%.8g, type1=%d, type2=%d", *min_dist, *max_dist, n1->geom_type, n2->geom_type);
 //	circ_tree_print(n1, 0);
 //	circ_tree_print(n2, 0);
 	
 	/* Short circuit if we've already hit the minimum */
-	if( FP_LT(*min_dist, threshold) )
+	if( *min_dist <= threshold )
 		return *min_dist;
 	
 	/* If your minimum is greater than anyone's maximum, you can't hold the winner */
@@ -535,127 +598,204 @@ circ_tree_distance_tree_internal(const CIRC_NODE* n1, const CIRC_NODE* n2, doubl
 	if( max < *max_dist )
 		*max_dist = max;
 
+	/* Polygon on one side, primitive type on the other. Check for point-in-polygon */
+	/* short circuit. */
+	if ( n1->geom_type == POLYGONTYPE && n2->geom_type && ! lwtype_is_collection(n2->geom_type) )
+	{
+		POINT2D pt;
+		circ_tree_get_point(n2, &pt);
+		LWDEBUGF(4, "n1 is polygon, testing if contains (%.5g,%.5g)", pt.x, pt.y);
+		if ( circ_tree_contains_point(n1, &pt, &(n1->pt_outside), NULL) )
+		{
+			LWDEBUG(4, "it does");
+			*min_dist = 0.0;
+			geographic_point_init(pt.x, pt.y, closest1);
+			geographic_point_init(pt.x, pt.y, closest2);
+			return *min_dist;
+		}			
+	}
+	/* Polygon on one side, primitive type on the other. Check for point-in-polygon */
+	/* short circuit. */
+	if ( n2->geom_type == POLYGONTYPE && n1->geom_type && ! lwtype_is_collection(n1->geom_type) )
+	{
+		POINT2D pt;
+		circ_tree_get_point(n1, &pt);
+		LWDEBUGF(4, "n2 is polygon, testing if contains (%.5g,%.5g)", pt.x, pt.y);
+		if ( circ_tree_contains_point(n2, &pt, &(n2->pt_outside), NULL) )
+		{
+			LWDEBUG(4, "it does");
+			geographic_point_init(pt.x, pt.y, closest1);
+			geographic_point_init(pt.x, pt.y, closest2);
+			*min_dist = 0.0;
+			return *min_dist;
+		}		
+	}
+	
 	/* Both leaf nodes, do a real distance calculation */
-	if( circ_node_is_leaf(n1) )
+	if( circ_node_is_leaf(n1) && circ_node_is_leaf(n2) )
 	{
-		if( circ_node_is_leaf(n2) )
+		double d;
+		GEOGRAPHIC_POINT close1, close2;
+		LWDEBUGF(4, "testing leaf pair [%d], [%d]", n1->edge_num, n2->edge_num);		
+		/* One of the nodes is a point */
+		if ( n1->p1 == n1->p2 || n2->p1 == n2->p2 )
 		{
-			double d;
-			GEOGRAPHIC_POINT close1, close2;
-			LWDEBUGF(4, "testing leaf pair [%d], [%d]", n1->edge_num, n2->edge_num);		
-			/* One of the nodes is a point */
-			if ( n1->p1 == n1->p2 || n2->p1 == n2->p2 )
-			{
-				GEOGRAPHIC_EDGE e;
-				GEOGRAPHIC_POINT gp1, gp2;
+			GEOGRAPHIC_EDGE e;
+			GEOGRAPHIC_POINT gp1, gp2;
 
-				/* Both nodes are points! */
-				if ( n1->p1 == n1->p2 && n2->p1 == n2->p2 )
-				{
-					geographic_point_init(n1->p1->x, n1->p1->y, &gp1);
-					geographic_point_init(n2->p1->x, n2->p1->y, &gp2);
-					close1 = gp1; close2 = gp2;
-					d = sphere_distance(&gp1, &gp2);
-				}				
-				/* Node 1 is a point */
-				else if ( n1->p1 == n1->p2 )
-				{
-					geographic_point_init(n1->p1->x, n1->p1->y, &gp1);
-					geographic_point_init(n2->p1->x, n2->p1->y, &(e.start));
-					geographic_point_init(n2->p2->x, n2->p2->y, &(e.end));
-					close1 = gp1;
-					d = edge_distance_to_point(&e, &gp1, &close2);
-				}
-				/* Node 2 is a point */
-				else
-				{
-					geographic_point_init(n2->p1->x, n2->p1->y, &gp1);
-					geographic_point_init(n1->p1->x, n1->p1->y, &(e.start));
-					geographic_point_init(n1->p2->x, n1->p2->y, &(e.end));
-					close1 = gp1;
-					d = edge_distance_to_point(&e, &gp1, &close2);
-				}
-				LWDEBUGF(4, "  got distance %g", d);		
+			/* Both nodes are points! */
+			if ( n1->p1 == n1->p2 && n2->p1 == n2->p2 )
+			{
+				geographic_point_init(n1->p1->x, n1->p1->y, &gp1);
+				geographic_point_init(n2->p1->x, n2->p1->y, &gp2);
+				close1 = gp1; close2 = gp2;
+				d = sphere_distance(&gp1, &gp2);
+			}				
+			/* Node 1 is a point */
+			else if ( n1->p1 == n1->p2 )
+			{
+				geographic_point_init(n1->p1->x, n1->p1->y, &gp1);
+				geographic_point_init(n2->p1->x, n2->p1->y, &(e.start));
+				geographic_point_init(n2->p2->x, n2->p2->y, &(e.end));
+				close1 = gp1;
+				d = edge_distance_to_point(&e, &gp1, &close2);
 			}
-			/* Both nodes are edges */
+			/* Node 2 is a point */
 			else
 			{
-				GEOGRAPHIC_EDGE e1, e2;
-				GEOGRAPHIC_POINT g;
-				POINT3D A1, A2, B1, B2;
-				geographic_point_init(n1->p1->x, n1->p1->y, &(e1.start));
-				geographic_point_init(n1->p2->x, n1->p2->y, &(e1.end));
-				geographic_point_init(n2->p1->x, n2->p1->y, &(e2.start));
-				geographic_point_init(n2->p2->x, n2->p2->y, &(e2.end));
-				geog2cart(&(e1.start), &A1);
-				geog2cart(&(e1.end), &A2);
-				geog2cart(&(e2.start), &B1);
-				geog2cart(&(e2.end), &B2);
-				if ( edge_intersects(&A1, &A2, &B1, &B2) )
-				{
-					d = 0.0;
-					edge_intersection(&e1, &e2, &g);
-					close1 = close2 = g;
-				}
-				else
-				{
-					d = edge_distance_to_edge(&e1, &e2, &close1, &close2);
-				}
-				LWDEBUGF(4, "edge_distance_to_edge returned %g", d);		
+				geographic_point_init(n2->p1->x, n2->p1->y, &gp1);
+				geographic_point_init(n1->p1->x, n1->p1->y, &(e.start));
+				geographic_point_init(n1->p2->x, n1->p2->y, &(e.end));
+				close1 = gp1;
+				d = edge_distance_to_point(&e, &gp1, &close2);
+			}
+			LWDEBUGF(4, "  got distance %g", d);		
+		}
+		/* Both nodes are edges */
+		else
+		{
+			GEOGRAPHIC_EDGE e1, e2;
+			GEOGRAPHIC_POINT g;
+			POINT3D A1, A2, B1, B2;
+			geographic_point_init(n1->p1->x, n1->p1->y, &(e1.start));
+			geographic_point_init(n1->p2->x, n1->p2->y, &(e1.end));
+			geographic_point_init(n2->p1->x, n2->p1->y, &(e2.start));
+			geographic_point_init(n2->p2->x, n2->p2->y, &(e2.end));
+			geog2cart(&(e1.start), &A1);
+			geog2cart(&(e1.end), &A2);
+			geog2cart(&(e2.start), &B1);
+			geog2cart(&(e2.end), &B2);
+			if ( edge_intersects(&A1, &A2, &B1, &B2) )
+			{
+				d = 0.0;
+				edge_intersection(&e1, &e2, &g);
+				close1 = close2 = g;
 			}
-			if ( d < *min_dist )
+			else
 			{
-				*min_dist = d;
-				*closest1 = close1;
-				*closest2 = close2;
+				d = edge_distance_to_edge(&e1, &e2, &close1, &close2);
 			}
-			return d;
+			LWDEBUGF(4, "edge_distance_to_edge returned %g", d);		
 		}
-		else
+		if ( d < *min_dist )
+		{
+			*min_dist = d;
+			*closest1 = close1;
+			*closest2 = close2;
+		}
+		return d;
+	}
+	else
+	{	
+		d_min = MAXFLOAT;
+		/* Drive the recursion into the COLLECTION types first so we end up with */
+		/* pairings of primitive geometries that can be forced into the point-in-polygon */
+		/* tests above. */
+		if ( n1->geom_type && lwtype_is_collection(n1->geom_type) )
+		{
+			for ( i = 0; i < n1->num_nodes; i++ )
+			{
+				d = circ_tree_distance_tree_internal(n1->nodes[i], n2, threshold, min_dist, max_dist, closest1, closest2);
+				d_min = FP_MIN(d_min, d);
+			}
+		}
+		else if ( n2->geom_type && lwtype_is_collection(n2->geom_type) )
 		{
-			d_min = MAXFLOAT;
 			for ( i = 0; i < n2->num_nodes; i++ )
 			{
 				d = circ_tree_distance_tree_internal(n1, n2->nodes[i], threshold, min_dist, max_dist, closest1, closest2);
 				d_min = FP_MIN(d_min, d);
 			}
-			return d_min;
 		}
-	}
-	else
-	{
-		d_min = MAXFLOAT;
-		for ( i = 0; i < n1->num_nodes; i++ )
+		else if ( ! circ_node_is_leaf(n1) )
 		{
-			d = circ_tree_distance_tree_internal(n2, n1->nodes[i], threshold, min_dist, max_dist, closest1, closest2);
-			d_min = FP_MIN(d_min, d);
+			for ( i = 0; i < n1->num_nodes; i++ )
+			{
+				d = circ_tree_distance_tree_internal(n1->nodes[i], n2, threshold, min_dist, max_dist, closest1, closest2);
+				d_min = FP_MIN(d_min, d);
+			}
 		}
+		else if ( ! circ_node_is_leaf(n2) )
+		{
+			for ( i = 0; i < n2->num_nodes; i++ )
+			{
+				d = circ_tree_distance_tree_internal(n1, n2->nodes[i], threshold, min_dist, max_dist, closest1, closest2);
+				d_min = FP_MIN(d_min, d);
+			}
+		}
+		else
+		{
+			/* Never get here */
+		}
+		
 		return d_min;
 	}
 }
 
 
+
+
+
 void circ_tree_print(const CIRC_NODE* node, int depth)
 {
 	int i;
-	
-	if ( node->num_nodes > 0 ) 
-	{
-		printf("%*s C(%.5g %.5g) R(%.5g)\n", 
-		  3*depth + 6, "NODE", 
-		  node->center.lon, node->center.lat,
-		  node->radius
-		);
-	}
-	else
+
+	if (circ_node_is_leaf(node))
 	{
-		printf("%*s[%d] C(%.5g %.5g) R(%.5g) ((%.5g %.5g),(%.5g,%.5g))\n", 
+		printf("%*s[%d] C(%.5g %.5g) R(%.5g) ((%.5g %.5g),(%.5g,%.5g))", 
 		  3*depth + 6, "NODE", node->edge_num,
 		  node->center.lon, node->center.lat,
 		  node->radius,
 		  node->p1->x, node->p1->y,
 		  node->p2->x, node->p2->y
 		);
+  		if ( node->geom_type )
+  		{
+  			printf(" %s", lwtype_name(node->geom_type));
+  		}		
+  		if ( node->geom_type == POLYGONTYPE )
+  		{
+  			printf(" O(%.5g %.5g)", node->pt_outside.x, node->pt_outside.y);
+  		}				
+  		printf("\n");
+		  
+	}	
+	else
+	{
+		printf("%*s C(%.5g %.5g) R(%.5g)", 
+		  3*depth + 6, "NODE", 
+		  node->center.lon, node->center.lat,
+		  node->radius
+		);
+		if ( node->geom_type )
+		{
+			printf(" %s", lwtype_name(node->geom_type));
+		}
+  		if ( node->geom_type == POLYGONTYPE )
+  		{
+  			printf(" O(%.5g %.5g)", node->pt_outside.x, node->pt_outside.y);
+  		}		
+		printf("\n");
 	}
 	for ( i = 0; i < node->num_nodes; i++ )
 	{
@@ -668,13 +808,19 @@ void circ_tree_print(const CIRC_NODE* node, int depth)
 static CIRC_NODE*
 lwpoint_calculate_circ_tree(const LWPOINT* lwpoint)
 {
-	return circ_tree_new(lwpoint->point);
+	CIRC_NODE* node;
+    node = circ_tree_new(lwpoint->point);
+    node->geom_type = lwgeom_get_type((LWGEOM*)lwpoint);;
+	return node;
 }
 
 static CIRC_NODE*
 lwline_calculate_circ_tree(const LWLINE* lwline)
 {
-	return circ_tree_new(lwline->points);
+	CIRC_NODE* node;
+    node = circ_tree_new(lwline->points);
+    node->geom_type = lwgeom_get_type((LWGEOM*)lwline);
+	return node;
 }
 
 static CIRC_NODE*
@@ -686,22 +832,31 @@ lwpoly_calculate_circ_tree(const LWPOLY* lwpoly)
 
 	/* One ring? Handle it like a line. */
 	if ( lwpoly->nrings == 1 )
-		return circ_tree_new(lwpoly->rings[0]);	
-	
-	/* Calculate a tree for each non-trivial ring of the polygon */
-	nodes = lwalloc(lwpoly->nrings * sizeof(CIRC_NODE*));
-	for ( i = 0; i < lwpoly->nrings; i++ )
 	{
-		node = circ_tree_new(lwpoly->rings[i]);
-		if ( node )
-			nodes[j++] = node;
+		node = circ_tree_new(lwpoly->rings[0]);			
 	}
-	/* Put the trees into a spatially correlated order */
-	circ_nodes_sort(nodes, j);
-	/* Merge the trees pairwise up to a parent node and return */
-	node = circ_nodes_merge(nodes, j);
-	/* Don't need the working list any more */
-	lwfree(nodes);
+	else
+	{
+		/* Calculate a tree for each non-trivial ring of the polygon */
+		nodes = lwalloc(lwpoly->nrings * sizeof(CIRC_NODE*));
+		for ( i = 0; i < lwpoly->nrings; i++ )
+		{
+			node = circ_tree_new(lwpoly->rings[i]);
+			if ( node )
+				nodes[j++] = node;
+		}
+		/* Put the trees into a spatially correlated order */
+		circ_nodes_sort(nodes, j);
+		/* Merge the trees pairwise up to a parent node and return */
+		node = circ_nodes_merge(nodes, j);
+		/* Don't need the working list any more */
+		lwfree(nodes);
+	}
+
+	/* Metatdata about polygons, we need this to apply P-i-P tests */
+	/* selectively when doing distance calculations */
+    node->geom_type = lwgeom_get_type((LWGEOM*)lwpoly);
+	lwpoly_pt_outside(lwpoly, &(node->pt_outside));
 	
 	return node;
 }
@@ -732,6 +887,8 @@ lwcollection_calculate_circ_tree(const LWCOLLECTION* lwcol)
 	/* Don't need the working list any more */
 	lwfree(nodes);
 	
+    node->geom_type = lwgeom_get_type((LWGEOM*)lwcol);
+    
 	return node;
 }
 
diff --git a/liblwgeom/lwgeodetic_tree.h b/liblwgeom/lwgeodetic_tree.h
index 60244ec..c80c412 100644
--- a/liblwgeom/lwgeodetic_tree.h
+++ b/liblwgeom/lwgeodetic_tree.h
@@ -16,6 +16,8 @@ typedef struct circ_node
 	int num_nodes;
 	struct circ_node** nodes;
 	int edge_num;
+    int geom_type;
+    POINT2D pt_outside;
 	POINT2D* p1;
 	POINT2D* p2;
 } CIRC_NODE;
@@ -26,5 +28,6 @@ void circ_tree_free(CIRC_NODE* node);
 int circ_tree_contains_point(const CIRC_NODE* node, const POINT2D* pt, const POINT2D* pt_outside, int* on_boundary);
 double circ_tree_distance_tree(const CIRC_NODE* n1, const CIRC_NODE* n2, const SPHEROID *spheroid, double threshold);
 CIRC_NODE* lwgeom_calculate_circ_tree(const LWGEOM* lwgeom);
+int circ_tree_get_point(const CIRC_NODE* node, POINT2D* pt);
 
 #endif /* _LWGEODETIC_TREE_H */
\ No newline at end of file
diff --git a/liblwgeom/lwin_geojson.c b/liblwgeom/lwin_geojson.c
index e4de54a..4ce16cb 100644
--- a/liblwgeom/lwin_geojson.c
+++ b/liblwgeom/lwin_geojson.c
@@ -82,29 +82,19 @@ parse_geojson_coord(json_object *poObj, int *hasz, POINTARRAY *pa)
 
 		// Read X coordinate
 		poObjCoord = json_object_array_get_idx( poObj, 0 );
-		iType = json_object_get_type(poObjCoord);
-		if (iType == json_type_double)
-			pt.x = json_object_get_double( poObjCoord );
-		else
-			pt.x = json_object_get_int( poObjCoord );
+		pt.x = json_object_get_double( poObjCoord );
 		LWDEBUGF(3, "parse_geojson_coord pt.x = %f.", pt.x );
 
-		// Read Y coordiante
+		// Read Y coordinate
 		poObjCoord = json_object_array_get_idx( poObj, 1 );
-		if (iType == json_type_double)
-			pt.y = json_object_get_double( poObjCoord );
-		else
-			pt.y = json_object_get_int( poObjCoord );
+		pt.y = json_object_get_double( poObjCoord );
 		LWDEBUGF(3, "parse_geojson_coord pt.y = %f.", pt.y );
 
 		if( nSize == 3 ) /* should this be >= 3 ? */
 		{
-			// Read Z coordiante
+			// Read Z coordinate
 			poObjCoord = json_object_array_get_idx( poObj, 2 );
-			if (iType == 3)
-				pt.z = json_object_get_double( poObjCoord );
-			else
-				pt.z = json_object_get_int( poObjCoord );
+			pt.z = json_object_get_double( poObjCoord );
 			LWDEBUGF(3, "parse_geojson_coord pt.z = %f.", pt.z );
 			*hasz = LW_TRUE;
 		}
@@ -190,49 +180,59 @@ parse_geojson_polygon(json_object *geojson, int *hasz,  int root_srid)
 	POINTARRAY **ppa;
 	json_object* rings = NULL;
 	int i = 0, j = 0;
-	int ring = 0;
+	int nRings = 0;
+	int nPoints = 0;
 
 	rings = findMemberByName( geojson, "coordinates" );
-	if ( ! rings ) {
+	if ( ! rings ) 
+	{
 		geojson_lwerror("Unable to find 'coordinates' in GeoJSON string", 4);
-    return NULL;
-  }
+		return NULL;
+	}
+
+	if ( json_type_array != json_object_get_type(rings) )
+	{
+		geojson_lwerror("The 'coordinates' in GeoJSON string are not an array", 4);
+		return NULL;
+	}
+	
+	nRings = json_object_array_length( rings );
+
+	if ( ! nRings )
+	{
+		return (LWGEOM *)lwpoly_construct_empty(root_srid, 0, 0);
+	}
 
 	ppa = (POINTARRAY**) lwalloc(sizeof(POINTARRAY*));
 
-	if( json_type_array == json_object_get_type( rings ) )
+	json_object* points = NULL;
+	ppa[0] = ptarray_construct_empty(1, 0, 1);
+	points = json_object_array_get_idx( rings, 0 );
+	nPoints = json_object_array_length( points );
+
+	for (i=0; i < nPoints; i++ )
+	{
+		json_object* coords = NULL;
+		coords = json_object_array_get_idx( points, i );
+		parse_geojson_coord(coords, hasz, ppa[0]);
+	}
+
+	for(i = 1; i < nRings; ++i)
 	{
 		int nPoints;
-		json_object* points = NULL;
-		ppa[0] = ptarray_construct_empty(1, 0, 1);
-		ring = json_object_array_length( rings );
-		points = json_object_array_get_idx( rings, 0 );
+		ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa, sizeof(POINTARRAY*) * (i + 1));
+		ppa[i] = ptarray_construct_empty(1, 0, 1);
+		points = json_object_array_get_idx( rings, i );
 		nPoints = json_object_array_length( points );
-
-		for (i=0; i < nPoints; i++ )
+		for (j=0; j < nPoints; j++ )
 		{
 			json_object* coords = NULL;
-			coords = json_object_array_get_idx( points, i );
-			parse_geojson_coord(coords, hasz, ppa[0]);
-		}
-
-		for(i = 1; i < ring; ++i)
-		{
-			int nPoints;
-			ppa = (POINTARRAY**) lwrealloc((POINTARRAY *) ppa, sizeof(POINTARRAY*) * (i + 1));
-			ppa[i] = ptarray_construct_empty(1, 0, 1);
-			points = json_object_array_get_idx( rings, i );
-			nPoints = json_object_array_length( points );
-			for (j=0; j < nPoints; j++ )
-			{
-				json_object* coords = NULL;
-				coords = json_object_array_get_idx( points, j );
-				parse_geojson_coord(coords, hasz, ppa[i]);
-			}
+			coords = json_object_array_get_idx( points, j );
+			parse_geojson_coord(coords, hasz, ppa[i]);
 		}
 	}
 
-	geom = (LWGEOM *) lwpoly_construct(root_srid, NULL, ring, ppa);
+	geom = (LWGEOM *) lwpoly_construct(root_srid, NULL, nRings, ppa);
 	return geom;
 }
 
diff --git a/libtool b/libtool
index 413ce5d..7e3ac41 100755
--- a/libtool
+++ b/libtool
@@ -2,7 +2,7 @@
 
 # libtool - Provide generalized library-building support services.
 # Generated automatically by config.status () 
-# Libtool was configured on host Tadpole.local:
+# Libtool was configured on host Butterfly.local:
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 #
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
@@ -66,16 +66,16 @@ PATH_SEPARATOR=":"
 
 # The host system.
 host_alias=
-host=x86_64-apple-darwin10.8.0
-host_os=darwin10.8.0
+host=x86_64-apple-darwin13.1.0
+host_os=darwin13.1.0
 
 # The build system.
 build_alias=
-build=x86_64-apple-darwin10.8.0
-build_os=darwin10.8.0
+build=x86_64-apple-darwin13.1.0
+build_os=darwin13.1.0
 
 # A sed program that does not truncate output.
-SED="/opt/local/bin/gsed"
+SED="/usr/bin/sed"
 
 # Sed that helps us avoid accidentally triggering echo(1) options like -n.
 Xsed="$SED -e 1s/^X//"
@@ -272,7 +272,7 @@ finish_eval=""
 hardcode_into_libs=no
 
 # Compile-time system search path for libraries.
-sys_lib_search_path_spec="/usr/lib/gcc/i686-apple-darwin10/4.2.1/x86_64 /usr/lib/i686-apple-darwin10/4.2.1 /usr/lib  /usr/local/lib"
+sys_lib_search_path_spec="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/5.1  /usr/local/lib"
 
 # Run-time system search path for libraries.
 sys_lib_dlsearch_path_spec="/usr/local/lib /lib /usr/lib"
@@ -292,7 +292,7 @@ striplib="strip -x"
 
 
 # The linker used to build libraries.
-LD="/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld"
+LD="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld"
 
 # How to create reloadable object files.
 reload_flag=" -r"
@@ -308,7 +308,7 @@ CC="gcc"
 with_gcc=yes
 
 # Compiler flag to turn off builtin functions.
-no_builtin_flag=" -fno-builtin"
+no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions"
 
 # Additional compiler flags for building library objects.
 pic_flag=" -fno-common -DPIC"
@@ -10091,7 +10091,7 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # ### BEGIN LIBTOOL TAG CONFIG: CXX
 
 # The linker used to build libraries.
-LD="/usr/libexec/gcc/i686-apple-darwin10/4.2.1/ld"
+LD="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld"
 
 # How to create reloadable object files.
 reload_flag=" -r"
diff --git a/postgis/geography_measurement_trees.c b/postgis/geography_measurement_trees.c
index ed163ea..59f537e 100644
--- a/postgis/geography_measurement_trees.c
+++ b/postgis/geography_measurement_trees.c
@@ -9,7 +9,7 @@
 * liblwgeom, where most of the circtree logic lives.
 */
 typedef struct {
-	int                         type;       // <GeomCache>
+	int                     type;       // <GeomCache>
 	GSERIALIZED*                geom1;      // 
 	GSERIALIZED*                geom2;      // 
 	size_t                      geom1_size; // 
@@ -76,16 +76,16 @@ GetCircTreeGeomCache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const
 	return (CircTreeGeomCache*)GetGeomCache(fcinfo, &CircTreeCacheMethods, g1, g2);
 }
 
+
 static int
-CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const LWGEOM* lwgeom2)
+CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const POINT4D* in_point)
 {
 	int tree1_type = gserialized_get_type(g1);
 	GBOX gbox1;
 	GEOGRAPHIC_POINT in_gpoint;
 	POINT3D in_point3d;
-	POINT4D in_point;
 
-	POSTGIS_DEBUGF(3, "tree1_type=%d, lwgeom2->type=%d", tree1_type, lwgeom2->type);
+	POSTGIS_DEBUGF(3, "tree1_type=%d", tree1_type);
 
 	/* If the tree'ed argument is a polygon, do the P-i-P using the tree-based P-i-P */
 	if ( tree1_type == POLYGONTYPE || tree1_type == MULTIPOLYGONTYPE )
@@ -99,17 +99,9 @@ CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const LWGEOM* lwgeom2
 			lwgeom_calculate_gbox_geodetic(lwgeom1, &gbox1);
 			lwgeom_free(lwgeom1);
 		}
-		
-		/* Need one point from the candidate geometry */
-		if ( LW_FAILURE == lwgeom_startpoint(lwgeom2, &in_point) )
-		{
-			lwerror("CircTreePIP unable to generate start point for lwgeom %p", lwgeom2);
-			POSTGIS_DEBUG(3, "unable to generate in_point, CircTreePIP returning FALSE");
-			return LW_FALSE;
-		}
-	
+			
 		/* Flip the candidate point into geographics */
-		geographic_point_init(in_point.x, in_point.y, &in_gpoint);
+		geographic_point_init(in_point->x, in_point->y, &in_gpoint);
 		geog2cart(&in_gpoint, &in_point3d);
 		
 		/* If the candidate isn't in the tree box, it's not in the tree area */
@@ -123,8 +115,8 @@ CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const LWGEOM* lwgeom2
 		{
 			POINT2D pt2d_outside; /* latlon */
 			POINT2D pt2d_inside;
-			pt2d_inside.x = in_point.x; 
-			pt2d_inside.y = in_point.y;
+			pt2d_inside.x = in_point->x; 
+			pt2d_inside.y = in_point->y;
 			/* Calculate a definitive outside point */
 			gbox_pt_outside(&gbox1, &pt2d_outside);
 			POSTGIS_DEBUGF(3, "p2d_inside=POINT(%g %g) p2d_outside=POINT(%g %g)", pt2d_inside.x, pt2d_inside.y, pt2d_outside.x, pt2d_outside.y);
@@ -133,81 +125,95 @@ CircTreePIP(const CIRC_NODE* tree1, const GSERIALIZED* g1, const LWGEOM* lwgeom2
 			return circ_tree_contains_point(tree1, &pt2d_inside, &pt2d_outside, NULL);
 		}
 	}
-	/* If the un-tree'd argument is a polygon and the tree'd argument isn't, we need to do a */
-	/* standard P-i-P on the un-tree'd side. */
-	else if ( lwgeom2->type == POLYGONTYPE || lwgeom2->type == MULTIPOLYGONTYPE )
-	{
-		int result;
-		LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
-		LWGEOM* lwpoint;
-		POINT4D p4d;
-		POSTGIS_DEBUG(3, "tree1 not polygonal, but lwgeom2 is, calculating using lwgeom_covers_lwgeom_sphere");
-		
-		if ( LW_FAILURE == lwgeom_startpoint(lwgeom1, &p4d) )
-		{
-			lwgeom_free(lwgeom1);
-			lwerror("CircTreePIP unable to get lwgeom_startpoint");
-			return LW_FALSE;
-		}  
-		lwpoint = lwpoint_as_lwgeom(lwpoint_make(lwgeom_get_srid(lwgeom1), lwgeom_has_z(lwgeom1), lwgeom_has_m(lwgeom1), &p4d));
-		result = lwgeom_covers_lwgeom_sphere(lwgeom2, lwpoint);
-		lwgeom_free(lwgeom1);
-		lwgeom_free(lwpoint);
-		return result;
-	}
 	else
 	{
-		POSTGIS_DEBUG(3, "neither tree1 nor lwgeom2 polygonal, so CircTreePIP returning FALSE");
+		POSTGIS_DEBUG(3, "tree1 not polygonal, so CircTreePIP returning FALSE");
 		return LW_FALSE;
 	}		
 }
 
-int
-geography_distance_cache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHEROID* s, double* distance)
+
+static int
+geography_distance_cache_tolerance(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHEROID* s, double tolerance, double* distance)
 {
 	CircTreeGeomCache* tree_cache = NULL;
+
+	int type1 = gserialized_get_type(g1);
+	int type2 = gserialized_get_type(g2);
 	
 	Assert(distance);
 	
 	/* Two points? Get outa here... */
-	if ( (gserialized_get_type(g1) == POINTTYPE) && (gserialized_get_type(g2) == POINTTYPE) )
+	if ( type1 == POINTTYPE && type2 == POINTTYPE )
 		return LW_FAILURE;
 
 	/* Fetch/build our cache, if appropriate, etc... */
 	tree_cache = GetCircTreeGeomCache(fcinfo, g1, g2);
 	
-	if ( tree_cache && tree_cache->argnum && tree_cache->index ) 
+	/* OK, we have an index at the ready! Use it for the one tree argument and */
+	/* fill in the other tree argument */
+	if ( tree_cache && tree_cache->argnum && tree_cache->index )
 	{
-		CIRC_NODE* circ_tree = NULL;
-		const GSERIALIZED* g = NULL;
+		CIRC_NODE* circtree_cached = tree_cache->index;
+		CIRC_NODE* circtree = NULL;
+		const GSERIALIZED* g_cached;
+		const GSERIALIZED* g;
 		LWGEOM* lwgeom = NULL;
-
+		int geomtype_cached;
+		int geomtype;
+		POINT4D p4d;
+		
 		/* We need to dynamically build a tree for the uncached side of the function call */
 		if ( tree_cache->argnum == 1 )
 		{
-			lwgeom = lwgeom_from_gserialized(g2);
-			g = g1;
+			g_cached = g1;
+			g = g2;
+			geomtype_cached = type1;
+			geomtype = type2;
 		}
 		else if ( tree_cache->argnum == 2 )
 		{
-			lwgeom = lwgeom_from_gserialized(g1);
-			g = g2;
+			g_cached = g2;
+			g = g1;
+			geomtype_cached = type2;
+			geomtype = type1;
 		}
 		else
-			lwerror("geography_distance_cache failed! This will never happen!");
-
-		if ( LW_TRUE == CircTreePIP(tree_cache->index, g, lwgeom) )
 		{
-			*distance = 0.0;
-			lwgeom_free(lwgeom);
-			return LW_SUCCESS;
+			lwerror("geography_distance_cache this cannot happen!");
+			return LW_FAILURE;
 		}
 		
-		/* We do tree/tree distance, so turn the candidate geometry into a tree */
-		circ_tree = lwgeom_calculate_circ_tree(lwgeom);
-		/* Calculate tree/tree distance */
-		*distance = circ_tree_distance_tree(tree_cache->index, circ_tree, s, FP_TOLERANCE);
-		circ_tree_free(circ_tree);
+		lwgeom = lwgeom_from_gserialized(g);
+		if ( geomtype_cached == POLYGONTYPE || geomtype_cached == MULTIPOLYGONTYPE )
+		{
+			lwgeom_startpoint(lwgeom, &p4d);
+			if ( CircTreePIP(circtree_cached, g_cached, &p4d) )
+			{
+				*distance = 0.0;
+				lwgeom_free(lwgeom);
+				return LW_SUCCESS;
+			}
+		}
+		
+		circtree = lwgeom_calculate_circ_tree(lwgeom);
+		if ( geomtype == POLYGONTYPE || geomtype == MULTIPOLYGONTYPE ) 
+		{
+			POINT2D p2d;
+			circ_tree_get_point(circtree_cached, &p2d);
+			p4d.x = p2d.x;
+			p4d.y = p2d.y;
+			if ( CircTreePIP(circtree, g, &p4d) )
+			{
+				*distance = 0.0;
+				circ_tree_free(circtree);
+				lwgeom_free(lwgeom);
+				return LW_SUCCESS;
+			}
+		}
+
+		*distance = circ_tree_distance_tree(circtree_cached, circtree, s, tolerance);
+		circ_tree_free(circtree);
 		lwgeom_free(lwgeom);	
 		return LW_SUCCESS;
 	}
@@ -217,65 +223,27 @@ geography_distance_cache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, co
 	}
 }
 
+
+int
+geography_distance_cache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHEROID* s, double* distance)
+{
+	return geography_distance_cache_tolerance(fcinfo, g1, g2, s, FP_TOLERANCE, distance);
+}
+
 int
 geography_dwithin_cache(FunctionCallInfoData* fcinfo, const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHEROID* s, double tolerance, int* dwithin)
 {
-	CircTreeGeomCache* tree_cache = NULL;
 	double distance;
-		
-	Assert(dwithin);
-	
-	/* Two points? Get outa here... */
-	if ( (gserialized_get_type(g1) == POINTTYPE) && (gserialized_get_type(g2) == POINTTYPE) )
-		return LW_FAILURE;
-	
-	/* Fetch/build our cache, if appropriate, etc... */
-	tree_cache = GetCircTreeGeomCache(fcinfo, g1, g2);
-	
-	if ( tree_cache && tree_cache->argnum && tree_cache->index ) 
+	/* TODO!!! Why does the tolerance stopper in the circ_tree_distance_tree_internal arbitrarily screw up? */
+/*	if ( LW_SUCCESS == geography_distance_cache_tolerance(fcinfo, g1, g2, s, tolerance, &distance) ) */
+	if ( LW_SUCCESS == geography_distance_cache_tolerance(fcinfo, g1, g2, s, FP_TOLERANCE, &distance) ) 
 	{
-		CIRC_NODE* circ_tree = NULL;
-		const GSERIALIZED* g = NULL;
-		LWGEOM* lwgeom = NULL;
-
-		/* We need to dynamically build a tree for the uncached side of the function call */
-		if ( tree_cache->argnum == 1 )
-		{
-			lwgeom = lwgeom_from_gserialized(g2);
-			g = g1;
-		}
-		else if ( tree_cache->argnum == 2 )
-		{
-			lwgeom = lwgeom_from_gserialized(g1);
-			g = g2;
-		}
-		else
-			lwerror("geography_dwithin_cache failed! This will never happen!");
-
-		if ( LW_TRUE == CircTreePIP(tree_cache->index, g, lwgeom) )
-		{
-			*dwithin = LW_TRUE;
-			lwgeom_free(lwgeom);
-			return LW_SUCCESS;
-		}
-		
-		/* We do tree/tree distance, so turn the candidate geometry into a tree */
-		circ_tree = lwgeom_calculate_circ_tree(lwgeom);
-		/* Calculate tree/tree distance */
-		distance = circ_tree_distance_tree(tree_cache->index, circ_tree, s, tolerance);
-		*dwithin = (distance <= tolerance ? LW_TRUE : LW_FALSE);
-		circ_tree_free(circ_tree);
-		lwgeom_free(lwgeom);	
+		*dwithin = (distance <= (tolerance + FP_TOLERANCE) ? LW_TRUE : LW_FALSE);
 		return LW_SUCCESS;
 	}
-	else
-	{
-		return LW_FAILURE;
-	}
-
+	return LW_FAILURE;
 }
-
-
+	
 int
 geography_tree_distance(const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHEROID* s, double tolerance, double* distance)
 {
@@ -283,13 +251,16 @@ geography_tree_distance(const GSERIALIZED* g1, const GSERIALIZED* g2, const SPHE
 	CIRC_NODE* circ_tree2 = NULL;
 	LWGEOM* lwgeom1 = NULL;
 	LWGEOM* lwgeom2 = NULL;
+	POINT4D pt1, pt2;
 	
 	lwgeom1 = lwgeom_from_gserialized(g1);
 	lwgeom2 = lwgeom_from_gserialized(g2);
 	circ_tree1 = lwgeom_calculate_circ_tree(lwgeom1);
 	circ_tree2 = lwgeom_calculate_circ_tree(lwgeom2);
+	lwgeom_startpoint(lwgeom1, &pt1);
+	lwgeom_startpoint(lwgeom2, &pt2);
 	
-	if ( CircTreePIP(circ_tree1, g1, lwgeom2) || CircTreePIP(circ_tree2, g2, lwgeom1) )
+	if ( CircTreePIP(circ_tree1, g1, &pt2) || CircTreePIP(circ_tree2, g2, &pt1) )
 	{
 		*distance = 0.0;
 	}
diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c
index 4e94600..2f46223 100644
--- a/postgis/gserialized_estimate.c
+++ b/postgis/gserialized_estimate.c
@@ -497,7 +497,7 @@ nd_box_init_bounds(ND_BOX *a)
 	for ( d = 0; d < ND_DIMS; d++ )
 	{
 		a->min[d] = FLT_MAX;
-		a->max[d] = FLT_MIN;
+		a->max[d] = -1 * FLT_MAX;
 	}
 	return TRUE;
 }
@@ -753,16 +753,18 @@ nd_box_array_distribution(const ND_BOX **nd_boxes, int num_boxes, const ND_BOX *
 
 		/* How dispersed is the distribution of features across bins? */
 		range = range_quintile(counts, num_bins);
+
 #if POSTGIS_DEBUG_LEVEL >= 3
 		average = avg(counts, num_bins);
 		sdev = stddev(counts, num_bins);
 		sdev_ratio = sdev/average;
-#endif
-		
+
 		POSTGIS_DEBUGF(3, " dimension %d: range = %d", d, range);
 		POSTGIS_DEBUGF(3, " dimension %d: average = %.6g", d, average);
 		POSTGIS_DEBUGF(3, " dimension %d: stddev = %.6g", d, sdev);
 		POSTGIS_DEBUGF(3, " dimension %d: stddev_ratio = %.6g", d, sdev_ratio);
+#endif
+		
 		distribution[d] = range;
 	}
 	
@@ -1074,6 +1076,10 @@ estimate_join_selectivity(const ND_STATS *s1, const ND_STATS *s2)
 	 * number of rows that can be returned.
 	 */
 	selectivity = val / ntuples_max;
+
+    /* Guard against over-estimates :) */
+    if ( selectivity > 1.0 ) 
+        selectivity = 1.0;
 	
 	return selectivity;
 }
diff --git a/postgis/gserialized_gist_2d.c b/postgis/gserialized_gist_2d.c
index 53f22b6..742701d 100644
--- a/postgis/gserialized_gist_2d.c
+++ b/postgis/gserialized_gist_2d.c
@@ -530,7 +530,15 @@ gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
 	** The most info we need is the 8 bytes of serialized header plus the 
 	** of floats necessary to hold the bounding box.
 	*/
-	gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 8 + sizeof(BOX2DF));
+	if (VARATT_IS_EXTENDED(gsdatum)) 
+	{ 
+		gpart = (GSERIALIZED*)PG_DETOAST_DATUM_SLICE(gsdatum, 0, 8 + sizeof(BOX2DF)); 
+	} 
+	else 
+	{ 
+		gpart = (GSERIALIZED*)PG_DETOAST_DATUM(gsdatum); 
+	} 
+
 	flags = gpart->flags;
 
 	POSTGIS_DEBUGF(4, "got flags %d", gpart->flags);
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index 2760950..2a699c3 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -1,5 +1,5 @@
 /**********************************************************************
- * $Id: lwgeom_in_gml.c 10767 2012-11-29 22:33:21Z colivier $
+ * $Id: lwgeom_in_gml.c 12362 2014-03-26 10:20:53Z colivier $
  *
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.refractions.net
@@ -1335,6 +1335,10 @@ static LWGEOM* parse_gml_patch(xmlNodePtr xnode, bool *hasz, int *root_srid)
 		}
 	}
 
+	/* Interior but no Exterior ! */ 
+	if ( ! ppa )
+ 		gml_lwerror("invalid GML representation", 48);
+
 	/* PolygonPatch/interior */
 	for (ring=1, xa = xnode->children ; xa != NULL ; xa = xa->next)
 	{
diff --git a/postgis/postgis.sql.in b/postgis/postgis.sql.in
index 7f7c640..b36630d 100644
--- a/postgis/postgis.sql.in
+++ b/postgis/postgis.sql.in
@@ -1,6 +1,6 @@
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 --
--- $Id: postgis.sql.in 12102 2013-11-06 16:32:54Z strk $
+-- $Id: postgis.sql.in 12272 2014-02-24 10:25:07Z strk $
 --
 -- PostGIS - Spatial Types for PostgreSQL
 -- http://postgis.refractions.net
@@ -27,6 +27,22 @@ SET client_min_messages TO warning;
 
 BEGIN;
 
+-- Check that no other postgis is installed
+DO $$
+DECLARE
+  rec RECORD;
+BEGIN
+  FOR rec IN
+    SELECT n.nspname, p.proname FROM pg_proc p, pg_namespace n
+    WHERE p.proname = 'postgis_version'
+    AND p.pronamespace = n.oid
+  LOOP
+    RAISE EXCEPTION 'PostGIS is already installed in schema ''%'', uninstall it first', rec.nspname;
+  END LOOP;
+END
+$$ LANGUAGE 'plpgsql';
+
+
 -- Let the user know about a deprecated signature and its new name, if any
 CREATE OR REPLACE FUNCTION _postgis_deprecate(oldname text, newname text, version text)
 RETURNS void AS
@@ -2577,6 +2593,10 @@ BEGIN
 		WHEN undefined_function OR invalid_schema_name THEN
 			topo_scr_ver := NULL;
 			RAISE NOTICE 'Function postgis_topology_scripts_installed() not found. Is topology support enabled and topology.sql installed?';
+		WHEN insufficient_privilege THEN
+			RAISE NOTICE 'Topology support cannot be inspected. Is current user granted USAGE on schema "topology" ?';
+		WHEN OTHERS THEN
+			RAISE NOTICE 'Function postgis_topology_scripts_installed() could not be called: % (%)', SQLERRM, SQLSTATE;
 	END;
 
 	BEGIN
diff --git a/postgis/sqldefines.h b/postgis/sqldefines.h
index 643ebc3..4d41aa8 100644
--- a/postgis/sqldefines.h
+++ b/postgis/sqldefines.h
@@ -9,7 +9,7 @@
 #define POSTGIS_PGSQL_VERSION 92
 #define POSTGIS_GEOS_VERSION 34
 #define POSTGIS_PROJ_VERSION 48
-#define POSTGIS_LIB_VERSION '2.1.1'
+#define POSTGIS_LIB_VERSION '2.1.2'
 #define POSTGIS_LIBXML2_VERSION 2.9.0
 
 /*
@@ -18,12 +18,12 @@
  * won't substitute within apostrophes)
  */
 #define _POSTGIS_SQL_SELECT_POSTGIS_VERSION 'SELECT ''2.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1''::text AS version'
-#define _POSTGIS_SQL_SELECT_POSTGIS_BUILD_DATE 'SELECT ''2013-11-08 19:46:11''::text AS version'
+#define _POSTGIS_SQL_SELECT_POSTGIS_BUILD_DATE 'SELECT ''2014-03-29 05:39:47''::text AS version'
 
 #if POSTGIS_SVN_REVISION
-#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '2.1.1'::text || ' r' || POSTGIS_SVN_REVISION::text AS version $$
+#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '2.1.2'::text || ' r' || POSTGIS_SVN_REVISION::text AS version $$
 #else
-#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '2.1.1'::text AS version $$
+#define _POSTGIS_SQL_SELECT_POSTGIS_SCRIPTS_VERSION $$ SELECT '2.1.2'::text AS version $$
 #endif
 
 #define SRID_USR_MAX 998999
diff --git a/postgis_svn_revision.h b/postgis_svn_revision.h
index 9625478..2754e98 100644
--- a/postgis_svn_revision.h
+++ b/postgis_svn_revision.h
@@ -1 +1 @@
-#define POSTGIS_SVN_REVISION 12113
+#define POSTGIS_SVN_REVISION 12389
diff --git a/raster/doc/RFC1-SerializedFormat b/raster/doc/RFC1-SerializedFormat
index ebed5be..e69a8f6 100644
--- a/raster/doc/RFC1-SerializedFormat
+++ b/raster/doc/RFC1-SerializedFormat
@@ -1,7 +1,7 @@
 RFC1: serialized format (storage) for RASTER type
 ------------------------------------------------------
 $Author: jorgearevalo $
-$Date: 2011-01-24 07:06:02 -0800 (Mon, 24 Jan 2011) $
+$Date: 2011-01-24 16:06:02 +0100 (Mon, 24 Jan 2011) $
 $Revision: 6716 $
 ------------------------------------------------------
 
diff --git a/raster/doc/RFC2-WellKnownBinaryFormat b/raster/doc/RFC2-WellKnownBinaryFormat
index 5d58a36..c8e61a3 100644
--- a/raster/doc/RFC2-WellKnownBinaryFormat
+++ b/raster/doc/RFC2-WellKnownBinaryFormat
@@ -1,7 +1,7 @@
 RFC2: Well Known Binary format for RASTER type
 ----------------------------------------------
 $Author: chodgson $
-$Date: 2011-06-23 16:50:13 -0700 (Thu, 23 Jun 2011) $
+$Date: 2011-06-24 01:50:13 +0200 (Fri, 24 Jun 2011) $
 $Revision: 7461 $
 ------------------------------------------------------
 
diff --git a/raster/rt_core/rt_api.c b/raster/rt_core/rt_api.c
index 5fa7c46..06be4e8 100644
--- a/raster/rt_core/rt_api.c
+++ b/raster/rt_core/rt_api.c
@@ -1,5 +1,5 @@
 /*
- * $Id: rt_api.c 12060 2013-10-28 19:44:03Z dustymugs $
+ * $Id: rt_api.c 12186 2014-01-17 03:46:18Z dustymugs $
  *
  * WKTRaster - Raster Types for PostGIS
  * http://trac.osgeo.org/postgis/wiki/WKTRaster
@@ -1795,7 +1795,10 @@ rt_band_load_offline_data(rt_band band) {
 	}
 
 	rt_util_gdal_register_all();
-	hdsSrc = GDALOpenShared(band->data.offline.path, GA_ReadOnly);
+	/*
+	 hdsSrc = GDALOpenShared(band->data.offline.path, GA_ReadOnly);
+	*/
+	hdsSrc = GDALOpen(band->data.offline.path, GA_ReadOnly);
 	if (hdsSrc == NULL) {
 		rterror("rt_band_load_offline_data: Cannot open offline raster: %s", band->data.offline.path);
 		return ES_ERROR;
@@ -1891,6 +1894,7 @@ rt_band_load_offline_data(rt_band band) {
 	GDALClose(hdsDst);
 	/* XXX: need to find a way to clean up the GDALOpenShared datasets at end of transaction */
 	/* GDALClose(hdsSrc); */
+	GDALClose(hdsSrc);
 
 	if (_rast == NULL) {
 		rterror("rt_band_load_offline_data: Cannot load data from offline raster: %s", band->data.offline.path);
@@ -9351,9 +9355,9 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) {
 	int nXValid, nYValid;
 	int iY;
 
-	void *values = NULL;
+	uint8_t *values = NULL;
 	uint32_t valueslen = 0;
-	void *ptr = NULL;
+	uint8_t *ptr = NULL;
 
 	assert(NULL != ds);
 
@@ -9477,34 +9481,7 @@ rt_raster_from_gdal_dataset(GDALDatasetH ds) {
 
 		/* allocate memory for values */
 		valueslen = ptlen * nXBlockSize * nYBlockSize;
-		switch (gdpixtype) {
-			case GDT_Byte:
-				values = (uint8_t *) rtalloc(valueslen);
-				break;
-			case GDT_UInt16:
-				values = (uint16_t *) rtalloc(valueslen);
-				break;
-			case GDT_Int16:
-				values = (int16_t *) rtalloc(valueslen);
-				break;
-			case GDT_UInt32:
-				values = (uint32_t *) rtalloc(valueslen);
-				break;
-			case GDT_Int32:
-				values = (int32_t *) rtalloc(valueslen);
-				break;
-			case GDT_Float32:
-				values = (float *) rtalloc(valueslen);
-				break;
-			case GDT_Float64:
-				values = (double *) rtalloc(valueslen);
-				break;
-			default:
-				/* should NEVER get here */
-				rterror("rt_raster_from_gdal_dataset: Could not allocate memory for unknown pixel type");
-				rt_raster_destroy(rast);
-				return NULL;
-		}
+		values = rtalloc(valueslen);
 		if (values == NULL) {
 			rterror("rt_raster_from_gdal_dataset: Could not allocate memory for GDAL band pixel values");
 			rt_raster_destroy(rast);
diff --git a/raster/rt_core/rt_api.h b/raster/rt_core/rt_api.h
index 4a5b4d1..d8cb278 100644
--- a/raster/rt_core/rt_api.h
+++ b/raster/rt_core/rt_api.h
@@ -1,5 +1,5 @@
 /*
- * $Id: rt_api.h 12060 2013-10-28 19:44:03Z dustymugs $
+ * $Id: rt_api.h 12336 2014-03-22 05:29:54Z robe $
  *
  * WKTRaster - Raster Types for PostGIS
  * http://www.postgis.org/support/wiki/index.php?WKTRasterHomePage
@@ -42,7 +42,7 @@
 #endif
 
 
-#if defined(__FreeBSD__) || defined(__OpenBSD__)    /* seems to work like Linux... */
+#if defined(__FreeBSD_kernel__) || defined(__OpenBSD__)    /* seems to work like Linux... */
 #if !defined(LINUX)
 #define LINUX
 #endif
diff --git a/raster/rt_pg/Makefile.in b/raster/rt_pg/Makefile.in
index f3beb9d..8dd3955 100644
--- a/raster/rt_pg/Makefile.in
+++ b/raster/rt_pg/Makefile.in
@@ -1,5 +1,5 @@
 #############################################################################
-# $Id: Makefile.in 12060 2013-10-28 19:44:03Z dustymugs $
+# $Id: Makefile.in 12349 2014-03-25 13:35:16Z strk $
 #
 # Copyright (c) 2009-2011 Sandro Santilli <strk at keybit.net>
 #
@@ -111,15 +111,15 @@ $(OBJS): ../../liblwgeom/.libs/liblwgeom.a ../../libpgcommon/libpgcommon.a ../..
 $(SQL_OBJS): ../../postgis/sqldefines.h ../../postgis_svn_revision.h
 
 #remove all create object types since these can't be done cleanly in an upgrade
-rtpostgis_upgrade.sql: rtpostgis.sql
-	$(PERL) -0777 -ne 's/^(CREATE|ALTER) (CAST|OPERATOR|TYPE|TABLE|SCHEMA|DOMAIN|TRIGGER).*?;//msg;print;' $< > $@
+rtpostgis_upgrade.sql: rtpostgis.sql ../../utils/postgis_proc_upgrade.pl
+	$(PERL) ../../utils/postgis_proc_upgrade.pl $< 2.0 > $@
+	#$(PERL) -0777 -ne 's/^(CREATE|ALTER) (CAST|OPERATOR|TYPE|TABLE|SCHEMA|DOMAIN|TRIGGER).*?;//msg;print;' $< > $@
 
 rtpostgis_upgrade_20_21.sql: rtpostgis_upgrade_cleanup.sql rtpostgis_drop.sql rtpostgis_upgrade.sql 
 	cat $^ > $@
 
-# same as 20_21 until 2.1.0 is released
-rtpostgis_upgrade_21_minor.sql: rtpostgis_upgrade_cleanup.sql rtpostgis_drop.sql rtpostgis_upgrade.sql 
-	cat $^ > $@
+rtpostgis_upgrade_21_minor.sql: rtpostgis.sql ../../utils/postgis_proc_upgrade.pl
+	$(PERL) ../../utils/postgis_proc_upgrade.pl rtpostgis.sql 2.1 > $@
 
 uninstall_rtpostgis.sql: rtpostgis.sql ../../utils/create_undef.pl 
 	$(PERL) ../../utils/create_undef.pl $< $(POSTGIS_PGSQL_VERSION) > $@
diff --git a/raster/rt_pg/rt_pg.c b/raster/rt_pg/rt_pg.c
index 50f1028..50b4b3e 100644
--- a/raster/rt_pg/rt_pg.c
+++ b/raster/rt_pg/rt_pg.c
@@ -1,5 +1,5 @@
 /*
- * $Id: rt_pg.c 12060 2013-10-28 19:44:03Z dustymugs $
+ * $Id: rt_pg.c 12153 2013-12-07 14:41:24Z dustymugs $
  *
  * WKTRaster - Raster Types for PostGIS
  * http://www.postgis.org/support/wiki/index.php?WKTRasterHomePage
@@ -617,6 +617,27 @@ rtpg_trim(const char *input) {
 	return rtn;
 }
 
+/*
+* reverse string search function from
+* http://stackoverflow.com/a/1634398
+*/
+static char *
+rtpg_strrstr(const char *s1, const char *s2) {
+	int s1len = strlen(s1);
+	int s2len = strlen(s2);
+	char *s;
+
+	if (s2len > s1len)
+		return NULL;
+
+	s = (char *) (s1 + s1len - s2len);
+	for (; s >= s1; --s)
+		if (strncmp(s, s2, s2len) == 0)
+			return s;
+
+	return NULL;
+}
+
 static char*
 rtpg_getSR(int srid)
 {
@@ -10297,7 +10318,7 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
 		PG_RETURN_NULL();
 	}
 	numBands = rt_raster_get_num_bands(raster);
-	POSTGIS_RT_DEBUGF(3, "RASTER_reclass: %d possible bands to be reclassified", n);
+	POSTGIS_RT_DEBUGF(3, "RASTER_reclass: %d possible bands to be reclassified", numBands);
 
 	/* process set of reclassarg */
 	POSTGIS_RT_DEBUG(3, "RASTER_reclass: Processing Arg 1 (reclassargset)");
@@ -10589,7 +10610,10 @@ Datum RASTER_reclass(PG_FUNCTION_ARGS) {
 					POSTGIS_RT_DEBUGF(5, "RASTER_reclass: min/max (double) %f", val);
 
 					/* strsplit removes dash (a.k.a. negative sign), compare now to restore */
-					junk = strstr(colon_set[b], dash_set[c]);
+					if (c < 1)
+						junk = strstr(colon_set[b], dash_set[c]);
+					else
+						junk = rtpg_strrstr(colon_set[b], dash_set[c]);
 					/* not beginning of string */
 					if (junk != colon_set[b]) {
 						/* prior is a dash */
diff --git a/raster/rt_pg/rtpostgis.sql.in b/raster/rt_pg/rtpostgis.sql.in
index 45429fe..275a34c 100644
--- a/raster/rt_pg/rtpostgis.sql.in
+++ b/raster/rt_pg/rtpostgis.sql.in
@@ -36,6 +36,8 @@
 
 SET client_min_messages TO warning;
 
+-- INSTALL VERSION: POSTGIS_LIB_VERSION
+
 BEGIN;
 
 ------------------------------------------------------------------------------
@@ -1746,6 +1748,10 @@ CREATE OR REPLACE FUNCTION st_astiff(rast raster, options text[] DEFAULT NULL, s
 		nodata double precision;
 		last_nodata double precision;
 	BEGIN
+		IF rast IS NULL THEN
+			RETURN NULL;
+		END IF;
+
 		num_bands := st_numbands($1);
 
 		-- TIFF only allows one NODATA value for ALL bands
@@ -1780,6 +1786,10 @@ CREATE OR REPLACE FUNCTION st_astiff(rast raster, compression text, srid integer
 		num_bands int;
 		options text[];
 	BEGIN
+		IF rast IS NULL THEN
+			RETURN NULL;
+		END IF;
+
 		compression2 := trim(both from upper(compression));
 
 		IF length(compression2) > 0 THEN
@@ -1867,6 +1877,10 @@ CREATE OR REPLACE FUNCTION st_asjpeg(rast raster, options text[] DEFAULT NULL)
 		num_bands int;
 		i int;
 	BEGIN
+		IF rast IS NULL THEN
+			RETURN NULL;
+		END IF;
+
 		num_bands := st_numbands($1);
 
 		-- JPEG allows 1 or 3 bands
@@ -1942,6 +1956,10 @@ CREATE OR REPLACE FUNCTION st_aspng(rast raster, options text[] DEFAULT NULL)
 		i int;
 		pt text;
 	BEGIN
+		IF rast IS NULL THEN
+			RETURN NULL;
+		END IF;
+
 		num_bands := st_numbands($1);
 
 		-- PNG allows 1, 3 or 4 bands
@@ -5432,23 +5450,27 @@ CREATE CAST (raster AS bytea)
 -------------------------------------------------------------------
 
 -- call PostgreSQL's hashvarlena() function
+-- Availability: 2.1.0
 CREATE OR REPLACE FUNCTION raster_hash(raster)
 	RETURNS integer
 	AS 'hashvarlena'
 	LANGUAGE 'internal' IMMUTABLE STRICT;
 
 -- use raster_hash() to compare
+-- Availability: 2.1.0
 CREATE OR REPLACE FUNCTION raster_eq(raster, raster)
 	RETURNS bool
 	AS $$ SELECT raster_hash($1) = raster_hash($2) $$
 	LANGUAGE 'sql' IMMUTABLE STRICT;
 
+-- Availability: 2.1.0
 CREATE OPERATOR = (
 	LEFTARG = raster, RIGHTARG = raster, PROCEDURE = raster_eq,
 	COMMUTATOR = '=',
 	RESTRICT = eqsel, JOIN = eqjoinsel
 );
 
+-- Availability: 2.1.0
 CREATE OPERATOR CLASS hash_raster_ops
 	DEFAULT FOR TYPE raster USING hash AS
 	OPERATOR	1	= ,
@@ -5629,7 +5651,7 @@ CREATE OPERATOR ~ (
 -- raster/geometry operators
 CREATE OPERATOR ~ (
     LEFTARG = raster, RIGHTARG = geometry, PROCEDURE = raster_geometry_contain,
-    COMMUTATOR = '@',
+    -- COMMUTATOR = '@', -- see http://trac.osgeo.org/postgis/ticket/2532
     RESTRICT = contsel, JOIN = contjoinsel
     );
 
@@ -5648,7 +5670,7 @@ CREATE OPERATOR && (
 -- geometry/raster operators
 CREATE OPERATOR ~ (
     LEFTARG = geometry, RIGHTARG = raster, PROCEDURE = geometry_raster_contain,
-    COMMUTATOR = '@',
+    -- COMMUTATOR = '@', -- see http://trac.osgeo.org/postgis/ticket/2532
     RESTRICT = contsel, JOIN = contjoinsel
     );
 
@@ -5722,6 +5744,7 @@ CREATE OR REPLACE FUNCTION _st_samealignment_finalfn(agg agg_samealignment)
 	AS $$ SELECT $1.aligned $$
 	LANGUAGE 'sql' IMMUTABLE STRICT;
 
+-- Availability: 2.1.0
 CREATE AGGREGATE st_samealignment(raster) (
 	SFUNC = _st_samealignment_transfn,
 	STYPE = agg_samealignment,
@@ -6427,6 +6450,7 @@ CREATE OR REPLACE FUNCTION _st_union_transfn(internal, raster, unionarg[])
 	AS 'MODULE_PATHNAME', 'RASTER_union_transfn'
 	LANGUAGE 'c' IMMUTABLE;
 
+-- Availability: 2.1.0
 CREATE AGGREGATE st_union(raster, unionarg[]) (
 	SFUNC = _st_union_transfn,
 	STYPE = internal,
@@ -6438,6 +6462,8 @@ CREATE OR REPLACE FUNCTION _st_union_transfn(internal, raster, integer, text)
 	AS 'MODULE_PATHNAME', 'RASTER_union_transfn'
 	LANGUAGE 'c' IMMUTABLE;
 
+-- Availability: 2.0.0
+-- Changed: 2.1.0 changed definition
 CREATE AGGREGATE st_union(raster, integer, text) (
 	SFUNC = _st_union_transfn,
 	STYPE = internal,
@@ -6449,6 +6475,8 @@ CREATE OR REPLACE FUNCTION _st_union_transfn(internal, raster, integer)
 	AS 'MODULE_PATHNAME', 'RASTER_union_transfn'
 	LANGUAGE 'c' IMMUTABLE;
 
+-- Availability: 2.0.0
+-- Changed: 2.1.0 changed definition
 CREATE AGGREGATE st_union(raster, integer) (
 	SFUNC = _st_union_transfn,
 	STYPE = internal,
@@ -6460,6 +6488,8 @@ CREATE OR REPLACE FUNCTION _st_union_transfn(internal, raster)
 	AS 'MODULE_PATHNAME', 'RASTER_union_transfn'
 	LANGUAGE 'c' IMMUTABLE;
 
+-- Availability: 2.0.0
+-- Changed: 2.1.0 changed definition
 CREATE AGGREGATE st_union(raster) (
 	SFUNC = _st_union_transfn,
 	STYPE = internal,
@@ -6471,6 +6501,8 @@ CREATE OR REPLACE FUNCTION _st_union_transfn(internal, raster, text)
 	AS 'MODULE_PATHNAME', 'RASTER_union_transfn'
 	LANGUAGE 'c' IMMUTABLE;
 
+-- Availability: 2.0.0
+-- Changed: 2.1.0 changed definition
 CREATE AGGREGATE st_union(raster, text) (
 	SFUNC = _st_union_transfn,
 	STYPE = internal,
diff --git a/raster/test/regress/rt_asjpeg.sql b/raster/test/regress/rt_asjpeg.sql
index b1bd594..12ffd5b 100644
--- a/raster/test/regress/rt_asjpeg.sql
+++ b/raster/test/regress/rt_asjpeg.sql
@@ -1,3 +1,4 @@
+SELECT ST_AsJPEG(NULL) IS NULL;
 SELECT CASE
 	WHEN length(
 		ST_AsJPEG(
diff --git a/raster/test/regress/rt_asjpeg_expected b/raster/test/regress/rt_asjpeg_expected
index e441e97..3131f34 100644
--- a/raster/test/regress/rt_asjpeg_expected
+++ b/raster/test/regress/rt_asjpeg_expected
@@ -1,3 +1,4 @@
+t
 ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
 1
 ERROR:  The pixel type of band 1 in the raster is not 8BUI.  The JPEG format can only be used with the 8BUI pixel type.
diff --git a/raster/test/regress/rt_aspng.sql b/raster/test/regress/rt_aspng.sql
index e063f53..60e6f71 100644
--- a/raster/test/regress/rt_aspng.sql
+++ b/raster/test/regress/rt_aspng.sql
@@ -1,3 +1,4 @@
+SELECT ST_AsPNG(NULL) IS NULL;
 SELECT CASE
 	WHEN length(
 		ST_AsPNG(
diff --git a/raster/test/regress/rt_aspng_expected b/raster/test/regress/rt_aspng_expected
index 430febc..92345d5 100644
--- a/raster/test/regress/rt_aspng_expected
+++ b/raster/test/regress/rt_aspng_expected
@@ -1,3 +1,4 @@
+t
 ERROR:  The pixel type of band 1 in the raster is not 8BUI or 16BUI.  The PNG format can only be used with 8BUI and 16BUI pixel types.
 1
 ERROR:  The pixel type of band 1 in the raster is not 8BUI or 16BUI.  The PNG format can only be used with 8BUI and 16BUI pixel types.
diff --git a/raster/test/regress/rt_astiff.sql b/raster/test/regress/rt_astiff.sql
index 0f05bbd..f59fccf 100644
--- a/raster/test/regress/rt_astiff.sql
+++ b/raster/test/regress/rt_astiff.sql
@@ -1,3 +1,5 @@
+SELECT ST_AsTIFF(NULL) IS NULL;
+SELECT ST_AsTIFF(NULL, 'JPEG') IS NULL;
 SELECT CASE
 	WHEN length(
 		ST_AsTIFF(
diff --git a/raster/test/regress/rt_astiff_expected b/raster/test/regress/rt_astiff_expected
index 0387b83..44ba5c4 100644
--- a/raster/test/regress/rt_astiff_expected
+++ b/raster/test/regress/rt_astiff_expected
@@ -1,3 +1,5 @@
+t
+t
 1
 1
 1
diff --git a/raster/test/regress/rt_reclass.sql b/raster/test/regress/rt_reclass.sql
index f4753b1..4dd85c7 100644
--- a/raster/test/regress/rt_reclass.sql
+++ b/raster/test/regress/rt_reclass.sql
@@ -168,3 +168,28 @@ FROM (
 		ROW(2, '-10000--100]:50-1,(-100-1000]:150-50,(1000-10000]:254-150', '8BUI', 0)
 	) AS rast
 ) AS t;
+
+-- ticket #2555
+SELECT
+	ST_Value(rast, 1, 2, 2),
+ 	ST_Value(rast, 1, 3, 3),
+ 	ST_Value(rast, 1, 4, 4)
+FROM (
+ 	SELECT ST_Reclass(
+	 	ST_SetValues(
+		 	ST_AddBand(
+			 	ST_MakeEmptyRaster(5, 5, 10, 10, 2, 2, 0, 0, 0),
+			 	1, '32BF', 1, -9999
+			),
+		 	1, 1, 1,
+		 	ARRAY[
+			 	[1, 1, 1, 1, 1],
+				[1, 9000, 1, 1, 1],
+			 	[1, 1, -9000, 1, 1],
+			 	[1, 1, 1, 9000, 1],
+			 	[1, 1, 1, 1, 1]
+			]::double precision[]
+		),
+	 	1, '[-9000-9000]:[-900-900]', '32BF'
+	) AS rast
+) AS t;
diff --git a/raster/test/regress/rt_reclass_expected b/raster/test/regress/rt_reclass_expected
index f7e6080..a41735d 100644
--- a/raster/test/regress/rt_reclass_expected
+++ b/raster/test/regress/rt_reclass_expected
@@ -8,3 +8,4 @@ NOTICE:  Invalid argument for reclassargset. Invalid expression of reclassexpr f
 3.1415901184082|2.71828007698059|0
 NOTICE:  Invalid argument for reclassargset. Invalid band index (must use 1-based) for reclassarg of index 0 . Returning original raster
 3.1415901184082|2.71828007698059|0
+900|-900|900
diff --git a/regress/empty.sql b/regress/empty.sql
index 1a0bd87..8150e67 100644
--- a/regress/empty.sql
+++ b/regress/empty.sql
@@ -123,14 +123,14 @@ WITH inp AS (SELECT
 WITH inp AS (SELECT
  'POLYGON EMPTY'::geometry as empty,
  1 as n
- ) SELECT 'ST_GeometryN(empty, n) == empty', ST_GeometryN(empty, n) FROM inp;
+ ) SELECT 'ST_GeometryN(empty, n) == empty', encode(ST_AsEWKB(ST_GeometryN(empty, n),'ndr'),'hex') FROM inp;
 WITH inp AS (SELECT
  'POLYGON EMPTY'::geometry as empty
- ) SELECT 'ST_ExteriorRing(empty) == empty', ST_ExteriorRing(empty) FROM inp;
+ ) SELECT 'ST_ExteriorRing(empty) == empty', encode(ST_AsEWKB(ST_ExteriorRing(empty),'ndr'),'hex') FROM inp;
 WITH inp AS (SELECT
  'POLYGON EMPTY'::geometry as empty,
  1 as n
- ) SELECT 'ST_InteriorRingN(empty, n) == NULL', ST_InteriorRingN(empty, n) FROM inp;
+ ) SELECT 'ST_InteriorRingN(empty, n) == NULL', encode(ST_AsEWKB(ST_InteriorRingN(empty, n),'ndr'),'hex') FROM inp;
 WITH inp AS (SELECT
  'POLYGON EMPTY'::geometry as empty
  ) SELECT 'ST_Area(empty) == 0', ST_Area(empty) FROM inp;
diff --git a/regress/in_geojson.sql b/regress/in_geojson.sql
index 36135b0..4b3d767 100644
--- a/regress/in_geojson.sql
+++ b/regress/in_geojson.sql
@@ -16,3 +16,6 @@ SELECT '#2130', ST_NPoints(ST_GeomFromGeoJSON('{"type":"MultiPolygon","coordinat
 
 -- #2216 --
 SELECT '#2216', ST_NPoints(ST_GeomFromGeoJSON('{"type":"MultiPolygon","coordinates":[[[[4,0],[0,-4],[-4,0],[0,4],[4,0]],[[2,0],[0,2],[-2,0],[0,-2],[2,0]]],[[[24,0],[20,-4],[16,0],[20,4],[24,0]],[[22,0],[20,2],[18,0],[20,-2],[22,0]]],[[[44,0],[40,-4],[36,0],[40,4],[44,0]],[[42,0],[40,2],[38,0],[40,-2],[42,0]]]]}'));
+
+-- #2619 --
+SELECT '#2619', ST_AsText(ST_GeomFromGeoJSON('{"type":"Polygon","bbox":[1,5,2,6],"coordinates":[]}'));
\ No newline at end of file
diff --git a/regress/in_geojson_expected b/regress/in_geojson_expected
index 701bb5f..30ae166 100644
--- a/regress/in_geojson_expected
+++ b/regress/in_geojson_expected
@@ -9,3 +9,4 @@ ERROR:  Unable to find 'coordinates' in GeoJSON string
 ERROR:  unexpected character (at offset 0)
 #2130|8
 #2216|30
+#2619|POLYGON EMPTY
diff --git a/regress/in_gml.sql b/regress/in_gml.sql
index a37ce95..d66747d 100644
--- a/regress/in_gml.sql
+++ b/regress/in_gml.sql
@@ -301,6 +301,8 @@ SELECT 'surface_21', ST_AsEWKT(ST_GeomFromGML('<gml:Surface><gml:patches><gml:Po
 -- ERROR: interpolation not planar
 SELECT 'surface_22', ST_AsEWKT(ST_GeomFromGML('<gml:Surface><gml:patches><gml:PolygonPatch interpolation="not_planar"><gml:exterior><gml:LinearRing><gml:coordinates>1,2 3,4 5,6 1,2</gml:coordinates></gml:LinearRing></gml:exterior></gml:PolygonPatch></gml:patches></gml:Surface>'));
 
+-- ERROR: interior but no exterior  
+SELECT 'surface_23', ST_AsEWKT(ST_GeomFromGML('<gml:Surface><gml:patches><gml:PolygonPatch><gml:interior><gml:LinearRing><gml:coordinates>1,2 3,4 5,6 1,2</gml:coordinates></gml:LinearRing></gml:interior></gml:PolygonPatch></gml:patches></gml:Surface>'));
 
 
 --
diff --git a/regress/in_gml_expected b/regress/in_gml_expected
index 60b0442..6fa4e2d 100644
--- a/regress/in_gml_expected
+++ b/regress/in_gml_expected
@@ -88,6 +88,7 @@ surface_19|POLYGON((1 2,3 4,5 6,1 2),(7 8,10 11,13 14,7 8))
 ERROR:  invalid GML representation
 surface_21|POLYGON((1 2,3 4,5 6,1 2))
 ERROR:  invalid GML representation
+ERROR:  invalid GML representation
 mpoint_1|MULTIPOINT(1 2)
 mpoint_2|MULTIPOINT(1 2,3 4)
 mpoint_3|SRID=4326;MULTIPOINT(1 2)
diff --git a/regress/legacy.sql b/regress/legacy.sql
index 88899da..dc68eee 100644
--- a/regress/legacy.sql
+++ b/regress/legacy.sql
@@ -8,8 +8,10 @@
 
 SET client_min_messages TO WARNING;
 
-\i 00-regress-install/share/contrib/postgis/legacy.sql
+\cd :scriptdir
+\i legacy.sql
 
+TRUNCATE spatial_ref_sys;
 INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4text") VALUES (4326,'EPSG',4326,'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]','+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs ');
 
 SELECT 'Starting up MapServer/Geoserver tests...';
@@ -54,4 +56,4 @@ SELECT 1869 As ticket_id, ST_AsText(ST_AsBinary('POINT(1 2)'));
 
 DELETE FROM spatial_ref_sys WHERE SRID = '4326';
 
-\i 00-regress-install/share/contrib/postgis/uninstall_legacy.sql
+\i uninstall_legacy.sql
diff --git a/regress/loader/ReprojectPts-pre.sql b/regress/loader/ReprojectPts-pre.sql
index 41413b2..84bc2b0 100644
--- a/regress/loader/ReprojectPts-pre.sql
+++ b/regress/loader/ReprojectPts-pre.sql
@@ -1,3 +1,5 @@
+--- In case this test is running in an extension context
+TRUNCATE spatial_ref_sys; 
 ---
 --- EPSG 4326 : WGS 84
 ---
diff --git a/regress/regress_ogc.sql b/regress/regress_ogc.sql
index 382d309..00c1737 100644
--- a/regress/regress_ogc.sql
+++ b/regress/regress_ogc.sql
@@ -4,98 +4,98 @@
 ---
 -- Repeat all tests with new function names.
 SET client_min_messages TO NOTICE;
-SELECT 'buffer', ST_astext(ST_SnapToGrid(ST_buffer('POINT(0 0)', 1, 2), 1.0e-6));
+SELECT 'buffer', ST_astext(ST_SnapToGrid(ST_buffer('POINT(0 0)'::geometry, 1, 2), 1.0e-6));
 
-SELECT 'geomunion', ST_astext(ST_union('POINT(0 0)', 'POINT(1 1)'));
-SELECT 'convexhull', ST_asewkt(ST_convexhull('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'));
-SELECT 'relate', ST_relate('POINT(0 0)', 'LINESTRING(0 0, 1 1)');
-SELECT 'relate', ST_relate('POINT(0 0)', 'LINESTRING(0 0, 1 1)', 'F0FFFF*02');
-SELECT 'relate', ST_relate('POINT(0 0)', 'LINESTRING(0 0, 1 1)', 'F0FFF0*02');
-SELECT 'disjoint', ST_disjoint('POINT(0 0)', 'LINESTRING(0 0, 1 1)');
-SELECT 'touches', ST_touches('LINESTRING(0 10, 0 -10)', 'LINESTRING(0 0, 1 1)');
-SELECT 'intersects', ST_intersects('LINESTRING(0 10, 0 -10)', 'LINESTRING(0 0, 1 1)');
-SELECT 'crosses', ST_crosses('LINESTRING(0 10, 0 -10)', 'LINESTRING(0 0, 1 1)');
-SELECT 'crosses', ST_crosses('LINESTRING(0 10, 0 -10)', 'LINESTRING(-4 0, 1 1)');
+SELECT 'geomunion', ST_astext(ST_union('POINT(0 0)'::geometry, 'POINT(1 1)'::geometry));
+SELECT 'convexhull', ST_asewkt(ST_convexhull('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'::geometry));
+SELECT 'relate', ST_relate('POINT(0 0)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry);
+SELECT 'relate', ST_relate('POINT(0 0)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry, 'F0FFFF*02');
+SELECT 'relate', ST_relate('POINT(0 0)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry, 'F0FFF0*02');
+SELECT 'disjoint', ST_disjoint('POINT(0 0)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry);
+SELECT 'touches', ST_touches('LINESTRING(0 10, 0 -10)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry);
+SELECT 'intersects', ST_intersects('LINESTRING(0 10, 0 -10)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry);
+SELECT 'crosses', ST_crosses('LINESTRING(0 10, 0 -10)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry);
+SELECT 'crosses', ST_crosses('LINESTRING(0 10, 0 -10)'::geometry, 'LINESTRING(-4 0, 1 1)'::geometry);
 -- PIP - point within polygon
-SELECT 'within100', ST_within('POINT(5 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'within100', ST_within('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on vertex of polygon
-SELECT 'within101', ST_within('POINT(0 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'within101', ST_within('POINT(0 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point outside polygon
-SELECT 'within102', ST_within('POINT(-1 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'within102', ST_within('POINT(-1 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on edge of polygon
-SELECT 'within103', ST_within('POINT(0 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'within103', ST_within('POINT(0 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'within104', ST_within('POINT(0 12)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'within104', ST_within('POINT(0 12)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'within105', ST_within(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - repeated vertex 
 SELECT 'within106', ST_within(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - point within polygon
-SELECT 'disjoint100', ST_disjoint('POINT(5 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint100', ST_disjoint('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon vertex
-SELECT 'disjoint101', ST_disjoint('POINT(0 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint101', ST_disjoint('POINT(0 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point outside polygon
-SELECT 'disjoint102', ST_disjoint('POINT(-1 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint102', ST_disjoint('POINT(-1 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon edge
-SELECT 'disjoint103', ST_disjoint('POINT(0 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint103', ST_disjoint('POINT(0 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'disjoint104', ST_disjoint('POINT(0 12)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint104', ST_disjoint('POINT(0 12)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'disjoint105', ST_disjoint(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - repeated vertex 
 SELECT 'disjoint106', ST_disjoint(ST_GeomFromText('POINT(521543 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - point within polygon
-SELECT 'disjoint150', ST_disjoint('POINT(5 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint150', ST_disjoint('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon vertex
-SELECT 'disjoint151', ST_disjoint('POINT(0 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint151', ST_disjoint('POINT(0 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point outside polygon
-SELECT 'disjoint152', ST_disjoint('POINT(-1 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint152', ST_disjoint('POINT(-1 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon edge
-SELECT 'disjoint153', ST_disjoint('POINT(0 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint153', ST_disjoint('POINT(0 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'disjoint154', ST_disjoint('POINT(0 12)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'disjoint154', ST_disjoint('POINT(0 12)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'disjoint155', ST_disjoint(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - repeated vertex
 SELECT 'disjoint156', ST_disjoint(ST_GeomFromText('POINT(521543 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - point within polygon
-SELECT 'intersects100', ST_intersects('POINT(5 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects100', ST_intersects('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon vertex
-SELECT 'intersects101', ST_intersects('POINT(0 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects101', ST_intersects('POINT(0 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point outside polygon
-SELECT 'intersects102', ST_intersects('POINT(-1 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects102', ST_intersects('POINT(-1 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon edge
-SELECT 'intersects103', ST_intersects('POINT(0 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects103', ST_intersects('POINT(0 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'intersects104', ST_intersects('POINT(0 12)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects104', ST_intersects('POINT(0 12)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'intersects105', ST_intersects(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - repeated vertex
 SELECT 'intersects106', ST_intersects(ST_GeomFromText('POINT(521543 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - point within polygon
-SELECT 'intersects150', ST_intersects('POINT(5 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects150', ST_intersects('POINT(5 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon vertex
-SELECT 'intersects151', ST_intersects('POINT(0 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects151', ST_intersects('POINT(0 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point outside polygon
-SELECT 'intersects152', ST_intersects('POINT(-1 0)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects152', ST_intersects('POINT(-1 0)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point on polygon edge
-SELECT 'intersects153', ST_intersects('POINT(0 5)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects153', ST_intersects('POINT(0 5)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'intersects154', ST_intersects('POINT(0 12)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
+SELECT 'intersects154', ST_intersects('POINT(0 12)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'intersects155', ST_intersects(ST_GeomFromText('POINT(521513 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - repeated vertex
 SELECT 'intersects156', ST_intersects(ST_GeomFromText('POINT(521543 5377804)', 32631), ST_GeomFromText('POLYGON((521526 5377783, 521482 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631));
 -- PIP - point within polygon
-SELECT 'contains100', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(5 5)');
+SELECT 'contains100', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'POINT(5 5)'::geometry);
 -- PIP - point on vertex of polygon
-SELECT 'contains101', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(0 0)');
+SELECT 'contains101', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'POINT(0 0)'::geometry);
 -- PIP - point outside polygon
-SELECT 'contains102', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(-1 0)');
+SELECT 'contains102', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'POINT(-1 0)'::geometry);
 -- PIP - point on edge of polygon
-SELECT 'contains103', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(0 5)');
+SELECT 'contains103', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'POINT(0 5)'::geometry);
 -- PIP - point in line with polygon edge
-SELECT 'contains104', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'POINT(0 12)');
+SELECT 'contains104', ST_contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'POINT(0 12)'::geometry);
 -- PIP - point vertically aligned with polygon vertex 
 SELECT 'contains105', ST_contains(ST_GeomFromText('POLYGON((521526 5377783, 521481 5377811, 521494 5377832, 521539 5377804, 521526 5377783))', 32631), ST_GeomFromText('POINT(521513 5377804)', 32631));
 -- PIP - repeated vertex 
@@ -103,25 +103,25 @@ SELECT 'contains106', ST_contains(ST_GeomFromText('POLYGON((521526 5377783, 5214
 -- moved here from regress.sql
 select 'within119', ST_within('LINESTRING(-1 -1, -1 101, 101 101, 101 -1)'::GEOMETRY,'BOX3D(0 0, 100 100)'::BOX3D);
 select 'within120', ST_within('LINESTRING(-1 -1, -1 100, 101 100, 101 -1)'::GEOMETRY,'BOX3D(0 0, 100 100)'::BOX3D);
-SELECT 'contains110', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'LINESTRING(1 10, 9 10, 9 8)');
-SELECT 'contains111', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))', 'LINESTRING(1 10, 10 10, 10 8)');
-SELECT 'within130', ST_Within('LINESTRING(1 10, 9 10, 9 8)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
-SELECT 'within131', ST_Within('LINESTRING(1 10, 10 10, 10 8)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
-SELECT 'overlaps', ST_overlaps('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))','POINT(5 5)');
-SELECT 'isvalid', ST_isvalid('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))');
-SELECT 'isvalid', ST_isvalid('POLYGON((0 0, 0 10, 10 10, -5 10, 10 0, 0 0))');
-SELECT 'isvalid', ST_isvalid('GEOMETRYCOLLECTION EMPTY');
-SELECT 'intersection', ST_astext(ST_intersection('LINESTRING(0 10, 0 -10)', 'LINESTRING(0 0, 1 1)'));
+SELECT 'contains110', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 9 10, 9 8)'::geometry);
+SELECT 'contains111', ST_Contains('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry, 'LINESTRING(1 10, 10 10, 10 8)'::geometry);
+SELECT 'within130', ST_Within('LINESTRING(1 10, 9 10, 9 8)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'within131', ST_Within('LINESTRING(1 10, 10 10, 10 8)'::geometry, 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'overlaps', ST_overlaps('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry,'POINT(5 5)'::geometry);
+SELECT 'isvalid', ST_isvalid('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'::geometry);
+SELECT 'isvalid', ST_isvalid('POLYGON((0 0, 0 10, 10 10, -5 10, 10 0, 0 0))'::geometry);
+SELECT 'isvalid', ST_isvalid('GEOMETRYCOLLECTION EMPTY'::geometry);
+SELECT 'intersection', ST_astext(ST_intersection('LINESTRING(0 10, 0 -10)'::geometry, 'LINESTRING(0 0, 1 1)'::geometry));
 SELECT 'difference', ST_astext(ST_difference('LINESTRING(0 10, 0 -10)'::GEOMETRY, 'LINESTRING(0 2, 0 -2)'::GEOMETRY));
-SELECT 'boundary', ST_astext(ST_boundary('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'));
-SELECT 'symdifference', ST_astext(ST_symdifference('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))', 'LINESTRING(0 0, 20 20)'));
-SELECT 'issimple', ST_issimple('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))');
-SELECT 'equals', ST_equals('LINESTRING(0 0, 1 1)', 'LINESTRING(1 1, 0 0)');
+SELECT 'boundary', ST_astext(ST_boundary('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'::geometry));
+SELECT 'symdifference', ST_astext(ST_symdifference('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'::geometry, 'LINESTRING(0 0, 20 20)'::geometry));
+SELECT 'issimple', ST_issimple('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'::geometry);
+SELECT 'equals', ST_equals('LINESTRING(0 0, 1 1)'::geometry, 'LINESTRING(1 1, 0 0)'::geometry);
 WITH inp AS ( SELECT
  'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'
 ::geometry as g )
 SELECT 'pointonsurface', ST_Contains(g, ST_pointonsurface(g)) from inp;
-SELECT 'centroid', ST_astext(ST_centroid('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'));
+SELECT 'centroid', ST_astext(ST_centroid('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0),(2 2, 2 4, 4 4, 4 2, 2 2))'::geometry));
 SELECT 'exteriorring', ST_astext(ST_exteriorring(ST_PolygonFromText('POLYGON((52 18,66 23,73 9,48 6,52 18),(59 18,67 18,67 13,59 13,59 18))')));
 SELECT 'polygonize_garray', ST_astext(ST_polygonize('{0102000000020000000000000000000000000000000000000000000000000024400000000000000000:0102000000020000000000000000002440000000000000000000000000000000000000000000000000:0102000000020000000000000000002440000000000000244000000000000000000000000000000000:0102000000020000000000000000002440000000000000244000000000000024400000000000000000:0102000000020000000000000000002440000000000000244000000000000000000000000000002440:01020000000200000000000 [...]
 
@@ -138,14 +138,14 @@ select 'intersects', ST_intersects(
 select 'ST_GeometryN', ST_asewkt(ST_GeometryN('LINESTRING(0 0, 1 1)'::geometry, 1));
 select 'ST_NumGeometries', ST_NumGeometries('LINESTRING(0 0, 1 1)'::geometry);
 select 'ST_Union1', ST_AsText(ST_Union(ARRAY['POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))'::geometry, 'POLYGON((0.5 0.5, 1.5 0.5, 1.5 1.5, 0.5 1.5, 0.5 0.5))'::geometry]));
-select 'ST_StartPoint1',ST_AsText(ST_StartPoint('LINESTRING(0 0, 1 1, 2 2)'));
-select 'ST_EndPoint1', ST_AsText(ST_Endpoint('LINESTRING(0 0, 1 1, 2 2)'));
-select 'ST_PointN1', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)',2));
-select 'ST_PointN2', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)',3));
-select 'ST_PointN3',  ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)',4));
-select 'ST_PointN4', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)',0));
-select 'ST_PointN5', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)',1));
-select 'ST_PointN6', ST_AsText(ST_PointN('POLYGON((0 0, 1 1, 0 1, 0 0))',1));
+select 'ST_StartPoint1',ST_AsText(ST_StartPoint('LINESTRING(0 0, 1 1, 2 2)'::geometry));
+select 'ST_EndPoint1', ST_AsText(ST_Endpoint('LINESTRING(0 0, 1 1, 2 2)'::geometry));
+select 'ST_PointN1', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)'::geometry,2));
+select 'ST_PointN2', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)'::geometry,3));
+select 'ST_PointN3',  ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)'::geometry,4));
+select 'ST_PointN4', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)'::geometry,0));
+select 'ST_PointN5', ST_AsText(ST_PointN('LINESTRING(0 0, 1 1, 2 2)'::geometry,1));
+select 'ST_PointN6', ST_AsText(ST_PointN('POLYGON((0 0, 1 1, 0 1, 0 0))'::geometry,1));
 
 -- issues with EMPTY --
-select 'ST_Buffer(empty)', ST_AsText(ST_Buffer('POLYGON EMPTY', 0.5));
+select 'ST_Buffer(empty)', ST_AsText(ST_Buffer('POLYGON EMPTY'::geometry, 0.5));
diff --git a/regress/regress_proj.sql b/regress/regress_proj.sql
index 3e63818..de3b55e 100644
--- a/regress/regress_proj.sql
+++ b/regress/regress_proj.sql
@@ -10,7 +10,7 @@ INSERT INTO "spatial_ref_sys" ("srid","auth_name","auth_srid","srtext","proj4tex
 
 -- Repeat all tests with the new function names.
 --- test #0: NULL values
-SELECT 0,coalesce(ST_AsText(ST_transform(NULL, 100001)),'EMPTY');
+SELECT 0,coalesce(ST_AsText(ST_transform(NULL::geometry, 100001)),'EMPTY');
 
 --- test #1: a simple projection
 SELECT 1,ST_AsEWKT(ST_SnapToGrid(ST_transform(ST_GeomFromEWKT('SRID=100002;POINT(16 48)'),100001),10));
diff --git a/regress/run_test.pl b/regress/run_test.pl
index cf8a66f..82fd882 100755
--- a/regress/run_test.pl
+++ b/regress/run_test.pl
@@ -200,16 +200,6 @@ else
 	}
 }
 
-if ( $OPT_UPGRADE )
-{
-	upgrade_spatial();
-}
-
-
-##################################################################
-# Report PostGIS environment
-##################################################################
-
 my $libver = sql("select postgis_lib_version()");
 
 if ( ! $libver )
@@ -220,6 +210,24 @@ if ( ! $libver )
 	exit(1);
 }
 
+
+if ( $OPT_UPGRADE )
+{
+	if ( $OPT_EXTENSIONS )
+	{	
+		upgrade_spatial_extensions();
+	}
+	else
+	{
+	  upgrade_spatial();
+  }
+}
+
+
+##################################################################
+# Report PostGIS environment
+##################################################################
+
 my $geosver =  sql("select postgis_geos_version()");
 my $projver = sql("select postgis_proj_version()");
 my $svnrev = sql("select postgis_svn_version()");
@@ -540,7 +548,21 @@ sub run_simple_test
 	mkpath($betmpdir);
 	chmod 0777, $betmpdir;
 
-	my $cmd = "psql -v \"VERBOSITY=terse\" -v \"tmpfile='$tmpfile'\" -tXA $DB < $sql > $outfile 2>&1";
+	my $scriptdir;
+	if ( $OPT_EXTENSIONS ) {
+		# TODO: allow override this default with env variable ?
+		my $pgis_majmin = $libver;
+		$pgis_majmin =~ s/^([1-9]*\.[1-9]*).*/\1/;
+		$scriptdir = `pg_config --sharedir`;
+		chop $scriptdir;
+		$scriptdir .= "/contrib/postgis-" . $pgis_majmin;
+	} else {
+		$scriptdir = $STAGED_SCRIPTS_DIR;
+	}
+	my $cmd = "psql -v \"VERBOSITY=terse\""
+          . " -v \"tmpfile='$tmpfile'\""
+          . " -v \"scriptdir=$scriptdir\""
+          . " -tXA $DB < $sql > $outfile 2>&1";
 	my $rv = system($cmd);
 
 	# Check for ERROR lines
@@ -1111,6 +1133,29 @@ sub upgrade_spatial
     return 1;
 }
 
+# Upgrade an existing database (soft upgrade, extension method)
+sub upgrade_spatial_extensions
+{
+    print "Upgrading PostGIS in '${DB}' using 'ALTER EXTENSION'\n" ;
+
+    # ON_ERROR_STOP is used by psql to return non-0 on an error
+    my $psql_opts = "--no-psqlrc --variable ON_ERROR_STOP=true";
+    my $cmd = "psql $psql_opts -c \"ALTER EXTENSION postgis UPDATE TO '${libver}next'\" $DB >> $REGRESS_LOG 2>&1";
+    my $rv = system($cmd);
+    die "\nError encountered altering EXTENSION POSTGIS, see $REGRESS_LOG for details\n\n"
+	    if $rv;
+
+    if ( $OPT_WITH_TOPO ) 
+    {
+      my $cmd = "psql $psql_opts -c \"ALTER EXTENSION postgis_topology UPDATE TO '${libver}next'\" $DB >> $REGRESS_LOG 2>&1";
+      my $rv = system($cmd);
+      die "\nError encountered altering EXTENSION POSTGIS_TOPOLOGY, see $REGRESS_LOG for details\n\n"
+        if $rv;
+    }
+    
+    return 1;
+}
+
 sub drop_spatial
 {
 	my $ok = 1;
diff --git a/regress/sql-mm-curvepoly.sql b/regress/sql-mm-curvepoly.sql
index 4e8dae6..a45b882 100644
--- a/regress/sql-mm-curvepoly.sql
+++ b/regress/sql-mm-curvepoly.sql
@@ -336,7 +336,7 @@ SELECT 'valid ewkb curve polygon 2', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000
 SELECT 'valid ewkb curve polygon 3', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000001000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec0', 'hex')));
 SELECT 'valid ewkb curve polygon 4', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010800000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00102000000060000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c0000000e0107f6240000000c0a10440c04e1c0c14624c624 [...]
 SELECT 'valid ewkb curve polygon 5', ST_asEWKT(ST_GeomFromEWKB(decode('010a00000002000000010200000007000000ccdf061ad9f3614054093e6d99093ec0ab9085dbb6dd614081540229216040c0ebd7a828c33e62409bf026782a7e41c0000000c06bb2624000000020adb440c08e632f616ead6240c9f7b0bf1dd33dc09011eec0de4362407dd6672f76323ec0ccdf061ad9f3614054093e6d99093ec00109000000030000000108000000030000006844c4fe011b6240342e2993e0423fc0d45daf9d93066240c4a0c305d62240c000000080ac31624000000020fbbe40c001020000000200000000000080ac3 [...]
-SELECT 'valid curve 6', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');
-SELECT 'valid curve 7', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )');
-SELECT 'valid curve 8', ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )');
+SELECT 'valid curve 6', encode(ST_AsBinary(ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'),'ndr'),'hex');
+SELECT 'valid curve 7', encode(ST_AsBinary(ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), (1.7 1, 1.4 0.4, 1.7 1) )'),'ndr'),'hex');
+SELECT 'valid curve 8', encode(ST_AsBinary(ST_GeomFromText('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'),'ndr'),'hex');
 SELECT 'null response', ST_NumPoints(ST_GeomFromEWKT('CURVEPOLYGON(COMPOUNDCURVE(CIRCULARSTRING(0 0,2 0, 2 1, 2 3, 4 3),(4 3, 4 5, 1 4, 0 0)), CIRCULARSTRING(1.7 1, 1.4 0.4, 1.7 1) )'));
diff --git a/regress/sql-mm-curvepoly_expected b/regress/sql-mm-curvepoly_expected
index 5c75152..082ff70 100644
--- a/regress/sql-mm-curvepoly_expected
+++ b/regress/sql-mm-curvepoly_expected
@@ -89,7 +89,7 @@ valid ewkb curve polygon 2|CURVEPOLYGON((143.620251668383 -30.0374973560768,142.
 valid ewkb curve polygon 3|CURVEPOLYGON(CIRCULARSTRING(143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768))
 valid ewkb curve polygon 4|CURVEPOLYGON(CIRCULARSTRING(143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768),(144.843993552527 -31.2612392402209,144.205519526017 -32.2721564488616,145.552307128906 -33.4920387268066,147.970809936523 -32.0361862182617,146.386972449926 -31.4740639157242,144.843993552527 [...]
 valid ewkb curve polygon 5|CURVEPOLYGON((143.620251668383 -30.0374973560768,142.928571472997 -32.751011968744,145.961323098919 -34.9856710615288,149.575653076172 -33.4115333557129,149.419724075848 -29.8246726805735,146.120941605547 -30.1971158627043,143.620251668383 -30.0374973560768),COMPOUNDCURVE(CIRCULARSTRING(144.843993552527 -31.2612392402209,144.205519526017 -32.2721564488616,145.552307128906 -33.4920387268066),(145.552307128906 -33.4920387268066,147.970809936523 -32.0361862182617) [...]
-valid curve 6|010A0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000F03F00000000000000400000000000000840000000000000104000000000000008400102000000040000000000000000001040000000000000084000000000000010400000000000001440000000000000F03F000000000000104000000000000000000000000000000000010800000003000000333333333333FB3F000000000000F03F666666666666F63F9A9999999999D93F333333333333FB3F000000000000F03F
+valid curve 6|010a0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000f03f00000000000000400000000000000840000000000000104000000000000008400102000000040000000000000000001040000000000000084000000000000010400000000000001440000000000000f03f000000000000104000000000000000000000000000000000010800000003000000333333333333fb3f000000000000f03f666666666666f63f9a9999999999d93f333333333333fb3f000000000000f03f
 ERROR:  geometry requires more points
-valid curve 8|010A0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000F03F00000000000000400000000000000840000000000000104000000000000008400102000000020000000000000000001040000000000000084000000000000000000000000000000000010800000003000000333333333333FB3F000000000000F03F666666666666F63F9A9999999999D93F333333333333FB3F000000000000F03F
+valid curve 8|010a0000000200000001090000000200000001080000000500000000000000000000000000000000000000000000000000004000000000000000000000000000000040000000000000f03f00000000000000400000000000000840000000000000104000000000000008400102000000020000000000000000001040000000000000084000000000000000000000000000000000010800000003000000333333333333fb3f000000000000f03f666666666666f63f9a9999999999d93f333333333333fb3f000000000000f03f
 null response|
diff --git a/regress/tickets.sql b/regress/tickets.sql
index b18cc64..46fcc2d 100644
--- a/regress/tickets.sql
+++ b/regress/tickets.sql
@@ -52,7 +52,7 @@ SELECT '#44', ST_Relate(g1, g2, 'T12101212'), ST_Relate(g1, g2, 't12101212') FRO
 ) AS v(g1, g2);
 
 -- #58 --
-SELECT '#58', round(ST_xmin(g)),round(ST_ymin(g)),round(ST_xmax(g)),round(ST_ymax(g)) FROM (SELECT ST_Envelope('CIRCULARSTRING(220268.439465645 150415.359530563,220227.333322076 150505.561285879,220227.353105332 150406.434743975)') as g)  AS foo;
+SELECT '#58', round(ST_xmin(g)),round(ST_ymin(g)),round(ST_xmax(g)),round(ST_ymax(g)) FROM (SELECT ST_Envelope('CIRCULARSTRING(220268.439465645 150415.359530563,220227.333322076 150505.561285879,220227.353105332 150406.434743975)'::geometry) as g)  AS foo;
 
 -- #65 --
 SELECT '#65', ST_AsGML(ST_GeometryFromText('CURVEPOLYGON(CIRCULARSTRING(4 2,3 -1.0,1 -1,-1.0 4,4 2))'));
@@ -602,7 +602,7 @@ FROM inp;
 -- #1150
 insert into spatial_ref_sys (srid, proj4text) values (500001,NULL);
 insert into spatial_ref_sys (srid, proj4text) values (500002, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs');
-select '#1150', st_astext(st_transform('SRID=500002;POINT(0 0)',500001));
+select '#1150', st_astext(st_transform('SRID=500002;POINT(0 0)'::geometry,500001));
 
 -- #1038
 select '#1038', ST_AsSVG('POLYGON EMPTY'::geometry);
@@ -850,5 +850,14 @@ SELECT '#2168',  ST_Distance(g1,g2)::numeric(16,8)  As dist_g1_g2, ST_Distance(g
   FROM (SELECT 'POINT(18.5107234 54.7587757)'::geography As g1, 'POINT(18.58218 54.7344227)'::geography As g2) As a;
 
 
+-- #2556 --
+
+CREATE TABLE images (id integer, name varchar, extent geography(POLYGON,4326));
+INSERT INTO images VALUES (47409, 'TDX-1_2010-10-06T19_44_2375085', 'SRID=4326;POLYGON((-59.4139571913088 82.9486103943668,-57.3528882462655 83.1123152898828,-50.2302874208478 81.3740574826097,-51.977353304689 81.2431047148532,-59.4139571913088 82.9486103943668))'::geography);
+INSERT INTO images VALUES (1, 'first_image', 'SRID=4326;POLYGON((-162.211667 88.046667,-151.190278 87.248889,-44.266389 74.887778,-40.793889 75.043333,-162.211667 88.046667))'::geography);
+SELECT '#2556' AS ticket, id, round(ST_Distance(extent, 'SRID=4326;POLYGON((-46.625977 81.634149,-46.625977 81.348076,-48.999023 81.348076,-48.999023 81.634149,-46.625977 81.634149))'::geography)) from images;
+DROP TABLE images;
+
+
 -- Clean up
 DELETE FROM spatial_ref_sys;
diff --git a/regress/tickets_expected b/regress/tickets_expected
index 7601b28..1745829 100644
--- a/regress/tickets_expected
+++ b/regress/tickets_expected
@@ -253,3 +253,5 @@ ERROR:  invalid GML representation
 #2424|MULTILINESTRING((0 0,10 0,24 3,30 10))
 #2427|POINT(-1 0)
 #2168|5340.76237395|5340.76237395|0
+#2556|47409|20623
+#2556|1|0
diff --git a/topology/sql/export/TopoJSON.sql.in b/topology/sql/export/TopoJSON.sql.in
index 3a58600..4a27b08 100644
--- a/topology/sql/export/TopoJSON.sql.in
+++ b/topology/sql/export/TopoJSON.sql.in
@@ -119,7 +119,7 @@ BEGIN
     EXECUTE 'SET search_path TO ' || quote_ident(toponame) || ',' || old_search_path;
 
     SELECT array_agg(id) as f
-    FROM ( SELECT (GetTopoGeomElements(tg))[1] as id ) as f
+    FROM ( SELECT (topology.GetTopoGeomElements(tg))[1] as id ) as f
     INTO all_faces;
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
diff --git a/topology/sql/populate.sql.in b/topology/sql/populate.sql.in
index 657f60e..537c8ef 100644
--- a/topology/sql/populate.sql.in
+++ b/topology/sql/populate.sql.in
@@ -138,7 +138,7 @@ BEGIN
 		|| ', ST_EndPoint(geom))'
 	LOOP
     IF allowEdgeSplitting THEN
-      RETURN ST_ModEdgeSplit(atopology, rec.edge_id, apoint);
+      RETURN topology.ST_ModEdgeSplit(atopology, rec.edge_id, apoint);
     ELSE
 		  RAISE EXCEPTION 'An edge crosses the given node.';
     END IF;
@@ -783,7 +783,7 @@ BEGIN
         RAISE WARNING 'Edge within % distance from node still does not contain the node after snapping to it with tolerance %', tol, snaptol;
       END IF;
 #endif
-      PERFORM ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
+      PERFORM topology.ST_ChangeEdgeGeom(atopology, rec.edge_id, snapedge);
     END IF;
     id := topology.ST_ModEdgeSplit(atopology, rec.edge_id, prj);
   ELSE
@@ -1056,7 +1056,7 @@ BEGIN
 
   -- 3. Find faces covered by input polygon
   --    NOTE: potential snapping changed polygon edges
-  sql := 'SELECT DISTINCT f.face_id FROM ' || quote_ident(atopology)
+  sql := 'SELECT f.face_id FROM ' || quote_ident(atopology)
     || '.face f WHERE f.mbr && '
     || quote_literal(apoly::text)
     || '::geometry';
@@ -1065,7 +1065,7 @@ BEGIN
 #endif
   FOR rec IN EXECUTE sql LOOP
     -- check for actual containment
-    fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
+    fgeom := ST_PointOnSurface(topology.ST_GetFaceGeometry(atopology, rec.face_id));
     IF NOT ST_Covers(apoly, fgeom) THEN
 #ifdef POSTGIS_TOPOLOGY_DEBUG
       RAISE DEBUG 'Face % not covered by input polygon', rec.face_id;
diff --git a/topology/sql/sqlmm.sql.in b/topology/sql/sqlmm.sql.in
index a7b81f5..e04d99c 100644
--- a/topology/sql/sqlmm.sql.in
+++ b/topology/sql/sqlmm.sql.in
@@ -57,7 +57,7 @@ BEGIN
     RAISE EXCEPTION 'SQL/MM Spatial exception - null argument';
   END IF;
 
-  IF NOT EXISTS(SELECT name FROM topology WHERE name = toponame)  THEN
+  IF NOT EXISTS(SELECT name FROM topology.topology WHERE name = toponame)  THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - invalid topology name';
   END IF;
 
@@ -1393,7 +1393,7 @@ BEGIN
     RAISE EXCEPTION 'SQL/MM Spatial exception - null argument';
   END IF;
 
-  IF NOT EXISTS(SELECT name FROM topology WHERE name = toponame)  THEN
+  IF NOT EXISTS(SELECT name FROM topology.topology WHERE name = toponame)  THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - invalid topology name';
   END IF;
 
@@ -1464,10 +1464,10 @@ BEGIN
      'SQL/MM Spatial exception - null argument';
   END IF;
 
-      --
+  --
   -- Atopology must  be registered
   -- 
-  IF NOT EXISTS(SELECT name FROM topology WHERE topology.name = atopology) THEN
+  IF NOT EXISTS(SELECT name FROM topology.topology WHERE topology.name = atopology) THEN
     RAISE EXCEPTION
      'SQL/MM Spatial exception - invalid topology name';
   END IF;
@@ -2523,7 +2523,7 @@ DECLARE
 BEGIN
   WITH edgestar AS (
     SELECT *, count(*) over () AS cnt
-    FROM GetNodeEdges(atopology, anode)
+    FROM topology.GetNodeEdges(atopology, anode)
   )
   SELECT ARRAY[ (
       SELECT p.edge AS prev FROM edgestar p
@@ -2854,7 +2854,7 @@ BEGIN
   IF oldedge.left_face != 0 THEN
     sql := 'UPDATE ' || quote_ident(atopology) || '.face '
       || ' SET mbr = ' || quote_literal(
-        ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.left_face))::text
+        ST_Envelope(topology.ST_GetFaceGeometry(atopology, oldedge.left_face))::text
         )
       || '::geometry WHERE face_id = ' || oldedge.left_face;
     EXECUTE sql;
@@ -2862,7 +2862,7 @@ BEGIN
   IF oldedge.right_face != 0 AND oldedge.right_face != oldedge.left_face THEN
     sql := 'UPDATE ' || quote_ident(atopology) || '.face '
       || ' SET mbr = ' || quote_literal(
-        ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.right_face))::text
+        ST_Envelope(topology.ST_GetFaceGeometry(atopology, oldedge.right_face))::text
         )
       || '::geometry WHERE face_id = ' || oldedge.right_face;
     EXECUTE sql;
@@ -3052,11 +3052,12 @@ BEGIN
        )::text )
     || ') AND ';
   IF ishole THEN sql := sql || 'NOT '; END IF;
-  sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text)
+  sql := sql || '( ' || quote_literal(fan.shell::text)
+    || ' && geom AND _ST_Contains(' || quote_literal(fan.shell::text)
     -- We only need to check a single point, but must not be an endpoint
-    || '::geometry, ST_LineInterpolatePoint(geom, 0.2))';
+    || '::geometry, ST_LineInterpolatePoint(geom, 0.2)) )';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
-  RAISE DEBUG 'Updating edges bounding the old face';
+  RAISE DEBUG 'Updating edges bounding the old face: %', sql;
 #endif
   EXECUTE sql;
 
@@ -3222,7 +3223,7 @@ BEGIN
   IF newedge.start_node_geom IS NULL
   THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent node';
-  ELSIF NOT Equals(newedge.start_node_geom, ST_StartPoint(acurve))
+  ELSIF NOT ST_Equals(newedge.start_node_geom, ST_StartPoint(acurve))
   THEN
     RAISE EXCEPTION
       'SQL/MM Spatial exception - start node not geometry start point.';
@@ -3231,7 +3232,7 @@ BEGIN
   IF newedge.end_node_geom IS NULL
   THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent node';
-  ELSIF NOT Equals(newedge.end_node_geom, ST_EndPoint(acurve))
+  ELSIF NOT ST_Equals(newedge.end_node_geom, ST_EndPoint(acurve))
   THEN
     RAISE EXCEPTION
       'SQL/MM Spatial exception - end node not geometry end point.';
@@ -3853,7 +3854,7 @@ BEGIN
   IF newedge.start_node_geom IS NULL
   THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent node';
-  ELSIF NOT Equals(newedge.start_node_geom, ST_StartPoint(acurve))
+  ELSIF NOT ST_Equals(newedge.start_node_geom, ST_StartPoint(acurve))
   THEN
     RAISE EXCEPTION
       'SQL/MM Spatial exception - start node not geometry start point.';
@@ -3862,7 +3863,7 @@ BEGIN
   IF newedge.end_node_geom IS NULL
   THEN
     RAISE EXCEPTION 'SQL/MM Spatial exception - non-existent node';
-  ELSIF NOT Equals(newedge.end_node_geom, ST_EndPoint(acurve))
+  ELSIF NOT ST_Equals(newedge.end_node_geom, ST_EndPoint(acurve))
   THEN
     RAISE EXCEPTION
       'SQL/MM Spatial exception - end node not geometry end point.';
diff --git a/topology/sql/topoelement/topoelement_agg.sql.in b/topology/sql/topoelement/topoelement_agg.sql.in
index fd1e3e7..95cbe05 100644
--- a/topology/sql/topoelement/topoelement_agg.sql.in
+++ b/topology/sql/topoelement/topoelement_agg.sql.in
@@ -49,6 +49,7 @@ LANGUAGE 'sql' IMMUTABLE;
 --
 -- Aggregates a set of TopoElement values into a TopoElementArray
 --
+-- Availability: 2.0.0
 DROP AGGREGATE IF EXISTS topology.TopoElementArray_agg(topology.TopoElement);
 CREATE AGGREGATE topology.TopoElementArray_agg(
 	sfunc = topology.TopoElementArray_append,
diff --git a/topology/sql/topogeometry/simplify.sql.in b/topology/sql/topogeometry/simplify.sql.in
index 9604310..11529fd 100644
--- a/topology/sql/topogeometry/simplify.sql.in
+++ b/topology/sql/topogeometry/simplify.sql.in
@@ -63,7 +63,7 @@ BEGIN
 
     sql := 'SELECT st_multi(st_union(topology.ST_Simplify('
       || quote_ident(child_layer_info.feature_column)
-      || '))) as geom FROM '
+      || ',' || tolerance || '))) as geom FROM '
       || quote_ident(child_layer_info.schema_name) || '.'
       || quote_ident(child_layer_info.table_name)
       || ', ' || quote_ident(topology_info.name) || '.relation pr'
diff --git a/topology/test/Makefile b/topology/test/Makefile
index 2a46c24..7a7cf9e 100644
--- a/topology/test/Makefile
+++ b/topology/test/Makefile
@@ -2,7 +2,7 @@ DATABASE=postgis_topo_regress
 
 PSQL=psql
 PERL=/opt/local/bin/perl
-GEOS_NUMERIC_VERSION=30403
+GEOS_NUMERIC_VERSION=30402
 
 all: 
 	@echo "Use 'make check' to run all tests"
diff --git a/topology/test/regress/st_createtopogeo.sql b/topology/test/regress/st_createtopogeo.sql
index b9131ab..6a47ad2 100644
--- a/topology/test/regress/st_createtopogeo.sql
+++ b/topology/test/regress/st_createtopogeo.sql
@@ -1,6 +1,7 @@
 \set VERBOSITY terse
 set client_min_messages to ERROR;
 
+TRUNCATE spatial_ref_sys;
 INSERT INTO spatial_ref_sys ( auth_name, auth_srid, srid, proj4text ) VALUES ( 'EPSG', 4326, 4326, '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' );
 
 -- Invalid topologies
diff --git a/topology/test/regress/st_simplify.sql b/topology/test/regress/st_simplify.sql
index 0497b59..f13a627 100644
--- a/topology/test/regress/st_simplify.sql
+++ b/topology/test/regress/st_simplify.sql
@@ -1,10 +1,12 @@
 set client_min_messages to WARNING;
 
-SELECT CreateTopology('tt') > 1;
+SELECT CreateTopology('tt') > 0;
 CREATE TABLE tt.areas(id serial, g geometry);
 INSERT INTO tt.areas(g) VALUES ('POLYGON((0 0,1 1,1 3,0 4,-2 3,-1 1,0 0))'),
                                ('POLYGON((0 0,1 1,1 3,2 3,2 0,0 0))');
-SELECT 'L' || AddTopoGeometryColumn('tt', 'tt', 'areas', 'tg', 'polygon');
+CREATE TEMP TABLE _test_layers AS SELECT 1 as id,
+  AddTopoGeometryColumn('tt', 'tt', 'areas', 'tg', 'polygon') as layer_id;
+SELECT 'L' || layer_id FROM _test_layers WHERE id = 1;
 UPDATE tt.areas SET tg = toTopoGeom(g, 'tt', 1);
 
 -- ensures this point won't be removed
@@ -20,4 +22,30 @@ SELECT 'S2',
   ST_Equals(ST_Simplify(tg, 1), 'POLYGON((0 0,1 3,2 0,0 0))')
 FROM tt.areas WHERE id = 2;
 
+-- Test hierarchical -- see http://trac.osgeo.org/postgis/ticket/2547
+
+CREATE TABLE tt.bigareas(id serial, g geometry);
+INSERT INTO _test_layers SELECT 2,
+  AddTopoGeometryColumn('tt', 'tt', 'bigareas', 'tg', 'polygon', layer_id)
+  FROM _test_layers WHERE id = 1;
+SELECT 'L' || layer_id FROM _test_layers WHERE id = 2;
+INSERT INTO tt.bigareas (tg) SELECT
+  topology.CreateTopoGeom( 'tt', 3,
+    (select layer_id from _test_layers where id = 2),
+    TopoElementArray_agg(ARRAY[r.topogeo_id, r.layer_id]))
+  FROM tt.relation r, _test_layers l1
+  WHERE r.layer_id = l1.layer_id AND l1.id = 1
+  GROUP BY r.topogeo_id;
+UPDATE tt.bigareas SET g = tg;
+
+SELECT 'HS1',
+  -- Point 1 3 is removed when simplifying the simple (unconstrained) geometry
+  ST_Equals(ST_Simplify( g, 1), 'POLYGON((0 0,1 3,-2 3,0 0))'),
+  ST_Equals(ST_Simplify(tg, 1), 'POLYGON((0 0,1 3,-2 3,0 0))')
+FROM tt.bigareas WHERE id = 1;
+SELECT 'HS2',
+  ST_Equals(ST_Simplify( g, 1), 'POLYGON((0 0,1 3,2 0,0 0))'),
+  ST_Equals(ST_Simplify(tg, 1), 'POLYGON((0 0,1 3,2 0,0 0))')
+FROM tt.bigareas WHERE id = 2;
+
 SELECT DropTopology('tt') IS NULL;
diff --git a/topology/test/regress/st_simplify_expected b/topology/test/regress/st_simplify_expected
index 75152ce..2177681 100644
--- a/topology/test/regress/st_simplify_expected
+++ b/topology/test/regress/st_simplify_expected
@@ -3,4 +3,7 @@ L1
 N2
 S1|f|t
 S2|f|t
+L2
+HS1|f|t
+HS2|f|t
 f
diff --git a/utils/postgis_proc_upgrade.pl b/utils/postgis_proc_upgrade.pl
index 93b82ff..8dbd10e 100755
--- a/utils/postgis_proc_upgrade.pl
+++ b/utils/postgis_proc_upgrade.pl
@@ -37,7 +37,21 @@ use warnings;
 # if the major numbers in version_from are less than the version_to
 # number.
 #
+# TODO: move configuration outside of code
+#
 my $objs = {
+ 	"102" => { 
+		"aggregates" => {
+			"st_extent(geometry)" => 1,
+			"st_memcollect(geometry)" => 1,
+			"st_memunion(geometry)" => 1,
+			"st_accum(geometry)" => 1,
+			"st_union(geometry)" => 1,
+			"st_collect(geometry)" => 1,
+			"st_polygonize(geometry)" => 1,
+			"st_makeline(geometry)" => 1
+		}
+	},
  	"104" => { 
 		"types" => {
 			"box3d_extent" => 1,
@@ -64,6 +78,28 @@ my $objs = {
 			"geography" => 1,
 			"gidx" => 1
 		}
+	},
+ 	"200" => { 
+		"aggregates" => {
+			"st_3dextent(geometry)" => 1,
+      "topology.topoelementarray_agg(topology.topoelement)" => 1
+		}
+	},
+ 	"201" => { 
+		"aggregates" => {
+			"st_samealignment(raster)" => 1,
+			"st_union(raster,unionarg[])" => 1,
+			"st_union(raster,integer,text)" => 1,
+			"st_union(raster,integer)" => 1,
+			"st_union(raster)" => 1,
+			"st_union(raster,text)" => 1
+		},
+		"operators" => {
+			"raster =" => 1
+		},
+		"opclasses" => {
+			"hash_raster_ops" => 1
+		},
 	}
 };
 
@@ -75,6 +111,7 @@ die "Usage: perl postgis_proc_upgrade.pl <postgis.sql> <version_from> [<schema>]
 	if ( @ARGV < 1 || @ARGV > 3 );
 
 my $sql_file = $ARGV[0];
+my $module = 'postgis';
 my $version_to = "";
 my $version_to_num = 0;
 my $version_from = $ARGV[1];
@@ -109,6 +146,10 @@ while(<INPUT>)
 				$version_to = $1;
 				last;
 	}
+	elsif (/TYPE raster/)
+	{
+        $module = 'postgis_raster';
+	}
 }
 close(INPUT); 
 
@@ -142,6 +183,7 @@ print "SET search_path TO $schema;\n" if $schema;
 while(<DATA>)
 {
 	s/NEWVERSION/$version_to/g;
+  s/MODULE/$module/g;
 	print;
 }
 
@@ -211,24 +253,46 @@ while(<INPUT>)
 		my $type1 = $1;
 		my $type2 = $2;
 		my $def = $_;
+    unless (/;$/) { 
+      while(<INPUT>) {
+        $def .= $_;
+        last if /;$/;
+      }
+    }
 		print "DROP CAST IF EXISTS ($type1 AS $type2);\n";
 		print $def;
 	}
 
 	# This code handles aggregates by dropping and recreating them.
-	if ( /^create aggregate\s+(\S+)\s*\(/i )
+	if ( /^create aggregate\s+([^(]+)\s*\(/i )
 	{
 		my $aggname = $1;
+    #print "-- Aggname ${aggname}\n";
 		my $aggtype = 'unknown';
 		my $def = $_;
+    if ( /^create aggregate\s+\S+\s*\(([^)]*)\)/i ) {
+	    $aggtype = $1;
+      $aggtype =~ s/\s*,\s*/,/g; # drop spaces around commas
+      $aggtype =~ s/\s\s*/ /g; # collapse multiple spaces into one
+    }
 		while(<INPUT>)
 		{
 			$def .= $_;
 			$aggtype = $1 if ( /basetype\s*=\s*([^,]*)\s*,/i );
 			last if /\);/;
 		}
-		print "DROP AGGREGATE IF EXISTS $aggname($aggtype);\n";
-		print $def;
+		my $aggsig = "$aggname($aggtype)";
+		my $ver = $version_from_num + 1;
+    #print "-- Checking ${aggsig} -- From: ${version_from_num} -- To: ${version_to_num}\n";
+		while( $version_from_num < $version_to_num && $ver <= $version_to_num )
+		{
+			if( $objs->{$ver}->{"aggregates"}->{$aggsig} )
+			{
+        print "DROP AGGREGATE IF EXISTS $aggsig;\n";
+        print $def;
+			}
+			$ver++;
+		}
 	}
 	
 	# This code handles operators by creating them if we are doing a major upgrade
@@ -338,10 +402,10 @@ BEGIN
 	-- 
 
 	BEGIN
-		SELECT into old_scripts postgis_lib_version();
+		SELECT into old_scripts MODULE_lib_version();
 	EXCEPTION WHEN OTHERS THEN
 		RAISE DEBUG ''Got %'', SQLERRM;
-		SELECT into old_scripts postgis_scripts_installed();
+		SELECT into old_scripts MODULE_scripts_installed();
 	END;
 
 	SELECT into new_scripts ''NEWVERSION'';
@@ -349,7 +413,7 @@ BEGIN
 	SELECT into new_maj substring(new_scripts from 1 for 2);
 
 	IF old_maj != new_maj THEN
-		RAISE EXCEPTION ''Upgrade from version % to version % requires a dump/reload. See PostGIS manual for instructions'', old_scripts, new_scripts;
+		RAISE EXCEPTION ''Upgrade of MODULE from version % to version % requires a dump/reload. See PostGIS manual for instructions'', old_scripts, new_scripts;
 	ELSE
 		RETURN ''Scripts versions checked for upgrade: ok'';
 	END IF;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/postgis.git



More information about the Pkg-grass-devel mailing list