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.webapp.action;
24  
25  import java.util.HashMap;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Set;
29  
30  import org.springframework.beans.factory.annotation.Required;
31  
32  import com.gisgraphy.domain.geoloc.entity.Country;
33  import com.gisgraphy.domain.repository.ICountryDao;
34  import com.gisgraphy.domain.valueobject.GisgraphyConfig;
35  import com.gisgraphy.domain.valueobject.Output;
36  import com.gisgraphy.domain.valueobject.Pagination;
37  import com.gisgraphy.fulltext.Constants;
38  import com.gisgraphy.fulltext.FulltextQuery;
39  import com.gisgraphy.fulltext.IFullTextSearchEngine;
40  import com.gisgraphy.fulltext.SolrResponseDto;
41  import com.opensymphony.xwork2.Action;
42  import com.opensymphony.xwork2.ActionSupport;
43  
44  /**
45   * Ggeocoding Action
46   * 
47   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
48   */
49  public class GeocodingAction extends ActionSupport implements
50  	GoogleMapApiKeyAware {
51  
52      //private static Logger logger = LoggerFactory.getLogger(GeocodingAction.class);
53  
54      /**
55       * 
56       */
57      private static final long serialVersionUID = 1L;
58  
59      /**
60       * The cities in case that more than one result match 
61       */
62      private List<SolrResponseDto> ambiguousCities;
63  
64      /**
65       * the name of the city chosen in the ambiguous cities list 
66       */
67      private String ambiguousCity;
68  
69      /**
70       * th search field value
71       */
72      private String city;
73  
74      private String lng;
75  
76      private String lat;
77  
78      /**
79       * whether the city has been found (no more ambiguous)
80       */
81      private boolean cityFound = false;
82  
83      private IFullTextSearchEngine fullTextSearchEngine;
84  
85      Map<Long, String> featureIdLatLongMap = new HashMap<Long, String>();
86  
87      private String message = "";
88  
89      private String errorMessage = "";
90  
91      private ICountryDao countryDao;
92  
93      private String countryCode;
94  
95      @SuppressWarnings("unchecked")
96      @Override
97      public String execute() throws Exception {
98  	try {
99  
100 	    if (city != null) {
101 		if (countryCode == null || "".equals(countryCode)) {
102 		    errorMessage = getText("search.country.required");
103 		    return Action.SUCCESS;
104 		}
105 		FulltextQuery fulltextQuery = new FulltextQuery(city,
106 			Pagination.DEFAULT_PAGINATION, Output.DEFAULT_OUTPUT,
107 			Constants.ONLY_CITY_PLACETYPE, getCountryCode());
108 		ambiguousCities = fullTextSearchEngine.executeQuery(
109 			fulltextQuery).getResults();
110 		int numberOfPossibleCitiesThatMatches = ambiguousCities.size();
111 		if (numberOfPossibleCitiesThatMatches == 0) {
112 		    return Action.SUCCESS;
113 		} else if (numberOfPossibleCitiesThatMatches == 1) {
114 		    SolrResponseDto cityfound = ambiguousCities.get(0);
115 		    lat = cityfound.getLat().toString();
116 		    lng = cityfound.getLng().toString();
117 		    city = buildCityDisplayName(cityfound); 
118 		    cityFound = true;
119 		    return Action.SUCCESS;
120 		} else {
121 		    //more than one city suits
122 		    return Action.SUCCESS;
123 		}
124 
125 	    } else if (ambiguousCity != null) {
126 		return Action.SUCCESS;
127 	    }
128 
129 	} catch (Exception e) {
130 	    errorMessage = getText("search.error", e.getMessage());
131 	}
132 
133 	return Action.SUCCESS;
134     }
135 
136 	protected String buildCityDisplayName(SolrResponseDto cityfound) {
137 		String diplayName = cityfound.getName();
138 		Set<String> zipcodes = cityfound.getZipcodes();
139 		if (zipcodes != null && zipcodes.size()==1) {
140 			diplayName = cityfound.getName() + " (" + zipcodes.iterator().next() + ")";
141 		}
142 		return diplayName;
143 	}
144 
145     public String getLatLongJson() {
146 	if (ambiguousCities == null) {
147 	    return "";
148 	}
149 	StringBuffer sb = new StringBuffer("[");
150 	int index = 1;
151 	for (SolrResponseDto city : ambiguousCities) {
152 	    sb.append("{\"lat\":");
153 	    sb.append(city.getLat());
154 	    sb.append(",");
155 	    sb.append("\"lng\":");
156 	    sb.append(city.getLng());
157 	    sb.append("}");
158 	    if (index != ambiguousCities.size()) {
159 		sb.append(",");
160 	    }
161 	    index = index + 1;
162 
163 	}
164 	sb.append("]");
165 	return sb.toString();
166     }
167 
168     /**
169      * @return the ambiguousCities
170      */
171     public List<SolrResponseDto> getAmbiguousCities() {
172 	return ambiguousCities;
173     }
174 
175     public void setAmbiguousCities(List<SolrResponseDto> ambiguousCities) {
176 	this.ambiguousCities = ambiguousCities;
177     }
178 
179     /**
180      * @return the ambiguousCity
181      */
182     public String getAmbiguousCity() {
183 	return ambiguousCity;
184     }
185 
186     /**
187      * @return the available countries
188      */
189     public List<Country> getCountries() {
190 	return countryDao.getAllSortedByName();
191     }
192 
193     /**
194      * @param ambiguousCity the ambiguousCity to set
195      */
196     public void setAmbiguousCity(String ambiguousCity) {
197 	this.ambiguousCity = ambiguousCity;
198     }
199 
200     /**
201      * @param countryDao
202      *                the countryDao to set
203      */
204     @Required
205     public void setCountryDao(ICountryDao countryDao) {
206 	this.countryDao = countryDao;
207     }
208 
209     /**
210      * @param fullTextSearchEngine the fullTextSearchEngine to set
211      */
212     public void setFullTextSearchEngine(
213 	    IFullTextSearchEngine fullTextSearchEngine) {
214 	this.fullTextSearchEngine = fullTextSearchEngine;
215     }
216 
217     /**
218      * @return the city
219      */
220     public String getCity() {
221 	return city;
222     }
223 
224     /**
225      * @param city the city to set
226      */
227     public void setCity(String city) {
228 	this.city = city;
229     }
230 
231     /**
232      * @return the countryCode
233      */
234     public String getCountryCode() {
235 	return countryCode;
236     }
237 
238     /**
239      * @param countryCode the countryCode to set
240      */
241     public void setCountryCode(String countryCode) {
242 	this.countryCode = countryCode;
243     }
244 
245     /**
246      * @return the message
247      */
248     public String getMessage() {
249 	return message;
250     }
251 
252     /**
253      * @return the errorMessage
254      */
255     public String getErrorMessage() {
256 	return errorMessage;
257     }
258 
259     /**
260      * @return the lng
261      */
262     public String getLng() {
263 	return lng;
264     }
265 
266     /**
267      * @param lng the lng to set
268      */
269     public void setLng(String lng) {
270 	this.lng = lng;
271     }
272 
273     /**
274      * @return the lat
275      */
276     public String getLat() {
277 	return lat;
278     }
279 
280     /**
281      * @param lat the lat to set
282      */
283     public void setLat(String lat) {
284 	this.lat = lat;
285     }
286 
287     /**
288      * @return the googleMapAPIKey
289      */
290     public String getGoogleMapAPIKey() {
291 	return GisgraphyConfig.googleMapAPIKey == null ? ""
292 		: GisgraphyConfig.googleMapAPIKey;
293     }
294 
295     /**
296      * @return the cityFound
297      */
298     public boolean isCityFound() {
299 	return cityFound;
300     }
301 
302 }