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  /**
24   * This work was partially supported by the European Commission, under the 6th
25   * Framework Programme, contract IST-2-004688-STP. This library is free
26   * software; you can redistribute it and/or modify it under the terms of the GNU
27   * Lesser General Public License as published by the Free Software Foundation;
28   * either version 2.1 of the License, or (at your option) any later version.
29   * This library is distributed in the hope that it will be useful, but WITHOUT
30   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
31   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
32   * details. You should have received a copy of the GNU Lesser General Public
33   * License along with this library; if not, write to the Free Software
34   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35   */
36  package com.gisgraphy.hibernate.projection;
37  
38  import org.hibernate.Criteria;
39  import org.hibernate.Hibernate;
40  import org.hibernate.HibernateException;
41  import org.hibernate.criterion.CriteriaQuery;
42  import org.hibernate.criterion.SimpleProjection;
43  import org.hibernate.type.Type;
44  
45  import com.gisgraphy.domain.valueobject.SRID;
46  import com.vividsolutions.jts.geom.Point;
47  
48  /**
49   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a> Some
50   *         Spatial Projections. distance_sphere...
51   */
52  public class SpatialProjection {
53      
54      public static final String DISTANCE_FUNCTION = "st_distance";
55      public static final String DISTANCE_SPHERE_FUNCTION = "st_distance_sphere";
56      public static String ST_LINE_INTERPOLATE_POINT_FUNCTION = "st_line_interpolate_point";
57      public static String ST_CLOSEST_POINT = "ST_ClosestPoint";
58      public static String ST_LINE_LOCATE_POINT_FUNCTION = "st_line_locate_point";
59      public static String LINEMERGE_FUNCTION = "st_linemerge";
60  
61      /**
62  	 * projection to get the distance_sphere between a point and a LineString
63  	 * 
64  	 * @param point
65  	 *                the point to get the distance
66  	 * @param lineStringColumnName the name of the lineString column
67  	 * @return the projection
68  	 * @see #distance(Point, String)
69  	 */
70  	public static SimpleProjection distance_pointToLine(final Point point, final String lineStringColumnName) {
71  	    return new SimpleProjection() {
72  
73  		private static final long serialVersionUID = -7424596977297450115L;
74  
75  		/*
76  		 * (non-Javadoc)
77  		 * 
78  		 * @see org.hibernate.criterion.Projection#getTypes(org.hibernate.Criteria,
79  		 *      org.hibernate.criterion.CriteriaQuery)
80  		 */
81  		public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
82  			return new Type[] { Hibernate.DOUBLE };
83  		}
84  
85  		/*
86  		 * (non-Javadoc)
87  		 * 
88  		 * @see org.hibernate.criterion.Projection#toSqlString(org.hibernate.Criteria,
89  		 *      int, org.hibernate.criterion.CriteriaQuery)
90  		 */
91  		public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
92  			String columnName = criteriaQuery.getColumn(criteria, lineStringColumnName);
93  			String pointAsString = new StringBuffer("st_GeometryFromText( 'POINT(")
94  			.append(point.getX()).append(" ").append(point.getY()).append(")',").append(SRID.WGS84_SRID.getSRID()).append(")").toString();
95  			
96  			/*String lineMerge = new StringBuffer(LINEMERGE_FUNCTION)
97  			.append("(")
98  			.append(columnName)
99  			.append(")").toString();*/
100 			 String shape = columnName;
101 			
102 			String sqlString = new StringBuffer()
103 			.append(DISTANCE_SPHERE_FUNCTION)
104 			.append("(")
105 			.append(pointAsString)
106 			.append(",")
107 			.append(ST_CLOSEST_POINT)
108 				.append("(")
109 					.append(shape)
110 					.append(",")
111 					.append(pointAsString)
112 				.append(")")
113 			.append(")")
114 			.append("as y").append(position).append("_")
115 			.toString();
116 			
117 			
118 			 
119 			return sqlString;
120 		}
121 
122 	};
123 	}
124 
125     
126 
127 	/**
128 	 * projection to get the distance_sphere of a point
129 	 * if you're on a Cartesian ref use {@link SpatialProjection#distance(Point, String)}
130 	 * @param point
131 	 *                the point to get the distance
132 	 * @param locationColumnName the name of the column we want the distance
133 	 * @return the projection
134 	 * @see #distance(Point, String)
135 	 */
136 	public static SimpleProjection distance_sphere(final Point point, final String locationColumnName) {
137 		return distance_function(point, locationColumnName, DISTANCE_SPHERE_FUNCTION);
138 	}
139 	
140 
141 	/**
142 	 * projection to get the distance from a point
143 	 * if you're on a lat/long ref, use @link {@link #distance_sphere(Point, String)}
144 	 * 
145 	 * @param point
146 	 *                the point to get the distance
147 	 * @param locationColumnName the name of the column we want the distance
148 	 * @return the projection
149 	 * @see #distance_sphere(Point, String)
150 	 */
151 	public static SimpleProjection distance(final Point point, final String locationColumnName) {
152 		return distance_function(point, locationColumnName, DISTANCE_FUNCTION);
153 	}
154 
155 	private static SimpleProjection distance_function(final Point point, final String locationColumnName, final String distanceFunction) {
156 		return new SimpleProjection() {
157 
158 			/**
159 			 * 
160 			 */
161 			private static final long serialVersionUID = -8771843067497785957L;
162 
163 			/*
164 			 * (non-Javadoc)
165 			 * 
166 			 * @see org.hibernate.criterion.Projection#getTypes(org.hibernate.Criteria,
167 			 *      org.hibernate.criterion.CriteriaQuery)
168 			 */
169 			public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
170 				return new Type[] { Hibernate.DOUBLE };
171 			}
172 
173 			/*
174 			 * (non-Javadoc)
175 			 * 
176 			 * @see org.hibernate.criterion.Projection#toSqlString(org.hibernate.Criteria,
177 			 *      int, org.hibernate.criterion.CriteriaQuery)
178 			 */
179 			public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) throws HibernateException {
180 				String columnName = criteriaQuery.getColumn(criteria, locationColumnName);
181 				StringBuffer sb = new StringBuffer();
182 				String sqlString = sb.append(distanceFunction).append("(").append(columnName).append(", st_GeometryFromText( 'POINT(").append(point.getX()).append(" ").append(point.getY()).append(")',").append(SRID.WGS84_SRID.getSRID()).append(")) as y").append(position).append("_").toString();
183 				return sqlString;
184 			}
185 
186 		};
187 
188 	}
189 
190 }