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学习笔记

OpenDrive学习笔记

OpenX系列标准:OpenDRIVE标准简述

OpenX系列标准:OpenDRIVE标准简述

xodr高精地图在线查看器OpenDRIVE

Python - OpenDrive Map - 使用菲涅耳积分的螺旋/ Clothoid / Euler螺旋/ Curu螺旋插值