From e1dc60ed3f418d1fd70054581f2bb8962d6e9a98 Mon Sep 17 00:00:00 2001
From: nuno <nmco51845@gmail.com>
Date: Mon, 7 May 2012 11:47:58 +0100
Subject: [PATCH] Add 3D coordinates support to PostGIS.

---
 .../main/java/org/geotools/jdbc/JDBCDataStore.java |    2 +-
 .../main/java/org/geotools/jdbc/SQLDialect.java    |   38 ++++++++++++++++++++
 .../org/geotools/data/postgis/PostGISDialect.java  |   35 ++++++++++++++++++
 3 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java b/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
index 9776158..7cc4636 100644
--- a/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
+++ b/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStore.java
@@ -4384,7 +4384,7 @@ public final class JDBCDataStore extends ContentDataStore
     		return;    		
     	}
 
-        dialect.encodeGeometryColumn(gatt,prefix,srid, sql);
+        dialect.encodeGeometryColumn(gatt,prefix,srid, sql, hints);
     }
     
     /**
diff --git a/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java b/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
index 0c0c68a..a298649 100644
--- a/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
+++ b/modules/library/jdbc/src/main/java/org/geotools/jdbc/SQLDialect.java
@@ -705,10 +705,48 @@ public abstract class SQLDialect {
     * This default implementation simply uses the column name without any
     * wrapping function, subclasses must override.
     * </p>
+    * 
+    * @deprecated use {@link #encodeGeometryColumn(GeometryDescriptor, String, int, StringBuffer, Hints)}
     */
     public void encodeGeometryColumn(GeometryDescriptor gatt, String prefix, int srid, StringBuffer sql) {
         encodeColumnName(prefix, gatt.getLocalName(), sql);
     }
+    
+	/**
+	 * Encodes the name of a geometry column in a SELECT statement.
+	 * <p>
+	 * This method should wrap the column name in any functions that are used to
+	 * retrieve its value. For instance, often it is necessary to use the
+	 * function <code>asText</code>, or <code>asWKB</code> when fetching a
+	 * geometry.
+	 * </p>
+	 * <p>
+	 * This method must also be sure to properly encode the name of the column
+	 * with the {@link #encodeColumnName(String, String, StringBuffer)}
+	 * function.
+	 * </p>
+	 * <p>
+	 * Example:
+	 * </p>
+	 * 
+	 * <pre>
+	 *   <code>
+	 *   sql.append( "asText(" );
+	 *   column( gatt.getLocalName(), sql );
+	 *   sql.append( ")" );
+	 *   </code>
+	 * </pre>
+	 * 
+	 * </p>
+	 * <p>
+	 * This default implementation simply uses the column name without any
+	 * wrapping function, subclasses must override.
+	 * </p>
+	 */
+	public void encodeGeometryColumn(GeometryDescriptor gatt, String prefix,
+			int srid, StringBuffer sql, Hints hints) {
+		encodeColumnName(prefix, gatt.getLocalName(), sql);
+	}
 
     /**
      * Encodes a generalized geometry using a DB provided SQL function if available
diff --git a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
index 1f68d35..6cce869 100644
--- a/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
+++ b/modules/plugin/jdbc/jdbc-postgis/src/main/java/org/geotools/data/postgis/PostGISDialect.java
@@ -33,6 +33,7 @@ import java.util.UUID;
 import java.util.logging.Level;
 
 import org.geotools.data.jdbc.FilterToSQL;
+import org.geotools.factory.Hints;
 import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.jdbc.BasicSQLDialect;
 import org.geotools.jdbc.ColumnMetadata;
@@ -206,6 +207,40 @@ public class PostGISDialect extends BasicSQLDialect {
         }
         sql.append("),'base64')");
     }
+    
+	@Override
+	public void encodeGeometryColumn(GeometryDescriptor gatt, String prefix,
+			int srid, StringBuffer sql, Hints hints) {
+
+		boolean geography = "geography".equals(gatt.getUserData().get(
+				JDBCDataStore.JDBC_NATIVE_TYPENAME));
+
+		if(geography) {
+			sql.append("encode(ST_AsBinary(");
+			encodeColumnName(prefix, gatt.getLocalName(), sql);
+			sql.append("),'base64')");
+		}
+		
+		else {
+			boolean force2D = false;
+			if (hints.containsKey(Hints.FEATURE_2D)) {
+				if (hints.get(Hints.FEATURE_2D) == Boolean.TRUE) {
+					force2D = true;
+				}
+			}
+			
+			if(force2D) {
+				sql.append("encode(ST_AsBinary(ST_Force_2D(");
+				encodeColumnName(prefix, gatt.getLocalName(), sql);
+				sql.append(")),'base64')");
+			}
+			else {
+				sql.append("encode(ST_AsEWKB(");
+				encodeColumnName(prefix, gatt.getLocalName(), sql);
+				sql.append("),'base64')");
+			}
+		}
+	}
 
     @Override
     public void encodeGeometryEnvelope(String tableName, String geometryColumn,
-- 
1.7.1

