package org.androad.sys.ors.lus.google; import java.util.ArrayList; import org.osmdroid.util.GeoPoint; import org.androad.sys.ors.adt.Error; import org.androad.sys.ors.adt.GeocodedAddress; import org.androad.sys.ors.adt.lus.Country; import org.androad.sys.ors.exceptions.ORSException; import org.androad.util.constants.Constants; import org.androad.util.constants.TimeConstants; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; public class GoogleLUSParser extends DefaultHandler implements TimeConstants, Constants { // ==================================== // Constants // ==================================== protected static final int LATITUDE_OVERMAX = (int)(81 * 1E6); protected static final int LONGITUDE_OVERMAX = (int)(181 * 1E6); // ==================================== // Fields // ==================================== private final ArrayList<Error> mErrors = new ArrayList<Error>(); private ArrayList<GeocodedAddress> mAddresses; private float quality; private String thorough; private String locality; private String administrative; private String country; private boolean inKml = false; private boolean inResponse = false; private boolean inName = false; private boolean inStatus = false; private boolean inCode = false; private boolean inRequest = false; private boolean inPlacemark = false; private boolean inAddress = false; private boolean inAddressDetails = false; private boolean inCountry = false; private boolean inCountryNameCode = false; private boolean inCountryName = false; private boolean inAdministrativeArea = false; private boolean inAdministrativeAreaName = false; private boolean inLocality = false; private boolean inLocalityName = false; private boolean inThoroughfare = false; private boolean inThoroughfareName = false; private boolean inExtendedData = false; private boolean inLatLonBox = false; private boolean inPoint = false; private boolean inCoordinates = false; private GeocodedAddress mTmpGeocodedAddress; // =========================================================== // Constructors // =========================================================== // =========================================================== // Getter & Setter // =========================================================== public ArrayList<Error> getErrors(){ return this.mErrors; } public ArrayList<GeocodedAddress> getAddresses() throws ORSException{ if(this.mErrors != null && this.mErrors.size() > 0) { throw new ORSException(this.mErrors); } return this.mAddresses; } // ==================================== // Methods from Superclasses // ==================================== @Override public void startDocument() throws SAXException { this.mAddresses = new ArrayList<GeocodedAddress>(); super.startDocument(); } @Override public void startElement(final String uri, final String localName, final String name, final Attributes attributes) throws SAXException { this.sb.setLength(0); if(localName.equals("kml")){ this.inKml = true; } else if(localName.equals("Response")){ this.inResponse = true; } else if(localName.equals("name")){ this.inName = true; } else if(localName.equals("Status")){ this.inStatus = true; } else if(localName.equals("code")){ this.inCode = true; } else if(localName.equals("request")){ this.inRequest = true; } else if(localName.equals("Placemark")){ this.inPlacemark = true; } else if(localName.equals("address")){ this.inAddress = true; } else if(localName.equals("AddressDetails")){ this.quality = Float.parseFloat(attributes.getValue("", "Accuracy")); this.inAddressDetails = true; } else if(localName.equals("Country")){ this.inCountry = true; } else if(localName.equals("CountryNameCode")){ this.inCountryNameCode = true; } else if(localName.equals("CountryName")){ this.inCountryName = true; } else if(localName.equals("AdministrativeArea")){ this.inAdministrativeArea = true; } else if(localName.equals("AdministrativeAreaName")){ this.inAdministrativeAreaName = true; } else if(localName.equals("Locality")){ this.inLocality = true; } else if(localName.equals("LocalityName")){ this.inLocalityName = true; } else if(localName.equals("Thoroughfare")){ this.inThoroughfare = true; } else if(localName.equals("ThoroughfareName")){ this.inThoroughfareName = true; } else if(localName.equals("ExtendedData")){ this.inExtendedData = true; } else if(localName.equals("LatLonBox")){ this.inLatLonBox = true; } else if(localName.equals("Point")){ this.inPoint = true; } else if(localName.equals("coordinates")){ this.inCoordinates = true; } else { Log.w(DEBUGTAG, "Unexpected tag: '" + name + "'"); } super.startElement(uri, localName, name, attributes); } protected StringBuilder sb = new StringBuilder(); @Override public void characters(final char[] chars, final int start, final int length) throws SAXException { this.sb.append(chars, start, length); super.characters(chars, start, length); } @Override public void endElement(final String uri, final String localName, final String name) throws SAXException { if(localName.equals("kml")){ this.inKml = false; } else if(localName.equals("Response")){ this.inResponse = false; } else if(localName.equals("name")){ this.inName = false; } else if(localName.equals("Status")){ this.inStatus = false; } else if(localName.equals("code")){ this.inCode = false; } else if(localName.equals("request")){ this.inRequest = false; } else if(localName.equals("Placemark")){ this.inPlacemark = false; } else if(localName.equals("address")){ this.inAddress = false; } else if(localName.equals("AddressDetails")){ this.inAddressDetails = false; } else if(localName.equals("Country")){ this.inCountry = false; } else if(localName.equals("CountryNameCode")){ this.country = this.sb.toString(); this.inCountryNameCode = false; } else if(localName.equals("CountryName")){ this.inCountryName = false; } else if(localName.equals("AdministrativeArea")){ this.inAdministrativeArea = false; } else if(localName.equals("AdministrativeAreaName")){ this.administrative = this.sb.toString(); this.inAdministrativeAreaName = false; } else if(localName.equals("Locality")){ this.inLocality = false; } else if(localName.equals("LocalityName")){ this.locality = this.sb.toString(); this.inLocalityName = false; } else if(localName.equals("Thoroughfare")){ this.inThoroughfare = false; } else if(localName.equals("ThoroughfareName")){ this.thorough = this.sb.toString(); this.inThoroughfareName = false; } else if(localName.equals("ExtendedData")){ this.inExtendedData = false; } else if(localName.equals("LatLonBox")){ this.inLatLonBox = false; } else if(localName.equals("Point")){ this.inPoint = false; } else if(localName.equals("coordinates")){ final String s = this.sb.toString(); final int spacerPos1 = s.indexOf(','); final int spacerPos2 = s.indexOf(',', (spacerPos1 + 1)); final String lo = s.substring(0, spacerPos1); final String la = s.substring(spacerPos1 + 1, spacerPos2); final int longitude = (int) (Double.parseDouble(lo) * 1E6); final int latitude = (int) (Double.parseDouble(la) * 1E6); final GeoPoint gp = new GeoPoint(latitude, longitude); this.mTmpGeocodedAddress = new GeocodedAddress(gp); this.mTmpGeocodedAddress.setAccuracy(this.quality); this.mTmpGeocodedAddress.setStreetNameOfficial(this.thorough); this.mTmpGeocodedAddress.setMunicipality(this.locality); this.mTmpGeocodedAddress.setCountrySubdivision(this.administrative); this.mTmpGeocodedAddress.setNationality(Country.fromAbbreviation(this.country)); this.mAddresses.add(this.mTmpGeocodedAddress); this.inCoordinates = false; } else { Log.w(DEBUGTAG, "Unexpected tag: '" + name + "'"); } // Reset the stringbuffer this.sb.setLength(0); super.endElement(uri, localName, name); } @Override public void endDocument() throws SAXException { super.endDocument(); } }