/** * ** 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; }
/* 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; }