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 java.util.List;
26  
27  import org.apache.commons.lang.RandomStringUtils;
28  import org.hibernate.exception.ConstraintViolationException;
29  import org.junit.Assert;
30  import org.junit.Test;
31  import org.springframework.dao.DataIntegrityViolationException;
32  
33  import com.gisgraphy.domain.geoloc.entity.OpenStreetMap;
34  import com.gisgraphy.domain.geoloc.service.fulltextsearch.AbstractIntegrationHttpSolrTestCase;
35  import com.gisgraphy.domain.geoloc.service.fulltextsearch.StreetSearchMode;
36  import com.gisgraphy.domain.geoloc.service.geoloc.street.StreetType;
37  import com.gisgraphy.domain.valueobject.GisgraphyConfig;
38  import com.gisgraphy.domain.valueobject.SRID;
39  import com.gisgraphy.domain.valueobject.StreetDistance;
40  import com.gisgraphy.helper.GeolocHelper;
41  import com.gisgraphy.helper.StringHelper;
42  import com.gisgraphy.test.GeolocTestHelper;
43  import com.vividsolutions.jts.geom.LineString;
44  import com.vividsolutions.jts.geom.Point;
45  
46  
47  public class OpenStreetMapDaoTest extends AbstractIntegrationHttpSolrTestCase{
48  
49   IOpenStreetMapDao openStreetMapDao;
50      
51   @Test
52   public void testCouldNotSaveNonUniqueGID(){
53       OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
54  	openStreetMapDao.save(streetOSM);
55  	assertNotNull(openStreetMapDao.get(streetOSM.getId()));
56  	
57  	OpenStreetMap streetOSM2 = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
58  	try {
59  	    openStreetMapDao.save(streetOSM2);
60  	    openStreetMapDao.flushAndClear();
61  	    fail("we should not save street with non unique GID");
62  	} catch (DataIntegrityViolationException e) {
63  	  assertTrue("a ConstraintViolationException should be throw when saving an openstreetmap with a non unique gid ",e.getCause() instanceof ConstraintViolationException);
64  	}
65  	
66  	
67   }
68   
69   
70    @Test
71    public void testGetNearestAndDistanceFromShouldNotAcceptNullStreetSearchModeIfNameIsNotNull() {
72  	 try {
73  		openStreetMapDao.getNearestAndDistanceFrom(GeolocHelper.createPoint(30.1F, 30.1F), 10000, 1, 1, null, null,"john keN",null);
74  		fail("getNearestAndDistanceFrom should not accept a null streetSearchmode if name is not null");
75  	} catch (IllegalArgumentException e) {
76  		//ok
77  	}
78   }
79   
80      @Test
81      public void testGetNearestAndDistanceFromShouldReturnValidDTO() {
82      LineString shape = GeolocHelper.createLineString("LINESTRING (6.9416088 50.9154239,6.9410001 50.99999)");
83      shape.setSRID(SRID.WGS84_SRID.getSRID());
84  	
85  	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
86  	streetOSM.setShape(shape);
87  	openStreetMapDao.save(streetOSM);
88  	assertNotNull(openStreetMapDao.get(streetOSM.getId()));
89  	
90  	//we create a multilineString a little bit closest than the first one 
91  	OpenStreetMap streetOSM2 = new OpenStreetMap();
92  	LineString shape2 = GeolocHelper.createLineString("LINESTRING (6.9416088 50.9154239,6.9410001 50.9154734)");
93  	shape2.setSRID(SRID.WGS84_SRID.getSRID());
94  	
95  	
96  	streetOSM2.setShape(shape2);
97  	streetOSM2.setGid(2L);
98  	//Simulate middle point
99  	streetOSM2.setLocation(GeolocHelper.createPoint(6.94130445F , 50.91544865F));
100 	streetOSM2.setOneWay(false);
101 	streetOSM2.setStreetType(StreetType.FOOTWAY);
102 	streetOSM2.setName("John Kenedy");
103 	StringHelper.updateOpenStreetMapEntityForIndexation(streetOSM2);
104 	openStreetMapDao.save(streetOSM2);
105 	assertNotNull(openStreetMapDao.get(streetOSM2.getId()));
106 	
107 	int numberOfLineUpdated = openStreetMapDao.updateTS_vectorColumnForStreetNameSearch();
108 		if (GisgraphyConfig.PARTIAL_SEARH_EXPERIMENTAL){
109 			assertEquals("It should have 4 lines updated : (streetosm +streetosm2) for partial + (streetosm +streetosm2) for fulltext",4, numberOfLineUpdated);
110 		} else {
111 			assertEquals("It should have 2 lines updated : (streetosm +streetosm2) for fulltext",2, numberOfLineUpdated);
112 		}
113 	
114 	
115 	Point searchPoint = GeolocHelper.createPoint(6.9412748F, 50.9155829F);
116 	
117 	List<StreetDistance> nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null,null, null,null);
118 	assertEquals(1,nearestStreet.size());
119 	assertEquals("the street is not the expected one, there is probably a problem with the distance",streetOSM2.getGid(),nearestStreet.get(0).getGid());
120 	//test distance 
121 	//the following line test the distance when the nearest point is taken, with distance_sphere
122 	Assert.assertEquals("There is probably a problem with the distance",14.7, nearestStreet.get(0).getDistance(),0.1);
123 	//the following line test the distance when the middle of the street is taken with distance
124 	//Assert.assertEquals("There is probably a problem with the distance",searchPoint.distance(streetOSM2.getShape()), nearestStreet.get(0).getDistance().longValue(),5);
125 	//the following line test the distance when the middle of the street is taken with distance_sphere
126 	//Assert.assertEquals(GeolocHelper.distance(searchPoint, nearestStreet.get(0).getLocation()), nearestStreet.get(0).getDistance().longValue(),5);
127 	
128 	
129 	//test streettype
130 	assertEquals(0,openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, StreetType.UNCLASSIFIED,null, null,null).size());
131 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, StreetType.FOOTWAY,null, null,null);
132 	assertEquals(1,nearestStreet.size());
133 	assertEquals(streetOSM2.getGid(),nearestStreet.get(0).getGid());
134 	
135 	//test name in full text
136 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"keN",StreetSearchMode.FULLTEXT);
137 	assertEquals("the street name should not match if a part of the name is given and street search mode is "+StreetSearchMode.FULLTEXT,0,nearestStreet.size());
138 	
139 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"Kenedy",StreetSearchMode.FULLTEXT);
140 	assertEquals("the street name should  match if a name is given with an entire word and street search mode is "+StreetSearchMode.FULLTEXT,1,nearestStreet.size());
141 	
142 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"Kenedy john",StreetSearchMode.FULLTEXT);
143 	assertEquals("the street name should match if a name is given with more than one entire word and street search mode is "+StreetSearchMode.FULLTEXT,1,nearestStreet.size());
144 	
145 	
146 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"Kenedy smith",StreetSearchMode.FULLTEXT);
147 	assertEquals("the street name should not match if only one word is given and street search mode is "+StreetSearchMode.FULLTEXT,0,nearestStreet.size());
148 	
149 	
150 	//test name with contains
151 	assertEquals(0,openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null,null, "unknow name",StreetSearchMode.CONTAINS).size());
152 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"John",StreetSearchMode.CONTAINS);
153 	assertEquals(1,nearestStreet.size());
154 	assertEquals(streetOSM2.getGid(),nearestStreet.get(0).getGid());
155 	
156 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"john keN",StreetSearchMode.CONTAINS);
157 	assertEquals("the name should be case insensitive",1,nearestStreet.size());
158 	assertEquals(streetOSM2.getGid(),nearestStreet.get(0).getGid());
159 	
160 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"keN",StreetSearchMode.CONTAINS);
161 	assertEquals("the street name should match if a part of the name is given and street search mode is "+StreetSearchMode.CONTAINS,1,nearestStreet.size());
162 
163 	
164 	//test OneWay
165 	assertEquals(0,openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null,true, null,null).size());
166 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null,false,null,null);
167 	assertEquals(1,nearestStreet.size());
168 	assertEquals(streetOSM2.getGid(),nearestStreet.get(0).getGid());
169 	
170 	//test pagination
171 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 2, null,null, null,null);
172 	assertEquals(2,nearestStreet.size());
173 	
174 	//test Order
175 	nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 2, null,null, null,null);
176 	assertEquals(2,nearestStreet.size());
177 	Double firstDist = nearestStreet.get(0).getDistance();
178 	Double secondDist = nearestStreet.get(1).getDistance();
179 	assertTrue("result should be sorted by distance : "+firstDist +"  should be < " +secondDist ,firstDist < secondDist);
180     
181     }
182 
183     @Test
184     public void testCountEstimate(){
185 	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
186 	streetOSM.setGid(1L);
187 	streetOSM.setGid(3L);
188 	
189 	OpenStreetMap streetOSM2 = GeolocTestHelper.createOpenStreetMapForJohnKenedyStreet();
190 	openStreetMapDao.save(streetOSM);
191 	openStreetMapDao.save(streetOSM2);
192 	
193 	long estimateCount = openStreetMapDao.countEstimate();
194 	Assert.assertEquals("countestimate should return the max gid, the estimation is based on the fact that the importer start the gid to 0",3L, estimateCount);
195 	
196     }
197 
198     
199     @Test
200     public void testGetByGidShouldRetrieveIfEntityExists(){
201 	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
202 	openStreetMapDao.save(streetOSM);
203 	assertNotNull(openStreetMapDao.get(streetOSM.getId()));
204 	
205 	OpenStreetMap retrieveOSM = openStreetMapDao.getByGid(streetOSM.getGid());
206 	assertNotNull("getByGid should not return null if the entity exists",retrieveOSM);
207 	assertEquals("getByGid should return the entity if the entity exists",streetOSM, retrieveOSM);
208 	
209     }
210     
211     @Test
212     public void testSaveShouldsaveLongName(){
213 	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
214 	String longString = RandomStringUtils.random(StringHelper.MAX_STRING_INDEXABLE_LENGTH+1,new char[] {'e'});
215 	Assert.assertEquals("the string to test is not of the expected size the test will fail",StringHelper.MAX_STRING_INDEXABLE_LENGTH+1, longString.length());
216 	streetOSM.setName(longString);
217 	openStreetMapDao.save(streetOSM);
218 	assertNotNull(openStreetMapDao.get(streetOSM.getId()));
219 	
220 	OpenStreetMap retrieveOSM = openStreetMapDao.getByGid(streetOSM.getGid());
221 	assertNotNull("getByGid should not return null if the entity exists",retrieveOSM);
222 	assertEquals("getByGid should return the entity if the entity exists",streetOSM, retrieveOSM);
223 	
224     }
225     
226     @Test
227     public void testGetByGidShouldReturnNullIfEntityDoesnTExist(){
228 	OpenStreetMap retrieveOSM = openStreetMapDao.getByGid(1L);
229 	assertNull("getByGid should return null if the entity doesn't exist",retrieveOSM);
230 	
231     }
232     
233     @Test
234     public void testGetByGidShouldThrowsIfGidIsNull(){
235 	try {
236 	    openStreetMapDao.getByGid(null);
237 	    fail("getByGid should throws if gid is null");
238 	} catch (RuntimeException e) {
239 	    	//ok
240 	}
241 	
242     }
243     
244 
245 
246     
247     @Test
248     public void testUpdateTS_vectorColumnForStreetNameSearch(){
249     	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
250     	openStreetMapDao.save(streetOSM);
251     	assertNotNull(openStreetMapDao.get(streetOSM.getId()));
252     	
253     	
254     	    	
255     	Point searchPoint = GeolocHelper.createPoint(30.1F, 30.1F);
256     	
257     	List<StreetDistance> nearestStreet = openStreetMapDao.getNearestAndDistanceFrom(searchPoint, 10000, 1, 1, null, null,"John",StreetSearchMode.CONTAINS);
258     	assertEquals(0,nearestStreet.size());
259     	
260     	int numberOfLineUpdated = openStreetMapDao.updateTS_vectorColumnForStreetNameSearch();
261     	if (GisgraphyConfig.PARTIAL_SEARH_EXPERIMENTAL){
262     		assertEquals("It should have 2 lines updated : streetosm for fulltext and partial",2, numberOfLineUpdated);
263     	} else {
264     		assertEquals("It should have 1 lines updated : streetosm for fulltext",1, numberOfLineUpdated);
265     	}
266     	
267     }
268     
269     @Test
270     public void testclearTextSearchName(){
271 	OpenStreetMap streetOSM = GeolocTestHelper.createOpenStreetMapForPeterMartinStreet();
272 	String partialSearchName = "partial";
273 	streetOSM.setTextSearchName(partialSearchName);
274     	openStreetMapDao.save(streetOSM);
275     	OpenStreetMap streetWithPartialSearchNameRetrieved =openStreetMapDao.getByGid(streetOSM.getGid());
276     	assertEquals("partialsearchName should be persist",partialSearchName,streetWithPartialSearchNameRetrieved.getTextSearchName());
277     	openStreetMapDao.clearTextSearchName();
278     	//we clear cache
279     	openStreetMapDao.flushAndClear();
280     	OpenStreetMap streetWithOutPartailSearchNameRetrieved =openStreetMapDao.getByGid(streetOSM.getGid());
281     	assertNull("partialsearchName should be null after clearTextSearchName has been called",streetWithOutPartailSearchNameRetrieved.getTextSearchName());
282     }
283     
284     
285     @Test
286     public void testCreateSpatialIndexesShouldNotThrow(){
287     	openStreetMapDao.createSpatialIndexes();
288     }
289     
290     @Test
291     public void testCreateFulltextIndexesShouldNotThrow(){
292     	openStreetMapDao.createFulltextIndexes();
293     }
294     
295 
296     
297     public void setOpenStreetMapDao(IOpenStreetMapDao openStreetMapDao) {
298         this.openStreetMapDao = openStreetMapDao;
299     }
300     
301 }