Java解析OpenDrive,OpenDrive格式解析
Posted 爱是与世界平行
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java解析OpenDrive,OpenDrive格式解析相关的知识,希望对你有一定的参考价值。
1 介绍
项目地址:https://gitee.com/AiShiYuShiJiePingXing/open-drive-convert
分支:dev
找了很多笔记和参考资料,解析OpenDrive得很多开源项目几乎都是C++或者Python做的,奈何那两块都没那么熟悉,只能通过Java实现了,参考了一个项目,实现了Java解析OpenDrive。
1.1 运行
clone项目:
git clone -b dev https://gitee.com/AiShiYuShiJiePingXing/open-drive-convert.git
找到/src/main/java/OpenDriveConvert.java
修改openDrivePath
得路径,运行main方法即可完成测试。
2 Java解析OpenDrive
2.1 pom.xml
先添加几个依赖,下酒菜。
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.69</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0</version>
</dependency>
</dependencies>
2.2 读取本地xodr文件
public static String readFromFile(String xodrPath)
log.info("OpenDRIVE地图文件路径:", xodrPath);
//xodrPath:eg:D://project//test.xodr
String xodrStr = null;
try
xodrStr = FileUtils.readFileToString(new File(xodrPath), "UTF-8");
catch (IOException e)
e.printStackTrace();
return xodrStr;
2.3 开始解析Map
public static MapDataContainer parse(String input)
log.info("开始解析地图...");
List<Road> roads = new ArrayList<>();
List<Junction> junctions = new ArrayList<>();
List<LaneSection> laneSections = new ArrayList<>();
List<Lane> lanes = new ArrayList<>();
List<Connection> connections = new ArrayList<>();
List<LaneLink> laneLinks = new ArrayList<>();
roadMap = new HashMap<>();
laneSectionMap = new HashMap<>();
laneMap = new HashMap<>();
junctionMap = new HashMap<>();
laneSectionId = 0;
laneSingleId = 0;
roadIndex = 0;
laneSectionIndex = 0;
laneIndex = 0;
junctionIndex = 0;
connectionIndex = 0;
laneLinkIndex = 0;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document document = documentBuilder.parse(new InputSource(new StringReader(input)));
Element root = document.getDocumentElement();
// 1. 解析road及子元素
NodeList roadList = root.getElementsByTagName("road");
parseRoad(roadList, roads, laneSections, lanes);
// 2. 解析junction及子元素
NodeList junctionList = root.getElementsByTagName("junction");
parseJunction(junctionList, junctions, connections, laneLinks);
// 3. 初始化index; 初始化connection的direction
initIndex(roads, laneSections, lanes, junctions, connections, laneLinks);
log.info("解析地图完成!");
return new MapDataContainer(roads, junctions, laneSections, lanes, connections, laneLinks);
catch (ParserConfigurationException | SAXException | IOException e)
e.printStackTrace();
log.error("解析OpenDRIVE文件时发生错误!");
return null;
2.4 解析Road
private static void parseRoad(NodeList roadList, List<Road> roads, List<LaneSection> laneSections, List<Lane> lanes)
try
for (int i = 0; i < roadList.getLength(); i++)
Element roadElement = (Element) roadList.item(i);
Road road = new Road();
// int elementType;
road.setElementType(ElementType.ROAD.getValue());
// int roadId;
int roadId = Integer.parseInt(roadElement.getAttribute("id"));
road.setRoadId(roadId);
road.setIndex(roadIndex); // 初始化index
roadMap.put(roadId, roadIndex++);
// int junctionId;
int junctionId = Integer.parseInt(roadElement.getAttribute("junction"));
road.setJunctionId(junctionId);
// int length;
double length = Double.parseDouble(roadElement.getAttribute("length"));
road.setLength(length);
// int predecessorElementType;
// int successorElementType;
int predecessorId = -1;
int successorId = -1;
ElementType predecessorElementType = ElementType.NONE;
ElementType successorElementType = ElementType.NONE;
NodeList linkList = roadElement.getElementsByTagName("link");
Element myLinkList = (Element) linkList.item(0);
NodeList predecessorList = null, successorList = null;
if (myLinkList != null)
predecessorList = myLinkList.getElementsByTagName("predecessor");
successorList = myLinkList.getElementsByTagName("successor");
if (predecessorList != null)
Element predecessor = (Element) predecessorList.item(0);
if (predecessor != null)
String elementId = predecessor.getAttribute("elementId");
String elementType = predecessor.getAttribute("elementType");
if (elementId != null && elementType != null && elementId.length() != 0 && elementType.length() != 0)
predecessorId = Integer.parseInt(elementId);
predecessorElementType = elementType.equalsIgnoreCase("junction")
? ElementType.JUNCTION : ElementType.ROAD;
road.setPredecessorElementType(predecessorElementType.getValue());
road.setPredecessorElementType(predecessorElementType.getValue());
road.setPredecessorId(predecessorId);
if (successorList != null)
Element successor = (Element) successorList.item(0);
if (successor != null)
String elementId = successor.getAttribute("elementId");
String elementType = successor.getAttribute("elementType");
if (elementId != null && elementType != null && elementId.length() != 0 && elementType.length() != 0)
successorId = Integer.parseInt(elementId);
successorElementType = elementType.equalsIgnoreCase("junction")
? ElementType.JUNCTION : ElementType.ROAD;
road.setSuccessorElementType(successorElementType.getValue());
road.setSuccessorId(successorId);
// int maxSpeed;
NodeList typeNodeList = roadElement.getElementsByTagName("type");
if (typeNodeList != null)
Element typeElement = (Element) typeNodeList.item(0);
if (typeElement != null)
NodeList speedNodeList = typeElement.getElementsByTagName("speed");
if (speedNodeList != null)
Element speedElement = (Element) speedNodeList.item(0);
double maxSpeed = Double.parseDouble(speedElement.getAttribute("max"));
road.setMaxSpeed(maxSpeed);
else
road.setMaxSpeed(UppaalUtil.INT16_MAX * 1.0 / UppaalUtil.K);
// laneSections
NodeList lanesNodeList = roadElement.getElementsByTagName("lanes");
Element lanesElement = (Element) lanesNodeList.item(0);
NodeList laneSectionList = lanesElement.getElementsByTagName("laneSection");
parseLaneSection(laneSectionList, road, laneSections, lanes);
roads.add(road);
catch (Exception e)
e.printStackTrace();
2.5 解析车道属性
private static void parseLaneSection(NodeList laneSectionList, Road road, List<LaneSection> laneSections, List<Lane> lanes)
try
List<LaneSection> roadLaneSections = new ArrayList<>();
List<Integer> laneSectionsIndex = new ArrayList<>();
for (int i = 0; i < laneSectionList.getLength(); i++)
Element laneSectionElement = (Element) laneSectionList.item(i);
LaneSection laneSection = new LaneSection();
//private int elementType;
laneSection.setElementType(ElementType.LANE_SECTION.getValue());
//private int roadIndex;
//private int roadId;
laneSection.setRoadId(road.getRoadId());
laneSection.setRoadIndex(road.getIndex());
//private int laneSectionId;
laneSection.setLaneSectionId(laneSectionId);
laneSection.setIndex(laneSectionIndex);
laneSectionsIndex.add(laneSectionIndex);
laneSectionMap.put(laneSectionId++, laneSectionIndex++);
//private double startPosition;
double s = Double.parseDouble(laneSectionElement.getAttribute("s"));
laneSection.setStartPosition(s);
//private double length;
double length = 0; // 本车道段起始位置减去上一个的起始位置
laneSection.setLength(length);
// lanes
NodeList laneList = laneSectionElement.getElementsByTagName("lane");
parseLane(laneList, laneSection, lanes);
roadLaneSections.add(laneSection);
laneSections.add(laneSection);
road.setLaneSectionsIndex(laneSectionsIndex);
road.setLaneSections(roadLaneSections);
catch (Exception e)
e.printStackTrace();
2.6 解析车道
private static void parseLane(NodeList laneList, LaneSection laneSection, List<Lane> lanes)
try
List<Lane> laneSectionLanes = new ArrayList<>();
List<Integer> lanesIndex = new ArrayList<>();
for (int i = 0; i < laneList.getLength(); i++)
Element laneElement = (Element) laneList.item(i);
Lane lane = new Lane();
// private int elementType;
lane.setElementType(ElementType.LANE.getValue());
// private int roadId;
lane.setRoadId(laneSection.getRoadId());
// private int roadIndex;
lane.setRoadIndex(laneSection.getRoadIndex());
// private int laneSectionIndex;
lane.setLaneSectionIndex(laneSection.getIndexOpenDrive学习笔记
Python - OpenDrive Map - 使用菲涅耳积分的螺旋/ Clothoid / Euler螺旋/ Curu螺旋插值