View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package org.hibernatespatial.postgis;
24  
25  import org.hibernate.Hibernate;
26  import org.hibernate.dialect.PostgreSQLDialect;
27  import org.hibernate.dialect.function.StandardSQLFunction;
28  import org.hibernate.type.CustomType;
29  import org.hibernate.usertype.UserType;
30  import org.hibernatespatial.SpatialDialect;
31  import org.hibernatespatial.SpatialRelation;
32  
33  import com.gisgraphy.domain.repository.DatabaseHelper;
34  
35  /**
36   * Extends the PostgreSQLDialect by also including information on spatial
37   * operators, constructors and processing functions.
38   * 
39   * @author Karel Maesen
40   */
41  public class PostgisDialectNG extends PostgreSQLDialect implements SpatialDialect {
42  
43  	public PostgisDialectNG() {
44  		super();
45  		registerColumnType(java.sql.Types.STRUCT, "geometry");
46  
47          // Gisgraphy text normalization function
48  		registerFunction(DatabaseHelper.NORMALIZE_TEXT_FUNCTION_NAME, new StandardSQLFunction(DatabaseHelper.NORMALIZE_TEXT_FUNCTION_NAME, Hibernate.INTEGER));
49  
50  		// registering SQL/MM Spatial functions
51  		registerFunction("st_dimension", new StandardSQLFunction("st_dimension", Hibernate.INTEGER));
52  		registerFunction("st_geometrytype", new StandardSQLFunction("st_geometrytype", Hibernate.STRING));
53  		registerFunction("st_srid", new StandardSQLFunction("st_srid", Hibernate.INTEGER));
54  		registerFunction("st_envelope", new StandardSQLFunction("st_envelope", new CustomType(PGGeometryUserType.class, null)));
55  		registerFunction("st_astext", new StandardSQLFunction("st_astext", Hibernate.STRING));
56  		registerFunction("st_asbinary", new StandardSQLFunction("st_asbinary", Hibernate.BINARY));
57  		registerFunction("st_isempty", new StandardSQLFunction("st_isempty", Hibernate.BOOLEAN));
58  		registerFunction("st_issimple", new StandardSQLFunction("st_issimple", Hibernate.BOOLEAN));
59  		registerFunction("st_boundary", new StandardSQLFunction("st_boundary", new CustomType(PGGeometryUserType.class, null)));
60  
61  		// Register functions for spatial relation constructs
62  		registerFunction("st_overlaps", new StandardSQLFunction("st_overlaps", Hibernate.BOOLEAN));
63  		registerFunction("st_intersects", new StandardSQLFunction("st_intersects", Hibernate.BOOLEAN));
64  		registerFunction("st_equals", new StandardSQLFunction("st_equals", Hibernate.BOOLEAN));
65  		registerFunction("st_contains", new StandardSQLFunction("st_contains", Hibernate.BOOLEAN));
66  		registerFunction("st_crosses", new StandardSQLFunction("st_crosses", Hibernate.BOOLEAN));
67  		registerFunction("st_disjoint", new StandardSQLFunction("st_disjoint", Hibernate.BOOLEAN));
68  		registerFunction("st_touches", new StandardSQLFunction("st_touches", Hibernate.BOOLEAN));
69  		registerFunction("st_within", new StandardSQLFunction("st_within", Hibernate.BOOLEAN));
70  		registerFunction("st_relate", new StandardSQLFunction("st_relate", Hibernate.BOOLEAN));
71  
72  		// register the spatial analysis functions
73  		registerFunction("st_distance", new StandardSQLFunction("st_distance", Hibernate.DOUBLE));
74  		registerFunction("st_distance_sphere", new StandardSQLFunction("st_distance_sphere", Hibernate.DOUBLE));
75  		registerFunction("st_line_locate_point", new StandardSQLFunction("st_line_locate_point", Hibernate.DOUBLE));
76  		registerFunction("st_buffer", new StandardSQLFunction("st_buffer", new CustomType(PGGeometryUserType.class, null)));
77  		registerFunction("st_convexhull", new StandardSQLFunction("st_convexhull", new CustomType(PGGeometryUserType.class, null)));
78  		registerFunction("st_difference", new StandardSQLFunction("st_difference", new CustomType(PGGeometryUserType.class, null)));
79  		registerFunction("st_intersection", new StandardSQLFunction("st_intersection", new CustomType(PGGeometryUserType.class, null)));
80  		registerFunction("st_symdifference", new StandardSQLFunction("st_symdifference", new CustomType(PGGeometryUserType.class, null)));
81  		registerFunction("st_union", new StandardSQLFunction("st_union", new CustomType(PGGeometryUserType.class, null)));
82  		registerKeyword("&&");
83  	}
84  
85  	/*
86  	 * (non-Javadoc)
87  	 * 
88  	 * @see org.walkonweb.spatial.dialect.SpatialEnabledDialect#getSpatialRelateExpression(java.lang.String,
89  	 *      int, boolean)
90  	 */
91  	public String getSpatialRelateSQL(String columnName, int spatialRelation, boolean hasFilter) {
92  		switch (spatialRelation) {
93  			case SpatialRelation.WITHIN:
94  				return hasFilter ? "(" + columnName + " && ? AND st_within(" + columnName + ", ?))" : " st_within(" + columnName + ",?)";
95  			case SpatialRelation.CONTAINS:
96  				return hasFilter ? "(" + columnName + " && ? AND st_contains(" + columnName + ", ?))" : " st_contains(" + columnName + ", ?)";
97  			case SpatialRelation.CROSSES:
98  				return hasFilter ? "(" + columnName + " && ? AND st_crosses(" + columnName + ", ?))" : " st_crosses(" + columnName + ", ?)";
99  			case SpatialRelation.OVERLAPS:
100 				return hasFilter ? "(" + columnName + " && ? AND st_overlaps(" + columnName + ", ?))" : " st_overlaps(" + columnName + ", ?)";
101 			case SpatialRelation.DISJOINT:
102 				return hasFilter ? "(" + columnName + " && ? AND st_disjoint(" + columnName + ", ?))" : " st_disjoint(" + columnName + ", ?)";
103 			case SpatialRelation.INTERSECTS:
104 				return hasFilter ? "(" + columnName + " && ? AND st_intersects(" + columnName + ", ?))" : " st_intersects(" + columnName + ", ?)";
105 			case SpatialRelation.TOUCHES:
106 				return hasFilter ? "(" + columnName + " && ? AND st_touches(" + columnName + ", ?))" : " st_touches(" + columnName + ", ?)";
107 			case SpatialRelation.EQUALS:
108 				return hasFilter ? "(" + columnName + " && ? AND st_equals(" + columnName + ", ?))" : " st_equals(" + columnName + ", ?)";
109 			default:
110 				throw new IllegalArgumentException("Spatial relation is not known by this dialect");
111 		}
112 
113 	}
114 
115 	/*
116 	 * (non-Javadoc)
117 	 * 
118 	 * @see org.walkonweb.spatial.dialect.SpatialEnabledDialect#getSpatialFilterExpression(java.lang.String)
119 	 */
120 	public String getSpatialFilterExpression(String columnName) {
121 		return "(" + columnName + " && ? ) ";
122 	}
123 
124 	/*
125 	 * (non-Javadoc)
126 	 * 
127 	 * @see org.hibernatespatial.SpatialDialect#getGeometryUserType()
128 	 */
129 	public UserType getGeometryUserType() {
130 		return new PGGeometryUserType();
131 	}
132 
133 }