예제 #1
0
def find_route(names: list,
               pos: (float, float),
               file_name: str = 'names.csv') -> dict:
    '''
    creates a file with distance matrix among chosen places
    :param names: names of the places you want to visit
    :param pos: your position at the moment (starting point) ((yet has no use))
    :param file_name: name of a file with name,lat,lon lines
    :return: return a dictionary {1: 'first place', 2: 'second place', ...} (for later in code)
    '''
    places_number_name = dict()
    places_name_coor = dict()
    name_in = 'SampleIn_1.txt'
    name_out = 'SampleOut.txt'

    for i in range(len(names)):
        places_number_name[i + 1] = names[i]

    file = open(file_name, 'r')

    for line in file.readlines():
        if line.split(sep=',')[0] in names:
            places_name_coor[line.split(sep=',')[0]] = (float(
                line.split(sep=',')[1]), float(line.split(sep=',')[2]))

    file.close()

    file_m = open(name_in, 'w', encoding='UTF-8')
    file_m.write(str(len(names)) + '\n')

    router = Router('car')

    for name_start in places_name_coor.keys():
        start = router.findNode(places_name_coor[name_start][0],
                                places_name_coor[name_start][1])
        for name_end in places_name_coor.keys():
            end = router.findNode(places_name_coor[name_end][0],
                                  places_name_coor[name_end][1])
            if name_start == name_end:
                file_m.write('-1 ')
                continue
            status, route = router.doRoute(start, end)
            print(status)
            if status == 'success':
                routeLatLons = list(map(router.nodeLatLon, route))

                sum_ = 0

                for i in range(len(routeLatLons) - 1):
                    sum_ += router.distance(routeLatLons[i],
                                            routeLatLons[i + 1])
                file_m.write(' ' + str(sum_)[:5] + ' ')
        file_m.write('\n')

    file_m.close()

    return places_number_name
예제 #2
0
파일: Routing.py 프로젝트: Nebras1/Rover
class RoutingUsage:
    def __init__(self,Mode):
        self.router = Router(Mode) # Initialise it
    
    def node(self,lat,longit):
        return [lat,longit]
    
    def getRouteMultiple(self,nodesNew):
        queueNodesNewRight = []
        for index in range(0,len(nodesNew)-1):
            nodeStart = nodesNew[index]
            nodeEnd = nodesNew[index+1]
            route = self.getTheRouteBetweenTwoNodes(nodeStart[0],nodeStart[1],nodeEnd[0],nodeEnd[1])
            if len(route[0]) == 0 and route[1] > 0:
                return None
            queueNodesNewRight.append(route)
        return queueNodesNewRight
    
    def arrangeNodesDependsOnLength(self,nodes):
        for nodeStartIndex in range(0,len(nodes)-1): 
            lastDistance = self.router.distance(nodes[nodeStartIndex],nodes[nodeStartIndex+1])
            for nodeNowIndex in range(nodeStartIndex+1,len(nodes)):
                theReturnedNodeWhichisNearst=nodes[nodeStartIndex+1]
                nowLength = self.router.distance(nodes[nodeStartIndex],nodes[nodeNowIndex])
                #print(nowLength)
                theReturnedNodeIndex = nodeStartIndex
                if nowLength < lastDistance :
                    theReturnedNodeWhichisNearst = nodes[nodeNowIndex]
                    theReturnedNodeIndex = nodeNowIndex
                    lastDistance = self.router.distance(nodes[nodeStartIndex],nodes[nodeNowIndex])
            ReserveNode = nodes[nodeStartIndex+1]
            nodes[nodeStartIndex+1] = nodes[theReturnedNodeIndex]
            nodes[theReturnedNodeIndex] = ReserveNode
            #print("length: %f"%lastDistance)
        return nodes

    def getTheRouteBetweenTwoNodes(self,lat1,long1,lat2,long2):
        

        start = self.router.findNode(lat1,long1) # Find start and end nodes
        end = self.router.findNode(lat2,long2)

##        print("start : %s,   Lat: %s,  Lon: %s "% (start,lat1,long1))
##        print("end : %s,   Lat: %s,  Lon: %s "% (end,lat2,long2))
        

        status, route = self.router.doRoute(start, end) # Find the route - a list of OSM nodes

        if status == 'success':
            routeLatLons = list(map(self.router.nodeLatLon, route)) # Get actual route coordinates
            
            # list the lat/long
            queueNodes = []
            sumPath = 0
            l = len(route)
            for index, obj in enumerate(route):
                thisElement = route[index]
                newDistance = 0
                if index < l-1 :
                  nextElement = route[index+1]
                  thisElementD = [self.router.nodeLatLon(thisElement)[0],self.router.nodeLatLon(thisElement)[1]]
                  nextElementD = [self.router.nodeLatLon(nextElement)[0],self.router.nodeLatLon(nextElement)[1]]
                  newDistance = self.router.distance(nextElementD,thisElementD)
                  sumPath = sumPath + newDistance
                elif index == l -1:
                  nextElement = route[index-1]

                  
                typeData = self.router.getNodeWay(thisElement,nextElement)
                #get width Depends on the Category
                width = self.router.getRouteWidth(typeData["tag"]["highway"])

                #get width Depends on the way lanes numbers
                NumberOfLanes = typeData["tag"].get("lanes")

                #Const Lanes Width it will be 3 meter
                laneWidth = 3/12742/6*1.1 #Meter
                if NumberOfLanes != None:
                    width = int(NumberOfLanes)*laneWidth

                
                #get width Depends on the way width
                widthUnCalibrated = typeData["tag"].get("width")
                if widthUnCalibrated != None:
                    width = float(widthUnCalibrated)/12742/6*1.1

                nodeNow=self.router.nodeLatLon(thisElement)
                nodeNext=self.router.nodeLatLon(nextElement)
                queueNodes.append([route[index], nodeNow[0],nodeNow[1],width])
                if newDistance > 0.009:
                  newNodesBetween = self.router.getNumberOfNodesBetweenThose(7, nodeNow,nodeNext) 
                  for nodeBet in newNodesBetween:
                    queueNodes.append([str(index)+str(nodeBet[0])+"975", nodeBet[1],nodeBet[2],width])

            #/////////////////////////////////////////////////Shift the Nodes
            
            queueNodesNewRight = []
           
                
            for index, obj in enumerate(queueNodes):
               
                lV = len(queueNodes)
                if index < lV-1 :
                    nextElement = [queueNodes[index+1][1],queueNodes[index+1][2]]
                    nextElementId = queueNodes[index+1][0]
                    thisElement = [queueNodes[index][1],queueNodes[index][2]]
                    thisElementId = queueNodes[index][0]
                    newDistance = self.router.distance(thisElement,nextElement)
                elif index == lV -1:
                    nextElement = [queueNodes[index][1],queueNodes[index][2]]
                    thisElement = [queueNodes[index][1],queueNodes[index][2]]
                
                
                newNode = self.router.getLatLongWithNewWidth(queueNodes[index][3],newDistance, thisElement,nextElement)
                queueNodesNewRight.append([queueNodes[index][0], newNode[0],newNode[1],queueNodes[index][3]])
            return [queueNodesNewRight,sumPath]
        else:
            node1=self.node(lat1,long1)
            node2=self.node(lat2,long2)
            return [[],self.router.distance(node1,node2)]
예제 #3
0
from pyroutelib3 import Router
router = Router("car", "/home/user/Desktop/maps/RU-PRI.osm")

lat, lon = 45.944457, 133.805337
lat1, lon1 = 43.745925, 135.284925
start = router.data.findNode(lat, lon)  # Find start and end nodes
end = router.data.findNode(lat1, lon1)

status, route = router.doRoute(start,
                               end)  # Find the route - a list of OSM nodes

if status == 'success':
    routeLatLons = list(map(router.nodeLatLon,
                            route))  # Get actual route coordinates

#print(status)
print(route, routeLatLons, sep='\n')

distance = 0

for i in range(1, len(route)):
    distance += router.distance(route[i - 1], route[i])

print(distance)
예제 #4
0
class GetRoutInfo(object):
    def __init__(self, localFile):
        # https://wiki.openstreetmap.org/wiki/Routing
        pyroutelib3.TYPES["car"]['weights']['motorway'] = 20
        pyroutelib3.TYPES["car"]['weights']['trunk'] = 10
        pyroutelib3.TYPES["car"]['weights']['primary'] = 1
        pyroutelib3.TYPES["car"]['weights']['secondary'] = 1
        pyroutelib3.TYPES["car"]['weights']['tertiary'] = 1
        pyroutelib3.TYPES["car"]['weights']['unclassified'] = 1
        pyroutelib3.TYPES["car"]['weights']['residential'] = 0.5
        pyroutelib3.TYPES["car"]['weights']['track'] = 0
        pyroutelib3.TYPES["car"]['weights']['service'] = 0
        if localFile:
            self.router = Router("car", localFile)
        else:
            self.router = Router("car")

    """
    This methode is setting the weights for the used router
    Check out the follwoing web page for further details 
    # https://wiki.openstreetmap.org/wiki/Routing
    """

    def setRouteweights(self, motorway, trunk, primary, secondary, tertiary,
                        unclassified, residential, track, service):
        pyroutelib3.TYPES["car"]['weights']['motorway'] = motorway
        pyroutelib3.TYPES["car"]['weights']['trunk'] = trunk
        pyroutelib3.TYPES["car"]['weights']['primary'] = primary
        pyroutelib3.TYPES["car"]['weights']['secondary'] = secondary
        pyroutelib3.TYPES["car"]['weights']['tertiary'] = tertiary
        pyroutelib3.TYPES["car"]['weights']['unclassified'] = unclassified
        pyroutelib3.TYPES["car"]['weights']['residential'] = residential
        pyroutelib3.TYPES["car"]['weights']['track'] = track
        pyroutelib3.TYPES["car"]['weights']['service'] = service

    """
    This methode findes a route between two points defined by coordinates
    """

    def routeF(self, p1Lag, p1Long, p2Lag, p2Long):
        self.s = (p1Lag, p1Long)
        self.e = (p2Lag, p2Long)

        start = self.router.findNode(self.s[0], self.s[1])
        end = self.router.findNode(self.e[0], self.e[1])

        self.filesName = "{}_{}".format(start, end)
        routeFile = self.filesName + "_route.json"

        #if file already available load it
        if os.path.isfile(routeFile):
            with open(routeFile, 'r') as f:
                (self.route, self.routeLatLons) = json.load(f)
                #self.routeLatLons = list(map(self.router.nodeLatLon, self.route))
        #if no file is available calcualte route and store it
        else:
            status, self.route = self.router.doRoute(start, end)
            if status == 'success':
                self.routeLatLons = list(
                    map(self.router.nodeLatLon,
                        self.route))  # Get actual route coordinates
                with open(routeFile, 'w') as f:
                    json.dump([self.route, self.routeLatLons], f)
            else:
                raise Exception(
                    "could not find a route from two points p1: ({}) p2: ({}). Status:{}"
                    .format(start, end, status))

    """
    This methode prints the route into a map
    """

    def printRoute(self, dpi, width):
        tilemapbase.start_logging()
        tilemapbase.init(create=True)
        t = tilemapbase.tiles.build_OSM()

        if self.s[0] < self.e[0]:
            south = self.s[0]
            north = self.e[0]
        else:
            south = self.e[0]
            north = self.s[0]

        if self.s[1] < self.e[1]:
            east = self.s[1]
            west = self.e[1]
        else:
            east = self.e[1]
            west = self.s[1]

        degree_range = 0.1
        extent = tilemapbase.Extent.from_lonlat(east - degree_range,
                                                west + degree_range,
                                                south - degree_range,
                                                north + degree_range)

        fig, ax = plt.subplots(figsize=(8, 8), dpi=dpi)

        plotter = tilemapbase.Plotter(extent, t, width=width)
        plotter.plot(ax, t)

        for i in self.routeLatLons:
            x, y = tilemapbase.project(i[1], i[0])
            ax.scatter(x, y, marker=".", color="black", linewidth=2)
        plt.show()

    """
    This methode is used to find ways onto which the nodes are placed 
    This is done via Overpass API
    Due to the fact a node can be a member of several ways a simple algorithi is used which 
    search for the correct way. 
    """

    def getWay(self):
        #https://www.openstreetmap.org/node/34817889 -> To see node in osm.org
        #http://overpass-api.de/api/interpreter?data=[out:json];node(34817889);way(bn);out;
        #-> what we are doing with request.
        wayfile = self.filesName + "_way.json"
        if os.path.isfile(wayfile):
            with open(wayfile, 'r') as f:
                self.way = json.load(f)
        else:
            data = []
            overpass_url = "http://overpass-api.de/api/interpreter"
            for i in self.route:
                overpass_query = """
                [out:json];
                (node({});
                 way(bn);
                );
                out center;
                """.format(i)
                while True:
                    try:
                        response = requests.get(
                            overpass_url, params={'data': overpass_query})
                        data.append(response.json())
                        break
                    except:
                        print("error {}".format(i))

            #set_trace()
            with open(wayfile + "temp.json", 'w') as f:
                json.dump(data, f)

            #remove not needed information
            elements = []
            for i in range(0, len(data)):
                elements.append(data[i]['elements'])

            #filter ways a bit
            ways = []
            for i in elements:
                ways.append([])
                for j in i:
                    if j['type'] == 'way':
                        if 'tags' in j:
                            if 'highway' in j['tags']:
                                if j['tags']['highway'] != 'footway' \
                                        and j['tags']['highway'] != 'raceway' \
                                        and j['tags']['highway'] != 'bridleway' \
                                        and j['tags']['highway'] != 'steps' \
                                        and j['tags']['highway'] != 'path' \
                                        and j['tags']['highway'] != 'service':
                                    ways[-1].append(j)

            #algorithm to detect correct way out of multible ways of singel point
            #initail point
            way = []
            for i in range(0, len(ways[0])):
                for j in range(0, len(ways[1])):
                    if ways[0][i]['id'] == ways[1][j]['id']:
                        way.append(ways[0][i])
                        break

            #following points
            cnt = 0
            for i in range(1, len(ways)):
                if cnt > 1:
                    #set_trace()
                    print("{} duplicate found".format(cnt))
                    for i in range(0, cnt - 1):
                        del (way[-1])
                    #raise Exception("can't detect correct way point!")

                cnt = 0
                for j in range(0, len(ways[i])):
                    for k in range(0, len(ways[i - 1])):
                        if ways[i][j]['id'] == ways[i - 1][k]['id']:
                            way.append(ways[i][j])
                            cnt += 1

            self.way = way
            with open(wayfile, 'w') as f:
                json.dump(self.way, f)

    """
    This methode is used to extract the maxspeed data for the ways. 
    If no maxspeed is specifired a assumption depending on the 
    road classification is met
    """

    def getMaxSpeed(self):
        speed = []
        for i in self.way:
            if 'maxspeed' in i['tags'] and i['tags']['maxspeed'] != 'signals':
                speed.append(int(i['tags']['maxspeed']))
            else:
                if i['tags']['highway'] == 'motorway':
                    if 'tunnel' in i['tags'] and i['tags']['tunnel'] == 'yes':
                        speed.append(100)
                    else:
                        speed.append(130)
                elif i['tags']['highway'] == 'motorway_link':
                    speed.append(100)
                elif i['tags']['highway'] == 'trunk':
                    speed.append(100)
                elif i['tags']['highway'] == 'trunk_link':
                    speed.append(100)
                elif i['tags']['highway'] == 'primary':
                    speed.append(100)
                elif i['tags']['highway'] == 'primary_link':
                    speed.append(80)
                elif i['tags']['highway'] == 'secondary':
                    speed.append(100)
                elif i['tags']['highway'] == 'secondary_link':
                    speed.append(80)
                elif i['tags']['highway'] == 'tertiary':
                    speed.append(70)
                elif i['tags']['highway'] == 'tertiary_link':
                    speed.append(50)
                elif i['tags']['highway'] == 'unclassified':
                    speed.append(70)
                elif i['tags']['highway'] == 'residential':
                    speed.append(50)
                else:
                    raise Exception(
                        "can't find max speed of route:{}".format(i))

        self.maxSpeed = speed

    """ 
    This methode is used to create a list of distances between each node
    """

    def getDist(self):
        # list of distance between nodes
        self.distance = []
        #for i in range(0, len(self.routeLatLons) - 1):
        #    self.distance.append(self.router.distance(self.routeLatLons[i], self.routeLatLons[i + 1]))
        for i in range(0, len(self.way) - 1):
            self.distance.append(
                self.router.distance([
                    self.way[i]['center']['lat'], self.way[i]['center']['lon']
                ], [
                    self.way[i + 1]['center']['lat'],
                    self.way[i + 1]['center']['lon']
                ]))
예제 #5
0
def find_route(names: list, pos: (float, float), transport_type: str):
    """
    creates a file with distance matrix among chosen places

    :param names: names of the places you want to visit
    :param pos: your position at the moment (starting point)
    :param transport_type: obvious
    :return: None
    """

    global after_dot, routes, places_number_name, places_name_coor, name_in, city

    places_number_name[1] = 'curr_pos'

    for i in range(1, len(names) + 1):
        places_number_name[i + 1] = names[i - 1]

    places_name_coor['curr_pos'] = pos

    data = pd.read_csv(city + ".csv")
    all_names = data['Название']
    all_lon = data['Долгота']
    all_lat = data['Широта']
    wh = list()
    types = [
        'Памятники', 'Дома и дворцы', 'Башни и ворота', 'Современные здания',
        'Московское центральное кольцо (МЦК)'
    ]

    for name in names:
        places_name_coor[name] = (all_lon[pd.Index(all_names).get_loc(
            name.replace(',', '+++'))], all_lat[pd.Index(all_names).get_loc(
                name.replace(',', '+++'))])

    file_m = open(name_in, 'w', encoding='UTF-8')
    file_m.write(str(len(names) + 1) + '\n')
    router = Router(transport_type)  # , 'static/Moscow_test.osm')
    key = 0
    for name_start in places_name_coor.keys():
        if name_start != 'curr_pos':
            idx = pd.Index(all_names).get_loc(name_start.replace(',', '+++'))
            type = data['Тип Постройки'][pd.Index(all_names).get_loc(
                name_start.replace(',', '+++'))]
            week = [
                data['Mon'][idx], data['Tue'][idx], data['Wed'][idx],
                data['Thu'][idx], data['Fri'][idx], data['Sat'][idx],
                data['Sun'][idx]
            ]
            for d in week:
                if d != 'None':
                    wh.append(' 1 ')
                elif type not in types:
                    wh.append('-1 ')
                else:
                    wh.append(' 1 ')
        wh.append('\n')
        to_write = str()
        start = router.findNode(places_name_coor[name_start][0],
                                places_name_coor[name_start][1])
        for name_end in places_name_coor.keys():
            key += 1
            end = router.findNode(places_name_coor[name_end][0],
                                  places_name_coor[name_end][1])
            status, route = router.doRoute(start, end)
            if status == 'success':
                routeLatLons = list(map(router.nodeLatLon, route))
                routes[key] = routeLatLons
                sum_ = 0

                for i in range(len(routeLatLons) - 1):
                    sum_ += router.distance(routeLatLons[i],
                                            routeLatLons[i + 1])
                sum_ *= after_dot
                to_write += ' ' + str(sum_)[:str(sum_).index('.')] + ' '
            elif status == 'no_route':
                routes[key] = route
                to_write += '-1 '
        to_write = to_write.rstrip()
        file_m.write(to_write + '\n')

    for i in wh:
        file_m.write(i)
    file_m.close()