Apollo 10.0
自动驾驶开放平台
lanes_xml_parser.cc
浏览该文件的文档.
1/* Copyright 2017 The Apollo Authors. All Rights Reserved.
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14=========================================================================*/
16
18
19namespace {
20double ToMPS(double speed) { return speed * 1000.0 / 3600.0; }
21bool IsReferenceLane(int lane_id) { return lane_id == 0; }
22}; // namespace
23
24namespace apollo {
25namespace hdmap {
26namespace adapter {
27
28Status LanesXmlParser::Parse(const tinyxml2::XMLElement& xml_node,
29 const std::string& road_id,
30 std::vector<RoadSectionInternal>* sections) {
31 CHECK_NOTNULL(sections);
32 const auto lanes_node = xml_node.FirstChildElement("lanes");
33 CHECK_NOTNULL(lanes_node);
34 const tinyxml2::XMLElement* sub_node =
35 lanes_node->FirstChildElement("laneSection");
36 CHECK_NOTNULL(sub_node);
37
38 size_t section_cnt = 0;
39 while (sub_node) {
40 RoadSectionInternal section_internal;
41 std::string section_id = std::to_string(++section_cnt);
42 section_internal.id = section_id;
43 section_internal.section.mutable_id()->set_id(section_id);
44 RETURN_IF_ERROR(ParseLaneSection(*sub_node, &section_internal.lanes));
45 RETURN_IF_ERROR(ParseSectionBoundary(
46 *sub_node,
47 section_internal.section.mutable_boundary()->mutable_outer_polygon()));
48 sections->push_back(section_internal);
49
50 sub_node = sub_node->NextSiblingElement("laneSection");
51 }
52
53 CHECK_NE(sections->size(), 0U);
54
55 return Status::OK();
56}
57
58Status LanesXmlParser::ParseSectionBoundary(
59 const tinyxml2::XMLElement& xml_node, PbBoundaryPolygon* boundary) {
60 CHECK_NOTNULL(boundary);
61
62 auto boundaries_node = xml_node.FirstChildElement("boundaries");
63 if (boundaries_node == nullptr) {
64 std::string err_msg = "Error parse boundaries";
66 }
67
68 auto sub_node = boundaries_node->FirstChildElement("boundary");
69 while (sub_node) {
70 PbBoundaryEdge* boundary_edge = boundary->add_edge();
72 UtilXmlParser::ParseCurve(*sub_node, boundary_edge->mutable_curve()));
73 std::string type;
74 int checker = UtilXmlParser::QueryStringAttribute(*sub_node, "type", &type);
75 if (checker != tinyxml2::XML_SUCCESS) {
76 std::string err_msg = "Error parse boundary type";
77 return Status(apollo::common::ErrorCode::HDMAP_DATA_ERROR, err_msg);
78 }
79 PbBoundaryEdgeType boundary_type;
80 RETURN_IF_ERROR(ToPbBoundaryType(type, &boundary_type));
81 boundary_edge->set_type(boundary_type);
82
83 sub_node = sub_node->NextSiblingElement("boundary");
84 }
85
86 return Status::OK();
87}
88
89Status LanesXmlParser::ToPbBoundaryType(const std::string& type,
90 PbBoundaryEdgeType* boundary_type) {
91 CHECK_NOTNULL(boundary_type);
92
93 std::string upper_type = UtilXmlParser::ToUpper(type);
94
95 if (upper_type == "LEFTBOUNDARY") {
97 } else if (upper_type == "RIGHTBOUNDARY") {
99 } else {
100 *boundary_type = hdmap::BoundaryEdge::NORMAL;
101 }
102
103 return Status::OK();
104}
105
106Status LanesXmlParser::ParseLaneSection(const tinyxml2::XMLElement& xml_node,
107 std::vector<LaneInternal>* lanes) {
108 CHECK_NOTNULL(lanes);
109
110 // left
111 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("left");
112 if (sub_node) {
113 sub_node = sub_node->FirstChildElement("lane");
114 while (sub_node) {
115 LaneInternal lane_internal;
116 RETURN_IF_ERROR(ParseLane(*sub_node, &lane_internal));
117 *(lane_internal.lane.mutable_left_boundary()) =
118 lane_internal.lane.right_boundary();
119 lane_internal.lane.clear_right_boundary();
120 if (lanes->size() > 0) {
121 PbLane& left_neighbor_lane = lanes->back().lane;
122 *(left_neighbor_lane.mutable_right_boundary()) =
123 lane_internal.lane.left_boundary();
124 }
125 lanes->push_back(lane_internal);
126 sub_node = sub_node->NextSiblingElement("lane");
127 }
128 }
129
130 // center
131 LaneInternal reference_lane_internal;
132 sub_node = xml_node.FirstChildElement("center");
133 CHECK_NOTNULL(sub_node);
134 sub_node = sub_node->FirstChildElement("lane");
135 CHECK_NOTNULL(sub_node);
136 RETURN_IF_ERROR(ParseLane(*sub_node, &reference_lane_internal));
137 *(reference_lane_internal.lane.mutable_left_boundary()) =
138 reference_lane_internal.lane.right_boundary();
139 if (lanes->size() > 0) {
140 PbLane& left_neighbor_lane = lanes->back().lane;
141 *(left_neighbor_lane.mutable_right_boundary()) =
142 reference_lane_internal.lane.left_boundary();
143 }
144
145 // right
146 sub_node = xml_node.FirstChildElement("right");
147 if (sub_node) {
148 sub_node = sub_node->FirstChildElement("lane");
149 PbLane* left_neighbor_lane = &reference_lane_internal.lane;
150 while (sub_node) {
151 // PbLane lane
152 LaneInternal lane_internal;
153 RETURN_IF_ERROR(ParseLane(*sub_node, &lane_internal));
154 *(lane_internal.lane.mutable_left_boundary()) =
155 left_neighbor_lane->right_boundary();
156 lanes->push_back(lane_internal);
157 left_neighbor_lane = &lanes->back().lane;
158 sub_node = sub_node->NextSiblingElement("lane");
159 }
160 }
161 return Status::OK();
162}
163
164Status LanesXmlParser::ParseLane(const tinyxml2::XMLElement& xml_node,
165 LaneInternal* lane_internal) {
166 CHECK_NOTNULL(lane_internal);
167
168 PbLane* lane = &lane_internal->lane;
169 // lane id
170 int id = 0;
171 int checker = xml_node.QueryIntAttribute("id", &id);
172 if (checker != tinyxml2::XML_SUCCESS) {
173 std::string err_msg = "Error parse lane id";
175 }
176 std::string lane_id;
177 checker = UtilXmlParser::QueryStringAttribute(xml_node, "uid", &lane_id);
178 if (checker != tinyxml2::XML_SUCCESS) {
179 std::string err_msg = "Error parse lane uid";
181 }
182 lane->mutable_id()->set_id(lane_id);
183
184 // lane type
185 std::string lane_type;
186 checker = UtilXmlParser::QueryStringAttribute(xml_node, "type", &lane_type);
187 if (checker != tinyxml2::XML_SUCCESS) {
188 std::string err_msg = "Error parse lane type.";
190 }
191 PbLaneType pb_lane_type;
192 Status success = ToPbLaneType(lane_type, &pb_lane_type);
193 if (!success.ok()) {
194 std::string err_msg = "Error convert lane type to pb lane type.";
196 }
197 lane->set_type(pb_lane_type);
198
199 // border
200 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("border");
201 if (sub_node) {
202 PbLaneBoundary* lane_boundary = lane->mutable_right_boundary();
203 ACHECK(lane_boundary != nullptr);
204 success =
205 UtilXmlParser::ParseCurve(*sub_node, lane_boundary->mutable_curve());
206 if (!success.ok()) {
207 std::string err_msg = "Error parse lane border";
209 }
210 lane_boundary->set_length(
211 UtilXmlParser::CurveLength(*lane_boundary->mutable_curve()));
212
213 bool is_virtual = false;
214 std::string virtual_border = "FALSE";
215 checker = UtilXmlParser::QueryStringAttribute(*sub_node, "virtual",
216 &virtual_border);
217 if (checker == tinyxml2::XML_SUCCESS) {
218 if (virtual_border == "TRUE") {
219 is_virtual = true;
220 }
221 }
222 lane_boundary->set_virtual_(is_virtual);
223 }
224
225 // road mark
226 if (sub_node) {
227 sub_node = sub_node->FirstChildElement("borderType");
228 }
229 while (sub_node) {
230 PbLaneBoundary* lane_boundary = lane->mutable_right_boundary();
231 PbLaneBoundaryTypeType boundary_type;
232 success = ParseLaneBorderMark(*sub_node, &boundary_type);
233 if (!success.ok()) {
234 std::string err_msg = "Error parse lane border type";
236 }
237 double s_offset = 0.0;
238 checker = sub_node->QueryDoubleAttribute("sOffset", &s_offset);
239 if (checker != tinyxml2::XML_SUCCESS) {
240 std::string err_msg = "Error parse lane boundary type offset.";
242 }
243 auto lane_boundary_type = lane_boundary->add_boundary_type();
244 lane_boundary_type->set_s(s_offset);
245 lane_boundary_type->add_types(boundary_type);
246 sub_node = sub_node->NextSiblingElement("borderType");
247 }
248
249 // reference line
250 if (IsReferenceLane(id)) {
251 return Status::OK();
252 }
253
254 // turn type
255 std::string turn_type;
256 checker =
257 UtilXmlParser::QueryStringAttribute(xml_node, "turnType", &turn_type);
258 if (checker != tinyxml2::XML_SUCCESS) {
259 std::string err_msg = "Error parse lane turn type.";
261 }
262 PbTurnType pb_turn_type;
263 success = ToPbTurnType(turn_type, &pb_turn_type);
264 if (!success.ok()) {
265 std::string err_msg = "Error convert turn type to pb turn type.";
267 }
268 lane->set_turn(pb_turn_type);
269
270 // direction
271 RETURN_IF_ERROR(ParseDirection(xml_node, lane));
272
273 // link
274 sub_node = xml_node.FirstChildElement("link");
275 if (sub_node) {
276 ParseLaneLink(*sub_node, lane);
277 }
278
279 // center curve
280 RETURN_IF_ERROR(ParseCenterCurve(xml_node, lane));
281 // speed
282 RETURN_IF_ERROR(ParseSpeed(xml_node, lane));
283 // sample association
284 RETURN_IF_ERROR(ParseSampleAssociates(xml_node, lane));
285 // road sample association
286 RETURN_IF_ERROR(ParseRoadSampleAssociates(xml_node, lane));
287
288 // overlap object
289 ParseObjectOverlapGroup(xml_node, &lane_internal->overlap_objects);
290 // overlap signal
291 ParseSignalOverlapGroup(xml_node, &lane_internal->overlap_signals);
292 // overlap junction
293 ParseJunctionOverlapGroup(xml_node, &lane_internal->overlap_junctions);
294 // overlap lane
295 ParseLaneOverlapGroup(xml_node, &lane_internal->overlap_lanes);
296
297 return Status::OK();
298}
299
300Status LanesXmlParser::ParseDirection(const tinyxml2::XMLElement& xml_node,
301 PbLane* lane) {
302 CHECK_NOTNULL(lane);
303 std::string direction;
304 int checker =
305 UtilXmlParser::QueryStringAttribute(xml_node, "direction", &direction);
306 if (checker != tinyxml2::XML_SUCCESS) {
307 std::string err_msg = "Error parse lane direction.";
309 }
310 PbLaneDirection pb_lane_direction;
311 Status success = ToPbDirection(direction, &pb_lane_direction);
312 if (!success.ok()) {
313 std::string err_msg = "Error convert direction to pb direction";
315 }
316 lane->set_direction(pb_lane_direction);
317
318 return Status::OK();
319}
320
321Status LanesXmlParser::ParseCenterCurve(const tinyxml2::XMLElement& xml_node,
322 PbLane* lane) {
323 CHECK_NOTNULL(lane);
324 auto sub_node = xml_node.FirstChildElement("centerLine");
325 if (!sub_node) {
326 std::string err_msg = "Error parse lane center curve";
328 }
329
330 PbCurve* center_curve = lane->mutable_central_curve();
331 Status success = UtilXmlParser::ParseCurve(*sub_node, center_curve);
332 if (!success.ok()) {
333 std::string err_msg = "Error parse lane center curve";
335 }
336
337 lane->set_length(UtilXmlParser::CurveLength(*center_curve));
338
339 return Status::OK();
340}
341
342Status LanesXmlParser::ParseSpeed(const tinyxml2::XMLElement& xml_node,
343 PbLane* lane) {
344 double max_speed = 0.0;
345 auto sub_node = xml_node.FirstChildElement("speed");
346 if (sub_node) {
347 int checker = sub_node->QueryDoubleAttribute("max", &max_speed);
348 if (checker != tinyxml2::XML_SUCCESS) {
349 std::string err_msg = "Error parse lane speed attribute";
351 }
352 lane->set_speed_limit(ToMPS(max_speed));
353 }
354
355 return Status::OK();
356}
357
358Status LanesXmlParser::ParseSampleAssociates(
359 const tinyxml2::XMLElement& xml_node, PbLane* lane) {
360 CHECK_NOTNULL(lane);
361 auto sub_node = xml_node.FirstChildElement("sampleAssociates");
362 if (sub_node == nullptr) {
363 std::string err_msg = "Error parse sample associates";
365 }
366 sub_node = sub_node->FirstChildElement("sampleAssociate");
367 if (sub_node == nullptr) {
368 std::string err_msg = "Error parse sample associate";
370 }
371
372 while (sub_node) {
373 double left_width = 0.0;
374 double right_width = 0.0;
375 double s = 0.0;
376 int checker = sub_node->QueryDoubleAttribute("sOffset", &s);
377 checker += sub_node->QueryDoubleAttribute("leftWidth", &left_width);
378 checker += sub_node->QueryDoubleAttribute("rightWidth", &right_width);
379 if (checker != tinyxml2::XML_SUCCESS) {
380 std::string err_msg = "Error parse lane sample associate attribute";
382 }
383
384 auto left_sample = lane->add_left_sample();
385 left_sample->set_s(s);
386 left_sample->set_width(left_width);
387
388 auto right_sample = lane->add_right_sample();
389 right_sample->set_s(s);
390 right_sample->set_width(right_width);
391
392 sub_node = sub_node->NextSiblingElement("sampleAssociate");
393 }
394
395 return Status::OK();
396}
397
398Status LanesXmlParser::ParseSingleSideRoadSampleAssociates(
399 const tinyxml2::XMLElement& xml_node, bool bleft, PbLane* lane) {
400 CHECK_NOTNULL(lane);
401
402 auto sub_node = xml_node.FirstChildElement(
403 bleft ? "leftRoadSampleAssociations" : "rightRoadSampleAssociations");
404 if (sub_node == nullptr) {
405 std::string err_msg = "Error parse road sample associations";
407 }
408 sub_node = sub_node->FirstChildElement("sampleAssociation");
409 if (sub_node == nullptr) {
410 std::string err_msg = "Error parse road sample association";
412 }
413 while (sub_node) {
414 double width = 0.0;
415 double s = 0.0;
416 int checker = sub_node->QueryDoubleAttribute("sOffset", &s);
417 checker += sub_node->QueryDoubleAttribute("width", &width);
418 if (checker != tinyxml2::XML_SUCCESS) {
419 std::string err_msg = "Error parse road sample association attribute";
421 }
422
423 auto road_sample =
424 bleft ? lane->add_left_road_sample() : lane->add_right_road_sample();
425 road_sample->set_s(s);
426 road_sample->set_width(width);
427
428 sub_node = sub_node->NextSiblingElement("sampleAssociation");
429 }
430 return Status::OK();
431}
432
433Status LanesXmlParser::ParseLeftRoadSampleAssociates(
434 const tinyxml2::XMLElement& xml_node, PbLane* lane) {
435 CHECK_NOTNULL(lane);
436
437 return ParseSingleSideRoadSampleAssociates(xml_node, true, lane);
438}
439
440Status LanesXmlParser::ParseRightRoadSampleAssociates(
441 const tinyxml2::XMLElement& xml_node, PbLane* lane) {
442 CHECK_NOTNULL(lane);
443
444 return ParseSingleSideRoadSampleAssociates(xml_node, false, lane);
445}
446
447Status LanesXmlParser::ParseRoadSampleAssociates(
448 const tinyxml2::XMLElement& xml_node, PbLane* lane) {
449 CHECK_NOTNULL(lane);
450
451 auto sub_node = xml_node.FirstChildElement("roadSampleAssociations");
452 if (sub_node == nullptr) {
453 RETURN_IF_ERROR(ParseLeftRoadSampleAssociates(xml_node, lane));
454 RETURN_IF_ERROR(ParseRightRoadSampleAssociates(xml_node, lane));
455 } else {
456 sub_node = sub_node->FirstChildElement("sampleAssociation");
457 if (sub_node == nullptr) {
458 std::string err_msg = "Error parse road sample association";
460 }
461
462 while (sub_node) {
463 double left_width = 0.0;
464 double right_width = 0.0;
465 double s = 0.0;
466 int checker = sub_node->QueryDoubleAttribute("sOffset", &s);
467 checker += sub_node->QueryDoubleAttribute("leftWidth", &left_width);
468 checker += sub_node->QueryDoubleAttribute("rightWidth", &right_width);
469 if (checker != tinyxml2::XML_SUCCESS) {
470 std::string err_msg = "Error parse road sample association attribute";
472 }
473
474 auto left_road_sample = lane->add_left_road_sample();
475 left_road_sample->set_s(s);
476 left_road_sample->set_width(left_width);
477
478 auto right_road_sample = lane->add_right_road_sample();
479 right_road_sample->set_s(s);
480 right_road_sample->set_width(right_width);
481
482 sub_node = sub_node->NextSiblingElement("sampleAssociation");
483 }
484 }
485
486 return Status::OK();
487}
488
489Status LanesXmlParser::ParseObjectOverlapGroup(
490 const tinyxml2::XMLElement& xml_node,
491 std::vector<OverlapWithLane>* object_overlaps) {
492 CHECK_NOTNULL(object_overlaps);
493
494 auto object_overlap = xml_node.FirstChildElement("objectOverlapGroup");
495 if (object_overlap) {
496 auto sub_node = object_overlap->FirstChildElement("objectReference");
497 while (sub_node) {
498 std::string object_id;
499 double start_s = 0.0;
500 double end_s = 0.0;
501 int checker =
502 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
503 checker += sub_node->QueryDoubleAttribute("startOffset", &start_s);
504 checker += sub_node->QueryDoubleAttribute("endOffset", &end_s);
505 if (checker != tinyxml2::XML_SUCCESS) {
506 std::string err_msg = "Error parse lane object overlap";
508 }
509
510 bool is_merge = false;
511 checker = sub_node->QueryBoolAttribute("isMerge", &is_merge);
512 if (checker != tinyxml2::XML_SUCCESS) {
513 is_merge = false;
514 }
515
516 OverlapWithLane overlap_with_lane;
517 overlap_with_lane.object_id = object_id;
518 overlap_with_lane.start_s = start_s;
519 overlap_with_lane.end_s = end_s;
520 overlap_with_lane.is_merge = is_merge;
521
523 ParseRegionOverlap(*sub_node, &overlap_with_lane.region_overlaps));
524
525 if (overlap_with_lane.region_overlaps.size() > 0) {
527 *sub_node, "regionOverlapId", &overlap_with_lane.region_overlap_id);
528 }
529
530 object_overlaps->push_back(overlap_with_lane);
531
532 sub_node = sub_node->NextSiblingElement("objectReference");
533 }
534 }
535 return Status::OK();
536}
537
538Status LanesXmlParser::ParseSignalOverlapGroup(
539 const tinyxml2::XMLElement& xml_node,
540 std::vector<OverlapWithLane>* signal_overlaps) {
541 CHECK_NOTNULL(signal_overlaps);
542
543 auto signal_overlap = xml_node.FirstChildElement("signalOverlapGroup");
544 if (signal_overlap) {
545 auto sub_node = signal_overlap->FirstChildElement("signalReference");
546 while (sub_node) {
547 std::string object_id;
548 double start_s = 0.0;
549 double end_s = 0.0;
550 int checker =
551 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
552 checker += sub_node->QueryDoubleAttribute("startOffset", &start_s);
553 checker += sub_node->QueryDoubleAttribute("endOffset", &end_s);
554 if (checker != tinyxml2::XML_SUCCESS) {
555 std::string err_msg = "Error parse lane signal overlap";
557 }
558
559 bool is_merge = false;
560 checker = sub_node->QueryBoolAttribute("isMerge", &is_merge);
561 if (checker != tinyxml2::XML_SUCCESS) {
562 is_merge = false;
563 }
564
565 OverlapWithLane overlap_with_lane;
566 overlap_with_lane.object_id = object_id;
567 overlap_with_lane.start_s = start_s;
568 overlap_with_lane.end_s = end_s;
569 overlap_with_lane.is_merge = is_merge;
570
571 signal_overlaps->push_back(overlap_with_lane);
572
573 sub_node = sub_node->NextSiblingElement("signalReference");
574 }
575 }
576 return Status::OK();
577}
578
579Status LanesXmlParser::ParseJunctionOverlapGroup(
580 const tinyxml2::XMLElement& xml_node,
581 std::vector<OverlapWithLane>* junction_overlaps) {
582 CHECK_NOTNULL(junction_overlaps);
583
584 auto overlap_group = xml_node.FirstChildElement("junctionOverlapGroup");
585 if (overlap_group) {
586 auto sub_node = overlap_group->FirstChildElement("junctionReference");
587 while (sub_node) {
588 std::string object_id;
589 double start_s = 0.0;
590 double end_s = 0.0;
591 int checker =
592 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
593 checker += sub_node->QueryDoubleAttribute("startOffset", &start_s);
594 checker += sub_node->QueryDoubleAttribute("endOffset", &end_s);
595 if (checker != tinyxml2::XML_SUCCESS) {
596 std::string err_msg = "Error parse lane junction overlap";
598 }
599
600 bool is_merge = false;
601 checker = sub_node->QueryBoolAttribute("isMerge", &is_merge);
602 if (checker != tinyxml2::XML_SUCCESS) {
603 is_merge = false;
604 }
605
606 OverlapWithLane overlap_with_lane;
607 overlap_with_lane.object_id = object_id;
608 overlap_with_lane.start_s = start_s;
609 overlap_with_lane.end_s = end_s;
610 overlap_with_lane.is_merge = is_merge;
611
612 junction_overlaps->push_back(overlap_with_lane);
613
614 sub_node = sub_node->NextSiblingElement("junctionReference");
615 }
616 }
617 return Status::OK();
618}
619
620Status LanesXmlParser::ParseLaneOverlapGroup(
621 const tinyxml2::XMLElement& xml_node,
622 std::vector<OverlapWithLane>* lane_overlaps) {
623 CHECK_NOTNULL(lane_overlaps);
624
625 auto overlap_node = xml_node.FirstChildElement("laneOverlapGroup");
626 if (overlap_node) {
627 auto sub_node = overlap_node->FirstChildElement("laneReference");
628 while (sub_node) {
629 std::string lane_id;
630 double start_s = 0.0;
631 double end_s = 0.0;
632 int checker =
633 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &lane_id);
634 checker += sub_node->QueryDoubleAttribute("startOffset", &start_s);
635 checker += sub_node->QueryDoubleAttribute("endOffset", &end_s);
636 if (checker != tinyxml2::XML_SUCCESS) {
637 std::string err_msg = "Error parse lane lane overlap";
639 }
640
641 bool is_merge = false;
642 checker = sub_node->QueryBoolAttribute("isMerge", &is_merge);
643 if (checker != tinyxml2::XML_SUCCESS) {
644 is_merge = false;
645 }
646
647 OverlapWithLane overlap_with_lane;
648 overlap_with_lane.object_id = lane_id;
649 overlap_with_lane.start_s = start_s;
650 overlap_with_lane.end_s = end_s;
651 overlap_with_lane.is_merge = is_merge;
652
653 lane_overlaps->push_back(overlap_with_lane);
654
655 sub_node = sub_node->NextSiblingElement("laneReference");
656 }
657 }
658
659 return Status::OK();
660}
661
662Status LanesXmlParser::ToPbLaneType(const std::string& type,
663 PbLaneType* lane_type) {
664 CHECK_NOTNULL(lane_type);
665
666 std::string upper_str = UtilXmlParser::ToUpper(type);
667
668 if (upper_str == "NONE") {
669 *lane_type = hdmap::Lane::NONE;
670 } else if (upper_str == "DRIVING") {
671 *lane_type = hdmap::Lane::CITY_DRIVING;
672 } else if (upper_str == "BIKING") {
673 *lane_type = hdmap::Lane::BIKING;
674 } else if (upper_str == "PARKING") {
675 *lane_type = hdmap::Lane::PARKING;
676 } else if (upper_str == "SHOULDER") {
677 *lane_type = hdmap::Lane::SHOULDER;
678 } else if (upper_str == "SIDEWALK") {
679 *lane_type = hdmap::Lane::SIDEWALK;
680 } else {
681 std::string err_msg = "Error or unsupport lane type:" + type;
683 }
684
685 return Status::OK();
686}
687
688Status LanesXmlParser::ToPbTurnType(const std::string& type,
689 PbTurnType* pb_turn_type) {
690 CHECK_NOTNULL(pb_turn_type);
691
692 std::string upper_str = UtilXmlParser::ToUpper(type);
693
694 if (upper_str == "NOTURN") {
695 *pb_turn_type = hdmap::Lane::NO_TURN;
696 } else if (upper_str == "LEFTTURN") {
697 *pb_turn_type = hdmap::Lane::LEFT_TURN;
698 } else if (upper_str == "RIGHTTURN") {
699 *pb_turn_type = hdmap::Lane::RIGHT_TURN;
700 } else if (upper_str == "UTURN") {
701 *pb_turn_type = hdmap::Lane::U_TURN;
702 } else {
703 std::string err_msg = "Error or unsupport turn type:" + type;
705 }
706
707 return Status::OK();
708}
709
710Status LanesXmlParser::ToPbDirection(const std::string& type,
711 PbLaneDirection* pb_direction) {
712 CHECK_NOTNULL(pb_direction);
713
714 std::string upper_str = UtilXmlParser::ToUpper(type);
715
716 if (upper_str == "FORWARD") {
717 *pb_direction = hdmap::Lane::FORWARD;
718 } else if (upper_str == "BACKWARD") {
719 *pb_direction = hdmap::Lane::BACKWARD;
720 } else if (upper_str == "BIDIRECTION") {
721 *pb_direction = hdmap::Lane::BIDIRECTION;
722 } else {
723 std::string err_msg = "Error or unsupport dirction:" + type;
725 }
726
727 return Status::OK();
728}
729
730void LanesXmlParser::ParseLaneLink(const tinyxml2::XMLElement& xml_node,
731 PbLane* lane) {
732 CHECK_NOTNULL(lane);
733
734 const tinyxml2::XMLElement* sub_node =
735 xml_node.FirstChildElement("predecessor");
736 while (sub_node) {
737 std::string lane_id;
738 int checker =
739 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &lane_id);
740 if (checker == tinyxml2::XML_SUCCESS) {
741 PbID* pb_lane_id = lane->add_predecessor_id();
742 pb_lane_id->set_id(lane_id);
743 }
744 sub_node = sub_node->NextSiblingElement("predecessor");
745 }
746
747 sub_node = xml_node.FirstChildElement("successor");
748 while (sub_node) {
749 std::string lane_id;
750 int checker =
751 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &lane_id);
752 if (checker == tinyxml2::XML_SUCCESS) {
753 PbID* pb_lane_id = lane->add_successor_id();
754 pb_lane_id->set_id(lane_id);
755 }
756 sub_node = sub_node->NextSiblingElement("successor");
757 }
758
759 sub_node = xml_node.FirstChildElement("neighbor");
760 while (sub_node) {
761 std::string side;
762 std::string direction;
763 std::string lane_id;
764 int checker =
765 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &lane_id);
766 checker += UtilXmlParser::QueryStringAttribute(*sub_node, "side", &side);
767 checker +=
768 UtilXmlParser::QueryStringAttribute(*sub_node, "direction", &direction);
769 if (checker == tinyxml2::XML_SUCCESS) {
770 if (side == "left") {
771 if (direction == "same") {
772 lane->add_left_neighbor_forward_lane_id()->set_id(lane_id);
773 } else {
774 lane->add_left_neighbor_reverse_lane_id()->set_id(lane_id);
775 }
776 } else if (side == "right") {
777 if (direction == "same") {
778 lane->add_right_neighbor_forward_lane_id()->set_id(lane_id);
779 } else {
780 lane->add_right_neighbor_reverse_lane_id()->set_id(lane_id);
781 }
782 }
783 }
784 sub_node = sub_node->NextSiblingElement("neighbor");
785 }
786
787 sub_node = xml_node.FirstChildElement("selfReverse");
788 while (sub_node) {
789 std::string lane_id;
790 int checker =
791 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &lane_id);
792 if (checker == tinyxml2::XML_SUCCESS) {
793 lane->add_self_reverse_lane_id()->set_id(lane_id);
794 }
795 sub_node = sub_node->NextSiblingElement("selfReverse");
796 }
797}
798
799Status LanesXmlParser::ParseLaneBorderMark(
800 const tinyxml2::XMLElement& xml_node,
801 PbLaneBoundaryTypeType* boundary_type) {
802 CHECK_NOTNULL(boundary_type);
803
804 std::string type;
805 std::string color;
806
807 int checker = UtilXmlParser::QueryStringAttribute(xml_node, "type", &type);
808 checker += UtilXmlParser::QueryStringAttribute(xml_node, "color", &color);
809 if (checker != tinyxml2::XML_SUCCESS) {
810 std::string err_msg = "Error to parse lane border mark";
812 }
813
814 Status success = ToPbLaneMarkType(type, color, boundary_type);
815 if (!success.ok()) {
816 std::string err_msg = "fail to convert to pb lane border mark";
818 }
819
820 return Status::OK();
821}
822
823Status LanesXmlParser::ToPbLaneMarkType(const std::string& type,
824 const std::string& color,
825 PbLaneBoundaryTypeType* boundary_type) {
826 CHECK_NOTNULL(boundary_type);
827
828 std::string upper_type = UtilXmlParser::ToUpper(type);
829 std::string upper_color = UtilXmlParser::ToUpper(color);
830
831 if (upper_type == "CURB") {
832 *boundary_type = hdmap::LaneBoundaryType::CURB;
833 return Status::OK();
834 }
835
836 if (upper_type == "NONE") {
837 *boundary_type = hdmap::LaneBoundaryType::UNKNOWN;
838 return Status::OK();
839 }
840
841 if (upper_color == "YELLOW") {
842 if (upper_type == "SOLID") {
844 } else if (upper_type == "BROKEN") {
846 } else {
847 std::string err_msg = "Error or unsupport lane boundary type";
849 }
850 } else if (upper_color == "WHITE") {
851 if (upper_type == "SOLID") {
853 } else if (upper_type == "BROKEN") {
855 } else {
856 std::string err_msg = "Error or unsupport lane boundary type";
858 }
859 } else {
860 std::string err_msg = "Error or unsupport lane boundary color.";
862 }
863
864 return Status::OK();
865}
866
867Status LanesXmlParser::ParseRegionOverlap(
868 const tinyxml2::XMLElement& xml_node,
869 std::vector<PbRegionOverlap>* region_overlaps) {
870 CHECK_NOTNULL(region_overlaps);
871
872 auto region_overlap_node = xml_node.FirstChildElement("regionOverlap");
873 while (region_overlap_node != nullptr) {
874 PbRegionOverlap region_overlap;
875
876 std::string region_overlap_id;
877 int checker = UtilXmlParser::QueryStringAttribute(*region_overlap_node,
878 "id", &region_overlap_id);
879 if (checker != tinyxml2::XML_SUCCESS) {
880 std::string err_msg = "Error to parse region overlap id";
882 }
883
884 region_overlap.mutable_id()->set_id(region_overlap_id);
885
886 auto outline_node = region_overlap_node->FirstChildElement("outline");
887 while (outline_node != nullptr) {
889 *outline_node, region_overlap.add_polygon()));
890 outline_node = outline_node->NextSiblingElement("outline");
891 }
892
893 region_overlap_node =
894 region_overlap_node->NextSiblingElement("regionOverlap");
895
896 region_overlaps->emplace_back(region_overlap);
897 }
898
899 return Status::OK();
900}
901
902} // namespace adapter
903} // namespace hdmap
904} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
static Status OK()
generate a success status.
Definition status.h:60
static Status Parse(const tinyxml2::XMLElement &xml_node, const std::string &road_id, std::vector< RoadSectionInternal > *sections)
static std::string ToUpper(const std::string &s)
static double CurveLength(const PbCurve &curve)
static tinyxml2::XMLError QueryStringAttribute(const tinyxml2::XMLElement &xml_node, const std::string &name, std::string *value)
static Status ParseCurve(const tinyxml2::XMLElement &xml_node, PbCurve *curve)
static Status ParseOutline(const tinyxml2::XMLElement &xml_node, PbPolygon *polygon)
#define ACHECK(cond)
Definition log.h:80
#define RETURN_IF_ERROR(expr)
Definition status.h:25
uint32_t width
Width of point cloud
apollo::hdmap::BoundaryEdge_Type PbBoundaryEdgeType
apollo::hdmap::Lane_LaneType PbLaneType
apollo::hdmap::Curve PbCurve
apollo::hdmap::RegionOverlapInfo PbRegionOverlap
apollo::hdmap::LaneBoundary PbLaneBoundary
apollo::hdmap::Lane_LaneDirection PbLaneDirection
apollo::hdmap::Lane PbLane
apollo::hdmap::LaneBoundaryType_Type PbLaneBoundaryTypeType
apollo::hdmap::Lane_LaneTurn PbTurnType
apollo::hdmap::BoundaryEdge PbBoundaryEdge
apollo::hdmap::Id PbID
class register implement
Definition arena_queue.h:37
optional LaneBoundary left_boundary