// #ifndef _MAP_MATCHING_HPP_
// #define _MAP_MATCHING_HPP_

// #include <pthread.h>

// #include <list>
// #include <thread>

// #include "../../../runnable_ros/include/input_hd_map_define.h"
// #include "Locker.h"
// #include "MapApi.hpp"
// #include "Thread.h"
// #include "ros/ros.h"

// namespace zone {

// namespace fusion_localization {

// namespace map {

// enum class location_error {
//     // cv_error不会被map_error覆盖
//     no_error = 0,
//     map_error = 1,
//     cv_error = 2
// };

// struct Confidence {
//     int total;
//     int start_lane;
//     int start_status;
//     int horizontal;
//     int vertical;
// };

// class MapMatching : public Thread {
//    public:
//     MapMatching();
//     ~MapMatching();

//     void Init(const std::string& projectDir, const std::string& configJsonPath);

//     // void GetGnssLocationData(const IGnssLocationData& gnss_location_data);
//     // void GetVisionMap(const IVisionMap& vision_map);

//     /*
//      * @brief check if the thread is running
//      * @param None
//      * @return true if running
//      */
//     bool IsRunning();

//     /*
//      * @brief Start the Scanner
//      * @param None
//      * @return If start is success
//      */
//     bool Start() override;

//     /*
//      * @brief Stop the Scanner
//      * @param uTimeout: not used
//      * @param bForce: not used
//      * @return If stop is success
//      */
//     bool Stop();

//     typedef std::function<void(IAheadMap ahead)> cbPubAheadMap;
//     void RegPubAheadMapCb(cbPubAheadMap func);

//     typedef std::function<void(IGnssFootLocation foot)> cbPubGnssFootLoc;
//     void RegPubGnssFootLocCb(cbPubGnssFootLoc func);

//     void SaveGnssLocationData(const IGnssLocationData& gnss_location_data);
//     bool GetGnssLocationData(IGnssLocationData& outGnssLoc);
//     void SaveVisionMapData(const IVisionMap& vision_map_data);
//     bool GetVisionMapData(IVisionMap& outVisionMap);

//    private:
//     uint32_t Run() override;

//    private:
//     // 定位流程线程
//     void MapMatchingProc();
//     void MapMatchingOnce();

//     bool UpdateTotalConfidence(bool forceTotalFalse);
//     bool StepUpdateConfidence(const IGnssLocationData& gnssLoc, const IVisionMap& vision, jf::HdLinkId& outCurrentLink, bool& outLaneChange, int& outLaneNum, jf::Point& ptOutFootPoint, jf::Point& ptOutVisionHorizontalPoint,
//                               jf::Point& ptOutVisionVerticalPoint);
//     bool UpdateStartLaneConfidence(const IGnssLocationData& gnssLoc, const IVisionMap& vision, jf::HdLinkId& outCurrentLink, int& outLaneNum);
//     bool UpdateStartStatusConfidence();
//     bool UpdateHorizontalConfidence(const IGnssLocationData& gnssLoc, const IVisionMap& vision, jf::HdLinkId& outCurrentLink, bool& outLaneChange, int& lane_num, jf::Point& outFootPoint, jf::Point& ptOutVisionHorizontalPoint);
//     bool UpdateVerticalConfidence(const IGnssLocationData& gnssLoc, const IVisionMap& vision, const jf::HdLinkId& currentLink, jf::Point& ptOutVisionVerticalPoint);

//     bool LocateByGnss(const IGnssLocationData& gnssLoc, jf::HdLinkId& outCurrentLink, int& outLaneNum);

//     // 绑路流程
//     bool StepBindRoad(const IGnssLocationData& gnssLoc, jf::HdLinkId& outCurrentLink);

//     // 获取Edge信息
//     void GetEdgeFromMap(const jf::HdLinkId& currentLink, int lane_num, int& outLeftCross, int& outRightCross, int& outLeftColor, int& outRightColor);

//     // 匹配Edge信息
//     bool MatchEdgeInfo(const IVisionMap& vision, const jf::HdLinkId& currentLink, const std::vector<LaneMarkingSide>& checking_poses, int lane_num, bool strong_match = true);

//     // 根据绑路点得到当前link
//     void MakeAheadMapData(const jf::HdLinkId& currentLink, int lane_num, IAheadMap& outAheadMap);
//     void MakeGnssFootData(const IGnssLocationData& gnssLoc, const IVisionMap& vision, const jf::HdLinkId& currentLink, bool laneChange, int lane_num, const jf::Point& footPoint, const jf::Point& visionHorizontalPoint, const jf::Point&
//     visionVerticalPoint,
//                           IGnssFootLocation& outGnssFoot);

//     bool StepGetTunnelInfo(const jf::Point& ingps, const jf::HdLinkId currentLink, float& to_entry, float& to_exit);
//     bool GetTunnelToEntryExit(const jf::Point& outP, const jf::HdLinkId& from, bool forward, float& out_to_entry, float& out_to_exit);
//     bool GetFirstTunnelMetre(const jf::Point& current_pos, const jf::HdLinkId from, float iter_metre, bool backward, float& out_metre, jf::HdLinkId& out_link);
//     bool GetPosInHdLink(const jf::Point& ptCurPos, const jf::HdLinkId& id, float& dOutToHeadDis, float& dOutToTailDis);
//     void MergeVisionMapData(const IVisionMap& vision, IVisionMap& outVision);

//     void PrintQgis(const std::string& strQgisFile, double lon, double lat, int num, long id, int lane = 0);

//    private:
//     bool is_running_;
//     Locker gnss_locker_;
//     Locker vision_locker_;
//     // pthread_mutex_t gnss_mutex_;
//     // pthread_mutex_t vision_mutex_;

//     std::thread* map_matching_thread_;
//     std::list<IGnssLocationData> gnss_location_data_list_;
//     std::list<IVisionMap> vision_map_list_;
//     location_error le_;

//     Confidence confidence_;

//     cbPubAheadMap ahead_map_pub_;
//     cbPubGnssFootLoc gnss_foot_pub_;

//     std::string strQgisFileInput_;
//     std::string strQgisFileResult_;
//     int getGpsData_exec_num;

//     jf::MapLib map_lib_;
// };

// }  // namespace map

// }  // namespace fusion_localization

// }  // namespace zone
// #endif  // _MAP_MATCHING_HPP_