Skip to content

Commit de51148

Browse files
committed
feature: introduce OdrNode::xml_offset to locate an OdrNode in its source xodr xml, set during OpenDriveMap::load
1 parent ea5973d commit de51148

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

include/libodr/OdrNode.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22

3+
#include <cstddef>
34
#include <memory>
45

56
namespace odr
@@ -20,6 +21,8 @@ struct OdrNode
2021

2122
void set_parent(OdrNode* parent);
2223

24+
std::ptrdiff_t xml_offset = -1; // locate element in xml, is utf8-based offset for pugixml by default
25+
2326
private:
2427
std::shared_ptr<OdrNode*> self_;
2528
std::weak_ptr<OdrNode*> parent_;

src/OdrNode.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
namespace odr
66
{
77

8-
OdrNode::OdrNode(const OdrNode&) noexcept {}
8+
OdrNode::OdrNode(const OdrNode& other) noexcept : xml_offset(other.xml_offset) {}
99

10-
OdrNode::OdrNode(OdrNode&& other) noexcept : self_(std::move(other.self_)), parent_(std::move(other.parent_))
10+
OdrNode::OdrNode(OdrNode&& other) noexcept : xml_offset(other.xml_offset), self_(std::move(other.self_)), parent_(std::move(other.parent_))
1111
{
1212
if (self_)
1313
*self_ = this;
1414
other.parent_.reset();
1515
}
1616

17-
OdrNode& OdrNode::operator=(const OdrNode&) noexcept
17+
OdrNode& OdrNode::operator=(const OdrNode& other) noexcept
1818
{
19+
xml_offset = other.xml_offset;
1920
parent_.reset();
2021
return *this;
2122
}
@@ -30,6 +31,7 @@ OdrNode& OdrNode::operator=(OdrNode&& other) noexcept
3031
self_ = std::move(other.self_);
3132
*self_ = this;
3233
}
34+
xml_offset = other.xml_offset;
3335
parent_ = std::move(other.parent_);
3436
other.parent_.reset();
3537
return *this;

src/OpenDriveMap.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
8787
try_get_attribute<std::string>(header_node, "vendor"),
8888
try_get_attribute<std::string>(header_node, "version"),
8989
georef_node ? std::optional<std::string>(georef_node.text().as_string("")) : std::nullopt);
90+
this->header.xml_offset = header_node.offset_debug();
9091

9192
// Roads
9293
if (!odr_node.child("road"))
@@ -119,6 +120,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
119120
result.errors.push_back({road_node, ex.what()});
120121
continue;
121122
}
123+
road->xml_offset = road_node.offset_debug();
122124

123125
// parse road links
124126
const pugi::xml_node link_node = road_node.child("link");
@@ -139,6 +141,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
139141
result.errors.push_back({next_link_node, ex.what()});
140142
continue;
141143
}
144+
link->xml_offset = next_link_node.offset_debug();
142145

143146
std::optional<RoadLink>& road_link = is_predecessor ? road->predecessor : road->successor;
144147
road_link = link;
@@ -163,7 +166,9 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
163166
{
164167
const std::string speed_record_max = node.attribute("max").as_string("");
165168
const std::string speed_record_unit = node.attribute("unit").as_string("");
166-
road->s_to_speed.emplace(s, Speed(speed_record_max, speed_record_unit));
169+
Speed speed(speed_record_max, speed_record_unit);
170+
speed.xml_offset = node.offset_debug();
171+
road->s_to_speed.emplace(s, std::move(speed));
167172
}
168173
}
169174

@@ -348,6 +353,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
348353
invalid_lane_section = true;
349354
continue;
350355
}
356+
lane_section->xml_offset = lane_section_node.offset_debug();
351357

352358
for (const pugi::xpath_node lane_xpath_node : lane_section_node.select_nodes(".//lane"))
353359
{
@@ -372,6 +378,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
372378
.emplace(*lane_id,
373379
Lane(*lane_id, try_get_attribute<std::string>(lane_node, "type"), try_get_attribute<bool>(lane_node, "level")))
374380
.first->second;
381+
lane.xml_offset = lane_node.offset_debug();
375382

376383
if (const pugi::xml_attribute id_attr = lane_node.child("link").child("predecessor").attribute("id"))
377384
lane.predecessor = id_attr.as_int();
@@ -428,6 +435,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
428435
result.errors.push_back({lane_height_node, ex.what()});
429436
continue;
430437
}
438+
height_offset->xml_offset = lane_height_node.offset_debug();
431439
lane.s_to_height_offset.emplace(lane_section->s + height_offset->s_offset, *height_offset);
432440
}
433441
}
@@ -451,6 +459,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
451459
result.errors.push_back({roadmark_node, ex.what()});
452460
continue;
453461
}
462+
roadmark->xml_offset = roadmark_node.offset_debug();
454463

455464
if (const pugi::xml_node roadmark_type_node = roadmark_node.child("type"))
456465
{
@@ -467,6 +476,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
467476

468477
if (roadmark_type)
469478
{
479+
roadmark_type->xml_offset = roadmark_type_node.offset_debug();
470480
for (const pugi::xml_node roadmarks_line_node : roadmark_type_node.children("line"))
471481
{
472482
std::optional<RoadMarkLine> roadmark_line;
@@ -485,6 +495,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
485495
result.errors.push_back({roadmarks_line_node, ex.what()});
486496
continue;
487497
}
498+
roadmark_line->xml_offset = roadmarks_line_node.offset_debug();
488499

489500
roadmark_type->lines.emplace_back(std::move(*roadmark_line));
490501
}
@@ -590,6 +601,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
590601
result.errors.push_back({object_node, ex.what()});
591602
continue;
592603
}
604+
road_object->xml_offset = object_node.offset_debug();
593605

594606
for (const pugi::xml_node repeat_node : object_node.children("repeat"))
595607
{
@@ -606,6 +618,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
606618
try_get_attribute<double>(repeat_node, "zOffsetEnd"),
607619
try_get_attribute<double>(repeat_node, "widthStart"),
608620
try_get_attribute<double>(repeat_node, "widthEnd"));
621+
road_object->repeats.back().xml_offset = repeat_node.offset_debug();
609622
}
610623
catch (const std::exception& ex)
611624
{
@@ -622,6 +635,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
622635
try_get_attribute<std::string>(outline_node, "laneType"),
623636
try_get_attribute<bool>(outline_node, "outer"),
624637
try_get_attribute<bool>(outline_node, "closed"));
638+
road_object_outline.xml_offset = outline_node.offset_debug();
625639

626640
for (const pugi::xml_node corner_local_node : outline_node.children("cornerLocal"))
627641
{
@@ -634,6 +648,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
634648
corner_local_node.attribute("height").as_double(NAN),
635649
default_local_outline_type,
636650
try_get_attribute<int>(corner_local_node, "id"));
651+
road_object_outline.outline.back().xml_offset = corner_local_node.offset_debug();
637652
}
638653
catch (const std::exception& ex)
639654
{
@@ -652,6 +667,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
652667
corner_road_node.attribute("height").as_double(NAN),
653668
RoadObjectCorner::Type::Road,
654669
try_get_attribute<int>(corner_road_node, "id"));
670+
road_object_outline.outline.back().xml_offset = corner_road_node.offset_debug();
655671
}
656672
catch (const std::exception& ex)
657673
{
@@ -673,6 +689,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
673689
continue;
674690
}
675691
road_object->lane_validities.emplace_back(*from_lane, *to_lane);
692+
road_object->lane_validities.back().xml_offset = validity_node.offset_debug();
676693
}
677694

678695
road->id_to_object.emplace(*object_id, std::move(*road_object));
@@ -723,6 +740,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
723740
result.errors.push_back({signal_node, ex.what()});
724741
continue;
725742
}
743+
road_signal->xml_offset = signal_node.offset_debug();
726744

727745
for (const pugi::xml_node validity_node : signal_node.children("validity"))
728746
{
@@ -734,6 +752,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
734752
const int from_lane = validity_node.attribute("fromLane").as_int(INT_MIN);
735753
const int to_lane = validity_node.attribute("toLane").as_int(INT_MAX);
736754
road_signal->lane_validities.emplace_back(from_lane, to_lane);
755+
road_signal->lane_validities.back().xml_offset = validity_node.offset_debug();
737756
}
738757

739758
road->id_to_signal.emplace(*signal_id, std::move(*road_signal));
@@ -760,6 +779,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
760779

761780
Junction& junction =
762781
this->id_to_junction.emplace(*junction_id, Junction(*junction_id, try_get_attribute<std::string>(junction_node, "name"))).first->second;
782+
junction.xml_offset = junction_node.offset_debug();
763783

764784
for (const pugi::xml_node connection_node : junction_node.children("connection"))
765785
{
@@ -782,6 +802,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
782802
connection_node.attribute("connectingRoad").as_string(""),
783803
connection_node.attribute("contactPoint").as_string("")))
784804
.first->second;
805+
connection.xml_offset = connection_node.offset_debug();
785806

786807
for (const pugi::xml_node lane_link_node : connection_node.children("laneLink"))
787808
{
@@ -793,6 +814,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
793814
continue;
794815
}
795816
connection.lane_links.emplace_back(*from_lane, *to_lane);
817+
connection.lane_links.back().xml_offset = lane_link_node.offset_debug();
796818
}
797819
}
798820

@@ -811,6 +833,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
811833
continue;
812834
}
813835
junction.priorities.emplace_back(*prio_high, *prio_low);
836+
junction.priorities.back().xml_offset = priority_node.offset_debug();
814837
}
815838

816839
for (const pugi::xml_node controller_node : junction_node.children("controller"))
@@ -838,6 +861,7 @@ XodrParseResult OpenDriveMap::load(const pugi::xml_document& xml_doc,
838861
result.errors.push_back({controller_node, ex.what()});
839862
continue;
840863
}
864+
junction_controller->xml_offset = controller_node.offset_debug();
841865

842866
junction.id_to_controller.emplace(*controller_id, std::move(*junction_controller));
843867
}

0 commit comments

Comments
 (0)