Example #1
0
	def test_nonintersecting_roads(self):
		myMap = CvtdMap()
		myMap.nodeDict[0] = (CvtdNode(1, 1))
		myMap.nodeDict[1] = (CvtdNode(2, 1))
		myMap.nodeDict[2] = (CvtdNode(1, 4))
		myMap.nodeDict[3] = (CvtdNode(2, 6))
		myMap.nodeDict[4] = (CvtdNode(2, 9))
		myMap.nodeDict[5] = (CvtdNode(3, 3))
		myMap.nodeDict[6] = (CvtdNode(4, 6))
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 1,1 to 2,9"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(0, 0))
		thisRoad.points.append(CvtdRoadPoint(2, 60))
		thisRoad.points.append(CvtdRoadPoint(3, 90))
		thisRoad.points.append(CvtdRoadPoint(4, 100))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 2,1 to 4,6"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(1, 0))
		thisRoad.points.append(CvtdRoadPoint(5, 60))
		thisRoad.points.append(CvtdRoadPoint(6, 100))
		myMap.roadList.append(thisRoad)
		
		intersections = myMap.find_intersecting_roads(0, 0)
		self.assertEqual(0, len(intersections))
Example #2
0
    def test_insert_decreasing(self):
        road = CvtdRoad()
        road.points.append(CvtdRoadPoint(123, 160))
        road.points.append(CvtdRoadPoint(124, 120))
        road.points.append(CvtdRoadPoint(125, 85))

        road.insert(CvtdRoadPoint(1, 290))
        self.assertEqual(4, len(road.points))
        self.assertEqual(road.points[0].addr, 290)
        self.assertEqual(road.points[1].addr, 160)
        self.assertEqual(road.points[2].addr, 120)
        self.assertEqual(road.points[3].addr, 85)

        road.insert(CvtdRoadPoint(1, 145))
        self.assertEqual(5, len(road.points))
        self.assertEqual(road.points[0].addr, 290)
        self.assertEqual(road.points[1].addr, 160)
        self.assertEqual(road.points[2].addr, 145)
        self.assertEqual(road.points[3].addr, 120)
        self.assertEqual(road.points[4].addr, 85)

        road.insert(CvtdRoadPoint(1, 45))
        self.assertEqual(6, len(road.points))
        self.assertEqual(road.points[0].addr, 290)
        self.assertEqual(road.points[1].addr, 160)
        self.assertEqual(road.points[2].addr, 145)
        self.assertEqual(road.points[3].addr, 120)
        self.assertEqual(road.points[4].addr, 85)
        self.assertEqual(road.points[5].addr, 45)
Example #3
0
    def read_roads(self, filename):
        self.nodeDict = {}
        self.roadList = []

        editor = ""
        this_road = CvtdRoad()
        try:
            with open(filename, 'r') as f:
                for road in f:
                    if road.strip() == "NODE_LIST = [":
                        editor = "NODE_LIST"
                    elif road.strip() == "ROAD_LIST = [":
                        editor = "ROAD_LIST"
                    elif editor == "NODE_LIST" and len(
                            road.strip().split(',')) == 4:
                        lat = float(
                            road.split(',')[0].strip().replace('[', ''))
                        lon = float(
                            road.split(',')[1].strip().replace(']', ''))
                        key = int(road.split(',')[2].strip().replace(']', ''))
                        self.nodeDict[key] = CvtdNode(lat, lon)
                    elif editor == "ROAD_LIST" and len(
                            road.strip().split('",')) == 3:
                        this_road = CvtdRoad()
                        this_road.name = road.split('",')[0].replace(
                            '[', '').replace('"', '').strip()
                        this_road.dir = road.split('",')[1].replace(
                            '"', '').strip()
                        points = road.split('",')[2].split('], [')
                        points = [
                            p.replace('[', '').replace(']',
                                                       '').replace(',\n',
                                                                   '').strip()
                            for p in points
                        ]
                        this_road.points = [
                            CvtdRoadPoint(int(node), int(addr))
                            for node, addr in [x.split(', ') for x in points]
                        ]
                        self.roadList.append(this_road)
                print("Read successful, read {} nodes and {} roads".format(
                    len(self.nodeDict), len(self.roadList)))
        except FileNotFoundError:
            print("Error: File \"{}\" does not exist".format(filename))
Example #4
0
	def test_multipoint_intersecting_roads(self):
		myMap = CvtdMap()
		myMap.nodeDict[0] = (CvtdNode(1, 1))
		myMap.nodeDict[1] = (CvtdNode(1, 3))
		myMap.nodeDict[2] = (CvtdNode(1, 5))
		myMap.nodeDict[3] = (CvtdNode(3, 1))
		myMap.nodeDict[4] = (CvtdNode(3, 3))
		myMap.nodeDict[5] = (CvtdNode(3, 5))
		
		myMap.nodeDict[6] = (CvtdNode(2, 2))
		myMap.nodeDict[7] = (CvtdNode(2, 4))
		myMap.nodeDict[8] = (CvtdNode(4, 4))
		myMap.nodeDict[9] = (CvtdNode(4, 2))
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 1,1 to 3,5"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(0, 0))
		thisRoad.points.append(CvtdRoadPoint(1, 10))
		thisRoad.points.append(CvtdRoadPoint(2, 20))
		thisRoad.points.append(CvtdRoadPoint(3, 30))
		thisRoad.points.append(CvtdRoadPoint(4, 40))
		thisRoad.points.append(CvtdRoadPoint(5, 50))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 2,2 to 4,4"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(6, 0))
		thisRoad.points.append(CvtdRoadPoint(7, 10))
		thisRoad.points.append(CvtdRoadPoint(8, 20))
		thisRoad.points.append(CvtdRoadPoint(9, 30))
		myMap.roadList.append(thisRoad)

		intersections = myMap.find_intersecting_roads(0, 0)
		self.assertEqual(2, len(intersections))
Example #5
0
 def import_xml_file(self, filename):
   print("Importing file " + filename)
   tree = ET.parse(filename)
   root = tree.getroot()
   
   # Load all the nodes, using an extra components "tags"
   for node in root.iter('node'):
     this_node = CvtdNode(float(node.attrib['lat']), float(node.attrib['lon']))
     this_node.tags = {}
     this_node.attrib = node.attrib
     
     tag_keys = [t.attrib['k'] for t in node.iter('tag')]
     tag_vals = [t.attrib['v'] for t in node.iter('tag')]
     for ix, key in enumerate(tag_keys):
       this_node.tags[key] = tag_vals[ix]
     try:
       self.nodeDict[int(this_node.attrib['id'])] = this_node
     except KeyError:
       print("Fatal Error: Node did not have an ID field")
       return
   
   # Load all the ways, using an extra components "tags"
   for way in root.iter('way'):
     this_way = CvtdRoad()
     this_way.tags = {}
     this_way.attrib = way.attrib
     for nd in way.iter('nd'):
       p = CvtdRoadPoint(int(nd.attrib['ref']), None)
       this_way.points.append(p)
         
     tag_keys = [t.attrib['k'] for t in way.iter('tag')]
     tag_vals = [t.attrib['v'] for t in way.iter('tag')]
     for ix, key in enumerate(tag_keys):
       this_way.tags[key] = tag_vals[ix]
       if key == "name":
         this_way.name = tag_vals[ix]
     self.roadList.append(this_way)
Example #6
0
	def test_find_intersecting_roads(self):
		myMap = CvtdMap()
		myMap.nodeDict[0] = (CvtdNode(1, 1))
		myMap.nodeDict[1] = (CvtdNode(4, 4))
		myMap.nodeDict[2] = (CvtdNode(1, 4))
		myMap.nodeDict[3] = (CvtdNode(4, 1))
		myMap.nodeDict[4] = (CvtdNode(3, 4))
		myMap.nodeDict[5] = (CvtdNode(4, 3))
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 1,1 to 4,4"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(0, 0))
		thisRoad.points.append(CvtdRoadPoint(1, 60))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 1,4 to 4,1"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(2, 0))
		thisRoad.points.append(CvtdRoadPoint(3, 60))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 3,4 to 4,3"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(4, 0))
		thisRoad.points.append(CvtdRoadPoint(5, 50))
		myMap.roadList.append(thisRoad)
		
		intersections = myMap.find_intersecting_roads(0, 0)
		self.assertEqual(2, len(intersections))
		self.assertEqual(0, intersections[0][0].roadIx)
		self.assertEqual(30, intersections[0][0].addr)
		self.assertEqual(1, intersections[0][1].roadIx)
		self.assertEqual(30, intersections[0][1].addr)
		self.assertEqual(0, intersections[1][0].roadIx)
		self.assertEqual(50, intersections[1][0].addr)
		self.assertEqual(2, intersections[1][1].roadIx)
		self.assertEqual(25, intersections[1][1].addr)
Example #7
0
	def test_read_write_roads(self):
		myMap = CvtdMap()
		myMap.nodeDict[0] = (CvtdNode(1, 1))
		myMap.nodeDict[1] = (CvtdNode(4, 4))
		myMap.nodeDict[2] = (CvtdNode(1, 4))
		myMap.nodeDict[3] = (CvtdNode(4, 1))
		myMap.nodeDict[4] = (CvtdNode(3, 4))
		myMap.nodeDict[5] = (CvtdNode(4, 3))
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 0 to 60"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(0, 0))
		thisRoad.points.append(CvtdRoadPoint(1, 30))
		thisRoad.points.append(CvtdRoadPoint(2, 60))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 0 to 60"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(1, 0))
		thisRoad.points.append(CvtdRoadPoint(3, 30))
		thisRoad.points.append(CvtdRoadPoint(4, 50))
		thisRoad.points.append(CvtdRoadPoint(5, 60))
		myMap.roadList.append(thisRoad)
		
		thisRoad = CvtdRoad()
		thisRoad.name = "Road from 0 to 50"
		thisRoad.dir = "Up"
		thisRoad.points.append(CvtdRoadPoint(0, 0))
		thisRoad.points.append(CvtdRoadPoint(5, 50))
		myMap.roadList.append(thisRoad)

		myMap.write_roads("tmp_roads.txt")

		myCmpMap = CvtdMap()
		myCmpMap.read_roads("tmp_roads.txt")

		self.assertEqual(len(myMap.nodeDict), len(myCmpMap.nodeDict))
		self.assertEqual(len(myMap.roadList), len(myCmpMap.roadList))

		self.assertEqual(myMap.nodeDict[0].lat, myCmpMap.nodeDict[0].lat)
		self.assertEqual(myMap.nodeDict[0].lon, myCmpMap.nodeDict[0].lon)
		self.assertEqual(myMap.nodeDict[1].lat, myCmpMap.nodeDict[1].lat)
		self.assertEqual(myMap.nodeDict[1].lon, myCmpMap.nodeDict[1].lon)
		self.assertEqual(myMap.nodeDict[2].lat, myCmpMap.nodeDict[2].lat)
		self.assertEqual(myMap.nodeDict[2].lon, myCmpMap.nodeDict[2].lon)
		self.assertEqual(myMap.nodeDict[3].lat, myCmpMap.nodeDict[3].lat)
		self.assertEqual(myMap.nodeDict[3].lon, myCmpMap.nodeDict[3].lon)
		self.assertEqual(myMap.nodeDict[4].lat, myCmpMap.nodeDict[4].lat)
		self.assertEqual(myMap.nodeDict[4].lon, myCmpMap.nodeDict[4].lon)
		self.assertEqual(myMap.nodeDict[5].lat, myCmpMap.nodeDict[5].lat)
		self.assertEqual(myMap.nodeDict[5].lon, myCmpMap.nodeDict[5].lon)

		self.assertEqual(myMap.roadList[0].name, myCmpMap.roadList[0].name)
		self.assertEqual(myMap.roadList[0].dir, myCmpMap.roadList[0].dir)
		self.assertEqual(myMap.roadList[0].points[0].node, myCmpMap.roadList[0].points[0].node)
		self.assertEqual(myMap.roadList[0].points[0].addr, myCmpMap.roadList[0].points[0].addr)
		self.assertEqual(myMap.roadList[0].points[1].node, myCmpMap.roadList[0].points[1].node)
		self.assertEqual(myMap.roadList[0].points[1].addr, myCmpMap.roadList[0].points[1].addr)
		self.assertEqual(myMap.roadList[0].points[2].node, myCmpMap.roadList[0].points[2].node)
		self.assertEqual(myMap.roadList[0].points[2].addr, myCmpMap.roadList[0].points[2].addr)
		self.assertEqual(myMap.roadList[1].name, myCmpMap.roadList[1].name)
		self.assertEqual(myMap.roadList[1].dir, myCmpMap.roadList[1].dir)
		self.assertEqual(myMap.roadList[1].points[0].node, myCmpMap.roadList[1].points[0].node)
		self.assertEqual(myMap.roadList[1].points[0].addr, myCmpMap.roadList[1].points[0].addr)
		self.assertEqual(myMap.roadList[1].points[1].node, myCmpMap.roadList[1].points[1].node)
		self.assertEqual(myMap.roadList[1].points[1].addr, myCmpMap.roadList[1].points[1].addr)
		self.assertEqual(myMap.roadList[1].points[2].node, myCmpMap.roadList[1].points[2].node)
		self.assertEqual(myMap.roadList[1].points[2].addr, myCmpMap.roadList[1].points[2].addr)
		self.assertEqual(myMap.roadList[1].points[3].node, myCmpMap.roadList[1].points[3].node)
		self.assertEqual(myMap.roadList[1].points[3].addr, myCmpMap.roadList[1].points[3].addr)
		self.assertEqual(myMap.roadList[2].name, myCmpMap.roadList[2].name)
		self.assertEqual(myMap.roadList[2].dir, myCmpMap.roadList[2].dir)
		self.assertEqual(myMap.roadList[2].points[0].node, myCmpMap.roadList[2].points[0].node)
		self.assertEqual(myMap.roadList[2].points[0].addr, myCmpMap.roadList[2].points[0].addr)
		self.assertEqual(myMap.roadList[2].points[1].node, myCmpMap.roadList[2].points[1].node)
		self.assertEqual(myMap.roadList[2].points[1].addr, myCmpMap.roadList[2].points[1].addr)

		os.remove("tmp_roads.txt")
Example #8
0
def define_road_details():
  this_road = CvtdRoad()
  this_road.name = input('Street name: ')
  this_road.dir = input('Direction (most likely "N/S" or "E/W"): ')
  return this_road
Example #9
0
    def test_compare_road(self):
        nodeDict = {}
        nodeDict[1] = CvtdNode(1, 1)
        nodeDict[2] = CvtdNode(2, 2)
        nodeDict[3] = CvtdNode(3, 3)
        nodeDict[4] = CvtdNode(4, 4)
        nodeDict[5] = CvtdNode(5, 5)
        nodeDict[6] = CvtdNode(6, 6)
        nodeDict[7] = CvtdNode(7, 7)
        nodeDict[8] = CvtdNode(8, 8)
        nodeDict[9] = CvtdNode(9, 9)

        road1 = CvtdRoad()
        road1.name = "Road A"
        road1.dir = "Up"
        road1.points.append(CvtdRoadPoint(1, 1))
        road1.points.append(CvtdRoadPoint(2, 2))
        road1.points.append(CvtdRoadPoint(3, 3))
        road1.points.append(CvtdRoadPoint(4, 4))
        road1.points.append(CvtdRoadPoint(5, 5))

        road2 = CvtdRoad()
        road2.name = "Road B"
        road2.dir = "Up"
        road2.points.append(CvtdRoadPoint(3, 3))
        road2.points.append(CvtdRoadPoint(4, 4))
        road2.points.append(CvtdRoadPoint(5, 5))
        road2.points.append(CvtdRoadPoint(6, 6))
        road2.points.append(CvtdRoadPoint(7, 7))

        road3 = CvtdRoad()
        road3.name = "Road C"
        road3.dir = "Up"
        road3.points.append(CvtdRoadPoint(4, 4))
        road3.points.append(CvtdRoadPoint(5, 5))
        road3.points.append(CvtdRoadPoint(6, 6))

        road4 = CvtdRoad()
        road4.name = "Road D"
        road4.dir = "Up"
        road4.points.append(CvtdRoadPoint(9, 9))
        road4.points.append(CvtdRoadPoint(8, 8))
        road4.points.append(CvtdRoadPoint(7, 7))

        road5 = CvtdRoad()
        road5.name = "Road E"
        road5.dir = "Up"
        road5.points.append(CvtdRoadPoint(4, 4))
        road5.points.append(CvtdRoadPoint(7, 7))

        import pdb
        pdb.set_trace()
        self.assertEqual(0, road1.compare_road(nodeDict, road1, nodeDict))
        self.assertEqual(4, road1.compare_road(nodeDict, road2, nodeDict))
        self.assertEqual(4, road1.compare_road(nodeDict, road3, nodeDict))
        self.assertEqual(-1, road1.compare_road(nodeDict, road4, nodeDict))
        self.assertEqual(3, road1.compare_road(nodeDict, road5, nodeDict))

        self.assertEqual(4, road2.compare_road(nodeDict, road1, nodeDict))
        self.assertEqual(0, road2.compare_road(nodeDict, road2, nodeDict))
        self.assertEqual(1, road2.compare_road(nodeDict, road3, nodeDict))
        self.assertEqual(4, road2.compare_road(nodeDict, road4, nodeDict))
        self.assertEqual(3, road2.compare_road(nodeDict, road5, nodeDict))

        self.assertEqual(4, road3.compare_road(nodeDict, road1, nodeDict))
        self.assertEqual(2, road3.compare_road(nodeDict, road2, nodeDict))
        self.assertEqual(0, road3.compare_road(nodeDict, road3, nodeDict))
        self.assertEqual(-1, road3.compare_road(nodeDict, road4, nodeDict))
        self.assertEqual(4, road3.compare_road(nodeDict, road5, nodeDict))

        self.assertEqual(-1, road4.compare_road(nodeDict, road1, nodeDict))
        self.assertEqual(4, road4.compare_road(nodeDict, road2, nodeDict))
        self.assertEqual(-1, road4.compare_road(nodeDict, road3, nodeDict))
        self.assertEqual(0, road4.compare_road(nodeDict, road4, nodeDict))
        self.assertEqual(4, road4.compare_road(nodeDict, road5, nodeDict))

        self.assertEqual(3, road5.compare_road(nodeDict, road1, nodeDict))
        self.assertEqual(3, road5.compare_road(nodeDict, road2, nodeDict))
        self.assertEqual(4, road5.compare_road(nodeDict, road3, nodeDict))
        self.assertEqual(4, road5.compare_road(nodeDict, road4, nodeDict))
        self.assertEqual(0, road5.compare_road(nodeDict, road5, nodeDict))
Example #10
0
  def add_road(self, wayIx, baseRoadIx):
    way = self.roadList[wayIx]
    addedRoads = [wayIx]
    newRoad = CvtdRoad()
    if baseRoadIx is not None:
      # If we're appending onto a road, add all the nodes from the main map into this map
      baseRoad = self.mainMap.roadList[baseRoadIx]
      newRoad.name = baseRoad.name
      newRoad.dir = baseRoad.dir
      for point in baseRoad.points:
        self.nodeDict[point.node] = self.mainMap.nodeDict[point.node]
        newRoad.points.append(CvtdRoadPoint(point.node, point.addr))

    print(f"{way.name} goes from {self.nodeDict[way.points[0].node]} to {self.nodeDict[way.points[-1].node]} with {len(way.points)} points")

    newName = input(f'Enter a name for this road (leave blank for "{way.name}"): ')
    if newName:
      newRoad.name = newName
    else:
      newRoad.name = way.name
    newRoad.dir = input(f"Enter a direction for {newRoad.name} ('N/S', 'E/W', or other): ")
    minValue = None
    maxValue = None
    lastValue = None

    # Merge check, only once, at the end. Reset to True if they accept the merge
    mergeCheck = True

    # For each point in this way
    pointList = way.points
    # Let them come back to some points if desired
    while len(pointList) > 0:
      returnPointList = []
      for point in pointList:
        # Don't let the same point get added twice
        if point.node in [p.node for p in newRoad.points]:
          continue
        
        # Store the node in question
        node = self.nodeDict[point.node]

        # Look for ways in the OSM file that also use this node
        newIntersections = []
        for checkWay in self.roadList:
          if point.node in [checkPoint.node for checkPoint in checkWay.points]:
            newIntersections.append(checkWay)
        
        # Calculate the "best guess" for the address at this point
        interpolateAddress = newRoad.estimate_addr(node, self.nodeDict)
        print(f"\nNext point is ({node.lat}, {node.lon}), best guess {interpolateAddress}")
        if len(newIntersections) > 0:
          print(f"The following {len(newIntersections)} roads from the OSM file intersect at this node: ")
          for way in newIntersections:
            print(" - " + way.name + ': ' + str(way.tags))

        # Determine a max and a min value for this point
        if len(newRoad.points) == 0:
          minValue = None
          maxValue = None
          neValue = None
        elif len(newRoad.points) == 1:
          minValue = None
          maxValue = None
          neValue = newRoad.points[0].addr
        else:
          point_ix, proj_ratio, error = newRoad.compute_proj_ratio(node.lat, node.lon, self.nodeDict)
          inc = newRoad.increasing()
          if (proj_ratio < 0 and inc) or (proj_ratio > 1 and not inc):
            # Address must be less than the first address
            minValue = None
            maxValue = newRoad.points[0].addr - 1
            neValue = None
          elif (proj_ratio > 1 and inc) or (proj_ratio < 0 and not inc):
            # Address must be greater than the final address
            minValue = newRoad.points[-1].addr + 1
            maxValue = None
            neValue = None
          else:
            # Address must be between point #point_ix and the following point
            minValue = newRoad.points[point_ix].addr + 1 if inc else newRoad.points[point_ix + 1].addr - 1
            maxValue = newRoad.points[point_ix + 1].addr - 1 if inc else newRoad.points[point_ix].addr + 1
            neValue = None
          
        # Now let them choose an address, or 'skip' (ignore this point), or 'return' (come back to this point later)
        repeatThisAddr = True
        while repeatThisAddr:
          repeatThisAddr = False
          addr = CvtdUtil.input_int("Enter the address for this point, or 'skip', 'return' or 'edit': ", minValue, maxValue, neValue, ['skip', 'return', 'edit', 'quit', 's', 'r', 'e', 'q'])
          if addr is not None:
            if addr in ["skip", 's']:
              pass
            elif addr in ["return", 'r']:
              returnPointList.append(point)
            elif addr in ["edit", 'e']:
              newRoad.edit(self.nodeDict)
              repeatThisAddr = True
            elif addr in ["quit", 'q']:
              return
            else:
              newRoad.insert(CvtdRoadPoint(point.node, addr))
              newRoad.describe(self.nodeDict)
          else:
            return
      
      if len(returnPointList) > 0:
        pointList = returnPointList
      elif mergeCheck:
        pointList = []
        mergeCheck = False
        print("\nYou've defined the following road:")
        newRoad.describe(self.nodeDict)
        print('')

        # They successfully added all the points. See if they want to merge with another road
        possibleMerges = [way for way in self.roadList if newRoad.extendable(way)]

        if len(possibleMerges) > 0:
          print(f"There are {len(possibleMerges)} ways that you could merge into this road. ")
          for ix, way in enumerate(possibleMerges):
            print(f"[{ix+1}]: {way.name} has {len(way.points)} nodes")
            print(" " + ", ".join([f"({self.nodeDict[p.node].lat}, {self.nodeDict[p.node].lon})" for p in way.points]))
          
          mergeWay = CvtdUtil.input_int(f"Merge another road into this road? (1-{len(possibleMerges)}) or (n)o: ", 1, len(possibleMerges), validAnswers=['n', 'no'])
          if type(mergeWay) is int:
            mergeWay = mergeWay - 1
            pointList = possibleMerges[mergeWay].points
            addedRoads.append(self.roadList.index(possibleMerges[mergeWay]))
            mergeCheck = True
      else:
        # They were offered a merge check but they rejected it
        pointList = []

    confirm = 'e'
    while confirm == 'e':
      confirm = input("Add this new road to your map? (y/n/[e]dit): ")
      if confirm == 'e':
        newRoad.edit(self.nodeDict)
        print("\nYou've defined the following road:")
        newRoad.describe(self.nodeDict)
        print('')
      elif confirm == 'y':
        # If we are replacing a street (adding onto one), replace. Else add
        import pdb; pdb.set_trace()
        if baseRoadIx is not None:
          self.mainMap.replace_street_with_nodes(newRoad, self.nodeDict, baseRoadIx)
        else:
          self.mainMap.add_street_with_nodes(newRoad, self.nodeDict)
        print(f"You now have {len(self.mainMap.roadList)} roads.")

        # Remove each road, adjusting other indices for each road removed
        for ixOfIx, ixToRemove in enumerate(addedRoads):
          # Delete the ixToRemove'th index in self.roadList
          del self.roadList[ixToRemove]
          # Decrement all successive indices that are greater than ixToRemove
          for ixOfAdjustIx, ixToAdjust in enumerate(addedRoads[ixOfIx+1:]):
            if ixToAdjust > ixToRemove:
              addedRoads[ixOfAdjustIx] = addedRoads[ixOfAdjustIx] - 1
        return addedRoads