diff --git a/include/opendrive_geometry.h b/include/opendrive_geometry.h
index 1ca5939c82b7dace15748416e07f38a28fb72d3a..a49f6700825e70e620dc572e08f7337986fb0c60 100644
--- a/include/opendrive_geometry.h
+++ b/include/opendrive_geometry.h
@@ -13,6 +13,7 @@ class COpendriveGeometry
   friend class COpendriveRoadNode;
   private:
   protected:
+    void load(const planView::geometry_type &geometry_info);
     double scale_factor;
     double min_s; ///< Starting track coordenate "s" for the geometry.
     double max_s; ///< Ending track coordenate "s" for the geometry.
@@ -27,7 +28,6 @@ class COpendriveGeometry
     COpendriveGeometry(double min_s, double max_s, double x, double y, double heading);
     COpendriveGeometry(const COpendriveGeometry &object);
     virtual COpendriveGeometry *clone(void) = 0;
-    void load(const planView::geometry_type &geometry_info);
     bool get_local_pose(TOpendriveTrackPoint &track,TOpendriveLocalPoint &local) const;
     bool get_world_pose(TOpendriveTrackPoint &track,TOpendriveWorldPoint &world) const;
     bool in_range(double s) const;
diff --git a/include/opendrive_lane.h b/include/opendrive_lane.h
index f3b9a24246b5d943c4ed7f43878dd18e4ab460be..eeb4c409ecffdef6c809631dee92e9382b61005c 100644
--- a/include/opendrive_lane.h
+++ b/include/opendrive_lane.h
@@ -27,6 +27,7 @@ class COpendriveLane
     double offset;
     int id;
   protected:
+    void load(const right::lane_type &lane_info,COpendriveRoadSegment *segment);
     void link_neightbour_lane(COpendriveLane *lane);
     void link_lane(COpendriveLane *lane,opendrive_mark_t mark);
     void add_node(COpendriveRoadNode *node);
@@ -37,7 +38,6 @@ class COpendriveLane
   public:
     COpendriveLane();
     COpendriveLane(const COpendriveLane &object);
-    void load(const right::lane_type &lane_info,COpendriveRoadSegment *segment);
     unsigned int get_num_nodes(void) const;
     const COpendriveRoadNode &get_node(unsigned int index) const;
     const COpendriveRoadSegment &get_segment(void) const;
diff --git a/include/opendrive_object.h b/include/opendrive_object.h
index cb8bb160b31bcc0c0c6d95d11e3f619bdc798030..00ae2447ea8c9b9b985e7e6f5a28e2c4ec6448f5 100644
--- a/include/opendrive_object.h
+++ b/include/opendrive_object.h
@@ -39,6 +39,7 @@ typedef union
 
 class COpendriveObject
 {
+  friend class COpendriveRoadSegment;
   private:
     int id; ///< Object's id.
     TOpendriveTrackPoint pose;
@@ -47,10 +48,10 @@ class COpendriveObject
     std::string name; ///< Object's name.
     object_type_t object_type;
   protected:
+    void load(objects::object_type &object_info);
   public:
     COpendriveObject();
     COpendriveObject(const COpendriveObject& object);
-    void load(objects::object_type &object_info);
     TOpendriveTrackPoint get_pose(void) const;
     std::string get_type(void) const;
     std::string get_name(void) const;
diff --git a/include/opendrive_road.h b/include/opendrive_road.h
index 23f002fa611d3667bdef7dea5c09b09e7a1fffe8..b8c9a28e090ff63d84fb231f994e4f71bcb0f1ac 100644
--- a/include/opendrive_road.h
+++ b/include/opendrive_road.h
@@ -9,14 +9,20 @@
 
 class COpendriveRoad
 {
+  friend class COpendriveRoadSegment;
+  friend class COpendriveRoadNode;
   private:
     std::vector<COpendriveRoadSegment *> segments;
+    std::vector<COpendriveRoadNode *> nodes;
     double resolution;
     double scale_factor;
     double min_road_length;
   protected:
     COpendriveRoadSegment &operator[](std::string &key);
     void link_segments(OpenDRIVE &open_drive);
+    void add_node(COpendriveRoadNode *node);
+    bool node_exists_at(const TOpendriveWorldPoint &pose);
+    COpendriveRoadNode* get_node_at(const TOpendriveWorldPoint &pose) const;
     std::string get_junction_road_id(OpenDRIVE &open_drive,std::string &incoming,std::string &connecting);
   public:
     COpendriveRoad();
@@ -30,6 +36,8 @@ class COpendriveRoad
     double get_min_road_length(void) const;
     unsigned int get_num_segments(void) const;
     const COpendriveRoadSegment& get_segment(unsigned int index) const;
+    unsigned int get_num_nodes(void) const;
+    const COpendriveRoadNode& get_node(unsigned int index) const;
     const COpendriveRoadSegment& operator[](std::size_t index);
     void operator=(const COpendriveRoad& object);
     friend std::ostream& operator<<(std::ostream& out, COpendriveRoad &road);
diff --git a/include/opendrive_road_node.h b/include/opendrive_road_node.h
index 2db3d6e9f03431d187df958580a08aa38f16e990..49c920d7707284fbfbceebb5c6d561a7cac4330e 100644
--- a/include/opendrive_road_node.h
+++ b/include/opendrive_road_node.h
@@ -16,26 +16,29 @@ class COpendriveRoadNode
     double resolution;
     double scale_factor;
     TOpendriveWorldPoint start_point;
-    COpendriveLane *lane;
-    COpendriveGeometry *geometry;
-    unsigned int index;
+    std::vector<COpendriveLane *> lanes;
+    std::vector<COpendriveGeometry *> geometries;
+    std::vector<unsigned int> indexes;
   protected:
+    void load(const planView::geometry_type &geom_info,COpendriveLane *lane);
     void add_link(COpendriveRoadNode *node,opendrive_mark_t mark);
     void set_resolution(double res);
     void set_scale_factor(double scale);
-    void set_index(unsigned int index);
+    void set_index(unsigned int lane_index,unsigned int index);
+    void add_lane(const planView::geometry_type &geom_info,COpendriveLane *lane);
   public:
     COpendriveRoadNode();
     COpendriveRoadNode(const COpendriveRoadNode &object);
-    void load(const planView::geometry_type &node_info,COpendriveLane *lane);
     double get_resolution(void) const;
     double get_scale_factor(void) const;
-    unsigned int get_index(void) const;
+    unsigned int get_index(unsigned int lane_index) const;
     TOpendriveWorldPoint get_start_pose(void) const;
     unsigned int get_num_links(void) const;
     const COpendriveLink &get_link(unsigned int index) const;
-    const COpendriveLane &get_lane(void) const;
-    const COpendriveGeometry &get_geometry(void) const;
+    unsigned int get_num_lanes(void) const; 
+    const COpendriveLane &get_lane(unsigned int index) const;
+    unsigned int get_num_geometries(void) const;
+    const COpendriveGeometry &get_geometry(unsigned int index) const;
     void operator=(const COpendriveRoadNode &object);
     friend std::ostream& operator<<(std::ostream& out, COpendriveRoadNode &node);
     ~COpendriveRoadNode();
diff --git a/include/opendrive_road_segment.h b/include/opendrive_road_segment.h
index fd83131f757d0ec48ebb547fc40ec8d1d7668f08..255b411e4d98a300123a8fcc54039dffa7b8f5bf 100644
--- a/include/opendrive_road_segment.h
+++ b/include/opendrive_road_segment.h
@@ -10,12 +10,14 @@
 #include "opendrive_object.h"
 
 class COpendriveLane;
+class COpendriveRoad;
 
 class COpendriveRoadSegment
 {
   friend class COpendriveRoad;
   private:
     std::map<int,COpendriveLane *> lanes;
+    COpendriveRoad *parent_road;
     double resolution;
     double scale_factor;
     double min_road_length;
@@ -27,10 +29,12 @@ class COpendriveRoadSegment
     std::string name;
     unsigned int id;
   protected:
+    void load(OpenDRIVE::road_type &road_info);
     void free(void);
     void set_resolution(double res);
     void set_scale_factor(double scale);
     void set_min_road_length(double length);
+    void set_parent_road(COpendriveRoad *parent);
     void update_references(std::map<COpendriveRoadSegment *,COpendriveRoadSegment *> refs);
     void add_lanes(lanes::laneSection_type &lane_section);
     void add_nodes(OpenDRIVE::road_type &road_info);
@@ -40,12 +44,12 @@ class COpendriveRoadSegment
   public:
     COpendriveRoadSegment();
     COpendriveRoadSegment(const COpendriveRoadSegment &object);
-    void load(OpenDRIVE::road_type &road_info);
     std::string get_name(void) const;
     unsigned int get_id(void) const;
     unsigned int get_num_right_lanes(void) const;
     unsigned int get_num_left_lanes(void) const;
     const COpendriveLane &get_lane(int index) const;
+    const COpendriveRoad &get_parent_road(void) const;
     unsigned int get_num_signals(void) const;
     const COpendriveSignal &get_signal(unsigned int index) const;
     unsigned int get_num_obstacles(void) const;
diff --git a/include/opendrive_signal.h b/include/opendrive_signal.h
index 3f162933862ffa1450b6062a1e7e5deec9a6b367..f49a6f1923ddbee17087d857ac5c679ca92260a9 100644
--- a/include/opendrive_signal.h
+++ b/include/opendrive_signal.h
@@ -8,6 +8,7 @@
 
 class COpendriveSignal
 {
+  friend class COpendriveRoadSegment;
   private:
     int id; ///< Signal's id.
     TOpendriveTrackPoint pose;
@@ -16,11 +17,11 @@ class COpendriveSignal
     int value; ///< Signal's value.
     std::string text; ///< Signal's text.    
   protected:
+    void load(signals::signal_type &signal_info);
   public:
     COpendriveSignal();
     COpendriveSignal(const COpendriveSignal &object);
     COpendriveSignal(int id, double s, double t, double heading, std::string type, std::string sub_type, int value, std::string text, bool reverse = false);
-    void load(signals::signal_type &signal_info);
     int get_id(void) const;
     TOpendriveTrackPoint get_pose(void) const;
     void get_type(std::string &type, std::string &sub_type) const;
diff --git a/src/opendrive_lane.cpp b/src/opendrive_lane.cpp
index 32c500c501cdc7e0e96eb1de2d8227b1f5316783..229dbac93bf2da3d6e646baeb46f2063f54e79d9 100644
--- a/src/opendrive_lane.cpp
+++ b/src/opendrive_lane.cpp
@@ -94,7 +94,11 @@ void COpendriveLane::add_node(COpendriveRoadNode *node)
     if(this->nodes[i]==node)
       return;
   // add the new node
-  node->set_index(this->nodes.size());
+  for(unsigned int i=0;i<node->get_num_lanes();i++)
+  {
+    if(&node->get_lane(i)==this)
+      node->set_index(i,this->nodes.size());
+  }
   this->nodes.push_back(node);
   // link the new node with the previous one in the current lane, if any
   if(this->nodes.size()>1)
@@ -321,18 +325,16 @@ std::ostream& operator<<(std::ostream& out, COpendriveLane &lane)
   }
   out << "    Number of nodes: " << lane.nodes.size() << std::endl;
   for(unsigned int i=0;i<lane.nodes.size();i++)
+  {
+    out << "    Node " << i << ":" << std::endl;
     out << *lane.nodes[i];
+  }
 
   return out;
 }
 
 COpendriveLane::~COpendriveLane()
 {
-  for(unsigned int i=0;i<this->nodes.size();i++)
-  {
-    delete this->nodes[i];
-    this->nodes[i]=NULL;
-  }
   this->nodes.clear();
   this->left_lane=NULL;
   this->left_mark=OD_MARK_NONE;
diff --git a/src/opendrive_link.cpp b/src/opendrive_link.cpp
index 4b68da248d93adb8e83554d4add15b8494925d6c..bb112cbd4d045711e89b34e9d77cb3738cb2e540 100644
--- a/src/opendrive_link.cpp
+++ b/src/opendrive_link.cpp
@@ -113,8 +113,32 @@ void COpendriveLink::operator=(const COpendriveLink &object)
 
 std::ostream& operator<<(std::ostream& out, COpendriveLink &link)
 {
-  out << "        Previous node: " << link.get_prev().get_index() << " of lane " << link.get_prev().get_lane().get_id() << " of road " << link.get_prev().get_lane().get_segment().get_name() << std::endl;
-  out << "        Next node: " << link.get_next().get_index() << " of lane " << link.get_next().get_lane().get_id() << " of road " << link.get_next().get_lane().get_segment().get_name() << std::endl;
+  TOpendriveTrackPoint end_point_track;
+  TOpendriveWorldPoint end_point_world;
+
+  for(unsigned int i=0;i<link.get_prev().get_num_lanes();i++)
+  {
+    if(link.get_prev().lanes[i]->get_id()<0)
+    {
+      end_point_track.t=link.get_prev().lanes[i]->get_offset()-link.get_prev().lanes[i]->get_width()/2.0;
+      end_point_track.s=link.get_prev().geometries[i]->get_length();
+    }
+    else
+    {
+      end_point_track.t=link.get_prev().lanes[i]->get_offset()+link.get_prev().lanes[i]->get_width()/2.0;
+      end_point_track.s=0.0;
+    }
+    end_point_track.heading=0.0;
+    link.get_prev().geometries[i]->get_world_pose(end_point_track,end_point_world);
+    for(unsigned int j=0;j<link.get_next().get_num_lanes();j++)
+    {
+      if(link.get_prev().lanes[i]->get_segment().get_parent_road().get_node_at(end_point_world)==link.next)
+      {
+        out << "        Previous node: " << link.get_prev().get_index(i) << " of lane " << link.get_prev().get_lane(i).get_id() << " of road " << link.get_prev().get_lane(i).get_segment().get_name() << std::endl;
+        out << "        Next node: " << link.get_next().get_index(j) << " of lane " << link.get_next().get_lane(j).get_id() << " of road " << link.get_next().get_lane(j).get_segment().get_name() << std::endl;
+      }
+    }
+  }
   out << "        Road mark: ";
   switch(link.mark)
   {
diff --git a/src/opendrive_road.cpp b/src/opendrive_road.cpp
index b0c67e439912f492bd235f923816821d4ba93fb9..6699c2bfdd1e0e255a396ab0352abc8ebad2ab01 100644
--- a/src/opendrive_road.cpp
+++ b/src/opendrive_road.cpp
@@ -9,11 +9,13 @@ COpendriveRoad::COpendriveRoad()
   this->scale_factor=DEFAULT_SCALE_FACTOR;
   this->min_road_length=DEFAULT_MIN_ROAD_LENGTH;
   this->segments.clear();
+  this->nodes.clear();
 }
 
 COpendriveRoad::COpendriveRoad(const COpendriveRoad& object)
 {
   COpendriveRoadSegment *segment;
+  COpendriveRoadNode *node;
   std::map<COpendriveRoadSegment *,COpendriveRoadSegment *> new_references;
 
   this->resolution=object.resolution;
@@ -26,6 +28,12 @@ COpendriveRoad::COpendriveRoad(const COpendriveRoad& object)
     this->segments.push_back(segment);
     new_references[object.segments[i]]=segment;
   }
+  this->nodes.clear();
+  for(unsigned int i=0;i<object.nodes.size();i++)
+  {
+    node=new COpendriveRoadNode(*object.nodes[i]);
+    this->nodes.push_back(node);
+  }
   for(unsigned int i=0;i<this->segments.size();i++)
     this->segments[i]->update_references(new_references);
 }
@@ -74,6 +82,44 @@ void COpendriveRoad::link_segments(OpenDRIVE &open_drive)
   }
 }
 
+void COpendriveRoad::add_node(COpendriveRoadNode *node)
+{
+  for(unsigned int i=0;i<this->nodes.size();i++)
+  {
+    if(this->nodes[i]==node)
+      throw CException(_HERE_,"Node already present");
+  }
+  this->nodes.push_back(node);
+}
+
+bool COpendriveRoad::node_exists_at(const TOpendriveWorldPoint &pose)
+{
+  TOpendriveWorldPoint node_pose;
+
+  for(unsigned int i=0;i<nodes.size();i++)
+  {
+    node_pose=this->nodes[i]->get_start_pose();
+    if(std::abs(pose.x-node_pose.x)<0.01 && std::abs(pose.y-node_pose.y)<0.01)
+      return true;
+  }
+
+  return false;
+}
+
+COpendriveRoadNode* COpendriveRoad::get_node_at(const TOpendriveWorldPoint &pose) const
+{
+  TOpendriveWorldPoint node_pose;
+
+  for(unsigned int i=0;i<nodes.size();i++)
+  {
+    node_pose=this->nodes[i]->get_start_pose();
+    if(std::abs(pose.x-node_pose.x)<0.01 && std::abs(pose.y-node_pose.y)<0.01)
+      return this->nodes[i];
+  }
+
+  return NULL;
+}
+
 std::string COpendriveRoad::get_junction_road_id(OpenDRIVE &open_drive,std::string &incoming,std::string &connecting)
 {
   bool predecessor_match,successor_match;
@@ -128,6 +174,8 @@ void COpendriveRoad::load(const std::string &filename)
           COpendriveRoadSegment *segment=new COpendriveRoadSegment();
           segment->set_resolution(this->resolution);
           segment->set_scale_factor(this->scale_factor);
+          segment->set_min_road_length(this->min_road_length);
+          segment->set_parent_road(this);
           segment->load(*road_it);
           this->segments.push_back(segment);
         }catch(CException &e){
@@ -246,6 +294,19 @@ const COpendriveRoadSegment& COpendriveRoad::get_segment(unsigned int index) con
     throw CException(_HERE_,"Invalid segment index");
 }
 
+unsigned int COpendriveRoad::get_num_nodes(void) const
+{
+  return this->nodes.size();
+}
+
+const COpendriveRoadNode& COpendriveRoad::get_node(unsigned int index) const
+{
+  if(index>=0 && index<this->nodes.size())
+    return *this->nodes[index];
+  else
+    throw CException(_HERE_,"Invalid node index");
+}
+
 const COpendriveRoadSegment& COpendriveRoad::operator[](std::size_t index)
 {
   if(index>=0 && index<this->segments.size())
@@ -256,12 +317,18 @@ const COpendriveRoadSegment& COpendriveRoad::operator[](std::size_t index)
 
 void COpendriveRoad::operator=(const COpendriveRoad& object)
 {
- COpendriveRoadSegment *segment;
+  COpendriveRoadSegment *segment;
+  COpendriveRoadNode *node;
   std::map<COpendriveRoadSegment *,COpendriveRoadSegment *> new_references;
 
   this->resolution=object.resolution;
   this->scale_factor=object.scale_factor;
   this->min_road_length=object.min_road_length;
+  for(unsigned int i=0;i<this->segments.size();i++)
+  {
+    delete this->segments[i];
+    this->segments[i]=NULL;
+  }
   this->segments.clear();
   for(unsigned int i=0;i<object.segments.size();i++)
   {
@@ -269,6 +336,17 @@ void COpendriveRoad::operator=(const COpendriveRoad& object)
     this->segments.push_back(segment);
     new_references[object.segments[i]]=segment;
   }
+  for(unsigned int i=0;i<this->nodes.size();i++)
+  {
+    delete this->nodes[i];
+    this->nodes[i]=NULL;
+  }
+  this->nodes.clear();
+  for(unsigned int i=0;i<object.nodes.size();i++)
+  {
+    node=new COpendriveRoadNode(*object.nodes[i]);
+    this->nodes.push_back(node);
+  }
   for(unsigned int i=0;i<this->segments.size();i++)
     this->segments[i]->update_references(new_references);
 }
@@ -278,6 +356,7 @@ std::ostream& operator<<(std::ostream& out, COpendriveRoad &road)
   out << "Resolution: " << road.resolution << std::endl;
   out << "Scale factor: " << road.scale_factor << std::endl;
   out << "Minimum road lenght: " << road.min_road_length << std::endl;
+  out << "Total number of nodes: " << road.nodes.size() << std::endl;
   for(unsigned int i=0;i<road.segments.size();i++)
     std::cout << *road.segments[i];
 
@@ -287,7 +366,15 @@ std::ostream& operator<<(std::ostream& out, COpendriveRoad &road)
 COpendriveRoad::~COpendriveRoad()
 {
   for(unsigned int i=0;i<this->segments.size();i++)
+  {
     delete this->segments[i];
+    this->segments[i]=NULL;
+  }
+  for(unsigned int i=0;i<this->nodes.size();i++)
+  {
+    delete this->nodes[i];
+    this->nodes[i]=NULL;
+  }
   this->segments.clear();
   this->resolution=DEFAULT_RESOLUTION;
   this->scale_factor=DEFAULT_SCALE_FACTOR;
diff --git a/src/opendrive_road_node.cpp b/src/opendrive_road_node.cpp
index 33a70c5d2626380ae9b543a04bacfe9553028e18..2c2b6f0b39b7cea100464e9929fd7be9aad3b294 100644
--- a/src/opendrive_road_node.cpp
+++ b/src/opendrive_road_node.cpp
@@ -1,4 +1,5 @@
 #include "opendrive_road_node.h"
+#include "opendrive_road.h"
 #include "exceptions.h"
 
 COpendriveRoadNode::COpendriveRoadNode()
@@ -8,9 +9,9 @@ COpendriveRoadNode::COpendriveRoadNode()
   this->start_point.x=0.0;
   this->start_point.y=0.0;
   this->start_point.heading=0.0;
-  this->lane=NULL;
-  this->geometry=NULL;
-  this->index=-1;
+  this->lanes.clear();
+  this->geometries.clear();
+  this->indexes.clear();
 }
 
 COpendriveRoadNode::COpendriveRoadNode(const COpendriveRoadNode &object)
@@ -22,15 +23,19 @@ COpendriveRoadNode::COpendriveRoadNode(const COpendriveRoadNode &object)
   this->start_point.x=object.start_point.x;
   this->start_point.y=object.start_point.y;
   this->start_point.heading=object.start_point.heading;
-  this->lane=object.lane;
-  this->geometry=object.geometry->clone();
+  this->lanes.resize(object.lanes.size());
+  for(unsigned int i=0;i<object.lanes.size();i++)
+    this->lanes[i]=object.lanes[i];
+  this->geometries.resize(object.geometries.size());
+  for(unsigned int i=0;i<object.geometries.size();i++)
+    this->geometries[i]=object.geometries[i]->clone();
   this->links.clear();
   for(unsigned int i=0;i<object.links.size();i++)
   {
     new_link=new COpendriveLink(*object.links[i]);
     this->links.push_back(new_link);
   }
-  this->index=object.index;
+  this->indexes=object.indexes;
 }
 
 void COpendriveRoadNode::add_link(COpendriveRoadNode *node,opendrive_mark_t mark)
@@ -38,15 +43,8 @@ void COpendriveRoadNode::add_link(COpendriveRoadNode *node,opendrive_mark_t mark
   COpendriveLink *new_link;
 
   for(unsigned int i=0;i<this->links.size();i++)
-  {
     if(this->links[i]->prev==this && this->links[i]->next==node)
-      throw CException(_HERE_,"Link already present in the source node");
-  }
-  for(unsigned int i=0;i<node->links.size();i++)
-  {
-    if(node->links[i]->prev==this && node->links[i]->next==node)
-      throw CException(_HERE_,"Link already present in the target node");
-  }
+      return;
   new_link=new COpendriveLink();
   new_link->set_prev(this);
   new_link->set_next(node);
@@ -74,50 +72,93 @@ void COpendriveRoadNode::set_scale_factor(double scale)
     this->links[i]->set_scale_factor(scale);
 }
 
-void COpendriveRoadNode::set_index(unsigned int index)
+void COpendriveRoadNode::set_index(unsigned int lane_index,unsigned int index)
+{
+  if(lane_index>=0 && lane_index<this->lanes.size())
+    this->indexes[lane_index]=index;
+  else
+    throw CException(_HERE_,"Invalid lane index");
+}
+
+void COpendriveRoadNode::add_lane(const planView::geometry_type &geom_info,COpendriveLane *lane)
 {
-  this->index=index;
+  COpendriveGeometry *geometry;
+
+  // import geometry
+  if(geom_info.line().present())
+    geometry=new COpendriveLine();
+  else if(geom_info.spiral().present())
+    geometry=new COpendriveSpiral();
+  else if(geom_info.arc().present())
+    geometry=new COpendriveArc();
+  else if(geom_info.paramPoly3().present())
+    geometry=new COpendriveParamPoly3();
+  else
+    throw CException(_HERE_,"Unsupported or Missing geometry");
+  geometry->set_scale_factor(this->scale_factor);
+  geometry->load(geom_info);
+  this->geometries.push_back(geometry);
+  this->lanes.push_back(lane);
+  this->indexes.resize(this->lanes.size());
 }
 
 void COpendriveRoadNode::load(const planView::geometry_type &geom_info,COpendriveLane *lane)
 {
   TOpendriveTrackPoint track_point;
+  COpendriveGeometry *geometry;
 
-  if(this->geometry!=NULL)
+  for(unsigned int i=0;i<this->geometries.size();i++)
   {
-    delete this->geometry;
-    this->geometry=NULL;
+    delete this->geometries[i];
+    this->geometries[i]=NULL;
   }
+  this->geometries.clear();
   // import geometry
   if(geom_info.line().present())
-    this->geometry=new COpendriveLine();
+    geometry=new COpendriveLine();
   else if(geom_info.spiral().present())
-    this->geometry=new COpendriveSpiral();
+    geometry=new COpendriveSpiral();
   else if(geom_info.arc().present())
-    this->geometry=new COpendriveArc();
+    geometry=new COpendriveArc();
   else if(geom_info.paramPoly3().present())
-    this->geometry=new COpendriveParamPoly3();
+    geometry=new COpendriveParamPoly3();
   else
     throw CException(_HERE_,"Unsupported or Missing geometry");
-  this->geometry->set_scale_factor(this->scale_factor);
-  this->geometry->load(geom_info);
+  geometry->set_scale_factor(this->scale_factor);
+  geometry->load(geom_info);
   // import start position
-  track_point.s=0.0;
-  track_point.t=lane->get_offset()+lane->get_width()/2.0;
+  if(lane->get_id()<0)
+  {
+    track_point.t=lane->get_offset()-lane->get_width()/2.0;
+    track_point.s=0.0;
+  }
+  else
+  {
+    track_point.t=lane->get_offset()+lane->get_width()/2.0;
+    track_point.s=geometry->get_length();
+  }
   track_point.heading=0.0;
-  if(!this->geometry->get_world_pose(track_point,this->start_point))
+  if(!geometry->get_world_pose(track_point,this->start_point))
   {
-    delete this->geometry;
-    this->geometry=NULL;
+    delete geometry;
+    geometry=NULL;
     throw CException(_HERE_,"Impossible to get world coordinates");
   }
+  else
+  {
+    if(lane->get_id()>0)
+      this->start_point.heading=normalize_angle(this->start_point.heading+3.14159);
+  }
+  this->geometries.push_back(geometry);
   for(unsigned int i=0;i<this->links.size();i++)
   {
     delete this->links[i];
     this->links[i]=NULL;
   }
   this->links.clear();
-  this->lane=lane;
+  this->lanes.clear();
+  this->lanes.push_back(lane);
+  this->indexes.resize(1);
 }
 
 double COpendriveRoadNode::get_resolution(void) const
@@ -130,9 +171,12 @@ double COpendriveRoadNode::get_scale_factor(void) const
   return this->scale_factor;
 }
 
-unsigned int COpendriveRoadNode::get_index(void) const
+unsigned int COpendriveRoadNode::get_index(unsigned int lane_index) const
 {
-  return this->index;
+  if(lane_index>=0 && lane_index<this->indexes.size())
+    return this->indexes[lane_index];
+  else
+    throw CException(_HERE_,"Invalid lane index");
 }
 
 TOpendriveWorldPoint COpendriveRoadNode::get_start_pose(void) const
@@ -153,14 +197,30 @@ const COpendriveLink &COpendriveRoadNode::get_link(unsigned int index) const
     throw CException(_HERE_,"Invalid link index");
 }
 
-const COpendriveLane &COpendriveRoadNode::get_lane(void) const
+unsigned int COpendriveRoadNode::get_num_lanes(void) const
 {
-  return *this->lane;
+  return this->lanes.size();
 }
 
-const COpendriveGeometry &COpendriveRoadNode::get_geometry(void) const
+const COpendriveLane &COpendriveRoadNode::get_lane(unsigned int index) const
 {
-  return *this->geometry;
+  if(index>=0 && index<this->lanes.size())
+    return *this->lanes[index];
+  else
+    throw CException(_HERE_,"Invalid lane index");
+}
+
+unsigned int COpendriveRoadNode::get_num_geometries(void) const
+{
+  return this->geometries.size();
+}
+
+const COpendriveGeometry &COpendriveRoadNode::get_geometry(unsigned int index) const
+{
+  if(index>=0 && index<this->geometries.size())
+    return *this->geometries[index];
+  else
+    throw CException(_HERE_,"Invalid geometry index");
 }
 
 void COpendriveRoadNode::operator=(const COpendriveRoadNode &object) 
@@ -172,8 +232,17 @@ void COpendriveRoadNode::operator=(const COpendriveRoadNode &object)
   this->start_point.x=object.start_point.x;
   this->start_point.y=object.start_point.y;
   this->start_point.heading=object.start_point.heading;
-  this->lane=object.lane;
-  this->geometry=object.geometry->clone();
+  this->lanes.resize(object.lanes.size());
+  for(unsigned int i=0;i<object.lanes.size();i++)
+    this->lanes[i]=object.lanes[i];
+  for(unsigned int i=0;i<this->geometries.size();i++)
+  {
+    delete this->geometries[i];
+    this->geometries[i]=NULL;
+  }
+  this->geometries.resize(object.geometries.size());
+  for(unsigned int i=0;i<object.geometries.size();i++)
+    this->geometries[i]=object.geometries[i]->clone();
   for(unsigned int i=0;i<this->links.size();i++)
   {
     delete this->links[i];
@@ -185,22 +254,20 @@ void COpendriveRoadNode::operator=(const COpendriveRoadNode &object)
     new_link=new COpendriveLink(*object.links[i]);
     this->links.push_back(new_link);
   }
-  this->index=object.index;
+  this->indexes=object.indexes;
 }
 
 std::ostream& operator<<(std::ostream& out, COpendriveRoadNode &node)
 {
-  out << "    Node " << node.index << ":" << std::endl;
-  out << "      parent lane: " << node.lane->get_id() << std::endl;
+//  out << "      parent lane: " << node.lane->get_id() << std::endl;
   out << "      start point: x: " << node.start_point.x << " y: " << node.start_point.y << " heading: " << node.start_point.heading << std::endl;
-  if(node.lane!=NULL)
-    out << "      lane id: " << node.lane->get_id() << std::endl;
-  else
-    out << "      Does not belong to a lane." << std::endl;
-  if(node.geometry!=NULL)
-    out << *node.geometry;
-  else
-    out << "      Does not have any associated geometry." << std::endl;
+  out << "      Number of parent lanes: " << node.lanes.size() << std::endl;
+  for(unsigned int i=0;i<node.lanes.size();i++)
+  {
+    out << "      Lane " << i << ":" << std::endl;
+    out << "        lane id: " << node.lanes[i]->get_id() << std::endl;
+    out << *node.geometries[i];
+  }
   out << "      Number of links: " << node.links.size() << std::endl;
   for(unsigned int i=0;i<node.links.size();i++)
   {
@@ -217,12 +284,13 @@ COpendriveRoadNode::~COpendriveRoadNode()
   this->start_point.x=0.0;
   this->start_point.y=0.0;
   this->start_point.heading=0.0;
-  this->lane=NULL;
-  if(this->geometry!=NULL)
+  this->lanes.clear();
+  for(unsigned int i=0;i<this->geometries.size();i++)
   {
-    delete this->geometry;
-    this->geometry=NULL;
+    delete this->geometries[i];
+    this->geometries[i]=NULL;
   }
+  this->geometries.clear();
   for(unsigned int i=0;i<this->links.size();i++)
   {
     delete this->links[i];
diff --git a/src/opendrive_road_segment.cpp b/src/opendrive_road_segment.cpp
index 8f64af09ff945985d9ac0f1606f8aa67dc624463..911130c5114af79c8bb9ef872e8ff2a3b263b573 100644
--- a/src/opendrive_road_segment.cpp
+++ b/src/opendrive_road_segment.cpp
@@ -1,4 +1,5 @@
 #include "opendrive_road_segment.h"
+#include "opendrive_road.h"
 #include "exceptions.h"
 
 COpendriveRoadSegment::COpendriveRoadSegment()
@@ -101,6 +102,11 @@ void COpendriveRoadSegment::set_min_road_length(double length)
   this->min_road_length=length;
 }
 
+void COpendriveRoadSegment::set_parent_road(COpendriveRoad *parent)
+{
+  this->parent_road=parent;
+}
+
 void COpendriveRoadSegment::update_references(std::map<COpendriveRoadSegment *,COpendriveRoadSegment *> refs)
 {
   for(unsigned int i=0;i<this->connecting.size();i++)
@@ -157,6 +163,7 @@ void COpendriveRoadSegment::add_nodes(OpenDRIVE::road_type &road_info)
   std::map<int,COpendriveLane *>::const_iterator lane_it;
   planView::geometry_iterator geom_it;
   COpendriveRoadNode *new_node;
+  TOpendriveWorldPoint node_pose;
   double lane_offset;
 
   try{
@@ -170,8 +177,17 @@ void COpendriveRoadSegment::add_nodes(OpenDRIVE::road_type &road_info)
         new_node->set_scale_factor(this->scale_factor);
         this->lanes[i]->set_offset(lane_offset);
         new_node->load(*geom_it,this->lanes[i]);
-        if(new_node->get_geometry().get_length()>this->min_road_length)
+        if(new_node->get_geometry(0).get_length()>this->min_road_length)
         {
+          node_pose=new_node->get_start_pose();
+          if(this->parent_road->node_exists_at(node_pose))
+          {
+            delete new_node;
+            new_node=this->parent_road->get_node_at(node_pose);
+            new_node->add_lane(*geom_it,this->lanes[i]);
+          }
+          else
+            this->parent_road->add_node(new_node);
           this->lanes[i]->add_node(new_node);
           lane_offset-=this->lanes[i]->get_width();
         }
@@ -188,8 +204,17 @@ void COpendriveRoadSegment::add_nodes(OpenDRIVE::road_type &road_info)
         new_node->set_scale_factor(this->scale_factor);
         this->lanes[i]->set_offset(lane_offset);
         new_node->load(*geom_it,this->lanes[i]);
-        if(new_node->get_geometry().get_length()>this->min_road_length)
+        if(new_node->get_geometry(0).get_length()>this->min_road_length)
         {
+          node_pose=new_node->get_start_pose();
+          if(this->parent_road->node_exists_at(node_pose))
+          {
+            delete new_node;
+            new_node=this->parent_road->get_node_at(node_pose);
+            new_node->add_lane(*geom_it,this->lanes[i]);
+          }
+          else
+            this->parent_road->add_node(new_node);
           this->lanes[i]->add_node(new_node);
           lane_offset+=this->lanes[i]->get_width();
         }
@@ -400,6 +425,11 @@ const COpendriveLane &COpendriveRoadSegment::get_lane(int index) const
   throw CException(_HERE_,"invalid lane index");
 }
 
+const COpendriveRoad &COpendriveRoadSegment::get_parent_road(void) const
+{
+  return *this->parent_road;
+}
+
 unsigned int COpendriveRoadSegment::get_num_signals(void) const
 {
   return this->signals.size();