X-Git-Url: http://gitweb.fperrin.net/?p=GpsPrune.git;a=blobdiff_plain;f=tim%2Fprune%2Fload%2Fxml%2FKmlHandler.java;h=47fc7213adb1d447a57e639edbb9e2aaa7c530f9;hp=787dd0bd1cfc8d1df08cdd3caeb74c471a497bcb;hb=649c5da6ee1bbc590699e11a92316ece2ea8512d;hpb=eebbb64b5d63f9eea43a0dff908c30361a376768 diff --git a/tim/prune/load/xml/KmlHandler.java b/tim/prune/load/xml/KmlHandler.java index 787dd0b..47fc721 100644 --- a/tim/prune/load/xml/KmlHandler.java +++ b/tim/prune/load/xml/KmlHandler.java @@ -12,12 +12,16 @@ import tim.prune.data.Field; */ public class KmlHandler extends XmlHandler { - private boolean _insidePlacemark = false; - private boolean _insideName = false; private boolean _insideCoordinates = false; - private String _name = null; + private String _value = null; + private String _name = null, _desc = null; + private String _imgLink = null; private StringBuffer _coordinates = null; private ArrayList _pointList = new ArrayList(); + private ArrayList _linkList = new ArrayList(); + // variables for gx extensions + private ArrayList _whenList = new ArrayList(); + private ArrayList _whereList = new ArrayList(); /** @@ -25,13 +29,12 @@ public class KmlHandler extends XmlHandler * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException + Attributes attributes) throws SAXException { String tagName = localName; if (tagName == null || tagName.equals("")) {tagName = qName;} - if (tagName.equalsIgnoreCase("Placemark")) _insidePlacemark = true; - else if (tagName.equalsIgnoreCase("coordinates")) {_insideCoordinates = true; _coordinates = null;} - else if (tagName.equalsIgnoreCase("name")) {_insideName = true; _name = null;} + if (tagName.equalsIgnoreCase("coordinates")) {_insideCoordinates = true; _coordinates = null;} + _value = null; super.startElement(uri, localName, qName, attributes); } @@ -48,10 +51,23 @@ public class KmlHandler extends XmlHandler if (tagName.equalsIgnoreCase("Placemark")) { processPlacemark(); - _insidePlacemark = false; + _name = _desc = _imgLink = null; } else if (tagName.equalsIgnoreCase("coordinates")) _insideCoordinates = false; - else if (tagName.equalsIgnoreCase("name")) _insideName = false; + else if (tagName.equalsIgnoreCase("name")) _name = _value; + else if (tagName.equalsIgnoreCase("description")) { + _desc = _value; + _imgLink = getImgLink(_desc); + } + else if (tagName.equalsIgnoreCase("when")) { + _whenList.add(_value); + } + else if (tagName.equalsIgnoreCase("gx:coord")) { + _whereList.add(_value); + } + else if (tagName.equalsIgnoreCase("gx:Track")) { + processGxTrack(); + } super.endElement(uri, localName, qName); } @@ -63,18 +79,19 @@ public class KmlHandler extends XmlHandler public void characters(char[] ch, int start, int length) throws SAXException { - if (_insidePlacemark && (_insideName || _insideCoordinates)) + String val = new String(ch, start, length); + if (_insideCoordinates) { - String value = new String(ch, start, length); - if (_insideName) {_name = value;} - else if (_insideCoordinates) - { - if (_coordinates == null) - { - _coordinates = new StringBuffer(); - } - _coordinates.append(value); + if (_coordinates == null) { + _coordinates = new StringBuffer(); } + _coordinates.append(val); + } + else + { + // Store string in _value + if (_value == null) _value = val; + else _value = _value + val; } super.characters(ch, start, length); } @@ -92,7 +109,8 @@ public class KmlHandler extends XmlHandler if (numPoints == 1) { // Add single waypoint to list - _pointList.add(makeStringArray(allCoords, _name)); + _pointList.add(makeStringArray(allCoords, _name, _desc)); + _linkList.add(_imgLink); } else if (numPoints > 1) { @@ -102,28 +120,94 @@ public class KmlHandler extends XmlHandler { if (coordArray[p] != null && coordArray[p].trim().length()>3) { - String[] pointArray = makeStringArray(coordArray[p], null); - if (firstPoint) {pointArray[4] = "1";} // start of segment flag + String[] pointArray = makeStringArray(coordArray[p], null, null); + if (firstPoint) {pointArray[5] = "1";} // start of segment flag firstPoint = false; _pointList.add(pointArray); } + _linkList.add(null); } } } + /** + * Process a Gx track including timestamps + */ + private void processGxTrack() + { + if (_whenList.size() > 0 && _whenList.size() == _whereList.size()) + { + // Add each of the unnamed track points to list + boolean firstPoint = true; + final int numPoints = _whenList.size(); + for (int p=0; p < numPoints; p++) + { + String when = _whenList.get(p); + String where = _whereList.get(p); + if (where != null) + { + String[] coords = where.split(" "); + if (coords.length == 3) + { + String[] pointArray = new String[7]; + pointArray[0] = coords[0]; + pointArray[1] = coords[1]; + pointArray[2] = coords[2]; + // leave name and description empty + if (firstPoint) {pointArray[5] = "1";} // start of segment flag + firstPoint = false; + pointArray[6] = when; // timestamp + _pointList.add(pointArray); + } + } + _linkList.add(null); + } + } + _whenList.clear(); + _whereList.clear(); + } + + /** + * Extract an image link from the point description + * @param inDesc description tag contents + * @return image link if found or null + */ + private static String getImgLink(String inDesc) + { + if (inDesc == null || inDesc.equals("")) {return null;} + // Pull out ', spos + 10); + if (spos < 0 || epos < 0) return null; + String imgtag = inDesc.substring(spos + 4, epos); + // Find the src attribute from img tag + int quotepos = imgtag.toLowerCase().indexOf("src="); + if (quotepos < 0) return null; + // source may be quoted with single or double quotes + char quotechar = imgtag.charAt(quotepos + 4); + int equotepos = imgtag.indexOf(quotechar, quotepos + 7); + if (equotepos < 0) return null; + return imgtag.substring(quotepos + 5, equotepos); + } /** * Construct the String array for the given coordinates and name * @param inCoordinates coordinate string in Kml format * @param inName name of waypoint, or null if track point + * @param inDesc description of waypoint, if any * @return String array for point */ - private static String[] makeStringArray(String inCoordinates, String inName) + private static String[] makeStringArray(String inCoordinates, + String inName, String inDesc) { - String[] result = new String[5]; + String[] result = new String[7]; String[] values = inCoordinates.split(","); - if (values.length == 3) {System.arraycopy(values, 0, result, 0, 3);} + final int numValues = values.length; + if (numValues == 3 || numValues == 2) { + System.arraycopy(values, 0, result, 0, numValues); + } result[3] = inName; + result[4] = inDesc; return result; } @@ -133,7 +217,8 @@ public class KmlHandler extends XmlHandler */ public Field[] getFieldArray() { - final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, Field.WAYPT_NAME, Field.NEW_SEGMENT}; + final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, + Field.WAYPT_NAME, Field.DESCRIPTION, Field.NEW_SEGMENT, Field.TIMESTAMP}; return fields; } @@ -147,11 +232,26 @@ public class KmlHandler extends XmlHandler int numPoints = _pointList.size(); // construct data array String[][] result = new String[numPoints][]; - for (int i=0; i