❤️JAVA写入与读取GPX文件工具类❤️
根据实际情况自定义这个三个实体类的名称和属性
1、TrackPoint类
import java.util.Date;
/**
* @Author: LEAVES
* @Version 1.0
* @Date: 2021年10月08日 10时18分56秒
* @Description: 每一个点的信息属性【其对应接收GPX中标签属性值】
*/
public class TrackPoint {
private double latitude;
private double longitude;
private Double elevation;
private Date time;
public TrackPoint() {
}
public TrackPoint(double latitude, double longitude, Double elevation, Date time) {
this.latitude = latitude;
this.longitude = longitude;
this.elevation = elevation;
this.time = time;
}
public double getLatitude() {
return this.latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getLongitude() {
return this.longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public Double getElevation() {
return this.elevation;
}
public void setElevation(Double elevation) {
this.elevation = elevation;
}
public Date getTime() {
return this.time;
}
public void setTime(Date time) {
this.time = time;
}
public double distanceTo(TrackPoint point) {
boolean r = true;
double latDistance = Math.toRadians(point.latitude - this.latitude);
double lonDistance = Math.toRadians(point.longitude - this.longitude);
double a = Math.sin(latDistance / 2.0D) * Math.sin(latDistance / 2.0D) + Math.cos(Math.toRadians(this.latitude)) * Math.cos(Math.toRadians(point.latitude)) * Math.sin(lonDistance / 2.0D) * Math.sin(lonDistance / 2.0D);
double c = 2.0D * Math.atan2(Math.sqrt(a), Math.sqrt(1.0D - a));
double distance = 6371.0D * c * 1000.0D;
if (point.elevation != null && this.elevation != null) {
double height = point.elevation - this.elevation;
distance = Math.pow(distance, 2.0D) + Math.pow(height, 2.0D);
}
return Math.sqrt(distance);
}
}
2、TrackSegment类
import java.util.ArrayList;
import java.util.List;
/**
* @Author: LEAVES
* @Version 1.0
* @Date: 2021年10月08日 10时55分37秒
* @Description: 每个点的集合【一段轨迹】
*/
public class TrackSegment {
private List<TrackPoint> points;
public TrackSegment() {
this.points = new ArrayList();
}
public TrackSegment(List<TrackPoint> points) {
this.points = points;
}
public void addTrackPoint(TrackPoint point) {
this.points.add(point);
}
public void removeTrackPoint(int index) {
this.points.remove(index);
}
public void clearTrackPoints() {
this.points.clear();
}
public List<TrackPoint> getPoints() {
return this.points;
}
public void setPoints(List<TrackPoint> points) {
this.points = points;
}
}
3、Track类
import java.util.ArrayList;
import java.util.List;
/**
* @Author: LEAVES
* @Version 1.0
* @Date: 2021年10月08日 11时18分47秒
* @Description: 整个轨迹信息
*/
public class Track {
private List<TrackSegment> segments;
public Track() {
this.segments = new ArrayList();
}
public Track(List<TrackSegment> segments) {
this.segments = segments;
}
public void addTrackSegment(TrackSegment segment) {
this.segments.add(segment);
}
public void removeTrackSegment(int index) {
this.segments.remove(index);
}
public void clearTrackSegments() {
this.segments.clear();
}
public List<TrackSegment> getSegments() {
return this.segments;
}
public void setSegments(List<TrackSegment> segments) {
this.segments = segments;
}
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Locale;
/**
* @Author: LEAVES
* @Version 1.0
* @Date: 2021年10月08日 14时10分32秒
* @Description: 写入GPX文件工具类
*/
public class GpxWriter {
private static final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
private final File gpxFile;
public GpxWriter(String path) {
this.gpxFile = new File(path);
if (this.gpxFile.isDirectory()) {
throw new RuntimeException("The given file is a directory.");
}
}
/**
* 写入GPX数据
*
* 标准的gpx就是下面这些标签名称,如有特殊请自行添加或修改
*
* @param track
*/
public void writeData(Track track) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
String coordsFormat = "%.7f";
String var5 = "%.1f";
try {
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
Document document = docBuilder.newDocument();
Element rootElement = document.createElement("gpx");
document.appendChild(rootElement);
Element trk = document.createElement("trk");
rootElement.appendChild(trk);
track.getSegments().forEach((s) -> {
Element trkseg = document.createElement("trkseg");
trk.appendChild(trkseg);
s.getPoints().forEach((p) -> {
Element trkpt = document.createElement("trkpt");
trkpt.setAttribute("lat", String.format(Locale.ROOT, "%.7f", p.getLatitude()));
trkpt.setAttribute("lon", String.format(Locale.ROOT, "%.7f", p.getLongitude()));
Element time;
if (p.getElevation() != null) {
time = document.createElement("ele");
time.setTextContent(String.format(Locale.ROOT, "%.1f", p.getElevation()));
trkpt.appendChild(time);
}
if (p.getTime() != null) {
time = document.createElement("time");
time.setTextContent(sdf1.format(p.getTime()));
trkpt.appendChild(time);
}
trkseg.appendChild(trkpt);
});
});
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty("indent", "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(document);
StreamResult console = new StreamResult(System.out);
StreamResult file = new StreamResult(this.gpxFile);
transformer.transform(source, console);
transformer.transform(source, file);
} catch (TransformerException | ParserConfigurationException var13) {
var13.printStackTrace();
}
}
}
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* @Author: LEAVES
* @Version 1.0
* @Date: 2021年10月08日 15时26分57秒
* @Description: 读取GPX文件工具类
*
* 参照JAVA读取XML文档的方法读取GPX文件
*/
public class GpxReader {
//这里时间格式根据GPX文件中的时间格式来选择确定
private static final SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static final SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
private static final SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
private final File gpxFile;
public GpxReader(String path) {
this.gpxFile = new File(path);
if (!this.gpxFile.exists()) {
throw new RuntimeException("File " + path + "does not exist.");
} else if (this.gpxFile.isDirectory()) {
throw new RuntimeException("The given file is a directory.");
}
}
/**
* 读取轨迹数据
*
* 标准的gpx就是下面这些标签名称,如有特殊请自行添加或修改
*
* @return
*/
public Track readData() {
Track track = new Track();
try {
//1、得到 DOM 解析器的工厂实例
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//2、然后从 DOM 工厂获得 DOM 解析器
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
//3、把要解析的 GPX 文档转化为输入流,以便 DOM 解析器解析它
Document document = dBuilder.parse(this.gpxFile);
//4、找出每个字节点(也可以理解其为根节点)
//获取指定节点
//需要的数据都在trk标签中
NodeList trk = document.getElementsByTagName("trk");
for (int i = 0; i < trk.getLength(); ++i) {
Node trkItem = trk.item(i);
if (trkItem.getNodeName().equals("trk")) {
NodeList trkSegments = trkItem.getChildNodes();
for (int j = 0; j < trkSegments.getLength(); ++j) {
Node trkSegment = trkSegments.item(j);
if (trkSegment.getNodeName().equals("trkseg")) {
TrackSegment segment = new TrackSegment();
track.addTrackSegment(segment);
//获取其对应字节点
NodeList trkPts = trkSegment.getChildNodes();
for (int k = 0; k < trkPts.getLength(); ++k) {
Node trkPt = trkPts.item(k);
String nodename = trkPt.getNodeName();
if (trkPt.getNodeName().equals("trkpt")) {
Element element = (Element) trkPt;
double lat = Double.parseDouble(element.getAttribute("lat"));
double lon = Double.parseDouble(element.getAttribute("lon"));
Double ele = null;
String time = null;
//获取其对应字节点
List<Node> nodes = toNodeList(element.getChildNodes());
Optional<Node> elev = nodes.stream().filter((e) -> {
return e.getNodeName().equals("ele");
}).findFirst();
if (elev.isPresent()) {
ele = Double.parseDouble(((Node) elev.get()).getTextContent());
}
Optional<Node> timeNode = nodes.stream().filter((e) -> {
return e.getNodeName().equals("time");
}).findFirst();
if (timeNode.isPresent()) {
time = ((Node) timeNode.get()).getTextContent();
}
segment.addTrackPoint(new TrackPoint(lat, lon, ele, this.parseDate(time)));
}
}
}
}
}
}
} catch (IOException | ParserConfigurationException | SAXException var26) {
var26.printStackTrace();
}
return track;
}
private static List<Node> toNodeList(NodeList nodeList) {
List<Node> nodes = new ArrayList();
for (int i = 0; i < nodeList.getLength(); ++i) {
nodes.add(nodeList.item(i));
}
return nodes;
}
private Date parseDate(String value) {
Date date = null;
try {
date = sdf1.parse(value);
} catch (ParseException var5) {
}
return date;
}
}
2、读取实现
public static void main(String[] args) {
String path = "D:\\test\\轨迹_20211007_134948.gpx";
GpxReader gpxFileReader = new GpxReader(path);
Track track = gpxFileReader.readData();
List<TrackSegment> segments = track.getSegments();
segments.forEach(x -> {
List<TrackPoint> points = x.getPoints();
points.forEach(y -> {
System.out.println("======================" );
double longitude = y.getLongitude();
System.out.println("经度 = " + longitude);
double latitude = y.getLatitude();
System.out.println("纬度 = " + latitude);
Double elevation = y.getElevation();
System.out.println("海拔 = " + elevation);
Date time = y.getTime();
System.out.println("时间 = " + time);
});
});
}