123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035 |
- /*
- * @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;
- }
|