OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / sdk / ddms / libs / ddmuilib / src / com / android / ddmuilib / location / KmlParser.java
diff --git a/sdk/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java b/sdk/ddms/libs/ddmuilib/src/com/android/ddmuilib/location/KmlParser.java
new file mode 100644 (file)
index 0000000..af485ac
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ddmuilib.location;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+/**
+ * A very basic KML parser to meet the need of the emulator control panel.
+ * <p/>
+ * It parses basic Placemark information.
+ */
+public class KmlParser {
+    
+    private final static String NS_KML_2 = "http://earth.google.com/kml/2.";  //$NON-NLS-1$
+        
+    private final static String NODE_PLACEMARK = "Placemark"; //$NON-NLS-1$
+    private final static String NODE_NAME = "name"; //$NON-NLS-1$
+    private final static String NODE_COORDINATES = "coordinates"; //$NON-NLS-1$
+    
+    private final static Pattern sLocationPattern = Pattern.compile("([^,]+),([^,]+)(?:,([^,]+))?");
+    
+    private static SAXParserFactory sParserFactory;
+    
+    static {
+        sParserFactory = SAXParserFactory.newInstance();
+        sParserFactory.setNamespaceAware(true);
+    }
+
+    private String mFileName;
+
+    private KmlHandler mHandler;
+    
+    /**
+     * Handler for the SAX parser.
+     */
+    private static class KmlHandler extends DefaultHandler {
+        // --------- parsed data --------- 
+        List<WayPoint> mWayPoints;
+        
+        // --------- state for parsing --------- 
+        WayPoint mCurrentWayPoint;
+        final StringBuilder mStringAccumulator = new StringBuilder();
+
+        boolean mSuccess = true;
+
+        @Override
+        public void startElement(String uri, String localName, String name, Attributes attributes)
+                throws SAXException {
+            // we only care about the standard GPX nodes.
+            try {
+                if (uri.startsWith(NS_KML_2)) {
+                    if (NODE_PLACEMARK.equals(localName)) {
+                        if (mWayPoints == null) {
+                            mWayPoints = new ArrayList<WayPoint>();
+                        }
+                        
+                        mWayPoints.add(mCurrentWayPoint = new WayPoint());
+                    }
+                }
+            } finally {
+                // no matter the node, we empty the StringBuilder accumulator when we start
+                // a new node.
+                mStringAccumulator.setLength(0);
+            }
+        }
+
+        /**
+         * Processes new characters for the node content. The characters are simply stored,
+         * and will be processed when {@link #endElement(String, String, String)} is called.
+         */
+        @Override
+        public void characters(char[] ch, int start, int length) throws SAXException {
+            mStringAccumulator.append(ch, start, length);
+        }
+        
+        @Override
+        public void endElement(String uri, String localName, String name) throws SAXException {
+            if (uri.startsWith(NS_KML_2)) {
+                if (NODE_PLACEMARK.equals(localName)) {
+                    mCurrentWayPoint = null;
+                } else if (NODE_NAME.equals(localName)) {
+                    if (mCurrentWayPoint != null) {
+                        mCurrentWayPoint.setName(mStringAccumulator.toString());
+                    }
+                } else if (NODE_COORDINATES.equals(localName)) {
+                    if (mCurrentWayPoint != null) {
+                        parseLocation(mCurrentWayPoint, mStringAccumulator.toString());
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void error(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+
+        @Override
+        public void fatalError(SAXParseException e) throws SAXException {
+            mSuccess = false;
+        }
+        
+        /**
+         * Parses the location string and store the information into a {@link LocationPoint}.
+         * @param locationNode the {@link LocationPoint} to receive the location data.
+         * @param location The string containing the location info.
+         */
+        private void parseLocation(LocationPoint locationNode, String location) {
+            Matcher m = sLocationPattern.matcher(location);
+            if (m.matches()) {
+                try {
+                    double longitude = Double.parseDouble(m.group(1));
+                    double latitude = Double.parseDouble(m.group(2));
+                    
+                    locationNode.setLocation(longitude, latitude);
+                    
+                    if (m.groupCount() == 3) {
+                        // looks like we have elevation data.
+                        locationNode.setElevation(Double.parseDouble(m.group(3)));
+                    }
+                } catch (NumberFormatException e) {
+                    // wrong data, do nothing.
+                }
+            }
+        }
+        
+        WayPoint[] getWayPoints() {
+            if (mWayPoints != null) {
+                return mWayPoints.toArray(new WayPoint[mWayPoints.size()]);
+            }
+
+            return null;
+        }
+
+        boolean getSuccess() {
+            return mSuccess;
+        }
+    }
+
+    /**
+     * Creates a new GPX parser for a file specified by its full path.
+     * @param fileName The full path of the GPX file to parse.
+     */
+    public KmlParser(String fileName) {
+        mFileName = fileName;
+    }
+
+    /**
+     * Parses the GPX file.
+     * @return <code>true</code> if success.
+     */
+    public boolean parse() {
+        try {
+            SAXParser parser = sParserFactory.newSAXParser();
+
+            mHandler = new KmlHandler();
+
+            parser.parse(new InputSource(new FileReader(mFileName)), mHandler);
+            
+            return mHandler.getSuccess();
+        } catch (ParserConfigurationException e) {
+        } catch (SAXException e) {
+        } catch (IOException e) {
+        } finally {
+        }
+
+        return false;
+    }
+    
+    /**
+     * Returns the parsed {@link WayPoint} objects, or <code>null</code> if none were found (or
+     * if the parsing failed.
+     */
+    public WayPoint[] getWayPoints() {
+        if (mHandler != null) {
+            return mHandler.getWayPoints();
+        }
+        
+        return null;
+    }
+}