Exemple #1
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)
Exemple #2
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