Apollo 10.0
自动驾驶开放平台
objects_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=========================================================================*/
15
17
18#include <string>
19
21
22namespace apollo {
23namespace hdmap {
24namespace adapter {
25
26Status ObjectsXmlParser::ParseCrosswalks(const tinyxml2::XMLElement& xml_node,
27 std::vector<PbCrosswalk>* crosswalks) {
28 CHECK_NOTNULL(crosswalks);
29 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("object");
30 while (sub_node) {
31 std::string object_type;
32 std::string object_id;
33 int checker =
34 UtilXmlParser::QueryStringAttribute(*sub_node, "type", &object_type);
35 checker += UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
36 if (checker != tinyxml2::XML_SUCCESS) {
37 std::string err_msg = "Error parse object type.";
39 }
40
41 if (object_type == "crosswalk") {
42 PbCrosswalk crosswalk;
43 crosswalk.mutable_id()->set_id(object_id);
44 PbPolygon* polygon = crosswalk.mutable_polygon();
45 const tinyxml2::XMLElement* outline_node =
46 sub_node->FirstChildElement("outline");
47 if (outline_node == nullptr) {
48 std::string err_msg = "Error parse crosswalk outline";
50 }
51 RETURN_IF_ERROR(UtilXmlParser::ParseOutline(*outline_node, polygon));
52 crosswalks->emplace_back(crosswalk);
53 }
54 sub_node = sub_node->NextSiblingElement("object");
55 }
56 return Status::OK();
57}
58
60 const tinyxml2::XMLElement& xml_node,
61 std::vector<PbClearArea>* clear_areas) {
62 CHECK_NOTNULL(clear_areas);
63 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("object");
64 while (sub_node) {
65 std::string object_type;
66 std::string object_id;
67 int checker =
68 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
69 checker +=
70 UtilXmlParser::QueryStringAttribute(*sub_node, "type", &object_type);
71 if (checker != tinyxml2::XML_SUCCESS) {
72 std::string err_msg = "Error parse object type.";
74 }
75
76 if (object_type == "clearArea") {
77 PbClearArea clear_area;
78 clear_area.mutable_id()->set_id(object_id);
79 PbPolygon* polygon = clear_area.mutable_polygon();
80 ACHECK(polygon != nullptr);
81 const tinyxml2::XMLElement* outline_node =
82 sub_node->FirstChildElement("outline");
83 if (outline_node == nullptr) {
84 std::string err_msg = "Error parse cleararea outline";
86 }
87 RETURN_IF_ERROR(UtilXmlParser::ParseOutline(*outline_node, polygon));
88 clear_areas->emplace_back(clear_area);
89 }
90 sub_node = sub_node->NextSiblingElement("object");
91 }
92
93 return Status::OK();
94}
95
97 const tinyxml2::XMLElement& xml_node,
98 std::vector<PbSpeedBump>* speed_bumps) {
99 CHECK_NOTNULL(speed_bumps);
100 const tinyxml2::XMLElement* object_node =
101 xml_node.FirstChildElement("object");
102 while (object_node) {
103 std::string object_type;
104 std::string object_id;
105 int checker =
106 UtilXmlParser::QueryStringAttribute(*object_node, "id", &object_id);
107 checker +=
108 UtilXmlParser::QueryStringAttribute(*object_node, "type", &object_type);
109 if (checker != tinyxml2::XML_SUCCESS) {
110 std::string err_msg = "Error parse object type.";
112 }
113
114 if (object_type == "speedBump") {
115 PbSpeedBump speed_bump;
116 const tinyxml2::XMLElement* sub_node =
117 object_node->FirstChildElement("geometry");
118 speed_bump.mutable_id()->set_id(object_id);
119 while (sub_node) {
120 PbCurve* curve = speed_bump.add_position();
121 PbCurveSegment* curve_segment = curve->add_segment();
122 RETURN_IF_ERROR(UtilXmlParser::ParseGeometry(*sub_node, curve_segment));
123 sub_node = sub_node->NextSiblingElement("geometry");
124 }
125 if (speed_bump.position().empty()) {
126 std::string err_msg = "Error speed bump miss stop line.";
128 }
129 speed_bumps->emplace_back(speed_bump);
130 }
131 object_node = object_node->NextSiblingElement("object");
132 }
133 return Status::OK();
134}
135
137 const tinyxml2::XMLElement& xml_node,
138 std::vector<StopLineInternal>* stop_lines) {
139 CHECK_NOTNULL(stop_lines);
140 const tinyxml2::XMLElement* object_node =
141 xml_node.FirstChildElement("object");
142 while (object_node) {
143 std::string object_type;
144 std::string object_id;
145 int checker =
146 UtilXmlParser::QueryStringAttribute(*object_node, "id", &object_id);
147 checker +=
148 UtilXmlParser::QueryStringAttribute(*object_node, "type", &object_type);
149 if (checker != tinyxml2::XML_SUCCESS) {
150 std::string err_msg = "Error parse object type.";
152 }
153
154 if (object_type == "stopline") {
155 StopLineInternal stop_line;
156 stop_line.id = object_id;
157 PbCurveSegment* curve_segment = stop_line.curve.add_segment();
158 ACHECK(curve_segment != nullptr);
159 const auto sub_node = object_node->FirstChildElement("geometry");
160 if (sub_node == nullptr) {
161 std::string err_msg = "Error parse stopline geometry";
163 }
164 RETURN_IF_ERROR(UtilXmlParser::ParseGeometry(*sub_node, curve_segment));
165 stop_lines->emplace_back(stop_line);
166 }
167 object_node = object_node->NextSiblingElement("object");
168 }
169 return Status::OK();
170}
171
173 const tinyxml2::XMLElement& xml_node,
174 std::vector<PbParkingSpace>* parking_spaces) {
175 CHECK_NOTNULL(parking_spaces);
176 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("object");
177 while (sub_node) {
178 std::string object_type;
179 std::string object_id;
180 int checker =
181 UtilXmlParser::QueryStringAttribute(*sub_node, "type", &object_type);
182 checker += UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
183 if (checker != tinyxml2::XML_SUCCESS) {
184 std::string err_msg = "Error parse object type.";
186 }
187
188 if (object_type == "parkingSpace") {
189 PbParkingSpace parking_space;
190 parking_space.mutable_id()->set_id(object_id);
191
192 double heading = 0.0;
193 checker = sub_node->QueryDoubleAttribute("heading", &heading);
194 if (checker != tinyxml2::XML_SUCCESS) {
195 std::string err_msg = "Error parse parking space heading.";
197 }
198 parking_space.set_heading(heading);
199
200 PbPolygon* polygon = parking_space.mutable_polygon();
201 const auto* outline_node = sub_node->FirstChildElement("outline");
202 if (outline_node == nullptr) {
203 std::string err_msg = "Error parse parking space outline";
205 }
206 RETURN_IF_ERROR(UtilXmlParser::ParseOutline(*outline_node, polygon));
207 parking_spaces->emplace_back(parking_space);
208 }
209 sub_node = sub_node->NextSiblingElement("object");
210 }
211 return Status::OK();
212}
213
215 const tinyxml2::XMLElement& xml_node,
216 std::vector<PbPNCJunction>* pnc_junctions) {
217 CHECK_NOTNULL(pnc_junctions);
218
219 const tinyxml2::XMLElement* sub_node = xml_node.FirstChildElement("object");
220 while (sub_node) {
221 std::string object_type;
222 std::string object_id;
223 int checker =
224 UtilXmlParser::QueryStringAttribute(*sub_node, "type", &object_type);
225 checker += UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
226 if (checker != tinyxml2::XML_SUCCESS) {
227 std::string err_msg = "Error parse object type.";
229 }
230
231 if (object_type == "PNCJunction") {
232 PbPNCJunction pnc_junction;
233 pnc_junction.mutable_id()->set_id(object_id);
234
235 PbPolygon* polygon = pnc_junction.mutable_polygon();
236 const auto* outline_node = sub_node->FirstChildElement("outline");
237 if (outline_node == nullptr) {
238 std::string err_msg = "Error parse pnc junction outline";
240 }
241 RETURN_IF_ERROR(UtilXmlParser::ParseOutline(*outline_node, polygon));
242
243 RETURN_IF_ERROR(ParsePassageGroup(*sub_node, &pnc_junction));
244
245 pnc_junctions->emplace_back(pnc_junction);
246 }
247
248 sub_node = sub_node->NextSiblingElement("object");
249 }
250
251 return Status::OK();
252}
253
254Status ObjectsXmlParser::ParsePassageGroup(const tinyxml2::XMLElement& xml_node,
255 PbPNCJunction* pnc_junction) {
256 CHECK_NOTNULL(pnc_junction);
257
258 auto sub_node = xml_node.FirstChildElement("passageGroup");
259 while (sub_node) {
260 std::string object_id;
261 std::string object_type;
262 PbPassageGroup* passage_group = pnc_junction->add_passage_group();
263 int checker =
264 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
265 if (checker != tinyxml2::XML_SUCCESS) {
266 std::string err_msg = "Error parse object type.";
268 }
269 passage_group->mutable_id()->set_id(object_id);
270
271 RETURN_IF_ERROR(ParsePassage(*sub_node, passage_group));
272
273 sub_node = sub_node->NextSiblingElement("passageGroup");
274 }
275
276 return Status::OK();
277}
278
279Status ObjectsXmlParser::ParsePassage(const tinyxml2::XMLElement& xml_node,
280 PbPassageGroup* passage_group) {
281 CHECK_NOTNULL(passage_group);
282
283 auto sub_node = xml_node.FirstChildElement("passage");
284 while (sub_node) {
285 std::string object_type;
286 int checker =
287 UtilXmlParser::QueryStringAttribute(*sub_node, "type", &object_type);
288 if (checker != tinyxml2::XML_SUCCESS) {
289 std::string err_msg = "Error parse object type.";
291 }
292
293 auto passage = passage_group->add_passage();
294 PbPassageType pb_passage_type;
295 RETURN_IF_ERROR(ToPassageType(object_type, &pb_passage_type));
296 passage->set_type(pb_passage_type);
297
298 std::vector<std::string> passage_node_ids;
299 RETURN_IF_ERROR(ParsePassageIds(*sub_node, "laneID", &passage_node_ids));
300 for (auto id : passage_node_ids) {
301 passage->add_lane_id()->set_id(id);
302 }
303
304 RETURN_IF_ERROR(ParsePassageIds(*sub_node, "signalID", &passage_node_ids));
305 for (auto id : passage_node_ids) {
306 passage->add_signal_id()->set_id(id);
307 }
308
309 RETURN_IF_ERROR(ParsePassageIds(*sub_node, "yieldlID", &passage_node_ids));
310 for (auto id : passage_node_ids) {
311 passage->add_yield_id()->set_id(id);
312 }
313
315 ParsePassageIds(*sub_node, "stopSignID", &passage_node_ids));
316 for (auto id : passage_node_ids) {
317 passage->add_stop_sign_id()->set_id(id);
318 }
319
320 sub_node = sub_node->NextSiblingElement("passage");
321 }
322
323 return Status::OK();
324}
325
327 const tinyxml2::XMLElement& xml_node, const std::string& child_node_name,
328 std::vector<std::string>* passage_node_ids) {
329 CHECK_NOTNULL(passage_node_ids);
330
331 passage_node_ids->clear();
332 auto sub_node = xml_node.FirstChildElement(child_node_name.c_str());
333 while (sub_node) {
334 std::string object_id;
335 int checker =
336 UtilXmlParser::QueryStringAttribute(*sub_node, "id", &object_id);
337 if (checker != tinyxml2::XML_SUCCESS) {
338 std::string err_msg = "Error parse passage lane id.";
340 }
341 passage_node_ids->push_back(object_id);
342
343 sub_node = sub_node->NextSiblingElement(child_node_name.c_str());
344 }
345
346 return Status::OK();
347}
348
350 PbPassageType* passage_type) {
351 CHECK_NOTNULL(passage_type);
352
353 std::string upper_str = UtilXmlParser::ToUpper(type);
354 if (upper_str == "ENTRANCE") {
355 *passage_type = apollo::hdmap::Passage_Type_ENTRANCE;
356 } else if (upper_str == "EXIT") {
357 *passage_type = apollo::hdmap::Passage_Type_EXIT;
358 } else {
359 *passage_type = apollo::hdmap::Passage_Type_UNKNOWN;
360 }
361
362 return Status::OK();
363}
364
366 const tinyxml2::XMLElement& xml_node,
367 std::vector<RSUInternal>* rsus) {
368 CHECK_NOTNULL(rsus);
369
370 auto rsu_node = xml_node.FirstChildElement("object");
371 while (rsu_node) {
372 std::string object_type;
373 std::string object_id;
374 int checker =
375 UtilXmlParser::QueryStringAttribute(*rsu_node, "type", &object_type);
376 checker +=
377 UtilXmlParser::QueryStringAttribute(*rsu_node, "id", &object_id);
378 if (checker != tinyxml2::XML_SUCCESS) {
379 std::string err_msg = "Error parse rsu type.";
381 }
382
383 if (object_type == "rsu") {
384 std::string junction_id;
385 checker = UtilXmlParser::QueryStringAttribute(*rsu_node,
386 "junctionID", &junction_id);
387 if (checker != tinyxml2::XML_SUCCESS) {
388 std::string err_msg = "Error parse rsu junction id.";
390 }
391
392 RSUInternal rsu;
393 rsu.rsu.mutable_id()->set_id(object_id);
394 rsu.rsu.mutable_junction_id()->set_id(junction_id);
395 rsu.id = object_id;
396 rsus->emplace_back(rsu);
397
398 rsu_node = rsu_node->NextSiblingElement("object");
399 }
400 }
401
402 return Status::OK();
403}
404
405Status ObjectsXmlParser::ParseObjects(const tinyxml2::XMLElement& xml_node,
406 ObjectInternal* objects) {
407 CHECK_NOTNULL(objects);
408
409 // objects
410 auto sub_node = xml_node.FirstChildElement("objects");
411 if (sub_node != nullptr) {
412 // rsus
413 RETURN_IF_ERROR(ObjectsXmlParser::ParseRSUs(*sub_node, &objects->rsus));
414 }
415
416 return Status::OK();
417}
418
419} // namespace adapter
420} // namespace hdmap
421} // 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 ParseObjects(const tinyxml2::XMLElement &xml_node, ObjectInternal *objects)
static Status ParsePassageIds(const tinyxml2::XMLElement &xml_node, const std::string &child_node_name, std::vector< std::string > *passage_node_ids)
static Status ParseSpeedBumps(const tinyxml2::XMLElement &xml_node, std::vector< PbSpeedBump > *speed_bumps)
static Status ParsePassage(const tinyxml2::XMLElement &xml_node, PbPassageGroup *passage_group)
static Status ParsePassageGroup(const tinyxml2::XMLElement &xml_node, PbPNCJunction *pnc_junction)
static Status ParseCrosswalks(const tinyxml2::XMLElement &xml_node, std::vector< PbCrosswalk > *crosswalks)
static Status ParseClearAreas(const tinyxml2::XMLElement &xml_node, std::vector< PbClearArea > *clear_areas)
static Status ParsePNCJunctions(const tinyxml2::XMLElement &xml_node, std::vector< PbPNCJunction > *pnc_junctions)
static Status ToPassageType(const std::string &type, PbPassageType *passage_type)
static Status ParseStopLines(const tinyxml2::XMLElement &xml_node, std::vector< StopLineInternal > *stop_lines)
static Status ParseParkingSpaces(const tinyxml2::XMLElement &xml_node, std::vector< PbParkingSpace > *parking_spaces)
static Status ParseRSUs(const tinyxml2::XMLElement &xml_node, std::vector< RSUInternal > *rsus)
static Status ParseGeometry(const tinyxml2::XMLElement &xml_node, PbCurveSegment *curve_segment)
static std::string ToUpper(const std::string &s)
static tinyxml2::XMLError QueryStringAttribute(const tinyxml2::XMLElement &xml_node, const std::string &name, std::string *value)
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
apollo::hdmap::Passage_Type PbPassageType
class register implement
Definition arena_queue.h:37
std::vector< RSUInternal > rsus