X-Git-Url: https://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fload%2Fxml%2FKmlHandler.java;h=e8f2c6a463fab9d2d8eda416dacaa8e88fef175c;hb=0a2480df5845e2d7190dfdec9b2653b1609e853d;hp=09706390c03b59506781f11da5570f3f8d051bd9;hpb=5625a1abadb5f2ca5f017fe7dbda1d5141cb637b;p=GpsPrune.git diff --git a/tim/prune/load/xml/KmlHandler.java b/tim/prune/load/xml/KmlHandler.java index 0970639..e8f2c6a 100644 --- a/tim/prune/load/xml/KmlHandler.java +++ b/tim/prune/load/xml/KmlHandler.java @@ -12,12 +12,18 @@ 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 boolean _insideGxTrack = false; + private String _value = null; + private String _name = null, _desc = null; + private String _timestamp = null, _imgLink = null; private StringBuffer _coordinates = null; - private ArrayList _pointList = new ArrayList(); + 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 +31,26 @@ 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;} + tagName = tagName.toLowerCase(); + + if (tagName.equals("placemark")) + { + _coordinateList = new ArrayList(); + } + else if (tagName.equals("coordinates")) + { + _insideCoordinates = true; + _coordinates = null; + } + else if (tagName.equals("gx:track")) + { + _insideGxTrack = true; + } + _value = null; super.startElement(uri, localName, qName, attributes); } @@ -45,13 +64,45 @@ public class KmlHandler extends XmlHandler { String tagName = localName; if (tagName == null || tagName.equals("")) {tagName = qName;} - if (tagName.equalsIgnoreCase("Placemark")) + tagName = tagName.toLowerCase(); + + if (tagName.equals("placemark")) { processPlacemark(); - _insidePlacemark = false; + _name = _desc = _imgLink = _timestamp = null; + } + else if (tagName.equals("coordinates")) + { + _insideCoordinates = false; + if (_coordinates != null) _coordinateList.add(_coordinates.toString().trim()); + } + else if (tagName.equals("name")) + { + _name = _value; + } + else if (tagName.equals("description")) + { + _desc = _value; + _imgLink = getImgLink(_desc); + } + else if (tagName.equals("when")) + { + if (!_insideGxTrack) + _timestamp = _value; + else + _whenList.add(_value); + } + else if (tagName.equals("gx:coord")) + { + if (_insideGxTrack) { + _whereList.add(_value); + } + } + else if (tagName.equals("gx:track")) + { + processGxTrack(); + _insideGxTrack = false; } - else if (tagName.equalsIgnoreCase("coordinates")) _insideCoordinates = false; - else if (tagName.equalsIgnoreCase("name")) _insideName = false; super.endElement(uri, localName, qName); } @@ -63,18 +114,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,38 +137,122 @@ public class KmlHandler extends XmlHandler */ private void processPlacemark() { - if (_coordinates == null) return; - String allCoords = _coordinates.toString(); - 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, _timestamp)); + _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, 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 (!_whereList.isEmpty()) { + // If the whens don't match, then throw them all away + if (_whenList.size() != _whereList.size()) {System.out.println("clearing!"); _whenList.clear();} + // Add each of the unnamed track points to list - for (int p=0; p', 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 + * @param inDesc timestamp 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 inTimestamp) { - String[] result = new String[4]; + 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; + result[6] = inTimestamp; return result; } @@ -126,7 +262,8 @@ public class KmlHandler extends XmlHandler */ public Field[] getFieldArray() { - final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, Field.WAYPT_NAME}; + final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE, + Field.WAYPT_NAME, Field.DESCRIPTION, Field.NEW_SEGMENT, Field.TIMESTAMP}; return fields; } @@ -140,11 +277,26 @@ public class KmlHandler extends XmlHandler int numPoints = _pointList.size(); // construct data array String[][] result = new String[numPoints][]; + for (int i=0; i