package com.frommap.ws.request;
import java.io.IOException;
import java.net.URL;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonToken;
import com.frommap.cassandra.dao.PlacesDao;
import com.frommap.ws.bean.Place;
public class GooglePlaces {
private final String _key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
private String _url;
private boolean _can_continue;
private final String _sc_ok = "OK";
private final String _sc_zero = "ZERO_RESULTS";
private final String _sc_limit = "OVER_QUERY_LIMIT";
private final String _sc_denied = "REQUEST_DENIED";
private final String _sc_invalid = "INVALID_OPERATION";
private Map<String, Boolean> _key_taken_map = new Hashtable<>();
public GooglePlaces() {
_url = "localhost";
init();
}
public GooglePlaces(String url) {
this._url = url;
init();
}
private void init(){
_key_taken_map.put(_key, false);
_can_continue = true;
}
/**
*
* @param query Must be the category to search on a desired city
* @param nextPageToken initially must be ""
* @return the nextPageToken
*/
public String placesSearchBy(String category, String andCity, String nextPageToken, List<Place> listOfPlaces) {
Place p = new Place();
JsonFactory factory = new JsonFactory();
String type = category;
String url = "https://maps.googleapis.com/maps/api/place/textsearch/";
url += "json?query=" + category + "+in+" + andCity + "&sensor=false";
url += "&key=" + _key;
if (!nextPageToken.isEmpty()) {
url += "&pagetoken=" + nextPageToken;
nextPageToken = "";
}
try {
JsonParser parser = factory.createJsonParser(new URL(url));
// loop until token equal to "}"
while (parser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = parser.getCurrentName();
if ("html_attributions".equals(fieldname)) {
parser.nextToken();
while (parser.nextToken() != JsonToken.END_ARRAY) {
parser.getText();
}
} else if ("next_page_token".equals(fieldname)) {
nextPageToken = parser.getText();
} else if ("results".equals(fieldname)) {
JsonToken token = parser.nextToken();
while ((token = parser.nextToken()) != JsonToken.END_ARRAY) {
String resultToken = parser.getText();
if (resultToken.equals("formatted_address")) {
token = parser.nextToken();
p.setAddr(parser.getText());
} else if (resultToken.equals("lat")) {
token = parser.nextToken();
p.setLat(Double.parseDouble(parser.getText()));
} else if (resultToken.equals("lng")) {
token = parser.nextToken();
p.setLng(Double.parseDouble(parser.getText()));
token = parser.nextToken();
token = parser.nextToken();
resultToken = parser.getText();
} else if (resultToken.equals("icon")) {
token = parser.nextToken();
String icon = parser.getText();
p.setIcon(icon);
type = icon.substring(icon.lastIndexOf("/")+1,icon.length()-7);
} else if (resultToken.equals("name")) {
token = parser.nextToken();
p.setName(parser.getText());
} else if (resultToken.equals("types")) {
while((token = parser.nextToken()) != JsonToken.END_ARRAY) {
if (token != JsonToken.START_ARRAY && token != JsonToken.END_ARRAY)
p.addTypes(parser.getText());
}
} else if (resultToken.equals("photos")) {
while((token = parser.nextToken()) != JsonToken.END_ARRAY){
resultToken = parser.getText();
if ("html_attributions".equals(resultToken)) {
parser.nextToken();
while (parser.nextToken() != JsonToken.END_ARRAY) {
parser.getText();
}
}
}
}
if (p.getTypes() != null && token == JsonToken.END_OBJECT) {
PlacesDao d = new PlacesDao(_url);
p.setCategory(type);
d.completeRecord(p);
if(p.getId() == null)
d.insertPlaces(p);
Place b = new Place();
b.setAddr(p.getAddr());
b.setCategory(p.getCategory());
b.setId(p.getId());
b.setIcon(p.getIcon());
b.setLat(p.getLat());
b.setLng(p.getLng());
b.setName(p.getName());
b.setTypes(p.getTypes());
listOfPlaces.add(b);
p = new Place();
d.close();
}
}
}
if ("status".equals(fieldname)) {
parser.nextToken();
String element = parser.getText();
if (element.equals(_sc_ok)) {
if (nextPageToken.isEmpty()) _can_continue = false;
return nextPageToken;
} else if (element.equals(_sc_zero) || element.equals(_sc_denied) || element.equals(_sc_invalid)) {
_can_continue = false;
} else if (element.equals(_sc_limit)) {
for(String key : _key_taken_map.keySet()) {
if (!_key_taken_map.get(key)) {
_key_taken_map.put(key, true);
_key = key;
break;
} else {
_can_continue = false;
}
}
return nextPageToken;
}
}
}
parser.close();
} catch (IOException e) {
e.printStackTrace();
}
return nextPageToken;
}
public String nearbySearchBy(String type,double lat, double lng, String nextPageToken, List<Place> listOfPlaces) {
Place p = new Place();
JsonFactory factory = new JsonFactory();
String category = type;
String url = "https://maps.googleapis.com/maps/api/place/nearbysearch/";
if (nextPageToken.isEmpty())
url += "json?location=" + lat + "," + lng + "&types=" + type + "&radius=50000";
else
url += "json?pagetoken=" + nextPageToken;
url += "&key=" + _key + "&sensor=false";
try {
JsonParser parser = factory.createJsonParser(new URL(url));
// loop until token equal to "}"
while (parser.nextToken() != JsonToken.END_OBJECT) {
String fieldname = parser.getCurrentName();
if ("html_attributions".equals(fieldname)) {
parser.nextToken();
while (parser.nextToken() != JsonToken.END_ARRAY) {
parser.getText();
}
} else if ("next_page_token".equals(fieldname)) {
nextPageToken = fieldname = parser.nextTextValue();
} else if ("results".equals(fieldname)) {
JsonToken token = parser.nextToken();
while ((token = parser.nextToken()) != JsonToken.END_ARRAY) {
String resultToken = parser.getText();
if (resultToken.equals("lat") && p.getLat() == 0.0) {
token = parser.nextToken();
p.setLat(Double.parseDouble(parser.getText()));
} else if (resultToken.equals("lng") && p.getLng() == 0.0) {
token = parser.nextToken();
p.setLng(Double.parseDouble(parser.getText()));
} else if (resultToken.equals("icon")) {
token = parser.nextToken();
String icon = parser.getText();
p.setIcon(icon);
category = icon.substring(icon.lastIndexOf("/")+1,icon.length()-7);
} else if (resultToken.equals("name")) {
token = parser.nextToken();
p.setName(parser.getText());
} else if (resultToken.equals("types")) {
while((token = parser.nextToken()) != JsonToken.END_ARRAY) {
if (token != JsonToken.START_ARRAY && token != JsonToken.END_ARRAY)
p.addTypes(parser.getText());
}
} else if (resultToken.equals("photos")) {
while((token = parser.nextToken()) != JsonToken.END_ARRAY){
resultToken = parser.getText();
if ("html_attributions".equals(resultToken)) {
parser.nextToken();
while (parser.nextToken() != JsonToken.END_ARRAY) {
parser.getText();
}
}
}
} else if (resultToken.equals("vicinity")) {
token = parser.nextToken();
p.setAddr(parser.getText());
}
if (p.getTypes() != null && token == JsonToken.END_OBJECT) {
PlacesDao d = new PlacesDao(_url);
p.setCategory(category);
d.completeRecord(p);
if(p.getId() == null)
d.insertPlaces(p);
Place b = new Place();
b.setAddr(p.getAddr());
b.setCategory(p.getCategory());
b.setId(p.getId());
b.setIcon(p.getIcon());
b.setLat(p.getLat());
b.setLng(p.getLng());
b.setName(p.getName());
b.setTypes(p.getTypes());
listOfPlaces.add(b);
p = new Place();
d.close();
}
}
}
if ("status".equals(fieldname)) {
parser.nextToken();
String element = parser.getText();
if (element.equals(_sc_ok)) {
if (nextPageToken.isEmpty()) _can_continue = false;
return nextPageToken;
} else if (element.equals(_sc_zero) || element.equals(_sc_denied) || element.equals(_sc_invalid)) {
_can_continue = false;
} else if (element.equals(_sc_limit)) {
for(String key : _key_taken_map.keySet()) {
if (!_key_taken_map.get(key)) {
_key_taken_map.put(key, true);
_key = key;
break;
} else {
_can_continue = false;
}
}
return nextPageToken;
}
}
}
parser.close();
} catch (IOException e) {
e.printStackTrace();
}
return nextPageToken;
}
public boolean canContinue() {
return _can_continue;
}
public void setCanContinue(boolean canContinue) {
this._can_continue = canContinue;
}
}