// Created by plusminus on 18:06:19 - 07.11.2008 package org.androad.sys.ors.ds.openrouteservice; import java.util.ArrayList; import org.osmdroid.util.GeoPoint; import org.androad.sys.ors.adt.Error; import org.androad.sys.ors.adt.ds.ORSPOI; import org.androad.sys.ors.adt.ds.POIType; 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; /** * Parses XML-Data like: * <pre><?xml version="1.0" encoding="UTF-8"?> * <xls:XLS xmlns:xls="http://www.opengis.net/xls" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" version="1.1" xsi:schemaLocation="http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/DirectoryService.xsd"> * <xls:ResponseHeader xsi:type="xls:ResponseHeaderType"/> * <xls:Response xsi:type="xls:ResponseType" requestID="123456789" version="1.1" numberOfResponses="13"> * <xls:DirectoryResponse xsi:type="xls:DirectoryResponseType"> * <xls:POIContext> * <xls:POI POIName="Kocaman" description="bakery" ID="293710580"> * <gml:Point> * <gml:pos srsName="EPSG:4326">7.0866882 50.7335413</gml:pos> * </gml:Point> * </xls:POI> * <xls:Distance uom="M" value="625"/> * </xls:POIContext> * ... * <xls:POIContext> * <xls:POI POIName="Domgorgen" description="bakery" ID="270495053"> * <gml:Point> * <gml:pos srsName="EPSG:4326">7.0922473 50.7741497</gml:pos> * </gml:Point> * </xls:POI> * <xls:Distance uom="KM" value="5"/> * </xls:POIContext> * </xls:DirectoryResponse> * </xls:Response> * </xls:XLS></pre> * * @author Nicolas Gramlich * */ public class OpenRouteServiceDSParser extends DefaultHandler implements TimeConstants, Constants{ // ==================================== // Constants // ==================================== // ==================================== // Fields // ==================================== private final ArrayList<Error> mErrors = new ArrayList<Error>(); private ArrayList<ORSPOI> mPOIs; private ORSPOI mCurPOI; private boolean inXLS = false; private boolean inRepsonseHeader = false; private boolean inRepsonse = false; private boolean inDirectoryResponse = false; private boolean inPOIContext = false; private boolean inPOI = false; private boolean inPoint = false; private boolean inPos = false; private boolean inDistance = false; // =========================================================== // Getter & Setter // =========================================================== public ArrayList<Error> getErrors(){ return this.mErrors; } public ArrayList<ORSPOI> getDSResponse() throws ORSException{ if(this.mErrors != null && this.mErrors.size() > 0) { throw new ORSException(this.mErrors); } return this.mPOIs; } // ==================================== // Methods from Superclasses // ==================================== @Override public void startDocument() throws SAXException { super.startDocument(); this.mPOIs = new ArrayList<ORSPOI>(); } @Override public void startElement(final String uri, final String localName, final String name, final Attributes attributes) throws SAXException { if(localName.equals("Error") || name.equals("Error")){ final String errorCode = attributes.getValue("", "errorCode"); final String severity = attributes.getValue("", "severity"); final String locationPath = attributes.getValue("", "locationPath"); final String message = attributes.getValue("", "message"); this.mErrors.add(new Error(errorCode, severity, locationPath, message)); } this.sb.setLength(0); if(localName.equals("XLS")){ this.inXLS = true; } else if(localName.equals("ResponseHeader")){ this.inRepsonseHeader = true; } else if(localName.equals("Response")){ this.inRepsonse = true; } else if(localName.equals("DirectoryResponse")){ this.inDirectoryResponse = true; } else if(localName.equals("POIContext")){ this.inPOIContext = true; } else if(localName.equals("POI")){ this.inPOI = true; this.mCurPOI = new ORSPOI(); final String poiname = attributes.getValue("", "POIName"); final String poitype = attributes.getValue("", "description"); this.mCurPOI.setName(poiname); this.mCurPOI.setPOIType(POIType.fromRawName(poitype)); this.mPOIs.add(this.mCurPOI); } else if(localName.equals("Point")){ this.inPoint = true; } else if(localName.equals("pos")){ this.inPos = true; } else if(localName.equals("Distance")){ this.inDistance = true; final String uom = attributes.getValue("", "uom"); float factor = 0; if(uom != null){ if(uom.equals("M")){ factor = 1; }else if(uom.equals("KM")){ factor = 1000; } } this.mCurPOI.setDistance((int)(factor * Float.parseFloat(attributes.getValue("", "value")))); } else { Log.w(DEBUGTAG, "Unexpected tag: '" + name + "'"); } super.startElement(uri, localName, name, attributes); } private final 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("XLS")){ this.inXLS = false; } else if(localName.equals("ResponseHeader")){ this.inRepsonseHeader = false; } else if(localName.equals("Response")){ this.inRepsonse = false; } else if(localName.equals("DirectoryResponse")){ this.inDirectoryResponse = false; } else if(localName.equals("POIContext")){ this.inPOIContext = false; } else if(localName.equals("POI")){ this.inPOI = false; } else if(localName.equals("Point")){ this.inPoint = false; } else if(localName.equals("pos")){ this.inPos = false; this.mCurPOI.setGeoPoint(GeoPoint.fromInvertedDoubleString(this.sb.toString(), ' ')); } else if(localName.equals("Distance")){ this.inDistance = false; } else { Log.w(DEBUGTAG, "Unexpected end-tag: '" + name + "'"); } // Reset the stringbuffer this.sb.setLength(0); super.endElement(uri, localName, name); } @Override public void endDocument() throws SAXException { if(this.mErrors == null || this.mErrors.size() == 0){ // Maybe do some finalization or similar... } super.endDocument(); } // ==================================== // Helper-Methods // ==================================== }