Преглед на файлове

change map_lanetoxodr. add xodrfunc.

yuchuli преди 3 години
родител
ревизия
26c1440ffd
променени са 2 файла, в които са добавени 864 реда и са изтрити 0 реда
  1. 810 0
      src/tool/map_lanetoxodr/xodrfunc.cpp
  2. 54 0
      src/tool/map_lanetoxodr/xodrfunc.h

+ 810 - 0
src/tool/map_lanetoxodr/xodrfunc.cpp

@@ -0,0 +1,810 @@
+#include "xodrfunc.h"
+
+#include "limits"
+#include <iostream>
+
+#include <Eigen/Dense>
+#include <Eigen/Cholesky>
+#include <Eigen/LU>
+#include <Eigen/QR>
+#include <Eigen/SVD>
+
+#include <QDebug>
+#include <QPointF>
+
+xodrfunc::xodrfunc()
+{
+
+}
+
+
+inline double xodrfunc::calcpointdis(QPointF p1,QPointF p2)
+{
+    return sqrt(pow(p1.x()-p2.x(),2)+pow(p1.y()-p2.y(),2));
+}
+
+bool xodrfunc::pointinarc(GeometryArc * parc,QPointF poingarc,QPointF point1)
+{
+    double hdg = CalcHdg(poingarc,point1);
+    if(parc->GetCurvature() >0)hdg = hdg + M_PI/2.0;
+    else hdg = hdg - M_PI/2.0;
+    if(hdg >= 2.0*M_PI)hdg = hdg - 2.0*M_PI;
+    if(hdg < 0)hdg = hdg + 2.0*M_PI;
+
+    double hdgrange = parc->GetLength()/(1.0/parc->GetCurvature());
+
+    double hdgdiff = hdg - parc->GetHdg();
+
+    if(hdgrange >= 0 )
+    {
+        if(hdgdiff < 0)hdgdiff = hdgdiff + M_PI*2.0;
+    }
+    else
+    {
+        if(hdgdiff > 0)hdgdiff = hdgdiff - M_PI*2.0;
+    }
+
+    if(fabs(hdgdiff ) < fabs(hdgrange))return true;
+    return false;
+
+}
+
+/**
+  * @brief CalcHdg
+  * 计算点0到点1的航向
+  * @param p0        Point 0
+  * @param p1        Point 1
+**/
+double xodrfunc::CalcHdg(QPointF p0, QPointF p1)
+{
+    double x0,y0,x1,y1;
+    x0 = p0.x();
+    y0 = p0.y();
+    x1 = p1.x();
+    y1 = p1.y();
+    if(x0 == x1)
+    {
+        if(y0 < y1)
+        {
+            return M_PI/2.0;
+        }
+        else
+            return M_PI*3.0/2.0;
+    }
+
+    double ratio = (y1-y0)/(x1-x0);
+
+    double hdg = atan(ratio);
+
+    if(ratio > 0)
+    {
+        if(y1 > y0)
+        {
+
+        }
+        else
+        {
+            hdg = hdg + M_PI;
+        }
+    }
+    else
+    {
+        if(y1 > y0)
+        {
+            hdg = hdg + M_PI;
+        }
+        else
+        {
+            hdg = hdg + 2.0*M_PI;
+        }
+    }
+
+    return hdg;
+}
+
+/**
+ * @brief GetParamPoly3Dis 获得点到贝塞尔曲线的距离。
+ * @param parc
+ * @param xnow
+ * @param ynow
+ * @param nearx
+ * @param neary
+ * @param nearhead
+ * @return
+ */
+double xodrfunc::GetParamPoly3Dis(GeometryParamPoly3 * parc,double xnow,double ynow,double & nearx,
+                        double & neary,double & nearhead,double & frels)
+{
+
+    double s = 0.1;
+    double fdismin = 100000.0;
+    frels = 0;
+
+    double xold,yold;
+    xold = parc->GetX();
+    yold = parc->GetY();
+
+    double fdis = calcpointdis(QPointF(parc->GetX(),parc->GetY()),QPointF(xnow,ynow));
+    if(fdis<fdismin)
+    {
+        fdismin = fdis;
+        nearhead = parc->GetHdg();
+        nearx = parc->GetX();
+        neary = parc->GetY();
+    }
+
+    while(s < parc->GetLength())
+    {
+
+        double x, y,xtem,ytem;
+        xtem = parc->GetuA() + parc->GetuB() * s + parc->GetuC() * s*s + parc->GetuD() * s*s*s;
+        ytem = parc->GetvA() + parc->GetvB() * s + parc->GetvC() * s*s + parc->GetvD() * s*s*s;
+        x = xtem*cos(parc->GetHdg()) - ytem * sin(parc->GetHdg()) + parc->GetX();
+        y = xtem*sin(parc->GetHdg()) + ytem * cos(parc->GetHdg()) + parc->GetY();
+
+        double hdg = CalcHdg(QPointF(xold,yold),QPointF(x,y));
+        double fdis = calcpointdis(QPointF(x,y),QPointF(xnow,ynow));
+        if(fdis<fdismin)
+        {
+            fdismin = fdis;
+            nearhead = hdg;
+            nearx = x;
+            neary = y;
+            frels = s;
+        }
+
+        xold = x;
+        yold = y;
+        s = s+ 0.1;
+    }
+
+    return fdismin;
+
+}
+
+
+/**
+  * @brief GetArcDis
+  * 计算点到圆弧的最短距离,首先用点和圆弧中心点的直线与圆的交点,计算点到交点的距离,如果交点在圆弧上,则最短距离是交点之一,否则计算点到圆弧两个端点的距离。
+  * @param parc        pointer to a arc geomery
+  * @param x           current x
+  * @param y           current y
+  * @param nearx       near x
+  * @param neary       near y
+  * @param nearhead    nearhead
+**/
+
+double xodrfunc::GetArcDis(GeometryArc * parc,double x,double y,double & nearx,
+                        double & neary,double & nearhead,double & frels)
+{
+
+    if((parc->GetS()>370)&&(parc->GetS()<370.1))
+    {
+        int a = 1;
+    }
+
+    if(parc->GetCurvature() == 0.0)return 1000.0;
+
+    double R = fabs(1.0/parc->GetCurvature());
+
+    frels = 0.0;
+
+    //calculate arc center
+    double x_center,y_center;
+    if(parc->GetCurvature() > 0)
+    {
+        x_center = parc->GetX() + R * cos(parc->GetHdg() + M_PI/2.0);
+        y_center = parc->GetY() + R * sin(parc->GetHdg()+ M_PI/2.0);
+    }
+    else
+    {
+        x_center = parc->GetX() + R * cos(parc->GetHdg() - M_PI/2.0);
+        y_center = parc->GetY() + R * sin(parc->GetHdg() - M_PI/2.0);
+    }
+
+    double hdgltoa = CalcHdg(QPointF(x,y),QPointF(x_center,y_center));
+
+
+    QPointF arcpoint;
+    arcpoint.setX(x_center);arcpoint.setY(y_center);
+
+    QPointF pointnow;
+    pointnow.setX(x);pointnow.setY(y);
+    QPointF point1,point2;
+    point1.setX(x_center + (R * cos(hdgltoa)));
+    point1.setY(y_center + (R * sin(hdgltoa)));
+    point2.setX(x_center + (R * cos(hdgltoa + M_PI)));
+    point2.setY(y_center + (R * sin(hdgltoa + M_PI)));
+
+    //calculat dis
+    bool bp1inarc,bp2inarc;
+    bp1inarc =pointinarc(parc,arcpoint,point1);
+    bp2inarc =pointinarc(parc,arcpoint,point2);
+    double fdis[4];
+    fdis[0] = calcpointdis(pointnow,point1);
+    fdis[1] = calcpointdis(pointnow,point2);
+    fdis[2] = calcpointdis(pointnow,QPointF(parc->GetX(),parc->GetY()));
+    QPointF pointend;
+    double hdgrange = parc->GetLength()*parc->GetCurvature();
+    double hdgend = parc->GetHdg() + hdgrange;
+    while(hdgend <0.0)hdgend = hdgend + 2.0 *M_PI;
+    while(hdgend >= 2.0*M_PI) hdgend = hdgend -2.0*M_PI;
+
+    if(parc->GetCurvature() >0)
+    {
+        pointend.setX(arcpoint.x() + R*cos(hdgend -M_PI/2.0 ));
+        pointend.setY(arcpoint.y() + R*sin(hdgend -M_PI/2.0) );
+    }
+    else
+    {
+        pointend.setX(arcpoint.x() + R*cos(hdgend +M_PI/2.0 ));
+        pointend.setY(arcpoint.y() + R*sin(hdgend +M_PI/2.0) );
+    }
+
+    fdis[3] = calcpointdis(pointnow,pointend);
+    int indexmin = -1;
+    double fdismin = 1000000.0;
+    if(bp1inarc)
+    {
+        indexmin = 0;fdismin = fdis[0];
+    }
+    if(bp2inarc)
+    {
+        if(indexmin == -1)
+        {
+            indexmin = 1;fdismin = fdis[1];
+        }
+        else
+        {
+            if(fdis[1]<fdismin)
+            {
+                indexmin = 1;fdismin = fdis[1];
+            }
+        }
+    }
+    if(indexmin == -1)
+    {
+        indexmin = 2;fdismin = fdis[2];
+    }
+    else
+    {
+        if(fdis[2]<fdismin)
+        {
+            indexmin = 2;fdismin = fdis[2];
+        }
+    }
+    if(fdis[3]<fdismin)
+    {
+        indexmin = 3;fdismin = fdis[3];
+    }
+
+    double hdgdiff;
+    switch (indexmin) {
+    case 0:
+        nearx = point1.x();
+        neary = point1.y();
+        if(parc->GetCurvature()<0)
+        {
+            nearhead = CalcHdg(arcpoint,point1) - M_PI/2.0;
+
+        }
+        else
+        {
+            nearhead = CalcHdg(arcpoint,point1) + M_PI/2.0;
+        }
+        while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
+        while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
+        hdgdiff = (nearhead-parc->GetHdg())*(parc->GetCurvature()/abs(parc->GetCurvature()));
+        if(hdgdiff>=2.0*M_PI)hdgdiff = hdgdiff - 2.0*M_PI;
+        if(hdgdiff<0)hdgdiff = hdgdiff + 2.0*M_PI;
+        frels = hdgdiff * R;
+        break;
+    case 1:
+        nearx = point2.x();
+        neary = point2.y();
+        if(parc->GetCurvature()<0)
+        {
+            nearhead = CalcHdg(arcpoint,point2) - M_PI/2.0;
+        }
+        else
+        {
+            nearhead = CalcHdg(arcpoint,point2) + M_PI/2.0;
+        }
+        while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
+        while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
+        hdgdiff = (nearhead-parc->GetHdg())*(parc->GetCurvature()/abs(parc->GetCurvature()));
+        if(hdgdiff>=2.0*M_PI)hdgdiff = hdgdiff - 2.0*M_PI;
+        if(hdgdiff<0)hdgdiff = hdgdiff + 2.0*M_PI;
+        frels = hdgdiff * R;
+        break;
+    case 2:
+        nearx = parc->GetX();
+        neary = parc->GetY();
+        nearhead = parc->GetHdg();
+        frels = 0;
+        break;
+    case 3:
+        nearx = pointend.x();
+        neary = pointend.y();
+        nearhead = hdgend;
+        frels = parc->GetLength();
+        break;
+    default:
+        std::cout<<"error in arcdis "<<std::endl;
+        break;
+    }
+
+    while(nearhead>2.0*M_PI)nearhead = nearhead -2.0*M_PI;
+    while(nearhead<0)nearhead = nearhead + 2.0*M_PI;
+    return fdismin;
+}
+
+double xodrfunc::GetSpiralDis(GeometrySpiral * pspiral,double xnow,double ynow,double & nearx,
+                        double & neary,double & nearhead,double & frels)
+{
+
+    double x,y,hdg;
+    double s = 0.0;
+    double fdismin = 100000.0;
+    double s0 = pspiral->GetS();
+
+    frels = 0;
+    while(s<pspiral->GetLength())
+    {
+        pspiral->GetCoords(s0+s,x,y,hdg);
+
+
+        double fdis = calcpointdis(QPointF(x,y),QPointF(xnow,ynow));
+        if(fdis<fdismin)
+        {
+            fdismin = fdis;
+            nearhead = hdg;
+            nearx = x;
+            neary = y;
+            frels = s;
+        }
+        s = s+0.1;
+    }
+
+    return fdismin;
+}
+
+/**
+ * @brief GetLineDis 获得点到直线Geometry的距离。
+ * @param pline
+ * @param x
+ * @param y
+ * @param nearx
+ * @param neary
+ * @param nearhead
+ * @return
+ */
+double xodrfunc::GetLineDis(GeometryLine * pline,const double x,const double y,double & nearx,
+                         double & neary,double & nearhead,double & frels)
+{
+    double fRtn = 1000.0;
+
+    double a1,a2,a3,a4,b1,b2;
+    double ratio = pline->GetHdg();
+    while(ratio >= 2.0* M_PI)ratio = ratio-2.0*M_PI;
+    while(ratio<0)ratio = ratio+2.0*M_PI;
+
+    double dis1,dis2,dis3;
+    double x1,x2,x3,y1,y2,y3;
+    x1 = pline->GetX();y1=pline->GetY();
+    if((ratio == 0)||(ratio == M_PI))
+    {
+        a1 = 0;a4=0;
+        a2 = 1;b1= pline->GetY();
+        a3 = 1;b2= x;
+    }
+    else
+    {
+        if((ratio == 0.5*M_PI)||(ratio == 1.5*M_PI))
+        {
+            a2=0;a3=0;
+            a1=1,b1=pline->GetX();
+            a4 = 1;b2 = y;
+        }
+        else
+        {
+            a1 = tan(ratio) *(-1.0);
+            a2 = 1;
+            a3 = tan(ratio+M_PI/2.0)*(-1.0);
+            a4 = 1;
+            b1 = a1*pline->GetX() + a2 * pline->GetY();
+            b2 = a3*x+a4*y;
+        }
+    }
+
+    y2 = y1 + pline->GetLength() * sin(ratio);
+    x2 = x1 + pline->GetLength() * cos(ratio);
+
+    Eigen::Matrix2d A;
+    A<<a1,a2,
+            a3,a4;
+    Eigen::Vector2d B(b1,b2);
+
+    Eigen::Vector2d opoint  = A.lu().solve(B);
+
+    x3 = opoint(0);
+    y3 = opoint(1);
+
+    dis1 = sqrt(pow(x1-x,2)+pow(y1-y,2));
+    dis2 = sqrt(pow(x2-x,2)+pow(y2-y,2));
+    dis3 = sqrt(pow(x3-x,2)+pow(y3-y,2));
+
+
+    if((dis1>pline->GetLength())||(dis2>pline->GetLength()))  //Outoff line
+    {
+ //       std::cout<<" out line"<<std::endl;
+        if(dis1<dis2)
+        {
+            fRtn = dis1;
+            nearx = x1;neary=y1;nearhead = pline->GetHdg();
+        }
+        else
+        {
+            fRtn = dis2;
+            nearx = x2;neary=y2;nearhead = pline->GetHdg();
+        }
+    }
+    else
+    {
+        fRtn = dis3;
+        nearx = x3;neary=y3;nearhead = pline->GetHdg();
+    }
+
+    frels = sqrt(pow(nearx - pline->GetX(),2)+pow(neary - pline->GetY(),2));
+
+    return fRtn;
+
+
+
+}
+
+
+int xodrfunc::GetNearPoint(const double x, const double y, OpenDrive *pxodr, Road **pObjRoad, GeometryBlock **pgeo, double &fdis, double &nearx, double &neary, double &nearhead, const double nearthresh,double * pfs,int * pnlane)
+{
+    double dismin = std::numeric_limits<double>::infinity();
+    fdis = dismin;
+    int i;
+    *pObjRoad = 0;
+    for(i=0;i<pxodr->GetRoadCount();i++)
+    {
+        int j;
+        Road * proad = pxodr->GetRoad(i);
+        double nx,ny,nh,frels;
+
+        for(j=0;j<proad->GetGeometryBlockCount();j++)
+        {
+            GeometryBlock * pgb = proad->GetGeometryBlock(j);
+            double dis;
+            RoadGeometry * pg;
+            int nlane = 1000;
+            pg = pgb->GetGeometryAt(0);
+
+            switch (pg->GetGeomType()) {
+            case 0:   //line
+                dis = GetLineDis((GeometryLine *) pg,x,y,nx,ny,nh,frels);
+                break;
+            case 1:
+                dis = GetSpiralDis((GeometrySpiral *)pg,x,y,nx,ny,nh,frels);
+                break;
+            case 2:  //arc
+                dis = GetArcDis((GeometryArc *)pg,x,y,nx,ny,nh,frels);
+                break;
+
+            case 3:
+                dis = 100000.0;
+                break;
+            case 4:
+                dis = GetParamPoly3Dis((GeometryParamPoly3 *)pg,x,y,nx,ny,nh,frels);
+                break;
+            default:
+                dis = 100000.0;
+                break;
+            }
+
+            if(dis < 100)
+            {
+                double faccuratedis;
+                faccuratedis = GetAcurateDis(x,y,proad,frels+pg->GetS(),nx,ny,nh,&nlane);
+                if(faccuratedis < dis)dis = faccuratedis;
+            }
+            if(dis < dismin)
+            {
+                dismin = dis;
+                nearx = nx;
+                neary = ny;
+                nearhead = nh;
+                fdis = dis;
+                *pObjRoad = proad;
+                *pgeo = pgb;
+                if(pfs != 0)*pfs = frels +pg->GetS();
+                if(pnlane != 0)*pnlane = nlane;
+            }
+        }
+    }
+
+
+    if(fdis > nearthresh)return -1;
+    return 0;
+}
+
+
+std::vector<iv::LanePoint> xodrfunc::GetAllLanePoint(Road *pRoad,  const double s,const double x, const double y,const double fhdg)
+{
+    int i;
+    int nLSCount = pRoad->GetLaneSectionCount();
+    double s_section = 0;
+
+    std::vector<iv::LanePoint> xvectorlanepoint;
+    for(i=0;i<nLSCount;i++)
+    {
+//        if((pRoad->GetRoadId() == "30012")&&(s>35))
+//        {
+//            int a= 1;
+//        }
+        LaneSection * pLS = pRoad->GetLaneSection(i);
+        if(i<(nLSCount -1))
+        {
+            if(pRoad->GetLaneSection(i+1)->GetS()<s)
+            {
+                continue;
+            }
+        }
+        s_section = pLS->GetS();
+        int nlanecount = pLS->GetLaneCount();
+        int j;
+        for(j=0;j<nlanecount;j++)
+        {
+            Lane * pLane = pLS->GetLane(j);
+
+            int nlanemarktype = -1; //default no lanetype
+            int nlanetype = 2; //driving
+            int nlanecolor = 0;
+            int k;
+            double s_lane = 0;
+            for(k=0;k<pLane->GetLaneRoadMarkCount();k++)
+            {
+                 LaneRoadMark * plrm = pLane->GetLaneRoadMark(k);
+                 if(k<(pLane->GetLaneRoadMarkCount()-1))
+                 {
+                     if(pLane->GetLaneRoadMark(k+1)->GetS()<s_lane)
+                     {
+                         continue;
+                     }
+                 }
+                 if(plrm->GetType() == "solid")
+                 {
+                     nlanemarktype = 0;
+                 }
+                 if(plrm->GetType() == "broken")
+                 {
+                     nlanemarktype = 1;
+                 }
+                 if(plrm->GetType() == "solid solid")
+                 {
+                     nlanemarktype = 2;
+                 }
+                 if(plrm->GetType() == "solid broken")
+                 {
+                     nlanemarktype = 3;
+                 }
+                 if(plrm->GetType() == "broken solid")
+                 {
+                     nlanemarktype = 4;
+                 }
+                 if(plrm->GetType() == "broken broken")
+                 {
+                     nlanemarktype = 5;
+                 }
+
+                 if(plrm->GetColor() == "standard")nlanecolor = 0;
+                 if(plrm->GetColor() == "blue")nlanecolor = 1;
+                 if(plrm->GetColor() == "green")nlanecolor = 2;
+                 if(plrm->GetColor() == "red")nlanecolor = 3;
+                 if(plrm->GetColor() == "white")nlanecolor = 4;
+                 if(plrm->GetColor() == "yellow")nlanecolor = 5;
+                 if(plrm->GetColor() == "orange")nlanecolor = 6;
+                 break;
+            }
+
+            if(pLane->GetType() == "shoulder")
+            {
+                nlanetype = 0;
+            }
+            if(pLane->GetType() == "border")
+            {
+                nlanetype = 1;
+            }
+            if(pLane->GetType() == "driving")
+            {
+                nlanetype = 2;
+            }
+            if(pLane->GetType() == "none")
+            {
+                nlanetype = 4;
+            }
+            if(pLane->GetType() == "biking")
+            {
+                nlanetype = 8;
+            }
+            if(pLane->GetType() == "sidewalk")
+            {
+                nlanetype = 9;
+            }
+
+
+            if(pLane->GetId() != 0)
+            {
+
+//                        if((pRoad->GetRoadId() == "10012")&&(pLane->GetId()==1))
+//                        {
+//                            int a= 1;
+//                        }
+
+//                int k;
+//                double s_lane = 0;
+                for(k=0;k<pLane->GetLaneWidthCount();k++)
+                {
+                    if(k<(pLane->GetLaneWidthCount()-1))
+                    {
+                        if((pLane->GetLaneWidth(k+1)->GetS()+s_section)<s)
+                        {
+                            continue;
+                        }
+                    }
+                    s_lane = pLane->GetLaneWidth(k)->GetS();
+                    break;
+                }
+                LaneWidth * pLW  = pLane->GetLaneWidth(k);
+                if(pLW == 0)
+                {
+                    std::cout<<"not find LaneWidth"<<std::endl;
+                    break;
+                }
+
+
+
+                iv::LanePoint lp;
+                lp.mnlanetype = nlanetype;
+                lp.mnlanemarktype = nlanemarktype;
+                lp.mnlanecolor = nlanecolor;
+                lp.mnlane = pLane->GetId();
+                lp.mnLaneSection = i;
+                double fds = s - s_lane - s_section;
+                lp.mflanewidth = pLW->GetA() + pLW->GetB() * fds
+                        +pLW->GetC() * pow(fds,2) + pLW->GetD() * pow(fds,3);
+                lp.mflanetocenter = 0;
+                lp.mnlanetype = nlanetype;
+                lp.mfhdg = fhdg;
+                lp.mS = s;
+                xvectorlanepoint.push_back(lp);
+
+            }
+            else
+            {
+                iv::LanePoint lp;
+                lp.mnlanetype = nlanetype;
+                lp.mnlanemarktype = nlanemarktype;
+                lp.mnlanecolor = nlanecolor;
+                lp.mnlane = 0;
+                lp.mnLaneSection = i;
+                lp.mflanewidth = 0;
+                lp.mflanetocenter = 0;
+                lp.mfhdg = fhdg;
+                lp.mS = s;
+                xvectorlanepoint.push_back(lp);
+            }
+        }
+
+        for(j=0;j<xvectorlanepoint.size();j++)
+        {
+            int k;
+            for(k=0;k<xvectorlanepoint.size();k++)
+            {
+                if(abs(xvectorlanepoint[k].mnlane)>abs((xvectorlanepoint[j].mnlane)))
+                {
+                    continue;
+                }
+                if(xvectorlanepoint[k].mnlane * xvectorlanepoint[j].mnlane <= 0)
+                {
+                    continue;
+                }
+                xvectorlanepoint[j].mflanetocenter = xvectorlanepoint[j].mflanetocenter + xvectorlanepoint[k].mflanewidth;
+            }
+        }
+
+        for(j=0;j<xvectorlanepoint.size();j++)
+        {
+            if(xvectorlanepoint[j].mnlane < 0)
+            {
+                xvectorlanepoint[j].mfX = x + xvectorlanepoint[j].mflanetocenter * cos(fhdg-M_PI/2.0);
+                xvectorlanepoint[j].mfY = y + xvectorlanepoint[j].mflanetocenter * sin(fhdg-M_PI/2.0);
+            }
+            else
+            {
+                xvectorlanepoint[j].mfX = x + xvectorlanepoint[j].mflanetocenter * cos(fhdg+M_PI/2.0);
+                xvectorlanepoint[j].mfY = y + xvectorlanepoint[j].mflanetocenter * sin(fhdg+M_PI/2.0);
+            }
+        }
+
+        break;
+
+    }
+
+    std::vector<iv::LanePoint> xvectorlanepointrtn;
+    bool bIsSort = true;
+    for(i=0;i<(xvectorlanepoint.size()-1);i++)
+    {
+        if(xvectorlanepoint[i].mnlane < xvectorlanepoint[i+1].mnlane)
+        {
+            bIsSort = false;
+            break;
+        }
+    }
+    if(bIsSort == false)
+    {
+        while(xvectorlanepoint.size() > 0)
+        {
+            int nlanemin;
+            nlanemin = 0;
+            int nlanenum = xvectorlanepoint[0].mnlane;
+            for(i=1;i<xvectorlanepoint.size();i++)
+            {
+                if(xvectorlanepoint[i].mnlane >= nlanenum)
+                {
+                    nlanenum = xvectorlanepoint[i].mnlane;
+                    nlanemin = i;
+                }
+            }
+            xvectorlanepointrtn.push_back(xvectorlanepoint[nlanemin]);
+            xvectorlanepoint.erase(xvectorlanepoint.begin() + nlanemin);
+        }
+    }
+    else
+    {
+        xvectorlanepointrtn = xvectorlanepoint;
+    }
+    return xvectorlanepointrtn;
+
+}
+
+double xodrfunc::GetAcurateDis(const double x, const double y, Road *pRoad,  const double s, const double nearx, const double neary, const double nearhead,int * pnlane)
+{
+    double fdismin = 1000;
+    if(pRoad->GetLaneSectionCount() < 1)return 1000;
+
+    std::vector<iv::LanePoint> xvectorlanepoint = GetAllLanePoint(pRoad,s,nearx,neary,nearhead);
+
+    double fdistoref = sqrt(pow(x-nearx,2)+pow(y-neary,2));
+
+    int i;
+    std::vector<double> xvectordis;
+    int nsize = xvectorlanepoint.size();
+    for(i=0;i<nsize;i++)
+    {
+        double fdis = sqrt(pow(x-xvectorlanepoint[i].mfX,2)+pow(y-xvectorlanepoint[i].mfY,2));
+        xvectordis.push_back(fdis);
+        if(fdismin>fdis)fdismin = fdis;
+
+    }
+    int nlane = -1000;
+    for(i=0;i<nsize;i++)
+    {
+        if((xvectordis[i]<=xvectorlanepoint[i].mflanewidth)&&(fdistoref <= xvectorlanepoint[i].mflanetocenter))
+        {
+            nlane = xvectorlanepoint[i].mnlane;
+            fdismin = 0; //On Lane, is very near.
+            break;
+        }
+    }
+
+    if(pnlane != 0)*pnlane = nlane;
+
+    return fdismin;
+
+
+}

+ 54 - 0
src/tool/map_lanetoxodr/xodrfunc.h

@@ -0,0 +1,54 @@
+#ifndef XODRFUNC_H
+#define XODRFUNC_H
+
+#include <OpenDrive/OpenDrive.h>
+
+#include <QPointF>
+
+
+namespace iv {
+struct LanePoint
+{
+    int mnlane;
+    int mnLaneSection;
+    double mS;
+    double mflanewidth;
+    double mflanetocenter;
+    double mfX;
+    double mfY;
+    double mfhdg;
+    int mnlanetype;  //0 driving 1 border 2 none 3 bike
+    int mnlanemarktype; // -1 no 0 solid 1 broken 2 solidsolid
+    int mnlanecolor;
+
+};
+
+}
+
+class xodrfunc
+{
+public:
+    xodrfunc();
+
+public:
+    static inline double calcpointdis(QPointF p1,QPointF p2);
+    static bool pointinarc(GeometryArc * parc,QPointF poingarc,QPointF point1);
+    static double CalcHdg(QPointF p0, QPointF p1);
+    static double GetParamPoly3Dis(GeometryParamPoly3 * parc,double xnow,double ynow,double & nearx,
+                            double & neary,double & nearhead,double & frels);
+    static double GetArcDis(GeometryArc * parc,double x,double y,double & nearx,
+                            double & neary,double & nearhead,double & frels);
+    static double GetSpiralDis(GeometrySpiral * pspiral,double xnow,double ynow,double & nearx,
+                            double & neary,double & nearhead,double & frels);
+    static double GetLineDis(GeometryLine * pline,const double x,const double y,double & nearx,
+                             double & neary,double & nearhead,double & frels);
+    static int GetNearPoint(const double x,const double y,OpenDrive * pxodr,Road ** pObjRoad,GeometryBlock ** pgeo, double & fdis,double & nearx,
+                     double & neary,double & nearhead,const double nearthresh,double * pfs=0,int * pnlane= 0);
+
+    static double GetAcurateDis(const double x,const double y,Road * pRoad,const  double  s,const double nearx,
+                                const double neary,const double nearhead,int * pnlane= 0);
+
+    static std::vector<iv::LanePoint> GetAllLanePoint(Road * pRoad,const double s,const double x, const double y,const double fhdg);
+};
+
+#endif // XODRFUNC_H