/*
 * @Description:
 * @Version: 1.0
 * @Autor: Sun Yalun
 * @Date: 2024-11-04 15:37:55
 * @LastEditors: Sun Yalun
 * @LastEditTime: 2024-11-08 14:41:50
 */

#include "utils.h"
#include <cmath>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <limits>

BoundingBox createBoundingBox(const Point &p1, const Point &p2)
{
    BoundingBox box;
    box.min_x = std::min(p1.pos_x, p2.pos_x);
    box.max_x = std::max(p1.pos_x, p2.pos_x);
    box.min_y = std::min(p1.pos_y, p2.pos_y);
    box.max_y = std::max(p1.pos_y, p2.pos_y);
    return box;
}

bool isPointInBoundingBox(const Point &p, const BoundingBox &box)
{
    return (p.pos_x >= box.min_x && p.pos_x <= box.max_x &&
            p.pos_y >= box.min_y && p.pos_y <= box.max_y);
}

std::vector<int> parseRef(const std::string &ref_str)
{
    std::vector<int> refs;
    std::string s = ref_str;
    if (s.size() >= 2 && s.front() == '[' && s.back() == ']')
    {
        s = s.substr(1, s.size() - 2);
    }

    std::stringstream ss(s);
    std::string token;
    while (std::getline(ss, token, ','))
    {
        try
        {
            refs.push_back(std::stoi(token));
        }
        catch (const std::invalid_argument &e)
        {
            std::cerr << "Invalid ref value: " << token << std::endl;
        }
    }
    return refs;
}

std::vector<Point> parseCoords(const std::string &coords_str)
{
    std::vector<Point> points;
    std::string s = coords_str;

    // 移除最外层的中括号
    if (!s.empty() && s.front() == '[' && s.back() == ']')
    {
        s = s.substr(1, s.size() - 2);
    }

    std::stringstream ss(s);
    std::string point_str;
    while (std::getline(ss, point_str, ']'))
    {
        // 每个点以 '[' 开始，移除它
        size_t start = point_str.find('[');
        if (start != std::string::npos)
        {
            std::string coords = point_str.substr(start + 1);
            // 将逗号替换为空格，以便于后续解析
            std::replace(coords.begin(), coords.end(), ',', ' ');
            std::stringstream coord_ss(coords);
            double x, y;
            coord_ss >> x >> y;
            Point p(0.0, 0.0, 0.0);
            p.pos_x = x;
            p.pos_y = y;
            points.push_back(p);
        }
        // 忽略逗号
        ss.ignore(1, ',');
    }

    return points;
}

double calculateDistance(double x1, double y1, double x2, double y2)
{
    double dx = x1 - x2;
    double dy = y1 - y2;
    return std::sqrt(dx * dx + dy * dy);
}

double pointToSegmentDistance(const Point &p, const Point &p1, const Point &p2)
{
    double x0 = p.pos_x;
    double y0 = p.pos_y;
    double x1 = p1.pos_x;
    double y1 = p1.pos_y;
    double x2 = p2.pos_x;
    double y2 = p2.pos_y;

    double dx = x2 - x1;
    double dy = y2 - y1;
    double mag = dx * dx + dy * dy;

    if (mag == 0.0)
    {
        return std::sqrt((x0 - x1) * (x0 - x1) + (y0 - y1) * (y0 - y1));
    }

    double u = ((x0 - x1) * dx + (y0 - y1) * dy) / mag;
    u = std::max(0.0, std::min(1.0, u));

    double x = x1 + u * dx;
    double y = y1 + u * dy;
    return std::sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0));
}

double computeMinDistanceToCurve(const Point &queryPoint, const std::vector<Point> &curve, size_t window_size)
{
    if (curve.size() < 2)
    {
        // std::cerr << "曲线点不足以形成线段。" << std::endl;
        return std::numeric_limits<double>::max();
    }

    double min_distance = std::numeric_limits<double>::max();

    // 初始滑动窗口范围
    for (size_t i = 0; i < curve.size() - 1; ++i)
    {
        BoundingBox box = createBoundingBox(curve[i], curve[i + 1]);
        if (!isPointInBoundingBox(queryPoint, box))
        {
            continue;
        }

        // 如果在窗口范围内，计算距离
        double dist = pointToSegmentDistance(queryPoint, curve[i], curve[i + 1]);
        if (dist < min_distance)
        {
            min_distance = dist;
        }

        // 滑动窗口: 超出窗口范围的段不计算
        if (i >= window_size && dist > min_distance)
        {
            break;
        }
    }

    return min_distance;
}

double computeBazierDistanceToCurve(const Point &queryPoint, const std::vector<Point> &coords)
{
    double min_dist = std::numeric_limits<double>::max();
    if (coords.size() < 2)
    {
        // std::cerr << "曲线点不足以形成线段。" << std::endl;
        return std::numeric_limits<double>::max();
    }
    for (int i = 0; i < coords.size() - 1; ++i)
    {
        double dist1 = pointToSegmentDistance(queryPoint, coords[i], coords[i + 1]);
        min_dist = std::min(min_dist, dist1);
    }
    return min_dist;
}

Point calculateCentroid(const std::vector<Point> &coords)
{
    double sum_x = 0.0, sum_y = 0.0;
    int n = coords.size();
    for (const auto &p : coords)
    {
        sum_x += p.pos_x;
        sum_y += p.pos_y;
    }
    return Point{sum_x / n, sum_y / n, 0.0};
}

std::vector<InterInfo> readIntersectionsFromCSV(const std::string &csvPath)
{
    std::vector<InterInfo> intersections;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开路口信息csv文件: " << csvPath << std::endl;
        return intersections;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "路口信息csv文件为空或无法读取表头。" << std::endl;
        return intersections;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"inter_id", "inter_type", "inter_in_shape", "inter_ref_link", "inter_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "路口信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return intersections;
        }
    }

    int inter_id_idx = headerMap["inter_id"];
    int inter_type_idx = headerMap["inter_type"];
    int inter_in_shape_idx = headerMap["inter_in_shape"];
    int inter_ref_link_idx = headerMap["inter_ref_link"];
    int inter_coords_idx = headerMap["inter_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        InterInfo inter;
        try
        {
            inter.inter_id = std::stoi(fields[inter_id_idx]);
            inter.inter_type = std::stoi(fields[inter_type_idx]);
            inter.inter_in_shape = std::stoi(fields[inter_in_shape_idx]);
            inter.inter_ref_link = parseRef(fields[inter_ref_link_idx]);
            inter.inter_coords = parseCoords(fields[inter_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }

        intersections.push_back(inter);
    }

    csvFile.close();
    return intersections;
}

std::vector<CrosswalkInfo> readCrosswalksFromCSV(const std::string &csvPath)
{
    std::vector<CrosswalkInfo> crosswalks;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开人行横道信息csv文件: " << csvPath << std::endl;
        return crosswalks;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "人行横道信息csv文件为空或无法读取表头。" << std::endl;
        return crosswalks;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"cross_id", "cross_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "人行横道信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return crosswalks;
        }
    }

    int cross_id_idx = headerMap["cross_id"];
    int cross_coords_idx = headerMap["cross_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        CrosswalkInfo cross;
        try
        {
            cross.cross_id = std::stoi(fields[cross_id_idx]);
            cross.cross_coords = parseCoords(fields[cross_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }

        crosswalks.push_back(cross);
    }

    csvFile.close();
    return crosswalks;
}

std::vector<TrafficlightInfo> readTrafficlightsFromCSV(const std::string &csvPath)
{
    std::vector<TrafficlightInfo> trafficlights;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开交通信号灯信息csv文件: " << csvPath << std::endl;
        return trafficlights;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "交通信号灯信息csv文件为空或无法读取表头。" << std::endl;
        return trafficlights;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"trafficlight_id", "trafficlight_ref_link", "trafficlight_ref_lane", "trafficlight_type", "trafficlight_head", "trafficlight_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "交通信号灯信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return trafficlights;
        }
    }

    int trafficlight_id_idx = headerMap["trafficlight_id"];
    int trafficlight_ref_link_idx = headerMap["trafficlight_ref_link"];
    int trafficlight_ref_lane_idx = headerMap["trafficlight_ref_lane"];
    int trafficlight_type_idx = headerMap["trafficlight_type"];
    int trafficlight_head_idx = headerMap["trafficlight_head"];
    int trafficlight_coords_idx = headerMap["trafficlight_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }
        TrafficlightInfo trafficlight;
        try
        {
            trafficlight.trafficlight_id = std::stoi(fields[trafficlight_id_idx]);
            trafficlight.trafficlight_ref_link = std::stoi(fields[trafficlight_ref_link_idx]);
            trafficlight.trafficlight_ref_lane = parseRef(fields[trafficlight_ref_lane_idx]);
            trafficlight.trafficlight_type = std::stoi(fields[trafficlight_type_idx]);
            trafficlight.trafficlight_head = parseRef(fields[trafficlight_head_idx]);
            trafficlight.trafficlight_coords = parseCoords(fields[trafficlight_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }

        trafficlights.push_back(trafficlight);
    }

    csvFile.close();
    return trafficlights;
}

std::vector<RoadInfo> readRoadsFromCSV(const std::string &csvPath)
{
    std::vector<RoadInfo> roads;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开道路信息csv文件: " << csvPath << std::endl;
        return roads;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "道路信息csv文件为空或无法读取表头。" << std::endl;
        return roads;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"link_id", "link_fc", "link_type", "link_speed_max", "link_speed_min", "link_direction", "link_lanenum", "link_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "道路信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return roads;
        }
    }

    int link_id_idx = headerMap["link_id"];
    int link_fc_idx = headerMap["link_fc"];
    int link_type_idx = headerMap["link_type"];
    int link_speed_max_idx = headerMap["link_speed_max"];
    int link_speed_min_idx = headerMap["link_speed_min"];
    int link_direction_idx = headerMap["link_direction"];
    int link_lanenum_idx = headerMap["link_lanenum"];
    int link_coords_idx = headerMap["link_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        RoadInfo road;
        try
        {
            road.link_id = std::stoi(fields[link_id_idx]);
            road.link_fc = std::stoi(fields[link_fc_idx]);
            road.link_type = std::stoi(fields[link_type_idx]);
            road.link_speed_max = std::stod(fields[link_speed_max_idx]);
            road.link_speed_min = std::stod(fields[link_speed_min_idx]);
            road.link_direction = std::stoi(fields[link_direction_idx]);
            road.link_lanenum = std::stoi(fields[link_lanenum_idx]);
            road.link_coords = parseCoords(fields[link_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }
        roads.push_back(road);
    }

    csvFile.close();
    return roads;
}

std::vector<LaneInfo> readLanesFromCSV(const std::string &csvPath)
{
    std::vector<LaneInfo> lanes;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开车道信息csv文件: " << csvPath << std::endl;
        return lanes;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "车道信息csv文件为空或无法读取表头。" << std::endl;
        return lanes;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"lane_id", "lane_length", "lane_type", "lane_width", "lane_turn", "lane_ref_link", "lane_speed_max", "lane_speed_min", "lane_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "车道信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return lanes;
        }
    }
    int lane_id_idx = headerMap["lane_id"];
    int lane_length_idx = headerMap["lane_length"];
    int lane_type_idx = headerMap["lane_type"];
    int lane_width_idx = headerMap["lane_width"];
    int lane_turn_idx = headerMap["lane_turn"];
    int lane_ref_link_idx = headerMap["lane_ref_link"];
    int lane_speed_max_idx = headerMap["lane_speed_max"];
    int lane_speed_min_idx = headerMap["lane_speed_min"];
    int lane_coords_idx = headerMap["lane_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        LaneInfo lane;
        try
        {
            lane.lane_id = std::stoi(fields[lane_id_idx]);
            lane.lane_length = std::stod(fields[lane_length_idx]);
            lane.lane_type = std::stoi(fields[lane_type_idx]);
            lane.lane_width = std::stod(fields[lane_width_idx]);
            lane.lane_turn = std::stoi(fields[lane_turn_idx]);
            lane.lane_ref_link = std::stoi(fields[lane_ref_link_idx]);
            lane.lane_speed_max = std::stoi(fields[lane_speed_max_idx]);
            lane.lane_speed_min = std::stoi(fields[lane_speed_min_idx]);
            lane.lane_coords = parseCoords(fields[lane_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }
        lanes.push_back(lane);
    }

    csvFile.close();
    return lanes;
}

std::vector<SignalInfo> readSignalsFromCSV(const std::string &csvPath)
{
    std::vector<SignalInfo> signs;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开交通标牌信息csv文件: " << csvPath << std::endl;
        return signs;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "交通标牌信息csv文件为空或无法读取表头。" << std::endl;
        return signs;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"sign_id", "sign_type", "sign_type1", "sign_ref_link", "sign_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "交通标牌信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return signs;
        }
    }

    int sign_id_idx = headerMap["sign_id"];
    int sign_type_idx = headerMap["sign_type"];
    int sign_type1_idx = headerMap["sign_type1"];
    int sign_ref_link_idx = headerMap["sign_ref_link"];
    int sign_coords_idx = headerMap["sign_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        SignalInfo sign;
        try
        {
            sign.sign_id = std::stoi(fields[sign_id_idx]);
            sign.sign_type = std::stoi(fields[sign_type_idx]);
            sign.sign_type1 = std::stoi(fields[sign_type1_idx]);
            sign.sign_ref_link = std::stoi(fields[sign_ref_link_idx]);
            sign.sign_coords = parseCoords(fields[sign_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }
        signs.push_back(sign);
    }

    csvFile.close();
    return signs;
}

// 从csv文件中读取停止线信息
std::vector<StoplineInfo> readStopLinesFromCSV(const std::string &csvPath)
{
    std::vector<StoplineInfo> stopLines;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开停止线信息csv文件: " << csvPath << std::endl;
        return stopLines;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "停止线信息csv文件为空或无法读取表头。" << std::endl;
        return stopLines;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"stopline_id", "stopline_ref_link", "stopline_ref_lane", "stopline_color", "stopline_type", "stopline_coords"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "停止线信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return stopLines;
        }
    }

    int stop_id_idx = headerMap["stopline_id"];
    int stop_ref_link_idx = headerMap["stopline_ref_link"];
    int stop_ref_lane_idx = headerMap["stopline_ref_lane"];
    int stop_color_idx = headerMap["stopline_color"];
    int stop_type_idx = headerMap["stopline_type"];
    int stop_coords_idx = headerMap["stopline_coords"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }

        StoplineInfo stopLine;
        try
        {
            stopLine.stopline_id = std::stoi(fields[stop_id_idx]);
            stopLine.stopline_ref_link = std::stoi(fields[stop_ref_link_idx]);
            stopLine.stopline_ref_lane = parseRef(fields[stop_ref_lane_idx]);
            stopLine.stopline_color = std::stoi(fields[stop_color_idx]);
            stopLine.stopline_type = std::stoi(fields[stop_type_idx]);
            stopLine.stopline_coords = parseCoords(fields[stop_coords_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }
        stopLines.push_back(stopLine);
    }

    csvFile.close();
    return stopLines;
}

// 从csv文件中读取箭头信息
std::vector<ArrowInfo> readArrowsFromCSV(const std::string &csvPath)
{
    std::vector<ArrowInfo> arrows;
    std::ifstream csvFile(csvPath);
    if (!csvFile.is_open())
    {
        std::cerr << "无法打开箭头信息csv文件: " << csvPath << std::endl;
        return arrows;
    }

    std::string line;
    // 读取表头
    if (!std::getline(csvFile, line))
    {
        std::cerr << "箭头信息csv文件为空或无法读取表头。" << std::endl;
        return arrows;
    }

    // 解析表头，建立列名到索引的映射
    std::unordered_map<std::string, int> headerMap;
    std::stringstream headerStream(line);
    std::string headerField;
    int index = 0;
    while (std::getline(headerStream, headerField, ','))
    {
        // 去除可能的引号和空格
        headerField.erase(std::remove(headerField.begin(), headerField.end(), '\"'), headerField.end());
        headerField.erase(std::remove(headerField.begin(), headerField.end(), ' '), headerField.end());
        headerMap[headerField] = index++;
    }

    // 检查是否存在所有必要的列
    std::vector<std::string> requiredColumns = {"arrow_id", "arrow_ref_lane", "arrow_direction"};
    for (const auto &col : requiredColumns)
    {
        if (headerMap.find(col) == headerMap.end())
        {
            std::cerr << "箭头信息csv文件中未找到列名为 " << col << " 的列。" << std::endl;
            return arrows;
        }
    }

    int arrow_id_idx = headerMap["arrow_id"];
    int arrow_lane_idx = headerMap["arrow_ref_lane"];
    int arrow_direction_idx = headerMap["arrow_direction"];

    // 读取每一行
    while (std::getline(csvFile, line))
    {
        std::stringstream ss(line);
        std::string field;
        std::vector<std::string> fields;
        bool in_quotes = false;
        std::string token;

        for (size_t i = 0; i < line.size(); ++i)
        {
            char c = line[i];
            if (c == '\"')
            {
                in_quotes = !in_quotes;
            }
            else if (c == ',' && !in_quotes)
            {
                fields.push_back(token);
                token.clear();
            }
            else
            {
                token += c;
            }
        }
        fields.push_back(token);

        // 检查字段数是否足够
        if (fields.size() < requiredColumns.size())
        {
            std::cerr << "字段数量不足，跳过行: " << line << std::endl;
            continue;
        }
        ArrowInfo arrow;
        try
        {
            arrow.arrow_id = std::stoi(fields[arrow_id_idx]);
            arrow.arrow_ref_lane = std::stoi(fields[arrow_lane_idx]);
            arrow.arrow_direction = parseRef(fields[arrow_direction_idx]);
        }
        catch (const std::exception &e)
        {
            std::cerr << "解析错误，跳过行: " << line << "\n错误信息: " << e.what() << std::endl;
            continue;
        }
        arrows.push_back(arrow);
    }

    csvFile.close();
    return arrows;
}