使用 SAX 解析器或 XmlPullParser 解析 GPX 文件

发布于 2025-01-08 11:52:03 字数 334 浏览 2 评论 0原文

我的应用程序创建了许多 gpx 文件,需要在应用程序的稍后阶段进行解析。 一般来说,我在解析它们时遇到困难。我在这个网站和其他网站上看到了很多解析器的示例,但它们都使用 TracksTrakcPoints 等对象,但找不到这些类包含的内容。我真的希望能够解析该文件并将其排序到 LocationArrayList 中。我需要从文件中获取经度和纬度以及时间和海拔。

有人可以帮我解决这个问题吗? 我不介意使用 SAX 解析器Xml pull 解析器 或其他方法。

I have a number of gpx files that my app creates and will need to parse at a later stage in the app.
I'm having trouble parsing them in general. I've seen alot of examples of parsers on this site and others but they all use objects like Tracksand TrakcPoints but what these classes contain can't be found. I would really like just to be able to parse the file and sort it into an ArrayList of Location. I will need to get the long and lat from the file as well as the time and elevation.

Can some one help me with this problem?
I don't mind if use SAX parser or an Xml pull parseror another method of doing it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

锦欢 2025-01-15 11:52:03

想通了,可能不是最优雅的方式,但它有效

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.location.Location;


public class GpxReader
{
private static final SimpleDateFormat gpxDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

public static List<Location> getPoints(File gpxFile)
{
    List<Location> points = null;
    try
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        FileInputStream fis = new FileInputStream(gpxFile);
        Document dom = builder.parse(fis);
        Element root = dom.getDocumentElement();
        NodeList items = root.getElementsByTagName("trkpt");

        points = new ArrayList<Location>();

        for(int j = 0; j < items.getLength(); j++)
        {
            Node item = items.item(j);
            NamedNodeMap attrs = item.getAttributes();
            NodeList props = item.getChildNodes();

            Location pt = new Location("test");

            pt.setLatitude(Double.parseDouble(attrs.getNamedItem("lat").getTextContent()));
            pt.setLongitude(Double.parseDouble(attrs.getNamedItem("lon").getTextContent()));

            for(int k = 0; k<props.getLength(); k++)
            {
                Node item2 = props.item(k);
                String name = item2.getNodeName();
                if(!name.equalsIgnoreCase("time")) continue;
                try
                {
                    pt.setTime((getDateFormatter().parse(item2.getFirstChild().getNodeValue())).getTime());
                }

                catch(ParseException ex)
                {
                    ex.printStackTrace();
                }
            }

            for(int y = 0; y<props.getLength(); y++)
            {
                Node item3 = props.item(y);
                String name = item3.getNodeName();
                if(!name.equalsIgnoreCase("ele")) continue;
                pt.setAltitude(Double.parseDouble(item3.getFirstChild().getNodeValue()));
            }

            points.add(pt);

        }

        fis.close();
    }

    catch(FileNotFoundException e)
    {
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    catch(ParserConfigurationException ex)
    {

    }

    catch (SAXException ex) {
    }

    return points;
}

public static SimpleDateFormat getDateFormatter()
  {
    return (SimpleDateFormat)gpxDate.clone();
  }

}

希望这可以帮助一些人

Figured it out, might not be the most elegant way of doing it but it works

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.location.Location;


public class GpxReader
{
private static final SimpleDateFormat gpxDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

public static List<Location> getPoints(File gpxFile)
{
    List<Location> points = null;
    try
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();

        FileInputStream fis = new FileInputStream(gpxFile);
        Document dom = builder.parse(fis);
        Element root = dom.getDocumentElement();
        NodeList items = root.getElementsByTagName("trkpt");

        points = new ArrayList<Location>();

        for(int j = 0; j < items.getLength(); j++)
        {
            Node item = items.item(j);
            NamedNodeMap attrs = item.getAttributes();
            NodeList props = item.getChildNodes();

            Location pt = new Location("test");

            pt.setLatitude(Double.parseDouble(attrs.getNamedItem("lat").getTextContent()));
            pt.setLongitude(Double.parseDouble(attrs.getNamedItem("lon").getTextContent()));

            for(int k = 0; k<props.getLength(); k++)
            {
                Node item2 = props.item(k);
                String name = item2.getNodeName();
                if(!name.equalsIgnoreCase("time")) continue;
                try
                {
                    pt.setTime((getDateFormatter().parse(item2.getFirstChild().getNodeValue())).getTime());
                }

                catch(ParseException ex)
                {
                    ex.printStackTrace();
                }
            }

            for(int y = 0; y<props.getLength(); y++)
            {
                Node item3 = props.item(y);
                String name = item3.getNodeName();
                if(!name.equalsIgnoreCase("ele")) continue;
                pt.setAltitude(Double.parseDouble(item3.getFirstChild().getNodeValue()));
            }

            points.add(pt);

        }

        fis.close();
    }

    catch(FileNotFoundException e)
    {
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    catch(ParserConfigurationException ex)
    {

    }

    catch (SAXException ex) {
    }

    return points;
}

public static SimpleDateFormat getDateFormatter()
  {
    return (SimpleDateFormat)gpxDate.clone();
  }

}

Hope this helps some people

×眷恋的温暖 2025-01-15 11:52:03

使用 SAX:
GpxImportActivity.java

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;

public class GpxImportActivity extends Activity {
private String fileName ="gpsTrack.gpx";
private File sdCard;
private List<Location> locationList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gpx_import);

    locationList = new ArrayList<Location>();

    sdCard = Environment.getExternalStorageDirectory();     
    if (!sdCard.exists() || !sdCard.canRead()) {
        Log.d("GpxImportActivity", "SD-Card not available or not readable");
        finish();
    }
    boolean availableFile = new File(sdCard, fileName).exists();
    if (!availableFile) {
        Log.d("GpxImportActivity", "File \"" +fileName+ "\" not available");
        finish();
    } else {
        Log.d("GpxImportActivity", "File \"" +fileName+ "\" found");
    }

    try {
    System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
    /*
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(true);
    spf.setValidating(false);
    SAXParser saxParser = spf.newSAXParser();
    XMLReader xmlReader = saxParser.getXMLReader();
    */      
    GpxFileContentHandler gpxFileContentHandler = new GpxFileContentHandler();
    xmlReader.setContentHandler(gpxFileContentHandler);

    FileReader fileReader = new FileReader(new File(sdCard,fileName));
    InputSource inputSource = new InputSource(fileReader);          
    xmlReader.parse(inputSource);

    locationList = gpxFileContentHandler.getLocationList(); 

    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.gpx_import, menu);
    return true;
    }
}

GpxFileContentHandler.java

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import android.location.Location;

public class GpxFileContentHandler implements ContentHandler {
    private String currentValue;
    private Location location;
    private List<Location> locationList;
    private final SimpleDateFormat GPXTIME_SIMPLEDATEFORMAT = new SimpleDateFormat(
        "yyyy-MM-dd'T'HH:mm:ss'Z'");

    public GpxFileContentHandler() {
        locationList = new ArrayList<Location>();
    }

    public List<Location> getLocationList() {
        return locationList;
    }

    @Override
    public void startElement(String uri, String localName, String qName,
        Attributes atts) throws SAXException {

        if (localName.equalsIgnoreCase("trkpt")) {
            location = new Location("gpxImport");
            location.setLatitude(Double.parseDouble(atts.getValue("lat").trim()));
            location.setLongitude(Double.parseDouble(atts.getValue("lon").trim()));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
        throws SAXException {
        if (localName.equalsIgnoreCase("ele")) {
            location.setAltitude(Double.parseDouble(currentValue.trim()));
        }

        if (localName.equalsIgnoreCase("time")) {
            try {
            Date date = GPXTIME_SIMPLEDATEFORMAT.parse(currentValue.trim());
            Long time = date.getTime();
            location.setTime(time);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (localName.equalsIgnoreCase("trkpt")) {
            locationList.add(location);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
        throws SAXException {
        currentValue = new String(ch, start, length);
    }

    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length)
        throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void processingInstruction(String target, String data)
        throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        // TODO Auto-generated method stub
    }

    @Override
    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
        public void startPrefixMapping(String prefix, String uri)
            throws SAXException {
            // TODO Auto-generated method stub
    }

}

with SAX:
GpxImportActivity.java

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;

public class GpxImportActivity extends Activity {
private String fileName ="gpsTrack.gpx";
private File sdCard;
private List<Location> locationList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gpx_import);

    locationList = new ArrayList<Location>();

    sdCard = Environment.getExternalStorageDirectory();     
    if (!sdCard.exists() || !sdCard.canRead()) {
        Log.d("GpxImportActivity", "SD-Card not available or not readable");
        finish();
    }
    boolean availableFile = new File(sdCard, fileName).exists();
    if (!availableFile) {
        Log.d("GpxImportActivity", "File \"" +fileName+ "\" not available");
        finish();
    } else {
        Log.d("GpxImportActivity", "File \"" +fileName+ "\" found");
    }

    try {
    System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
    /*
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(true);
    spf.setValidating(false);
    SAXParser saxParser = spf.newSAXParser();
    XMLReader xmlReader = saxParser.getXMLReader();
    */      
    GpxFileContentHandler gpxFileContentHandler = new GpxFileContentHandler();
    xmlReader.setContentHandler(gpxFileContentHandler);

    FileReader fileReader = new FileReader(new File(sdCard,fileName));
    InputSource inputSource = new InputSource(fileReader);          
    xmlReader.parse(inputSource);

    locationList = gpxFileContentHandler.getLocationList(); 

    } catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.gpx_import, menu);
    return true;
    }
}

GpxFileContentHandler.java

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import android.location.Location;

public class GpxFileContentHandler implements ContentHandler {
    private String currentValue;
    private Location location;
    private List<Location> locationList;
    private final SimpleDateFormat GPXTIME_SIMPLEDATEFORMAT = new SimpleDateFormat(
        "yyyy-MM-dd'T'HH:mm:ss'Z'");

    public GpxFileContentHandler() {
        locationList = new ArrayList<Location>();
    }

    public List<Location> getLocationList() {
        return locationList;
    }

    @Override
    public void startElement(String uri, String localName, String qName,
        Attributes atts) throws SAXException {

        if (localName.equalsIgnoreCase("trkpt")) {
            location = new Location("gpxImport");
            location.setLatitude(Double.parseDouble(atts.getValue("lat").trim()));
            location.setLongitude(Double.parseDouble(atts.getValue("lon").trim()));
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
        throws SAXException {
        if (localName.equalsIgnoreCase("ele")) {
            location.setAltitude(Double.parseDouble(currentValue.trim()));
        }

        if (localName.equalsIgnoreCase("time")) {
            try {
            Date date = GPXTIME_SIMPLEDATEFORMAT.parse(currentValue.trim());
            Long time = date.getTime();
            location.setTime(time);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if (localName.equalsIgnoreCase("trkpt")) {
            locationList.add(location);
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
        throws SAXException {
        currentValue = new String(ch, start, length);
    }

    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void ignorableWhitespace(char[] ch, int start, int length)
        throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void processingInstruction(String target, String data)
        throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
    public void setDocumentLocator(Locator locator) {
        // TODO Auto-generated method stub
    }

    @Override
    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub
    }

    @Override
        public void startPrefixMapping(String prefix, String uri)
            throws SAXException {
            // TODO Auto-generated method stub
    }

}
时光病人 2025-01-15 11:52:03

即用型、开源且功能齐全的 java GpxParser(以及更多)在这里
https://sourceforge.net/projects/geokarambola/

详细信息请参见此处
https://plus.google.com/u/0/communities/110606810455751902142

使用上述库解析 GPX 文件是一件简单的事情:

Gpx gpx = GpxFileIo.parseIn( "SomeGeoCollection.gpx" ) ;

获取其点、路线或轨迹是微不足道的太:

ArrayList<Route> routes = gpx.getRoutes( ) ;
Route route = routes.get(0) ; // First route.

然后你可以迭代路线的点并直接获取它们的纬度/经度/海拔高度

for(RoutePoint rtePt: route.getRoutePoints( ))
  Location loc = new Location( rtePt.getLatitude( ), rtePt.getLongitude( ) ) ;

Ready to use, open source, and fully functional java GpxParser (and much more) here
https://sourceforge.net/projects/geokarambola/

Details here
https://plus.google.com/u/0/communities/110606810455751902142

With the above library parsing a GPX file is a one liner:

Gpx gpx = GpxFileIo.parseIn( "SomeGeoCollection.gpx" ) ;

Getting its points, routes or tracks trivial too:

ArrayList<Route> routes = gpx.getRoutes( ) ;
Route route = routes.get(0) ; // First route.

Then you can iterate the route's points and get their lat/lon/ele directly

for(RoutePoint rtePt: route.getRoutePoints( ))
  Location loc = new Location( rtePt.getLatitude( ), rtePt.getLongitude( ) ) ;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文