+++ /dev/null
-package tim.prune.load.xml;
-
-import java.util.ArrayList;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-import tim.prune.data.Field;
-
-
-/**
- * Class for handling specifics of parsing Kml files
- */
-public class KmlHandler extends XmlHandler
-{
- private boolean _insideCoordinates = false;
- 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<String> _coordinateList = null;
- private ArrayList<String[]> _pointList = new ArrayList<String[]>();
- private ArrayList<String> _linkList = new ArrayList<String>();
- // variables for gx extensions
- private ArrayList<String> _whenList = new ArrayList<String>();
- private ArrayList<String> _whereList = new ArrayList<String>();
-
-
- /**
- * Receive the start of a tag
- * @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
- {
- String tagName = localName;
- if (tagName == null || tagName.equals("")) {tagName = qName;}
- tagName = tagName.toLowerCase();
-
- if (tagName.equals("placemark"))
- {
- _coordinateList = new ArrayList<String>();
- }
- 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);
- }
-
-
- /**
- * Process end tag
- * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
- */
- public void endElement(String uri, String localName, String qName)
- throws SAXException
- {
- String tagName = localName;
- if (tagName == null || tagName.equals("")) {tagName = qName;}
- tagName = tagName.toLowerCase();
-
- if (tagName.equals("placemark"))
- {
- processPlacemark();
- _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;
- }
- super.endElement(uri, localName, qName);
- }
-
-
- /**
- * Process character text (inside tags or between them)
- * @see org.xml.sax.ContentHandler#characters(char[], int, int)
- */
- public void characters(char[] ch, int start, int length)
- throws SAXException
- {
- String val = new String(ch, start, length);
- if (_insideCoordinates)
- {
- 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);
- }
-
-
- /**
- * Process a placemark entry, either a single waypoint or a whole track
- */
- private void processPlacemark()
- {
- if (_coordinateList == null || _coordinateList.isEmpty()) return;
- final boolean isSingleSelection = (_coordinateList.size() == 1);
- // Loop over coordinate sets in list (may have multiple <coordinates> tags within single placemark)
- for (String coords : _coordinateList)
- {
- 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; p<numPoints; p++)
- {
- if (coordArray[p] != null && coordArray[p].trim().length()>3)
- {
- 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);
- }
- }
- }
- }
-
- /**
- * 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
- boolean firstPoint = true;
- final int numPoints = _whenList.size();
- for (int p=0; p < numPoints; p++)
- {
- String when = (_whenList.isEmpty() ? null : _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 <img tag from description (if any)
- int spos = inDesc.indexOf("<img");
- int epos = inDesc.indexOf('>', 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, String inDesc, String inTimestamp)
- {
- String[] result = new String[7];
- String[] values = inCoordinates.split(",");
- 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;
- }
-
-
- /**
- * @see tim.prune.load.xml.XmlHandler#getFieldArray()
- */
- public Field[] getFieldArray()
- {
- final Field[] fields = {Field.LONGITUDE, Field.LATITUDE, Field.ALTITUDE,
- Field.WAYPT_NAME, Field.DESCRIPTION, Field.NEW_SEGMENT, Field.TIMESTAMP};
- return fields;
- }
-
-
- /**
- * Return the parsed information as a 2d array
- * @see tim.prune.load.xml.XmlHandler#getDataArray()
- */
- public String[][] getDataArray()
- {
- int numPoints = _pointList.size();
- // construct data array
- String[][] result = new String[numPoints][];
- for (int i=0; i<numPoints; i++) {
- result[i] = _pointList.get(i);
- }
- return result;
- }
-
- /**
- * @return array of links, or null if none
- */
- public String[] getLinkArray()
- {
- int numPoints = _linkList.size();
- boolean hasLink = false;
- String[] result = new String[numPoints];
- for (int i=0; i<numPoints; i++)
- {
- result[i] = _linkList.get(i);
- if (result[i] != null) {hasLink = true;}
- }
- if (!hasLink) {result = null;}
- return result;
- }
-}