172 lines
6.4 KiB
Java
172 lines
6.4 KiB
Java
package dk.network42.osmfocus;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import org.xml.sax.Attributes;
|
|
import org.xml.sax.helpers.DefaultHandler;
|
|
|
|
import android.util.Log;
|
|
|
|
public class OsmParser extends DefaultHandler {
|
|
private static final String TAG = "OsmParser";
|
|
private OsmDB mDb;
|
|
private OsmNode mCurrentNode;
|
|
private OsmWay mCurrentWay;
|
|
private OsmRelation mCurrentRel;
|
|
private OsmBounds mCurrentBound;
|
|
private final ArrayList<Exception> exceptions;
|
|
|
|
public OsmParser() {
|
|
super();
|
|
mDb = new OsmDB();
|
|
mCurrentNode = null;
|
|
mCurrentWay = null;
|
|
mCurrentRel = null;
|
|
mCurrentBound = null;
|
|
exceptions = new ArrayList<Exception>();
|
|
}
|
|
|
|
public OsmDB getStorage() {
|
|
return mDb;
|
|
}
|
|
|
|
public void startElement(final String uri, final String name, final String qName, final Attributes atts) {
|
|
//Log.d(TAG, "startElement(), name="+name);
|
|
try {
|
|
if (isOsmElement(name)) {
|
|
parseOsmElement(name, atts);
|
|
} else if (isWayNode(name)) {
|
|
parseWayNode(atts);
|
|
} else if (isTag(name)) {
|
|
parseTag(atts);
|
|
} else if (isRelationMember(name)) {
|
|
parseRelationElement(atts);
|
|
} else if (isBounds(name)) {
|
|
parseBounds(atts);
|
|
}
|
|
} catch (OsmParseException e) {
|
|
Log.e(TAG, "OsmParseException", e);
|
|
exceptions.add(e);
|
|
}
|
|
}
|
|
|
|
public void endElement(final String uri, final String name, final String qName) {
|
|
//Log.d(TAG, "endElement(), name="+name);
|
|
if (isNode(name)) {
|
|
mDb.insertNode(mCurrentNode);
|
|
mCurrentNode = null;
|
|
} else if (isWay(name)) {
|
|
mDb.insertWay(mCurrentWay);
|
|
mCurrentWay = null;
|
|
} else if (isRelation(name)) {
|
|
mDb.insertRelation(mCurrentRel);
|
|
mCurrentRel = null;
|
|
} else if (isBounds(name)) {
|
|
mDb.insertBounds(mCurrentBound);
|
|
mCurrentBound = null;
|
|
}
|
|
}
|
|
|
|
private void parseOsmElement(final String name, final Attributes atts) throws OsmParseException {
|
|
try {
|
|
long osmId = Long.parseLong(atts.getValue("id"));
|
|
long osmVersion = Long.parseLong(atts.getValue("version"));
|
|
|
|
if (isNode(name)) {
|
|
int lon = (int) (Double.parseDouble(atts.getValue("lon")) * 1E7);
|
|
int lat = (int) (Double.parseDouble(atts.getValue("lat")) * 1E7);
|
|
mCurrentNode = mDb.createNode(osmId, osmVersion/*, status*/, lon, lat);
|
|
//Log.d(TAG, "Node: id="+osmId+" pos="+lon+","+lat);
|
|
} else if (isWay(name)) {
|
|
mCurrentWay = mDb.createWay(osmId, osmVersion/*, status*/);
|
|
//Log.d(TAG, "Way: id="+osmId);
|
|
} else if (isRelation(name)) {
|
|
mCurrentRel = mDb.createRelation(osmId, osmVersion/*, status*/);
|
|
//Log.d(TAG, "Relation: id="+osmId);
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
throw new OsmParseException("Element unparsable");
|
|
}
|
|
}
|
|
|
|
private void parseBounds(final Attributes atts) throws OsmParseException {
|
|
try {
|
|
int minlat = (int) (Double.parseDouble(atts.getValue("minlat")) * 1E7);
|
|
int maxlat = (int) (Double.parseDouble(atts.getValue("maxlat")) * 1E7);
|
|
int minlon = (int) (Double.parseDouble(atts.getValue("minlon")) * 1E7);
|
|
int maxlon = (int) (Double.parseDouble(atts.getValue("maxlon")) * 1E7);
|
|
try {
|
|
mCurrentBound = mDb.createBounds(minlon, minlat, maxlon, maxlat);
|
|
} catch (OsmException e) {
|
|
throw new OsmParseException("Bounds are not correct");
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
throw new OsmParseException("Bounds unparsable");
|
|
}
|
|
}
|
|
|
|
private void parseTag(final Attributes atts) {
|
|
OsmElement currentOsmElement = getCurrentOsmElement();
|
|
if (currentOsmElement == null) {
|
|
Log.e(TAG, "Parsing Error: no mCurrentOsmElement set!");
|
|
} else {
|
|
String k = atts.getValue("k");
|
|
String v = atts.getValue("v");
|
|
currentOsmElement.addOrUpdateTag(k, v);
|
|
//Log.d(TAG, "Tag, "+k+"="+v);
|
|
}
|
|
}
|
|
|
|
private void parseWayNode(final Attributes atts) throws OsmParseException {
|
|
try {
|
|
if (mCurrentWay == null) {
|
|
Log.e(TAG, "No mCurrentWay set!");
|
|
} else {
|
|
long nodeOsmId = Long.parseLong(atts.getValue("ref"));
|
|
OsmNode node = mDb.getNode(nodeOsmId);
|
|
mCurrentWay.addNode(node);
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
throw new OsmParseException("WayNode unparsable");
|
|
}
|
|
}
|
|
|
|
private void parseRelationElement(final Attributes atts) throws OsmParseException {
|
|
try {
|
|
if (mCurrentRel == null) {
|
|
Log.e(TAG, "No mCurrentRel set!");
|
|
} else {
|
|
String type = atts.getValue("type");
|
|
String role = atts.getValue("role");
|
|
long ref = Long.parseLong(atts.getValue("ref"));
|
|
mCurrentRel.addMember(type, role, ref, mDb.getElement(ref));
|
|
//Log.d(TAG, "Rel, type="+type+" role="+role+" ref="+ref);
|
|
}
|
|
} catch (NumberFormatException e) {
|
|
throw new OsmParseException("RelationElement unparsable");
|
|
}
|
|
}
|
|
|
|
private OsmElement getCurrentOsmElement() {
|
|
if (mCurrentNode != null) {
|
|
return mCurrentNode;
|
|
}
|
|
if (mCurrentWay != null) {
|
|
return mCurrentWay;
|
|
}
|
|
if (mCurrentRel != null) {
|
|
return mCurrentRel;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static boolean isNode(final String name) { return name.equalsIgnoreCase("node"); }
|
|
private static boolean isWay(final String name) { return name.equalsIgnoreCase("way"); }
|
|
private static boolean isWayNode(final String name) { return name.equalsIgnoreCase("nd"); }
|
|
private static boolean isBounds(final String name) { return name.equalsIgnoreCase("bounds"); }
|
|
private static boolean isRelation(final String name) { return name.equalsIgnoreCase("relation"); }
|
|
private static boolean isRelationMember(final String name) { return name.equalsIgnoreCase("member"); }
|
|
private static boolean isTag(final String name) { return name.equalsIgnoreCase("tag"); }
|
|
private static boolean isOsmElement(final String name) { return isNode(name) || isWay(name) || isRelation(name); }
|
|
}
|