code: def _netconvert_carla_impl(
      xodr_file, output, tmpdir, guess_tls=False
  ):
      """
      Implements netconvert carla.
      """
      # ----------
      # netconvert
      # ----------
      basename = os.path.splitext(os.path.basename(xodr_file))[0]
      tmp_sumo_net = os.path.join(tmpdir, basename + ".net.xml")
  
      try:
          basedir = os.path.dirname(os.path.realpath(__file__))
          result = subprocess.call(
              [
                  "netconvert",
                  "--opendrive",
                  xodr_file,
                  "--output-file",
                  tmp_sumo_net,
                  "--geometry.min-radius.fix",
                  "--geometry.remove",
                  "--opendrive.curve-resolution",
                  "1",
                  "--opendrive.import-all-lanes",
                  "--type-files",
                  os.path.join(
                      basedir, "data/opendrive_netconvert.typ.xml"
                  ),
                  # Necessary to link odr and sumo ids.
                  "--output.original-names",
                  # Discard loading traffic lights as them will be inserted manually afterwards.
                  "--tls.discard-loaded",
                  "true",
              ]
          )
      except subprocess.CalledProcessError:
          raise RuntimeError(
              "There was an error when executing netconvert."
          )
      else:
          if result != 0:
              raise RuntimeError(
                  "There was an error when executing netconvert."
              )
  
      # --------
      # Sumo net
      # --------
      sumo_net = sumolib.net.readNet(tmp_sumo_net)
      sumo_topology = build_topology(sumo_net)
  
      # ---------
      # Carla map
      # ---------
      with open(xodr_file, "r") as f:
          carla_map = carla.Map("netconvert", str(f.read()))
  
      # ---------
      # Landmarks
      # ---------
      tls = {}  # {tlsid: SumoTrafficLight}
  
      landmarks = carla_map.get_all_landmarks_of_type("1000001")
      for landmark in landmarks:
          if landmark.name == "":
              # This is a workaround to avoid adding traffic lights without controllers.
              logging.warning(
                  "Landmark %s has not a valid name.", landmark.name
              )
              continue
  
          road_id = str(landmark.road_id)
          for from_lane, to_lane in landmark.get_lane_validities():
              for lane_id in range(from_lane, to_lane + 1):
                  if lane_id == 0:
                      continue
  
                  wp = carla_map.get_waypoint_xodr(
                      landmark.road_id, lane_id, landmark.s
                  )
                  if wp is None:
                      logging.warning(
                          "Could not find waypoint for landmark {} (road_id: {}, lane_id: {}, s:{}".format(
                              landmark.id,
                              landmark.road_id,
                              lane_id,
                              landmark.s,
                          )
                      )
                      continue
  
                  # When the landmark belongs to a junction, we place te traffic light at the
                  # entrance of the junction.
                  if wp.is_junction and sumo_topology.is_junction(
                      road_id, lane_id
                  ):
                      tlid = str(wp.get_junction().id)
                      if tlid not in tls:
                          tls[tlid] = SumoTrafficLight(tlid)
                      tl = tls[tlid]
  
                      if guess_tls:
                          for (
                              from_edge,
                              from_lane,
                          ) in sumo_topology.get_incoming(
                              road_id, lane_id
                          ):
                              successors = sumo_topology.get_successors(
                                  from_edge, from_lane
                              )
                              for to_edge, to_lane in successors:
                                  tl.add_landmark(
                                      landmark.id,
                                      tl.id,
                                      from_edge,
                                      to_edge,
                                      from_lane,
                                      to_lane,
                                  )
  
                      else:
                          connections = (
                              sumo_topology.get_path_connectivity(
                                  road_id, lane_id
                              )
                          )
                          for from_, to_ in connections:
                              from_edge, from_lane = from_
                              to_edge, to_lane = to_
  
                              tl.add_landmark(
                                  landmark.id,
                                  tl.id,
                                  from_edge,
                                  to_edge,
                                  from_lane,
                                  to_lane,
                              )
  
                  # When the landmarks does not belong to a junction (i.e., belongs to a std road),
                  # we place the traffic light between that std road and its successor.
                  elif (
                      not wp.is_junction
                      and not sumo_topology.is_junction(
                          road_id, lane_id
                      )
                  ):
                      from_edge, from_lane = sumo_topology.get_sumo_id(
                          road_id, lane_id, landmark.s
                      )
  
                      for (
                          to_edge,
                          to_lane,
                      ) in sumo_topology.get_successors(
                          from_edge, from_lane
                      ):
                          tlid = SumoTrafficLight.generate_tl_id(
                              from_edge, to_edge
                          )
                          if tlid not in tls:
                              tls[tlid] = SumoTrafficLight(tlid)
                          tl = tls[tlid]
  
                          tl.add_landmark(
                              landmark.id,
                              tl.id,
                              from_edge,
                              to_edge,
                              from_lane,
                              to_lane,
                          )
  
                  else:
                      logging.warning(
                          "Landmark %s could not be added.", landmark.id
                      )
  
      # ---------------
      # Modify sumo net
      # ---------------
      parser = ET.XMLParser(remove_blank_text=True)
      tree = ET.parse(tmp_sumo_net, parser)
      root = tree.getroot()
  
      for tl in tls.values():
          SumoTrafficLight.generate_default_program(tl)
          edges_tags = tree.xpath("//edge")
          if not edges_tags:
              raise RuntimeError("No edges found in sumo net.")
          root.insert(root.index(edges_tags[-1]) + 1, tl.to_xml())
  
          for connection in tl.connections:
              tags = tree.xpath(
                  '//connection[@from="{}" and @to="{}" and @fromLane="{}" and @toLane="{}"]'.format(
                      connection.from_road,
                      connection.to_road,
                      connection.from_lane,
                      connection.to_lane,
                  )
              )
  
              if tags:
                  if len(tags) > 1:
                      logging.warning(
                          "Found repeated connections from={} to={} fromLane={} toLane={}.".format(
                              connection.from_road,
                              connection.to_road,
                              connection.from_lane,
                              connection.to_lane,
                          )
                      )
  
                  tags[0].set("tl", str(connection.tlid))
                  tags[0].set("linkIndex", str(connection.link_index))
              else:
                  logging.warning(
                      "Not found connection from={} to={} fromLane={} toLane={}.".format(
                          connection.from_road,
                          connection.to_road,
                          connection.from_lane,
                          connection.to_lane,
                      )
                  )
  
      tree.write(
          output,
          pretty_print=True,
          encoding="UTF-8",
          xml_declaration=True,
      )
  
imports: import argparse
  import bisect
  import collections
  import logging
  import shutil
  import subprocess
  import tempfile
  import lxml.etree
  import glob
  import os
  import sys
  import carla
  import sumolib
label_desc: Use image node_id 2 for calling a global function with example usage: _netconvert_carla_impl(xodr_file, output, tmpdir, guess_tls) without return types