#pragma once
#include"cstring"
#include"string"
#include"Road.h"
#include"Junction.h"
#include"unordered_map"
#include"xml/tinyxml.h"
#include"xml/tinystr.h"
#include"glm/glm.hpp"
#include"DataDefines.h"
#include"Elevation.h"
#include"SignalReference.h"
#include"NavinfoGISCoord.h"
#include"LaneBase.h"
#include"RoadBase.h"
#include"stack"
#include"Grid.h"
#include<fstream>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
namespace OpenDrive
{
	class  OdrManager
	{
	public:
		explicit OdrManager();

		bool LoadFile(const char* name);//加载地图;
		const vector<OdrInfo> GetOdrInfo(const double & longitude, const double &latitude) const;//通过经纬度获取OdrInfo的信息;
		const vector<OdrInfo> GetOdrInfoByXY(const double & x, const double &y) const;//通过平面坐标获取OdrInfo的信息;
		bool  GetSucRoadID(const char* roadID, char**&vecRoadID, int &nSize);//得到道路RoadID的所有后继道路的ID号,如果有就是true,否则就是false;
		bool  GetPreRoadID(const char* roadID, char**&vecRoadID, int &nSize);//得到道路RoadID的所有前继道路的ID号,如果有就是true,否则就是false;
		bool  GetPreLaneID(const char* roadID, const char* sectionID, const char* laneID, char**&vecLane, int &nSize);//根据道路ID和车道段ID和车道ID,返回该车道的所有前继连接车道号的数组,如果有就是true,否则就是false;
		bool  GetSucLaneID(const char* roadID, const char* sectionID, const char* laneID, char**&vecLane, int &nSize);//根据道路ID和车道段ID和车道ID,返回该车道的所有后继连接车道号的数组,如果有就是true,否则就是false;
		bool  GetPreLaneRelationID(const char* roadID, const char* sectionID, const char* laneID, LaneRelation*&vecLaneRelation, int &nSize);//根据道路ID和车道段ID和车道ID,返回该车道的所有前继连接车道号的数组,如果有就是true,否则就是false;
		
		bool  GetSucLaneRelationID(const char* roadID, const char* sectionID, const char* laneID, LaneRelation*&vecLaneRelation, int &nSize);//根据道路ID和车道段ID和车道ID,返回该车道的所有后继连接车道号的数组,如果有就是true,否则就是false;
		bool  GetLeftLaneIDS(const char* roadID, const char* sectionID, const char* laneID, char**&vecLane, int &nSize);//根据道路ID和车道段ID和车道ID,返回该车道的左侧相邻的平行车道的数组,如果有就是true,否则就是false;
		bool  GetRightLaneIDS(const char* roadID, const char* sectionID, const char* laneID, char**&vecLane, int &nSize);//道路ID和车道段ID和车道ID,返回该车道的右侧相邻的平行车道的数组,如果有就是true,否则就是false;
		bool  GetAllDrivingLaneIDS(const char* roadID, const char* sectionID, char**&vecLane, int &nSize);//根据道路ID和车道段ID和车道ID,返回该道路包含的所有行驶车道ID的数组,如果有就是true,否则就是false;
		bool  GetAllLaneIDS(const char* roadID, const char* sectionID, char**&vecLane, int &nSize);//根据道路ID和车道段ID和车道ID,返回该道路包含的所有车道ID的数组,如果有就是true,否则就是false;
		bool  GetAllSectionIDS(const char* roadID, char**&vecSection, int &nSize);//根据道路ID,返回该道路包含的所有的车道段sectionID,如果有就是true,否则就是false;
		bool  GetAllRoadIDS(char**&vecRoad, int &nSize);//返回该地图所包含的所有的道路ID,如果有就是true,否则就是false;
		bool GetSectionWidthofRoad(const char* roadID, const char* sectionID, RoadWidth*&vecRoaDWidth, int &nSize);//根据道路ID和车道段ID,返回该车道所包含的路宽信息RoadWidth的数组,如果有就是true,否则就是false;


		bool  GetLanePosiontAndDircetions(const char* roadID, const char* sectionID, const char* laneID, const double & longitude, const double &latitude, Position*& pos, int &nSize);//根据道路ID和车道段ID和车道ID,经纬度,返回该车道所包含的相对于经纬度在平面中的相对位置,道路的s坐标和航向信息Position的数组,如果有就是true,否则就是false;
		bool  GetLanePosiontAndDircetionsByXY(const char* roadID, const char* sectionID, const char* laneID, const double &x, const double &y, Position*& pos, int &nSize);//根据道路ID和车道段ID和车道ID,平面地图坐标xy,返回该车道所包含的相对于xy在平面中的相对位置,道路的s坐标和航向信息Position的数组,如果有就是true,否则就是false;
		bool  GetLaneTurningAttributes(const char* roadID, const char* sectionID, const char* laneID, const double &headDir, TurningAttr*& turAtt, int &nSize);//根据道路ID和车道段ID和车道ID,当前位置的汽车的行驶方向headDir,返回该车道的转弯属性TurningAttr的数组,如果有就是true,否则就是false;

		 NearestDistance* GetNeartestRoadandLaneAttributes(const double & longitude, const double &latitude);//根据一个位置坐标点(经纬度),返回该点到其最近的左右车道线的距离、到左右道路边界的距离的结构体 NearestDistanc;
		 NearestDistance* GetNeartestRoadandLaneAttributesByXY(const double & x, const double &y);//根据一个平面地图坐标点xy,返回该点到其最近的左右车道线的距离、到左右道路边界的距离的结构体 NearestDistanc;

		NearestRoadMark GetNeartestLaneRoadMark(const double & longitude, const double &latitude);//根据一个位置坐标点(经纬度),返回该点所对应的最近车道左右侧车道线类型NearestRoadMark:
		NearestRoadMark GetNeartestLaneRoadMarkByXY(const double &x, const double &y);//根据一个平面地图坐标点xy,返回该点所对应的最近车道左右侧车道线类型NearestRoadMark:
		bool GetEdgePolygon(const double &longitude, const double &latitude, const double &radius, PosXY**& pos, int &nSize, int *&length);//根据一个位置坐标点(经纬度),半径,返回圆内的所有车道的坐标点集;
		bool GetEdgePolygonByXY(const double &x, const double &y, const double &radius, PosXY**& pos, int &nSize, int *&length);//根据一个平面地图坐标点xy,半径,返回圆内的所有车道的坐标点集;
		//const RoadProperty GetLaneProperty(const vector<Position> &vecPosition) const;
		bool GetEdgePolygon(const double &longitude, const double &latitude, const double &radius, PosXY*& pos, int &nSize);//根据一个位置坐标点(经纬度),半径,返回圆内的所有车道的坐标点集;
		bool GetEdgePolygonByXY(const double &x, const double &y, const double &radius, PosXY*& pos, int &nSize);//根据一个平面地图坐标点xy,半径,返回圆内的所有车道的坐标点集;
		const double GetLaneSpeed(const char* roadID, const char* sectionID, const char* laneID) const; //根据道路ID和车道段ID和车道ID,返回该车道的最大行驶速度m/s;
		bool GetLightPos(const double &longitude, const double &latitude, SignalPos*&pos, int &nSize) ;//根据一个位置坐标点(经纬度),返回该点所在道路的所有信号灯的数组,如果有就是true,否则就是false;
		bool GetLightPosByXY(const double &x, const double &y, SignalPos*&pos, int &nSize) ;//根据一个平面地图坐标点xy,返回该点所在道路的所有信号灯的数组,如果有就是true,否则就是false;
		bool GetStopLinePos(const double &longitude, const double &latitude, SignalPos*&pos, int &nSize) ;//根据一个位置坐标点(经纬度),返回该点所在道路的所有停止线的数组,如果有就是true,否则就是false;
		bool GetStopLinePosByXY(const double &x, const double &y, SignalPos*&pos, int &nSize) ;//根据一个位置坐标点(经纬度),返回该点所在道路的所有停止线的数组,如果有就是true,否则就是false;
		bool GetLeftLinePosFromLane(const char* roadID, const char* sectionID, const char* laneID, const double &longitude, const double &latitude, PosXY*& pos, int &nSize); //根据道路ID和车道段ID和车道ID,经纬度,返回该车道的左边界相对于经纬度在平面中的相对位置,如果有就是true,否则就是false;
		bool GetLeftLinePosFromLaneByXY(const char* roadID, const char* sectionID, const char* laneID, const double &x, const double &y, PosXY*& pos, int &nSize); //根据道路ID和车道段ID和车道ID,平面坐标(x,y),返回该车道的左边界相对于平面坐标(x, y)中的相对位置,如果有就是true,否则就是false;
		bool GetRightLinePosFromLane(const char* roadID, const char* sectionID, const char* laneID, const double &longitude, const double &latitude, PosXY*& pos, int &nSize);//根据道路ID和车道段ID和车道ID,经纬度,返回该车道的右边界相对于经纬度在平面中的相对位置,如果有就是true,否则就是false;
		bool GetRightLinePosFromLaneByXY(const char* roadID, const char* sectionID, const char* laneID, const double &x, const double &y, PosXY*& pos, int &nSize);//根据道路ID和车道段ID和车道ID,平面坐标(x,y),返回该车道的右边界相对于平面坐标(x, y)中的相对位置,如果有就是true,否则就是false;
		PosXY GetXYFromRoadID(const char* roadID, const double &s, const double &t);//根据道路ID,st坐标(s,t),返回该点随对应的三维坐标(x, y,z);
		PosXY GetSTFromRoadID(const char* roadID, const double &x, const double &y);//根据道路ID,平面坐标(x,y),返回该点随对应的三维坐标(s, t, z);
		PosXY LatLonToTM(const double &lon, const double &lat) const;//根据经纬度坐标(lon, lat),tm投影转化为平面坐标(x,y);
		PosXY XYToLatLonTM(const double &x, const double &y) const;//根据平面坐标(x,y),tm投影转化为经纬度坐标(lon, lat);
		PosXY LatLonToXYZTM(const double &lon, const double &lat) const;//根据经纬度坐标(lon, lat),tm投影转化为三维坐标(x,y,z);
		double LatLonToZTM(const double &lon, const double &lat) const;//根据经纬度坐标(lon, lat),tm投影转化得到当前位置的高程;
		double XYToZTM(const double &x, const double &y) const;//根据平面坐标(x,y),tm投影转化得到当前位置的高程;
		PosXY XYToLatLonZTM(const double &x, const double &y) const;//根据平面坐标(x,y),tm投影转化为三维坐标坐标(lon, lat,z);

		PosXY LatLonToUTM(const double &lon, const double &lat) const;//根据经纬度坐标(lon, lat),utm投影转化为平面坐标(x,y);
		PosXY XYToLatLonUTM(const double &x, const double &y) const; //根据平面坐标(x,y),utm投影转化为经纬度坐标(lon, lat);
		PosXY LatLonToXYZUTM(const double &lon, const double &lat) const; //根据经纬度坐标(lon, lat),utm投影转化为三维坐标(x,y,z);
																		  //
		                                                                  //
		                                                                  //
		                                                                  //
		                                                                  //
		PosXY XYToLatLonZUTM(const double &x, const double &y) const;//根据平面坐标(x,y),utm投影转化为三维坐标坐标(lon, lat,z);

		LaneBase* GetLaneBase(const char* roadID, const char* sectionID, const char* laneID);  //根据道路ID和车道段ID和车道ID,返回该车道的车道基类指针;
		RoadBase* GetRoadBase(const char* roadID); //根据道路ID,返回该道路的道路基类指针;
		Road* GetRoad(const char* roadID);//根据道路ID,返回该道路的道路指针;
		const LaneSection* GetLaneSection(const char* roadID, const char* sectionID)const; //根据道路ID,车道段ID,返回该车道的车道段指针;
		const Lane* GetLane(const char* roadID, const char* sectionID, const char* laneID)const; //根据道路ID和车道段ID和车道ID,返回该车道的车道基类指针;
		RoadDrivingAttr GetRoadDriveTurningAttr(const char* roadID);//根据道路ID,车道段ID,返回该车道的车道段指针;

		void PreRoadID(const char* roadID, const double &length, const double &dir, stack<string> &stkRoad);
		bool GetLaneInfor(const double &longitude, const double &latitude, const double &dir, const double &length, const double &width, bool bRoad_Edge, PosXY**& pos, int &nArraySize, int *&nSize, const double& thresholdDegreeValue);//根据一个位置坐标点(经纬度),长和宽,返回矩形框中的所有坐标点集;
		bool GetLaneInforByXY(const double &x, const double &y, const double &dir, const double &length , const double &width, bool bRoad_Edge, PosXY**& pos, int &nArraySize, int *&nSize, const double& thresholdDegreeValue);//根据一个位置平面坐标点(x, y),长和宽,返回矩形框中的所有坐标点集;
		void GetRoadLaneInfor(Road*road, vector<LaneGeoCoordinage> &vecGeo, const set<string> &setTerm, set<string> &hasRoad, const vector<glm::dvec2> &vecData);

		/////////////////
		/////·���滮;
		/////////////////
		

		bool IsJunction(const char *junctionID);//判断juctionID是否为高精度地图xodr中的junctionID;
		char* GetJunctionID(const char *roadID);//根据车道roadID,获取车道的juntionID;
		bool GetNextJuncionID(const char *currentJuncionID, char**&vecNodeID, int &nSize);//根据当前的junciotnID号,获取它的所有的后继juntionID的数组;
		bool GetNextJuncionID(const char *currentJuncionID, const char*inRoadID, char**&vecNodeID, int &nSize);//根据当前的junciotnID,输入道路的roadID,获取它所有的后继juntionID的数组;
		bool GetObjectsByType(const ObjSubType &objSubType, Object** &objs, int &nSize);//根据Object的子类型,获取该类型的所有objectde的数组;
		bool GetObjectType(ObjSubType *&objSubType, int &nSize);//获取object的所有子类型的数据;
		bool GetObjectsByLocationRoadID(const char *roadID, Object** &objs, int &nSize); //根据车道roadID,获取车道的Object的数组;
		bool GetObjectsByLogicRoadID(const char *roadID, Object** &objs, int &nSize); //根据车道roadID,获取车道的Object的数组;
		//bool GetNextJuncionID(const char *currentJuncionID, char**&vecRoadID, int &nSize);
		~OdrManager();
	private:
		vector<vector<glm::dvec3>> GetPrePolygon(const double &s, Road* road);
		vector<vector<glm::dvec3>> GetSucPolygon(Road* road, const double &len);
		vector<vector<glm::dvec3>> GetPolygon(const double &s, Road* road, const double &length);
	private:
	private:
		unordered_map<string, Road*> *_mapRoad;
		unordered_map<string, Junction*> *_mapJunction;

	};

}