package citation.query; import java.io.InputStream; import java.util.Vector; import javax.microedition.io.Connector; import javax.microedition.io.StreamConnection; public class HTTPGoogleAPI { public class ParseType { public static final int ADDRESS = 1; public static final int CITY = 2; public static final int STATE = 3; public static final int ZIP = 4; } public static final int MIN_ACCURACY_LEVEL = 6; public static final int MAX_ADDRESS_RESULTS = 8; /* * GEOCODE ACCURACY LEVELS 0 Unknown accuracy. 1 Country level accuracy. 2 * Region (state, province, prefecture, etc.) level accuracy. 3 Sub-region * (county, municipality, etc.) level accuracy. 4 Town (city, village) level * accuracy. 5 Post code (zip code) level accuracy. 6 Street level accuracy. * 7 Intersection level accuracy. 8 Address level accuracy. 9 Premise * (building name, property name, shopping center, etc.) level accuracy. */ /** * ReverseGeoQuery - runs the basic geo query to Google geo query service * */ public static String ReverseGeoQuery(double lat, double lon) { String response = null; StringBuffer url = new StringBuffer(); url.append("http://maps.google.com/maps/geo?"); url.append("q=" + Double.toString(lat) + "," + Double.toString(lon)); url.append("&output=json&sensor=true_or_false"); try { // String result = post(url.toString()); response = getPage(url.toString()); } // TODO clean up empty catch catch (Exception e) { System.out.println("HTTPGoogleAPI.getPage Exception: " + e.toString()); } return response; } /* * getPage - sample code from web for getting simple page results TODO clean * up code for error conditions and remove the 255 response limit */ private static String getPage(String url) { String response = null; StreamConnection s = null; try { // try wifi network connection first s = (StreamConnection) Connector.open(url + ";deviceside=true;interface=wifi"); } catch (Exception e) { // no-op; failure to open a wi-fi connection is quite likely } try { // wi-fi failed so try normal network connection if (s == null) { s = (StreamConnection) Connector.open(url); } // still no good - time to bail if (s == null) return response; InputStream input = s.openInputStream(); byte[] data = new byte[256]; int len = 0; StringBuffer raw = new StringBuffer(); while (-1 != (len = input.read(data))) { raw.append(new String(data, 0, len)); } response = raw.toString(); input.close(); s.close(); } // TODO clean up empty catch catch (Exception e) { System.out.println("StreamConnection Exception: " + e.toString()); } return response; } /** * getAddressList - return all geocode addresses with accuracy 6 or better * * @param _str * - full response string to the geocode request * @return vector of strings containing results */ public static String[] getAddressList(String _str) { String[] response; Vector addrList = new Vector(); String startAddressParseKey = "\"address\": "; String endParseKey = ",\n"; String accuracyParseKey = "\"Accuracy\" :"; int accuracyLevel = 0; int beginIndex = 0; int endIndex = 0; for (int i = 0; i < MAX_ADDRESS_RESULTS; i++) { beginIndex = _str.indexOf(startAddressParseKey, beginIndex) + startAddressParseKey.length() + 1; endIndex = _str.indexOf(endParseKey, beginIndex) - 1; String fullAddress = _str.substring(beginIndex, endIndex); beginIndex = endIndex + 1; beginIndex = _str.indexOf(accuracyParseKey, beginIndex) + accuracyParseKey.length() + 1; endIndex = _str.indexOf(endParseKey, beginIndex); String accStr = _str.substring(beginIndex, endIndex); accuracyLevel = Integer.parseInt(accStr.trim()); // only add items that meet minimum accuracy levels if ( accuracyLevel >= MIN_ACCURACY_LEVEL ) { addrList.addElement(fullAddress); } else { // remaining results will be at or below this accuracy, so we can break and return break; } } // transfer the vector into an appropriately sized array response = new String[addrList.size()]; for ( int j = 0; j < addrList.size(); j++) { response[j] = (String)addrList.elementAt(j); } return response; } /** * parseFullMapResult - take a geocode response, and parse out the first * address into the requested parts * * @param _str * @param addrType * @return */ public static String parseFullMapResult(String _str, int _addrType) { String fullAddress = null; String[] addrList = getAddressList(_str); if (addrList.length <= 0) { return null; } fullAddress = addrList[0]; return parseAddressResult(fullAddress, _addrType); } /** * parseAddressResult - parse a full address into it's constituent parts * * @param _str * - assumes input string is a full address as street, city, * state, zip * * @param addrType * - defines which portion of string to return * @return */ public static String parseAddressResult(String _str, int _addrType) { String response = null; String address; String city; String state; String zip; int beginIndex = 0; int endIndex = 0; endIndex = _str.indexOf(",", beginIndex); address = _str.substring(beginIndex, endIndex); beginIndex = endIndex + 2; endIndex = _str.indexOf(",", beginIndex); city = _str.substring(beginIndex, endIndex); beginIndex = endIndex + 2; endIndex = _str.indexOf(" ", beginIndex); state = _str.substring(beginIndex, endIndex); beginIndex = endIndex + 1; endIndex = _str.indexOf(",", beginIndex); zip = _str.substring(beginIndex, endIndex); if ((int) _addrType == ParseType.ADDRESS) { response = address; } else if (_addrType == ParseType.CITY) { response = city; } else if (_addrType == ParseType.STATE) { response = state; } else if (_addrType == ParseType.ZIP) { response = zip; } else { response = _str; } return response; } }