package org.androad.sys.ors.lus.yahoo;
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 YahooLUSParser 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 double a = -1;
private double b = -1;
private boolean inResultSet = false;
private boolean inError = false;
private boolean inErrorMessage = false;
private boolean inLocale = false;
private boolean inQuality = false;
private boolean inFound = false;
private boolean inResult = false;
private boolean inquality = false;
private boolean inlatitude = false;
private boolean inlongitude = false;
private boolean inoffsetlat = false;
private boolean inoffsetlon = false;
private boolean inradius = false;
private boolean inname = false;
private boolean inline1 = false;
private boolean inline2 = false;
private boolean inline3 = false;
private boolean inline4 = false;
private boolean inhouse = false;
private boolean instreet = false;
private boolean inxstreet = false;
private boolean inunittype = false;
private boolean inunit = false;
private boolean inpostal = false;
private boolean inneighborhood = false;
private boolean incity = false;
private boolean incounty = false;
private boolean instate = false;
private boolean incountry = false;
private boolean incountrycode = false;
private boolean instatecode = false;
private boolean incountycode = false;
private boolean inuzip = false;
private boolean inhash = false;
private boolean inwoeid = false;
private boolean inwoetype = 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("ResultSet")){
this.inResultSet = true;
} else if(localName.equals("Error")){
this.inError = true;
} else if(localName.equals("ErrorMessage")){
this.inErrorMessage = true;
} else if(localName.equals("Locale")){
this.inLocale = true;
} else if(localName.equals("Quality")){
this.inQuality = true;
} else if(localName.equals("Found")){
this.inFound = true;
} else if(localName.equals("Result")){
this.inResult = true;
} else if(localName.equals("quality")){
this.inquality = true;
} else if(localName.equals("latitude")){
this.inlatitude = true;
} else if(localName.equals("longitude")){
this.inlongitude = true;
} else if(localName.equals("offsetlat")){
this.inoffsetlat = true;
} else if(localName.equals("offsetlon")){
this.inoffsetlon = true;
} else if(localName.equals("radius")){
this.inradius = true;
} else if(localName.equals("name")){
this.inname = true;
} else if(localName.equals("line1")){
this.inline1 = true;
} else if(localName.equals("line2")){
this.inline2 = true;
} else if(localName.equals("line3")){
this.inline3 = true;
} else if(localName.equals("line4")){
this.inline4 = true;
} else if(localName.equals("house")){
this.inhouse = true;
} else if(localName.equals("street")){
this.instreet = true;
} else if(localName.equals("xstreet")){
this.inxstreet = true;
} else if(localName.equals("unittype")){
this.inunittype = true;
} else if(localName.equals("unit")){
this.inunit = true;
} else if(localName.equals("postal")){
this.inpostal = true;
} else if(localName.equals("neighborhood")){
this.inneighborhood = true;
} else if(localName.equals("city")){
this.incity = true;
} else if(localName.equals("county")){
this.incountry = true;
} else if(localName.equals("state")){
this.instate = true;
} else if(localName.equals("country")){
this.incountry = true;
} else if(localName.equals("countrycode")){
this.incountrycode = true;
} else if(localName.equals("statecode")){
this.instatecode = true;
} else if(localName.equals("countycode")){
this.incountycode = true;
} else if(localName.equals("uzip")){
this.inuzip = true;
} else if(localName.equals("hash")){
this.inhash = true;
} else if(localName.equals("woeid")){
this.inwoeid = true;
} else if(localName.equals("woetype")){
this.inwoetype = 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("ResultSet")){
this.inResultSet = false;
} else if(localName.equals("Error")){
this.inError = false;
} else if(localName.equals("ErrorMessage")){
this.inErrorMessage = false;
String error = this.sb.toString();
if (!"No error".equals(error)) {
this.mErrors.add(new Error("Err", "Sev", "", error));
}
} else if(localName.equals("Locale")){
this.inLocale = false;
} else if(localName.equals("Quality")){
this.inQuality = false;
} else if(localName.equals("Found")){
this.inFound = false;
} else if(localName.equals("Result")){
this.inResult = false;
} else if(localName.equals("quality")){
quality = Float.parseFloat(this.sb.toString());
this.inquality = false;
} else if(localName.equals("latitude")){
this.a = Double.parseDouble(this.sb.toString());
this.inlatitude = false;
} else if(localName.equals("longitude")){
this.b = Double.parseDouble(this.sb.toString());
this.inlongitude = false;
} else if(localName.equals("offsetlat")){
this.inoffsetlat = false;
} else if(localName.equals("offsetlon")){
this.inoffsetlon = false;
} else if(localName.equals("radius")){
this.inradius = false;
} else if(localName.equals("name")){
this.inname = false;
} else if(localName.equals("line1")){
this.inline1 = false;
} else if(localName.equals("line2")){
this.inline2 = false;
} else if(localName.equals("line3")){
this.inline3 = false;
} else if(localName.equals("line4")){
this.inline4 = false;
} else if(localName.equals("house")){
this.inhouse = false;
} else if(localName.equals("street")){
this.mTmpGeocodedAddress.setStreetNameOfficial(this.sb.toString());
this.instreet = false;
} else if(localName.equals("xstreet")){
this.inxstreet = false;
} else if(localName.equals("unittype")){
this.inunittype = false;
} else if(localName.equals("unit")){
this.inunit = false;
} else if(localName.equals("postal")){
this.mTmpGeocodedAddress.setPostalCode(this.sb.toString());
this.inpostal = false;
} else if(localName.equals("neighborhood")){
this.inneighborhood = false;
} else if(localName.equals("city")){
this.incity = false;
} else if(localName.equals("county")){
this.mTmpGeocodedAddress.setMunicipality(this.sb.toString());
this.incountry = false;
} else if(localName.equals("state")){
this.mTmpGeocodedAddress.setCountrySubdivision(this.sb.toString());
this.instate = false;
} else if(localName.equals("country")){
this.incountry = false;
} else if(localName.equals("countrycode")){
this.mTmpGeocodedAddress.setNationality(Country.fromAbbreviation(this.sb.toString()));
this.incountrycode = false;
} else if(localName.equals("statecode")){
this.instatecode = false;
} else if(localName.equals("countycode")){
this.incountycode = false;
} else if(localName.equals("uzip")){
this.inuzip = false;
} else if(localName.equals("hash")){
this.inhash = false;
} else if(localName.equals("woeid")){
this.inwoeid = false;
} else if(localName.equals("woetype")){
this.inwoetype = false;
} else {
Log.w(DEBUGTAG, "Unexpected end-tag: '" + name + "'");
}
// Reset the stringbuffer
this.sb.setLength(0);
if (this.a != -1 && this.b != -1) {
final GeoPoint gp = new GeoPoint((int) (a * 1E6), (int) (b * 1E6));
this.mTmpGeocodedAddress = new GeocodedAddress(gp);
this.mTmpGeocodedAddress.setAccuracy(quality);
this.mAddresses.add(this.mTmpGeocodedAddress);
this.a = -1;
this.b = -1;
}
super.endElement(uri, localName, name);
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
}