X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fload%2Fxml%2FKmlHandler.java;h=2ddd1cdb4aeb402c4b263d9cb2c14c2d90d20de1;hb=f1b92378a792131ac8fb33a869405851d5b2d1f7;hp=787dd0bd1cfc8d1df08cdd3caeb74c471a497bcb;hpb=112bb0c9b46894adca9a33ed8c99ea712b253185;p=GpsPrune.git diff --git a/tim/prune/load/xml/KmlHandler.java b/tim/prune/load/xml/KmlHandler.java index 787dd0b..2ddd1cd 100644 --- a/tim/prune/load/xml/KmlHandler.java +++ b/tim/prune/load/xml/KmlHandler.java @@ -12,12 +12,17 @@ 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 _coordinateList = 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 +30,18 @@ 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("Placemark")) { + _coordinateList = new ArrayList(); + } + else if (tagName.equalsIgnoreCase("coordinates")) { + _insideCoordinates = true; + _coordinates = null; + } + _value = null; super.startElement(uri, localName, qName, attributes); } @@ -48,10 +58,26 @@ public class KmlHandler extends XmlHandler if (tagName.equalsIgnoreCase("Placemark")) { processPlacemark(); - _insidePlacemark = false; + _name = _desc = _imgLink = null; + } + else if (tagName.equalsIgnoreCase("coordinates")) { + _insideCoordinates = false; + if (_coordinates != null) _coordinateList.add(_coordinates.toString().trim()); + } + 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(); } - else if (tagName.equalsIgnoreCase("coordinates")) _insideCoordinates = false; - else if (tagName.equalsIgnoreCase("name")) _insideName = false; super.endElement(uri, localName, qName); } @@ -63,18 +89,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); } @@ -85,45 +112,117 @@ public class KmlHandler extends XmlHandler */ private void processPlacemark() { - if (_coordinates == null) return; - String allCoords = _coordinates.toString().trim(); - String[] coordArray = allCoords.split("[ \n]"); - int numPoints = coordArray.length; - if (numPoints == 1) + if (_coordinateList == null || _coordinateList.isEmpty()) return; + final boolean isSingleSelection = (_coordinateList.size() == 1); + // Loop over coordinate sets in list (may have multiple tags within single placemark) + for (String coords : _coordinateList) { - // Add single waypoint to list - _pointList.add(makeStringArray(allCoords, _name)); + String[] coordArray = coords.split("[ \n]"); + int numPoints = coordArray.length; + if (numPoints == 1) + { + // Add single point to list + final String name = (isSingleSelection ? _name : null); + _pointList.add(makeStringArray(coords, name, _desc)); + _linkList.add(_imgLink); + } + else if (numPoints > 1) + { + // Add each of the unnamed track points to list + boolean firstPoint = true; + for (int p=0; p3) + { + String[] pointArray = makeStringArray(coordArray[p], null, null); + if (firstPoint) {pointArray[5] = "1";} // start of segment flag + firstPoint = false; + _pointList.add(pointArray); + } + _linkList.add(null); + } + } } - else if (numPoints > 1) + } + + /** + * 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; - for (int p=0; p3) + String when = _whenList.get(p); + String where = _whereList.get(p); + if (where != null) { - String[] pointArray = makeStringArray(coordArray[p], null); - if (firstPoint) {pointArray[4] = "1";} // start of segment flag - firstPoint = false; - _pointList.add(pointArray); + 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 +232,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 +247,26 @@ public class KmlHandler extends XmlHandler int numPoints = _pointList.size(); // construct data array String[][] result = new String[numPoints][]; - for (int i=0; i