|
@@ -0,0 +1,308 @@
|
|
|
+#include "dialogroadsplit.h"
|
|
|
+#include "ui_dialogroadsplit.h"
|
|
|
+
|
|
|
+
|
|
|
+#include "mainwindow.h"
|
|
|
+extern MainWindow * gw;
|
|
|
+
|
|
|
+DialogRoadSplit::DialogRoadSplit(Road * pRoad,OpenDrive * pxodr,QWidget *parent) :
|
|
|
+ QDialog(parent),
|
|
|
+ ui(new Ui::DialogRoadSplit)
|
|
|
+{
|
|
|
+ ui->setupUi(this);
|
|
|
+ mpRoad = pRoad;
|
|
|
+ mpxodr = pxodr;
|
|
|
+}
|
|
|
+
|
|
|
+DialogRoadSplit::~DialogRoadSplit()
|
|
|
+{
|
|
|
+ delete ui;
|
|
|
+}
|
|
|
+
|
|
|
+void DialogRoadSplit::on_pushButton_spalitats_clicked()
|
|
|
+{
|
|
|
+ if(mpRoad == 0)
|
|
|
+ {
|
|
|
+ QMessageBox::warning(this,"warning","no road");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ double s = ui->lineEdit_s->text().toDouble();
|
|
|
+ if(s<=0)
|
|
|
+ {
|
|
|
+ QMessageBox::warning(this,"warning","s is small",QMessageBox::YesAll);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if(s>=mpRoad->GetRoadLength())
|
|
|
+ {
|
|
|
+ QMessageBox::warning(this,"warning","s is exceed road length.",QMessageBox::YesAll);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ SplitRoad(mpxodr,mpRoad,s);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int DialogRoadSplit::SplitGeometryBlock(GeometryBlock *pa, GeometryBlock *pb, GeometryBlock *pc, const double s)
|
|
|
+{
|
|
|
+ //Only Split line or arc
|
|
|
+ if((pa->GetGeometryAt(0)->GetGeomType() !=0)&&(pa->GetGeometryAt(0)->GetGeomType() !=2))
|
|
|
+ {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(pa->GetGeometryAt(0)->GetS()>=s)
|
|
|
+ {
|
|
|
+ return -2;
|
|
|
+ }
|
|
|
+ if((pa->GetGeometryAt(0)->GetS() + pa->GetGeometryAt(0)->GetLength())<=s)
|
|
|
+ {
|
|
|
+ return -3;
|
|
|
+ }
|
|
|
+ //If Line
|
|
|
+ if(pa->GetGeometryAt(0)->GetGeomType() == 0)
|
|
|
+ {
|
|
|
+ double fsplits = s - pa->GetGeometryAt(0)->GetS();
|
|
|
+ double fsplitx,fsplity;
|
|
|
+ fsplitx = pa->GetGeometryAt(0)->GetX() + fsplits * cos(pa->GetGeometryAt(0)->GetHdg());
|
|
|
+ fsplity = pa->GetGeometryAt(0)->GetY() + fsplits * sin(pa->GetGeometryAt(0)->GetHdg());
|
|
|
+ pb->AddGeometryLine(pa->GetGeometryAt(0)->GetS(),pa->GetGeometryAt(0)->GetX(),
|
|
|
+ pa->GetGeometryAt(0)->GetY(),pa->GetGeometryAt(0)->GetHdg(),
|
|
|
+ fsplits);
|
|
|
+ pc->AddGeometryLine(pa->GetGeometryAt(0)->GetS()+fsplits,fsplitx,fsplity,
|
|
|
+ pa->GetGeometryAt(0)->GetHdg(),pa->GetGeometryAt(0)->GetLength() - fsplits);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ double fsplits = s - pa->GetGeometryAt(0)->GetS();
|
|
|
+ double fsplitx,fsplity;
|
|
|
+ double fhdg2;
|
|
|
+
|
|
|
+ GeometryArc * parc = (GeometryArc *)pa->GetGeometryAt(0);
|
|
|
+ if(parc->GetCurvature() == 0)
|
|
|
+ {
|
|
|
+ return -4;
|
|
|
+ }
|
|
|
+
|
|
|
+ double R = fabs(1.0/parc->GetCurvature());
|
|
|
+
|
|
|
+
|
|
|
+ //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 hdgdiff = fsplits/R;
|
|
|
+ if(parc->GetCurvature() >0)
|
|
|
+ {
|
|
|
+ fhdg2 = parc->GetHdg() + hdgdiff;
|
|
|
+ while(fhdg2>(2.0*M_PI))fhdg2 = fhdg2 - 2.0*M_PI;
|
|
|
+ fsplitx = x_center + R * cos(fhdg2 - M_PI/2.0);
|
|
|
+ fsplity = y_center + R * sin(fhdg2 - M_PI/2.0);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ fhdg2 = parc->GetHdg() - hdgdiff;
|
|
|
+ while(fhdg2<0)fhdg2 = fhdg2 + 2.0*M_PI;
|
|
|
+ fsplitx = x_center + R * cos(fhdg2 + M_PI/2.0);
|
|
|
+ fsplity = y_center + R * sin(fhdg2 + M_PI/2.0);
|
|
|
+ }
|
|
|
+
|
|
|
+ pb->AddGeometryArc(pa->GetGeometryAt(0)->GetS(),pa->GetGeometryAt(0)->GetX(),
|
|
|
+ pa->GetGeometryAt(0)->GetY(),pa->GetGeometryAt(0)->GetHdg(),
|
|
|
+ fsplits,parc->GetCurvature());
|
|
|
+ pc->AddGeometryArc(parc->GetS()+fsplits,fsplitx,fsplity,
|
|
|
+ fhdg2,parc->GetLength() - fsplits,parc->GetCurvature());
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int DialogRoadSplit::SplitElevation(Elevation *pa, Elevation **pb, Elevation **pc, const double s)
|
|
|
+{
|
|
|
+ if(pa == 0)
|
|
|
+ {
|
|
|
+ pb = 0;
|
|
|
+ pc = 0;
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if(pa->GetS()<s)return -2;
|
|
|
+ *pb = new Elevation(pa->GetS(),pa->GetA(),pa->GetB(),pa->GetC(),pa->GetD());
|
|
|
+ double a0,b0,c0,d0;
|
|
|
+ double a1,b1,c1,d1;
|
|
|
+ a0 = pa->GetA();
|
|
|
+ b0 = pa->GetB();
|
|
|
+ c0 = pa->GetC();
|
|
|
+ d0 = pa->GetD();
|
|
|
+ double s0 = s - pa->GetS();
|
|
|
+ a1 = a0 + b0*s0 + c0* s0*s0 + d0*s0*s0*s0;
|
|
|
+ b1 = b0 + 2*c0*s0 + 3*d0*s0*s0;
|
|
|
+ c1 = c0 + 3*d0*s0;
|
|
|
+ d1 = d0;
|
|
|
+ *pc = new Elevation(s,a1,b1,c1,d1);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+// Split Road
|
|
|
+//If line or arc split geometry
|
|
|
+//If not line or arc, geometry not split
|
|
|
+int DialogRoadSplit::SplitRoad(OpenDrive *pxodr, Road *pRoad,const double s)
|
|
|
+{
|
|
|
+ Road * proad1,*proad2;
|
|
|
+
|
|
|
+ if(s<=0)return -1;
|
|
|
+ if(pRoad == 0)return -2;
|
|
|
+ if(pxodr == 0)return -3;
|
|
|
+ if(s>=pRoad->GetRoadLength())return -4;
|
|
|
+
|
|
|
+ std::string strroadid = pRoad->GetRoadId();
|
|
|
+ int ngeocount = pRoad->GetGeometryBlockCount();
|
|
|
+
|
|
|
+ if(ngeocount < 1)return -5;
|
|
|
+
|
|
|
+ int i;
|
|
|
+ GeometryBlock * pgeobsel = 0;
|
|
|
+ int indexsplit = 0;
|
|
|
+ for(i=0;i<(ngeocount-1);i++)
|
|
|
+ {
|
|
|
+ GeometryBlock * pgeob = pRoad->GetGeometryBlock(i+1);
|
|
|
+ if(pgeob->GetGeometryAt(0)->GetS()>=s)
|
|
|
+ {
|
|
|
+ indexsplit = i;
|
|
|
+ pgeobsel = pRoad->GetGeometryBlock(i);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(pgeobsel == 0)pgeobsel = pRoad->GetGeometryBlock(0);
|
|
|
+
|
|
|
+ short ngeotype = pgeobsel->GetGeometryAt(0)->GetGeomType();
|
|
|
+
|
|
|
+ Road * pnewroad;
|
|
|
+ //not line or geo. split as this geo start.
|
|
|
+ //or line arc. but s at geo start.
|
|
|
+ if(((ngeotype !=0)&&(ngeotype !=2))||((indexsplit != 0)&&(pgeobsel->GetGeometryAt(0)->GetS() == s)))
|
|
|
+ {
|
|
|
+ if(indexsplit == 0)return -6; //not split
|
|
|
+ else
|
|
|
+ {
|
|
|
+ double flength = 0;
|
|
|
+ int j;
|
|
|
+ for(j=indexsplit;j<ngeocount;j++)
|
|
|
+ {
|
|
|
+ flength = flength + pRoad->GetGeometryBlock(j)->GetGeometryAt(0)->GetLength();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ double flength1 = pRoad->GetRoadLength() - flength;
|
|
|
+
|
|
|
+
|
|
|
+ int newroadid = gw->CreateRoadID();
|
|
|
+
|
|
|
+ unsigned int naddroadindex = pxodr->AddRoad("",flength,QString::number(newroadid).toStdString(),"-1");
|
|
|
+
|
|
|
+ unsigned int k;
|
|
|
+ for(k=0;k<pxodr->GetRoadCount();k++)
|
|
|
+ {
|
|
|
+ if(pxodr->GetRoad(k)->GetRoadId() == strroadid)
|
|
|
+ {
|
|
|
+ pRoad = pxodr->GetRoad(k);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Road * pnewroad = pxodr->GetRoad(naddroadindex);
|
|
|
+
|
|
|
+ *pnewroad = *pRoad;
|
|
|
+ pnewroad->SetRoadLength(flength);
|
|
|
+ pnewroad->SetRoadId(QString::number(newroadid).toStdString());
|
|
|
+ while(pRoad->GetGeometryBlockCount()>indexsplit)
|
|
|
+ {
|
|
|
+ pRoad->DeleteGeometryBlock(indexsplit);
|
|
|
+ }
|
|
|
+ pRoad->SetRoadLength(flength1);
|
|
|
+ for(j=0;j<indexsplit;j++)pnewroad->DeleteGeometryBlock(0);
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((indexsplit == 0)&&(pgeobsel->GetGeometryAt(0)->GetS() == s))
|
|
|
+ {
|
|
|
+ return -7; //At Start. so not split
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ GeometryBlock b,c;
|
|
|
+ int nrtn = SplitGeometryBlock(pgeobsel,&b,&c,s);
|
|
|
+
|
|
|
+ if(nrtn != 0)return -8;
|
|
|
+
|
|
|
+ int newroadid = gw->CreateRoadID();
|
|
|
+ int j;
|
|
|
+ double flength,flength1;
|
|
|
+
|
|
|
+ flength = c.GetGeometryAt(0)->GetLength();
|
|
|
+
|
|
|
+ for(j=(indexsplit+1);j<ngeocount;j++)
|
|
|
+ {
|
|
|
+ flength = flength + pRoad->GetGeometryBlock(j)->GetGeometryAt(0)->GetLength();
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ flength1 = pRoad->GetRoadLength() - flength;
|
|
|
+
|
|
|
+
|
|
|
+ unsigned int naddroadindex = pxodr->AddRoad("",flength,QString::number(newroadid).toStdString(),"-1");
|
|
|
+
|
|
|
+ unsigned int k;
|
|
|
+ for(k=0;k<pxodr->GetRoadCount();k++)
|
|
|
+ {
|
|
|
+ if(pxodr->GetRoad(k)->GetRoadId() == strroadid)
|
|
|
+ {
|
|
|
+ pRoad = pxodr->GetRoad(k);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Road * pnewroad = pxodr->GetRoad(naddroadindex);
|
|
|
+ *pnewroad = *pRoad;
|
|
|
+ pnewroad->SetRoadId(QString::number(newroadid).toStdString());
|
|
|
+ while(pRoad->GetGeometryBlockCount()>indexsplit)
|
|
|
+ {
|
|
|
+ pRoad->DeleteGeometryBlock(indexsplit);
|
|
|
+ }
|
|
|
+ pRoad->SetRoadLength(flength1);
|
|
|
+ pnewroad->SetRoadLength(flength);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ for(j=0;j<(indexsplit+1);j++)pnewroad->DeleteGeometryBlock(0);
|
|
|
+
|
|
|
+ vector<GeometryBlock> * pvectorele = pnewroad->GetGeometryBlockVector();
|
|
|
+ pvectorele->insert(pvectorele->begin(),c);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ pvectorele = pRoad->GetGeometryBlockVector();
|
|
|
+ pvectorele->push_back(b);
|
|
|
+
|
|
|
+ for(j=0;j<pnewroad->GetGeometryBlockCount();j++)
|
|
|
+ {
|
|
|
+ pnewroad->GetGeometryBlock(j)->GetGeometryAt(0)->SetS(pnewroad->GetGeometryBlock(j)->GetGeometryAt(0)->GetS() - s);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+}
|