public GoogleSig getSignature() { if (!this.signature_init) { this.signature_init = true; String key = this.getAuthorization(); if (!StringTools.isBlank(key) && key.startsWith(CLIENT_ID_PREFIX)) { String sigKey = this.getProperties().getString(PROP_signatureKey, ""); if (!StringTools.isBlank(sigKey)) { Print.logWarn("Setting SignatureKey: " + sigKey); this.signature = new GoogleSig(sigKey); } else { Print.logWarn("No signatureKey ..."); } } } return this.signature; }
private Document GetXMLDocument(String url) { try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); InputStream input = HTMLTools.inputStream_GET(url, 5000); InputStreamReader reader = new InputStreamReader(input, ENCODING_UTF8); InputSource inSrc = new InputSource(reader); inSrc.setEncoding(ENCODING_UTF8); return db.parse(inSrc); } catch (ParserConfigurationException pce) { Print.logError("Parse error: " + pce); return null; } catch (SAXException se) { Print.logError("Parse error: " + se); return null; } catch (IOException ioe) { Print.logError("IO error: " + ioe); return null; } }
/** ** Main entery point for debugging/testing */ public static void main(String argv[]) { RTConfig.setCommandLineArgs(argv); Print.setAllOutputToStdout(true); Print.setEncoding(ENCODING_UTF8); String accountID = RTConfig.getString(ARG_ACCOUNT, "demo"); GoogleGeocodeV2 gn = new GoogleGeocodeV2("google", null, null); /* reverse geocode */ if (RTConfig.hasProperty(ARG_REVGEOCODE)) { GeoPoint gp = new GeoPoint(RTConfig.getString(ARG_REVGEOCODE, null)); if (!gp.isValid()) { Print.logInfo("Invalid GeoPoint specified"); System.exit(1); } Print.logInfo("Reverse-Geocoding GeoPoint: " + gp); Print.sysPrintln( "RevGeocode = " + gn.getReverseGeocode(gp, null /*localeStr*/, false /*cache*/)); // Note: Even though the values are printed in UTF-8 character encoding, the // characters may not appear to be property displayed if the console display // does not support UTF-8. System.exit(0); } /* no options */ Print.sysPrintln("No options specified"); System.exit(1); }
/** ** Main entery point for debugging/testing */ public static void main(String argv[]) { RTConfig.setCommandLineArgs(argv); Print.setAllOutputToStdout(true); Print.setEncoding(ENCODING_UTF8); /* host */ String host = RTConfig.getString("host", null); if (!StringTools.isBlank(host)) { HOST_PRIMARY = host; } /* GeoPoint */ GeoPoint gp = new GeoPoint(RTConfig.getString("gp", null)); if (!gp.isValid()) { Print.logInfo("Invalid GeoPoint specified"); System.exit(1); } Print.logInfo("Reverse-Geocoding GeoPoint: " + gp); /* Reverse Geocoding */ Nominatim gn = new Nominatim("nominatim", null, RTConfig.getCommandLineProperties()); Print.sysPrintln("RevGeocode = " + gn.getReverseGeocode(gp, null /*localeStr*/)); }
/** * ** Returns a ReverseGeocode instance containing address information ** @param gp The GeoPoint * ** @return The ReverseGeocode instance */ private ReverseGeocode getAddressReverseGeocode(GeoPoint gp, String localeStr) { /* URL */ String url = this.getAddressReverseGeocodeURL(gp); Print.logInfo("Address URL: " + url); /* create XML document */ Document xmlDoc = GetXMLDocument(url); if (xmlDoc == null) { return null; } /* create ReverseGeocode response */ Element reversegeocode = xmlDoc.getDocumentElement(); if (!reversegeocode.getTagName().equalsIgnoreCase(TAG_reversegeocode)) { return null; } /* init */ String address_val = null; // null address String house_val = null; // house number String road_val = null; // street name String city_val = null; // city name String county_val = null; // county name String state_val = null; // state/province String postcode_val = null; // postal code String country_name_val = null; // country name String country_code_val = null; // country code // full address NodeList resultList = XMLTools.getChildElements(reversegeocode, TAG_result); for (int r = 0; r < resultList.getLength(); r++) { Element result = (Element) resultList.item(r); // String osmType = XMLTools.getAttribute(result, ATTR_osm_type, null, false); address_val = XMLTools.getNodeText(result, " ", false); break; // only the first element } // address components NodeList addresspartsList = XMLTools.getChildElements(reversegeocode, TAG_addressparts); for (int a = 0; (a < addresspartsList.getLength()); a++) { Element addressparts = (Element) addresspartsList.item(a); NodeList addresspartsChildren = addressparts.getChildNodes(); for (int ac = 0; ac < addresspartsChildren.getLength(); ac++) { Node child = addresspartsChildren.item(ac); if (!(child instanceof Element)) { continue; } Element elem = (Element) child; String elemName = elem.getNodeName(); if (elemName.equalsIgnoreCase(TAG_house)) { house_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_tram)) { // ignore } else if (elemName.equalsIgnoreCase(TAG_road)) { road_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_residential)) { // ignore } else if (elemName.equalsIgnoreCase(TAG_village)) { // ignore } else if (elemName.equalsIgnoreCase(TAG_town)) { if (StringTools.isBlank(city_val)) { city_val = XMLTools.getNodeText(elem, " ", false); } } else if (elemName.equalsIgnoreCase(TAG_city)) { city_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_county)) { county_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_postcode)) { postcode_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_state)) { state_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_country)) { country_name_val = XMLTools.getNodeText(elem, " ", false); } else if (elemName.equalsIgnoreCase(TAG_country_code)) { country_code_val = StringTools.trim(XMLTools.getNodeText(elem, " ", false)).toUpperCase(); } else { // elemName unrecognized } } break; // only the first element } /* populate ReverseGeocode instance */ ReverseGeocode rg = new ReverseGeocode(); StringBuffer addr = new StringBuffer(); // house number /road if (!StringTools.isBlank(house_val)) { addr.append(house_val); if (!StringTools.isBlank(road_val)) { addr.append(" "); addr.append(road_val); rg.setStreetAddress(house_val + " " + road_val); } else { rg.setStreetAddress(house_val); } } else if (!StringTools.isBlank(road_val)) { addr.append(road_val); rg.setStreetAddress(road_val); } // city/county if (!StringTools.isBlank(city_val)) { if (addr.length() > 0) { addr.append(", "); } addr.append(city_val); rg.setCity(city_val); } if (!StringTools.isBlank(county_val)) { if (StringTools.isBlank(city_val)) { // "city" not provided, at least include the "county" if (addr.length() > 0) { addr.append(", "); } addr.append("[").append(county_val).append("]"); } // rg.setCounty(county_val); } // state/province if (!StringTools.isBlank(state_val)) { if (addr.length() > 0) { addr.append(", "); } addr.append(state_val); rg.setStateProvince(state_val); if (!StringTools.isBlank(postcode_val)) { addr.append(" ").append(postcode_val); rg.setPostalCode(postcode_val); } } else { if (!StringTools.isBlank(postcode_val)) { if (addr.length() > 0) { addr.append(", "); } addr.append(postcode_val); rg.setPostalCode(postcode_val); } } // country if (!StringTools.isBlank(country_code_val)) { if (country_code_val.equalsIgnoreCase("US")) { // if (addr.length() > 0) { addr.append(", "); } // addr.append("USA"); } else if (!StringTools.isBlank(country_name_val)) { if (addr.length() > 0) { addr.append(", "); } addr.append(country_name_val); } else { if (addr.length() > 0) { addr.append(", "); } addr.append(country_code_val); } rg.setCountryCode(country_code_val); } // full address rg.setFullAddress(addr.toString()); return rg; }
// http://code.google.com/apis/maps/documentation/geocoding/index.html public GeoPoint getGeocode(String address, String country) { /* URL */ String url = this.getGeoPointGeocodeURL(address, country); Print.logDebug("Google GC URL: " + url); /* create XML document */ Document xmlDoc = GetXMLDocument(url, this.getGeocodeTimeout()); if (xmlDoc == null) { return null; } /* vars */ String errCode = null; GeoPoint geoPoint = null; /* parse "xml" */ Element kml = xmlDoc.getDocumentElement(); if (kml.getTagName().equalsIgnoreCase(TAG_kml)) { NodeList ResponseList = XMLTools.getChildElements(kml, TAG_Response); for (int g = 0; (g < ResponseList.getLength()); g++) { Element response = (Element) ResponseList.item(g); NodeList responseNodes = response.getChildNodes(); for (int n = 0; n < responseNodes.getLength(); n++) { Node responseNode = responseNodes.item(n); if (!(responseNode instanceof Element)) { continue; } Element responseElem = (Element) responseNode; String responseNodeName = responseElem.getNodeName(); if (responseNodeName.equalsIgnoreCase(TAG_name)) { // <name>1600 Amphitheatre Parkway, Mountain View, CA</name> } else if (responseNodeName.equalsIgnoreCase(TAG_Status)) { // <Status> ... </Status> NodeList statusNodes = responseElem.getChildNodes(); for (int st = 0; st < statusNodes.getLength(); st++) { Node statusNode = statusNodes.item(st); if (!(statusNode instanceof Element)) { continue; } Element statusElem = (Element) statusNode; String statusNodeName = statusElem.getNodeName(); if (statusNodeName.equalsIgnoreCase(TAG_code)) { errCode = StringTools.trim(GoogleGeocodeV2.GetNodeText(statusElem)); // expect "200" break; // we only care about the 'code' } } } else if (responseNodeName.equalsIgnoreCase(TAG_Placemark)) { // <Placemark> ... </Placemark> String id = responseElem.getAttribute(ATTR_id); if ((id != null) && id.equals("p1")) { NodeList placemarkNodes = responseElem.getChildNodes(); for (int pm = 0; (geoPoint == null) && (pm < placemarkNodes.getLength()); pm++) { Node placemarkNode = placemarkNodes.item(pm); if (!(placemarkNode instanceof Element)) { continue; } Element placemarkElem = (Element) placemarkNode; String placemarkNodeName = placemarkElem.getNodeName(); if (placemarkNodeName.equalsIgnoreCase(TAG_Point)) { NodeList pointNodes = placemarkElem.getChildNodes(); for (int ptn = 0; (geoPoint == null) && (ptn < pointNodes.getLength()); ptn++) { Node pointNode = pointNodes.item(ptn); if (!(pointNode instanceof Element)) { continue; } Element pointElem = (Element) pointNode; String pointNodeName = pointElem.getNodeName(); if (pointNodeName.equalsIgnoreCase(TAG_coordinates)) { String ll[] = StringTools.split(GoogleGeocodeV2.GetNodeText(pointElem), ','); if (ll.length >= 2) { double lon = StringTools.parseDouble(ll[0], 0.0); // longitude is first double lat = StringTools.parseDouble(ll[1], 0.0); if (GeoPoint.isValid(lat, lon)) { geoPoint = new GeoPoint(lat, lon); break; // we only care about the 'GeoPoint' } } } } } } } else { // Print.logInfo("Skipping Placemark ID = %s", id); } } } } } /* create address */ if (geoPoint != null) { // GeoPoint found return geoPoint; } /* check for Google reverse-geocode limit exceeded */ if ((errCode != null) && errCode.equals("620")) { Print.logError("!!!! Google Reverse-Geocode Limit Exceeded [Error 620] !!!!"); } /* no reverse-geocode available */ return null; }
/* return reverse-geocode using nearest address */ public ReverseGeocode getAddressReverseGeocode(GeoPoint gp, String localeStr, boolean cache) { /* check for failover mode */ if (this.isReverseGeocodeFailoverMode()) { ReverseGeocodeProvider frgp = this.getFailoverReverseGeocodeProvider(); return frgp.getReverseGeocode(gp, localeStr, cache); } /* URL */ String url = this.getAddressReverseGeocodeURL(gp, localeStr); Print.logDebug("Google RG URL: " + url); // byte xmlBytes[] = HTMLTools.readPage(url); /* create XML document */ Document xmlDoc = GetXMLDocument(url, this.getReverseGeocodeTimeout()); if (xmlDoc == null) { return null; } /* vars */ String errCode = null; String address = null; /* parse "xml" */ Element kml = xmlDoc.getDocumentElement(); if (kml.getTagName().equalsIgnoreCase(TAG_kml)) { NodeList ResponseList = XMLTools.getChildElements(kml, TAG_Response); for (int g = 0; (g < ResponseList.getLength()); g++) { Element response = (Element) ResponseList.item(g); NodeList responseNodes = response.getChildNodes(); for (int n = 0; n < responseNodes.getLength(); n++) { Node responseNode = responseNodes.item(n); if (!(responseNode instanceof Element)) { continue; } Element responseElem = (Element) responseNode; String responseNodeName = responseElem.getNodeName(); if (responseNodeName.equalsIgnoreCase(TAG_name)) { // <name>40.479581,-117.773438</name> } else if (responseNodeName.equalsIgnoreCase(TAG_Status)) { // <Status> ... </Status> NodeList statusNodes = responseElem.getChildNodes(); for (int st = 0; st < statusNodes.getLength(); st++) { Node statusNode = statusNodes.item(st); if (!(statusNode instanceof Element)) { continue; } Element statusElem = (Element) statusNode; String statusNodeName = statusElem.getNodeName(); if (statusNodeName.equalsIgnoreCase(TAG_code)) { errCode = StringTools.trim(GoogleGeocodeV2.GetNodeText(statusElem)); // expect "200" break; // we only care about the 'code' } } } else if (responseNodeName.equalsIgnoreCase(TAG_Placemark)) { // <Placemark> ... </Placemark> String id = responseElem.getAttribute(ATTR_id); if ((id != null) && id.equals("p1")) { NodeList placemarkNodes = responseElem.getChildNodes(); for (int pm = 0; pm < placemarkNodes.getLength(); pm++) { Node placemarkNode = placemarkNodes.item(pm); if (!(placemarkNode instanceof Element)) { continue; } Element placemarkElem = (Element) placemarkNode; String placemarkNodeName = placemarkElem.getNodeName(); if (placemarkNodeName.equalsIgnoreCase(TAG_address)) { address = GoogleGeocodeV2.GetNodeText(placemarkElem); break; // we only care about the 'address' } } } else { // Print.logInfo("Skipping Placemark ID = %s", id); } } } } } /* create address */ if (FAILOVER_DEBUG) { errCode = "620"; } else if (!StringTools.isBlank(address)) { // address found ReverseGeocode rg = new ReverseGeocode(); rg.setFullAddress(address); return rg; } /* check for Google reverse-geocode limit exceeded */ if ((errCode != null) && errCode.equals("620")) { Print.logError("!!!! Google Reverse-Geocode Limit Exceeded [Error 620] !!!!"); if (this.hasFailoverReverseGeocodeProvider()) { this.startReverseGeocodeFailoverMode(); ReverseGeocodeProvider frgp = this.getFailoverReverseGeocodeProvider(); Print.logWarn("Failing over to '" + frgp.getName() + "'"); return frgp.getReverseGeocode(gp, localeStr, cache); } } /* no reverse-geocode available */ return null; }