Esempio n. 1
0
 def edit(self, nodeDict):
     while True:
         print("n: Name: " + self.name)
         print("d: Direction: " + self.dir)
         for pointIx, point in enumerate(self.points):
             print(
                 f"{pointIx+1}: {point.addr} at {nodeDict[point.node].lat}, {nodeDict[point.node].lon}"
             )
         action = CvtdUtil.input_int(
             f"What do you want to edit or delete? Enter 'q' when done: ",
             1,
             len(self.points),
             validAnswers=['q', 'n', 'd'])
         if type(action) is int:
             realPointIx = action - 1
             pointAction = CvtdUtil.input_int(
                 f"Choose one of the following: (1) edit addr, (2) edit node, (3) delete point: ",
                 1, 3)
             if pointAction == 1:
                 # If we have more than one point, increasing/decreasing is defined and we can maintain the constraint
                 # Else, we just need to set neAddr to the current
                 if len(self.points) > 1:
                     if self.increasing:
                         minAddr = self.points[
                             realPointIx -
                             1].addr + 1 if realPointIx > 0 else None
                         maxAddr = self.points[
                             realPointIx + 1].addr - 1 if realPointIx < (
                                 len(self.points) - 1) else None
                     else:
                         maxAddr = self.points[
                             realPointIx -
                             1].addr - 1 if realPointIx > 0 else None
                         minAddr = self.points[
                             realPointIx + 1].addr + 1 if realPointIx < (
                                 len(self.points) - 1) else None
                 else:
                     minAddr = None
                     maxAddr = None
                 self.points[realPointIx].addr = CvtdUtil.input_int(
                     f"Enter a new address (min {minAddr}, max {maxAddr}): ",
                     minAddr, maxAddr)
             elif pointAction == 2:
                 print("Not Implemented Error. Sorry")
             elif pointAction == 3:
                 del self.points[realPointIx]
         elif action == 'n':
             self.name = input("Enter name for this road: ")
         elif action == 'd':
             self.dir = input(
                 f"Enter a direction for {self.name} ('N/S', 'E/W', or other'): "
             )
         else:
             break
Esempio n. 2
0
  def search_road(self):
    search = input("Search for a road with the following text: ")
    roadIxList = [i for i in range(len(self.roadList)) if search in self.roadList[i].name]
    ways = [self.roadList[way] for way in roadIxList]
    # ways = [way for way in self.roadList if search in way.name]

    if len(roadIxList) == 0:
      print("No ways found.")
      return

    # Print information about each of the matching ways
    for ix, way in enumerate(ways):
      try:
        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]))
      except KeyError:
        print(f"Unknown node")
    
    # Here, compare with what is currently in the file to see if we want to add onto a road, modify a road, or do nothing
    # For the present, we'll just add a new road
    whichWay = CvtdUtil.input_int("Adding a new road. Start with which way? ", 1, len(ways))
    if type(whichWay) is int:
      self.add_road(roadIxList[whichWay - 1], None)
Esempio n. 3
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