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 com.gisgraphy.domain.repository;
24  
25  import static com.gisgraphy.hibernate.projection.SpatialProjection.DISTANCE_SPHERE_FUNCTION;
26  
27  import java.util.ArrayList;
28  import java.util.List;
29  
30  import javax.persistence.PersistenceException;
31  
32  import org.apache.commons.lang.ArrayUtils;
33  import org.apache.commons.lang.NotImplementedException;
34  import org.hibernate.Criteria;
35  import org.hibernate.Query;
36  import org.hibernate.Session;
37  import org.hibernate.criterion.ProjectionList;
38  import org.hibernate.criterion.Restrictions;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  import org.springframework.beans.factory.annotation.Autowired;
42  import org.springframework.orm.hibernate3.HibernateCallback;
43  import org.springframework.stereotype.Repository;
44  import org.springframework.util.Assert;
45  
46  import com.gisgraphy.GisgraphyException;
47  import com.gisgraphy.domain.geoloc.entity.GisFeature;
48  import com.gisgraphy.domain.geoloc.entity.OpenStreetMap;
49  import com.gisgraphy.domain.geoloc.entity.Street;
50  import com.gisgraphy.domain.geoloc.entity.event.EventManager;
51  import com.gisgraphy.domain.geoloc.entity.event.GisFeatureDeletedEvent;
52  import com.gisgraphy.domain.geoloc.entity.event.GisFeatureStoredEvent;
53  import com.gisgraphy.domain.geoloc.entity.event.PlaceTypeDeleteAllEvent;
54  import com.gisgraphy.domain.valueobject.GisgraphyConfig;
55  import com.gisgraphy.domain.valueobject.SRID;
56  import com.gisgraphy.domain.valueobject.StreetDistance;
57  import com.gisgraphy.helper.GeolocHelper;
58  import com.gisgraphy.helper.IntrospectionHelper;
59  import com.gisgraphy.hibernate.criterion.DistanceRestriction;
60  import com.gisgraphy.hibernate.criterion.FulltextRestriction;
61  import com.gisgraphy.hibernate.criterion.IntersectsRestriction;
62  import com.gisgraphy.hibernate.criterion.NativeSQLOrder;
63  import com.gisgraphy.hibernate.criterion.ProjectionOrder;
64  import com.gisgraphy.hibernate.criterion.ResultTransformerUtil;
65  import com.gisgraphy.hibernate.projection.ProjectionBean;
66  import com.gisgraphy.hibernate.projection.SpatialProjection;
67  import com.gisgraphy.street.IStreetFactory;
68  import com.gisgraphy.street.StreetFactory;
69  import com.gisgraphy.street.StreetSearchMode;
70  import com.gisgraphy.street.StreetType;
71  import com.vividsolutions.jts.geom.Point;
72  import com.vividsolutions.jts.geom.Polygon;
73  
74  /**
75   * A data access object for {@link OpenStreetMap} Object
76   * 
77   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
78   */
79  @Repository
80  public class OpenStreetMapDao extends GenericDao<OpenStreetMap, Long> implements IOpenStreetMapDao
81  {
82  	private IStreetFactory streetFactory = new StreetFactory();
83  	 
84  	 private EventManager eventManager;
85  	
86  	/**
87       * The logger
88       */
89      protected static final Logger logger = LoggerFactory
90  	    .getLogger(OpenStreetMapDao.class);
91  
92  	protected static final int DEFAULT_DISTANCE = 1500;
93  	
94      /**
95       * Default constructor
96       */
97      public OpenStreetMapDao() {
98  	    super(OpenStreetMap.class);
99      }
100     
101 
102     /* (non-Javadoc)
103      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#getNearestAndDistanceFrom(com.vividsolutions.jts.geom.Point, double, int, int, java.lang.String, java.lang.String)
104      */
105     @SuppressWarnings("unchecked")
106     public List<StreetDistance> getNearestAndDistanceFrom(
107 	    final Point point, final double distance,
108 	    final int firstResult, final int maxResults,
109 	    final StreetType streetType, final Boolean oneWay ,final String name, final StreetSearchMode streetSearchMode,final boolean includeDistanceField) {
110 	if (streetSearchMode==StreetSearchMode.FULLTEXT && !GisgraphyConfig.STREET_SEARCH_FULLTEXT_MODE){
111 		throw new GisgraphyException("The fulltext mode has been removed in gisgraphy v 3.0 and has been replaced by fulltext webservice with placetype=street. please Consult user guide.");
112 	}
113 	if (name != null && streetSearchMode==null){
114 		throw new IllegalArgumentException("streetSearchmode can not be null if name is provided");
115 	}
116 	if (point == null && streetSearchMode==StreetSearchMode.CONTAINS){
117 		throw new IllegalArgumentException("you must specify lat/lng when streetsearchmode = "+StreetSearchMode.CONTAINS);
118 	}
119 	return (List<StreetDistance>) this.getHibernateTemplate().execute(
120 		new HibernateCallback() {
121 
122 		    public Object doInHibernate(Session session)
123 			    throws PersistenceException {
124 			Criteria criteria = session
125 				.createCriteria(OpenStreetMap.class);
126 			
127 			List<String> fieldList = IntrospectionHelper
128 				.getFieldsAsList(OpenStreetMap.class);
129 
130 			ProjectionList projections = ProjectionBean.fieldList(
131 				fieldList,false);
132 				if (includeDistanceField && point!=null){
133 				projections.add(
134 //				SpatialProjection.distance_sphere(point, GisFeature.LOCATION_COLUMN_NAME).as(
135 //					"distance"));
136 						SpatialProjection.distance_pointToLine(point, OpenStreetMap.SHAPE_COLUMN_NAME).as(
137 						"distance"));
138 				}
139 			criteria.setProjection(projections);
140 			if (includeDistanceField && point !=null){
141 			    criteria.addOrder(new ProjectionOrder("distance"));
142 			}
143 			if (maxResults > 0) {
144 			    criteria = criteria.setMaxResults(maxResults);
145 			}
146 			if (firstResult >= 1) {
147 			    criteria = criteria.setFirstResult(firstResult - 1);
148 			}
149 			if (point!=null){
150 			    Polygon polygonBox = GeolocHelper.createPolygonBox(point.getX(), point.getY(), distance);
151 			    criteria = criteria.add(new IntersectsRestriction(OpenStreetMap.SHAPE_COLUMN_NAME, polygonBox));
152 			}
153 			if (name != null) {
154 					if (streetSearchMode==StreetSearchMode.CONTAINS){
155 					    	criteria = criteria.add(Restrictions.isNotNull("name"));//optimisation!
156 					    	criteria = criteria.add(Restrictions.ilike(OpenStreetMap.FULLTEXTSEARCH_PROPERTY_NAME, "%"+name+"%"));
157 					    	//criteria = criteria.add(new PartialWordSearchRestriction(OpenStreetMap.PARTIALSEARCH_VECTOR_COLUMN_NAME, name));
158 					} else if (streetSearchMode == StreetSearchMode.FULLTEXT){
159 						  criteria = criteria.add(new FulltextRestriction(OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME, name));
160 					} else {
161 						throw new NotImplementedException(streetSearchMode+" is not implemented for street search");
162 					}
163 			}
164 			if (streetType != null) {
165 			    criteria = criteria.add(Restrictions.eq("streetType",streetType));
166 			}
167 			if (oneWay != null) {
168 			    criteria = criteria.add(Restrictions.eq("oneWay",oneWay));
169 			}
170 			criteria.setCacheable(true);
171 			// List<Object[]> queryResults =testCriteria.list();
172 			List<?> queryResults = criteria.list();
173 			
174 			if (queryResults != null && queryResults.size()!=0){
175 			    String[] propertiesNameArray ;
176 			    if (includeDistanceField && point!=null){
177 			propertiesNameArray = (String[]) ArrayUtils
178 			    	.add(
179 			    		IntrospectionHelper
180 			    			.getFieldsAsArray(OpenStreetMap.class),
181 			    		"distance");
182 			    } else  {
183 				propertiesNameArray = IntrospectionHelper
184 	    			.getFieldsAsArray(OpenStreetMap.class);
185 			    }
186 			List<StreetDistance> results = ResultTransformerUtil
187 				.transformToStreetDistance(
188 					propertiesNameArray,
189 					queryResults);
190 			return results;
191 			} else {
192 			    return new ArrayList<StreetDistance>();
193 			}
194 			
195 		    }
196 		});
197     }
198     
199 
200     /* (non-Javadoc)
201      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#getByGid(java.lang.Long)
202      */
203     public OpenStreetMap getByGid(final Long gid) {
204 	Assert.notNull(gid);
205 	return (OpenStreetMap) this.getHibernateTemplate().execute(
206 		new HibernateCallback() {
207 
208 		    public Object doInHibernate(Session session)
209 			    throws PersistenceException {
210 			String queryString = "from "
211 				+ OpenStreetMap.class.getSimpleName()
212 				+ " as c where c.gid= ?";
213 
214 			Query qry = session.createQuery(queryString);
215 			qry.setCacheable(true);
216 
217 			qry.setParameter(0, gid);
218 
219 			OpenStreetMap result = (OpenStreetMap) qry.uniqueResult();
220 			return result;
221 		    }
222 		});
223     }
224 
225     
226   
227     /* (non-Javadoc)
228      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#buildIndexForStreetNameSearch()
229      */
230     public Integer updateTS_vectorColumnForStreetNameSearch() {
231 	return (Integer) this.getHibernateTemplate().execute(
232 			 new HibernateCallback() {
233 
234 			    public Object doInHibernate(Session session)
235 				    throws PersistenceException {
236 				session.flush();
237 				logger.info("will update "+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+" field");
238 				String updateFulltextField = "UPDATE openStreetMap SET "+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+" = to_tsvector('simple',coalesce("+OpenStreetMap.FULLTEXTSEARCH_COLUMN_NAME+",'')) where name is not null";  
239 				Query qryUpdateFulltextField = session.createSQLQuery(updateFulltextField);
240 				int numberOfLineUpdatedForFulltext = qryUpdateFulltextField.executeUpdate();
241 				int numberOfLineUpdatedForPartial = 0;
242 				return Integer.valueOf(numberOfLineUpdatedForFulltext + numberOfLineUpdatedForPartial);
243 				
244 			    }
245 			});
246     }
247     
248     /* (non-Javadoc)
249      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#buildIndexForStreetNameSearch()
250      */
251     public Integer updateTS_vectorColumnForStreetNameSearchPaginate(final long from,final long to ) {
252 	return (Integer) this.getHibernateTemplate().execute(
253 			 new HibernateCallback() {
254 
255 			    public Object doInHibernate(Session session)
256 				    throws PersistenceException {
257 				session.flush();
258 				logger.info("will update "+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+" field");
259 				String updateFulltextField = "UPDATE openStreetMap SET "+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+" = to_tsvector('simple',coalesce("+OpenStreetMap.FULLTEXTSEARCH_COLUMN_NAME+",'')) where gid >= "+from+" and gid <= "+to+" and name is not null";  
260 				Query qryUpdateFulltextField = session.createSQLQuery(updateFulltextField);
261 				int numberOfLineUpdatedForFulltext = qryUpdateFulltextField.executeUpdate();
262 				int numberOfLineUpdatedForPartial = 0;
263 				return Integer.valueOf(numberOfLineUpdatedForFulltext + numberOfLineUpdatedForPartial);
264 				
265 			    }
266 			});
267     }
268 
269 
270     /* (non-Javadoc)
271      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#createGISTIndex()
272      */
273     public void createSpatialIndexes() {
274 	 this.getHibernateTemplate().execute(
275 			 new HibernateCallback() {
276 
277 			    public Object doInHibernate(Session session)
278 				    throws PersistenceException {
279 				session.flush();
280 
281 				String locationIndexName = OpenStreetMap.LOCATION_COLUMN_NAME.toLowerCase()+"indexopenstreetmap";
282 				logger.info("checking if "+locationIndexName+" exists");
283 				String checkingLocationIndex= "SELECT 1 FROM   pg_class c  JOIN   pg_namespace n ON n.oid = c.relnamespace WHERE  c.relname = '"+locationIndexName+"'";
284 				Query checkingLocationIndexQuery = session.createSQLQuery(checkingLocationIndex);
285 				Object locationIndexExists = checkingLocationIndexQuery.uniqueResult();
286 				if (locationIndexExists != null){
287 					logger.info("will create GIST index for  the "+OpenStreetMap.LOCATION_COLUMN_NAME+" column");
288 					String createIndexForLocation = "CREATE INDEX "+locationIndexName+" ON openstreetmap USING GIST ("+OpenStreetMap.LOCATION_COLUMN_NAME.toLowerCase()+")";  
289 					Query qryUpdateLocationIndex = session.createSQLQuery(createIndexForLocation);
290 					qryUpdateLocationIndex.executeUpdate();
291 				} else {
292 					logger.info("won't create GIST index for  the "+OpenStreetMap.LOCATION_COLUMN_NAME+" column because it already exists");
293 				}
294 				
295 				String shapeIndexName=OpenStreetMap.SHAPE_COLUMN_NAME.toLowerCase()+"indexopenstreetmap";
296 				logger.info("checking if "+shapeIndexName+" exists");
297 				String checkingShapeIndex= "SELECT 1 FROM   pg_class c  JOIN   pg_namespace n ON n.oid = c.relnamespace WHERE  c.relname = '"+shapeIndexName+"'";
298 				Query checkingShapeIndexQuery = session.createSQLQuery(checkingShapeIndex);
299 				Object shapeIndexExists = checkingShapeIndexQuery.uniqueResult();
300 				if (shapeIndexExists!=null){
301 					logger.info("will create GIST index for  the "+OpenStreetMap.SHAPE_COLUMN_NAME+" column");
302 					String createIndexForShape = "CREATE INDEX "+OpenStreetMap.SHAPE_COLUMN_NAME.toLowerCase()+"indexopenstreetmap ON openstreetmap USING GIST ("+OpenStreetMap.SHAPE_COLUMN_NAME.toLowerCase()+")";  
303 					Query qryUpdateShapeIndex = session.createSQLQuery(createIndexForShape);
304 					qryUpdateShapeIndex.executeUpdate();
305 				} else {
306 					logger.info("won't create GIST index for  the "+OpenStreetMap.SHAPE_COLUMN_NAME+" column because it already exists");
307 				}
308 				return null;
309 			    }
310 			});
311    }
312     
313     /* (non-Javadoc)
314      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#createGISTIndex()
315      */
316     public void createFulltextIndexes() {
317 	 this.getHibernateTemplate().execute(
318 			 new HibernateCallback() {
319 
320 			    public Object doInHibernate(Session session)
321 				    throws PersistenceException {
322 				session.flush();
323 				logger.info("will create Fulltext index");
324 				String createFulltextIndex = "CREATE INDEX "+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+"indexopenstreetmap ON openstreetmap USING gin("+OpenStreetMap.FULLTEXTSEARCH_VECTOR_PROPERTY_NAME.toLowerCase()+")";  
325 				Query fulltextIndexQuery = session.createSQLQuery(createFulltextIndex);
326 				fulltextIndexQuery.executeUpdate();
327 				
328 				return null;
329 			    }
330 			});
331    }
332     
333 
334     
335     /* (non-Javadoc)
336      * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#countEstimate()
337      */
338     public long countEstimate(){
339 	return (Long) this.getHibernateTemplate().execute(
340 		new HibernateCallback() {
341 
342 		    public Object doInHibernate(Session session)
343 			    throws PersistenceException {
344 			String queryString = "select max(gid)-min(gid)+1 from "
345 				+ persistentClass.getSimpleName();
346 
347 			Query qry = session.createQuery(queryString);
348 			qry.setCacheable(true);
349 			Long count = (Long) qry.uniqueResult();
350 			return count==null?0:count;
351 		    }
352 		});
353     }
354     
355     @Override
356     public OpenStreetMap save(OpenStreetMap openStreetMap) {
357 	OpenStreetMap savedEntity = super.save(openStreetMap);
358 	Street street = streetFactory.create(savedEntity);
359 	GisFeatureStoredEvent CreatedEvent = new GisFeatureStoredEvent(
360 		street);
361 	eventManager.handleEvent(CreatedEvent);
362 	return savedEntity;
363     }
364 
365     /*
366      * (non-Javadoc)
367      * 
368      * @see com.gisgraphy.domain.repository.GenericDao#remove(java.lang.Object)
369      */
370     @Override
371     public void remove(OpenStreetMap openStreetMap) {
372 	super.remove(openStreetMap);
373 	Street street = streetFactory.create(openStreetMap);
374 	GisFeatureDeletedEvent gisFeatureDeletedEvent = new GisFeatureDeletedEvent(
375 		street);
376 	eventManager.handleEvent(gisFeatureDeletedEvent);
377     }
378     
379     /*
380      * (non-Javadoc)
381      * 
382      * @see com.gisgraphy.domain.repository.GenericDao#deleteAll()
383      */
384     @Override
385     public int deleteAll() {
386 	int numberOfOpenStreetMapDeleted = super.deleteAll();
387 	PlaceTypeDeleteAllEvent placeTypeDeleteAllEvent = new PlaceTypeDeleteAllEvent(
388 		Street.class);
389 	eventManager.handleEvent(placeTypeDeleteAllEvent);
390 	return numberOfOpenStreetMapDeleted;
391     }
392     
393 
394 	public OpenStreetMap getByOpenStreetMapId(final Long openstreetmapId) {
395 		Assert.notNull(openstreetmapId);
396 		return (OpenStreetMap) this.getHibernateTemplate().execute(
397 			new HibernateCallback() {
398 
399 			    public Object doInHibernate(Session session)
400 				    throws PersistenceException {
401 				String queryString = "from "
402 					+ OpenStreetMap.class.getSimpleName()
403 					+ " as c where c.openstreetmapId= ?";
404 
405 				Query qry = session.createQuery(queryString);
406 				qry.setMaxResults(1);
407 				//we need to limit to 1 because a street can be in two countries
408 				qry.setCacheable(true);
409 
410 				qry.setParameter(0, openstreetmapId);
411 
412 				OpenStreetMap result = (OpenStreetMap) qry.uniqueResult();
413 				return result;
414 			    }
415 			});
416 	}
417 
418 
419 	/* (non-Javadoc)
420 	 * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#getMaxOpenstreetMapId()
421 	 */
422 	public long getMaxOpenstreetMapId() {
423 			return (Long) this.getHibernateTemplate().execute(
424 				new HibernateCallback() {
425 
426 				    public Object doInHibernate(Session session)
427 					    throws PersistenceException {
428 					String queryString = "select max(openstreetmapId) from "
429 						+ OpenStreetMap.class.getSimpleName();
430 
431 					Query qry = session.createQuery(queryString);
432 					qry.setCacheable(true);
433 					Long count = (Long) qry.uniqueResult();
434 					return count==null?0:count;
435 				    }
436 				});
437 	}
438 	
439 	@SuppressWarnings({ "unchecked", "rawtypes" })
440 	public OpenStreetMap getNearestByosmIds(final Point point,final List<Long> ids) {
441 		if (ids==null || ids.size()==0){
442 			return null;
443 		}
444 		return (OpenStreetMap) this.getHibernateTemplate().execute(
445 				new HibernateCallback() {
446 
447 				    public Object doInHibernate(Session session)
448 					    throws PersistenceException {
449 				    	
450 				    	Criteria criteria = session
451 								.createCriteria(OpenStreetMap.class);
452 							
453 							criteria.add(new DistanceRestriction(point,DEFAULT_DISTANCE,true));
454 							criteria.add(Restrictions.in("openstreetmapId", ids));
455 							
456 							String pointAsString = "ST_GeometryFromText('POINT("+point.getX()+" "+point.getY()+")',"+SRID.WGS84_SRID.getSRID()+")";
457 							String distanceCondition = new StringBuffer()
458 							.append(DISTANCE_SPHERE_FUNCTION)
459 							.append("(")
460 								.append(pointAsString)
461 								.append(",")
462 								.append(SpatialProjection.ST_CLOSEST_POINT)
463 								.append("(")
464 									.append("this_.").append(OpenStreetMap.SHAPE_COLUMN_NAME)
465 									.append(",")
466 									.append(pointAsString)
467 								.append(")")
468 							.append(")")
469 							.toString();
470 							criteria.addOrder(new NativeSQLOrder(distanceCondition));
471 							criteria = criteria.setMaxResults(1);
472 							criteria.setCacheable(true);
473 							// List<Object[]> queryResults =testCriteria.list();
474 							OpenStreetMap openStreetMap = (OpenStreetMap)criteria.uniqueResult();
475 							
476 							return openStreetMap;
477 							
478 						    }
479 						});
480 		    }
481 		    
482 	
483 	
484 	/* (non-Javadoc)
485 	 * @see com.gisgraphy.domain.repository.IOpenStreetMapDao#getMaxOpenstreetMapId()
486 	 */
487 	public long getMaxGid() {
488 			return (Long) this.getHibernateTemplate().execute(
489 				new HibernateCallback() {
490 
491 				    public Object doInHibernate(Session session)
492 					    throws PersistenceException {
493 					String queryString = "select max(gid) from "
494 						+ OpenStreetMap.class.getSimpleName();
495 
496 					Query qry = session.createQuery(queryString);
497 					qry.setCacheable(true);
498 					Long count = (Long) qry.uniqueResult();
499 					return count==null?0:count;
500 				    }
501 				});
502 	}
503 
504 
505 
506     @Autowired
507     public void setEventManager(EventManager eventManager) {
508         this.eventManager = eventManager;
509     }
510 
511 
512     public void setStreetFactory(IStreetFactory streetFactory) {
513         this.streetFactory = streetFactory;
514     }
515     
516     public OpenStreetMap getNearestRoadFrom(
517     	    final Point point) {
518     	return getNearestFrom(point,true,true);
519     
520     }
521     
522     public OpenStreetMap getNearestFrom(
523     	    final Point point) {
524     	return getNearestFrom(point,false,true);
525     }
526     
527  
528     
529     @SuppressWarnings({ "unchecked", "rawtypes" })
530 	public OpenStreetMap getNearestFrom(
531 	    final Point point,final boolean onlyroad,final boolean filterEmptyName) {
532     	if (point==null){
533     		return null;
534     	}
535 	return (OpenStreetMap) this.getHibernateTemplate().execute(
536 		new HibernateCallback() {
537 
538 		    public Object doInHibernate(Session session)
539 			    throws PersistenceException {
540 		    	
541 		    	Criteria criteria = session
542 						.createCriteria(OpenStreetMap.class);
543 					
544 					criteria.add(new DistanceRestriction(point,DEFAULT_DISTANCE,true));
545 					if (onlyroad) {
546 						criteria = criteria.add(Restrictions.ne("streetType",StreetType.FOOTWAY));
547 					}
548 					if (filterEmptyName){
549 						criteria = criteria.add(Restrictions.isNotNull("name"));
550 					}
551 					
552 					String pointAsString = "ST_GeometryFromText('POINT("+point.getX()+" "+point.getY()+")',"+SRID.WGS84_SRID.getSRID()+")";
553 					String distanceCondition = new StringBuffer()
554 					.append(DISTANCE_SPHERE_FUNCTION)
555 					.append("(")
556 						.append(pointAsString)
557 						.append(",")
558 						.append(SpatialProjection.ST_CLOSEST_POINT)
559 						.append("(")
560 							.append("this_.").append(OpenStreetMap.SHAPE_COLUMN_NAME)
561 							.append(",")
562 							.append(pointAsString)
563 						.append(")")
564 					.append(")")
565 					.toString();
566 					criteria.addOrder(new NativeSQLOrder(distanceCondition));
567 					criteria = criteria.setMaxResults(1);
568 					criteria.setCacheable(true);
569 					// List<Object[]> queryResults =testCriteria.list();
570 					OpenStreetMap openStreetMap = (OpenStreetMap)criteria.uniqueResult();
571 					
572 					return openStreetMap;
573 					
574 				    }
575 				});
576     }
577     
578     
579     public String getShapeAsWKTByGId(final Long gid) {
580 		if (gid ==null){
581 			return null;
582 		}
583 		return (String) this.getHibernateTemplate().execute(
584 				new HibernateCallback() {
585 
586 				    public Object doInHibernate(Session session)
587 					    throws PersistenceException {
588 					String queryString = "select ST_AsText("+GisFeature.SHAPE_COLUMN_NAME+") from " + persistentClass.getSimpleName()
589 			+ " as o where o.gid=?";
590 
591 					Query qry = session.createQuery(queryString);
592 					qry.setParameter(0, gid);
593 					qry.setCacheable(true);
594 					return (String) qry.uniqueResult();
595 				    }
596 				});
597 	}
598 
599 
600 
601 }