def osrmGetShapepointsTimeDist(startLoc, endLoc): """ A function to get a list of shapepoints from start coordinate to end coordinate, the result of this function is not as detailed as mpqGetShapepointTimeDist, however, it is faster. Parameters ---------- startLoc: list Start location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] endLoc: list End location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] Returns ------- path: list of lists A list of coordinates in sequence that shape the route from startLoc to endLoc timeInSeconds: double time between current shapepoint and previous shapepoint, the first element should be 0 distInMeters: double distance between current shapepoint and previous shapepoint, the first element should be 0 """ dicStartLoc = loc2Dict(startLoc) dicEndLoc = loc2Dict(endLoc) shapepointsUrl = ('http://router.project-osrm.org/route/v1/driving/%s,%s;%s,%s?steps=true') % (dicStartLoc['lon'], dicStartLoc['lat'], dicEndLoc['lon'], dicEndLoc['lat']) # OSRM use lon/lat data = [] try: http = urllib3.PoolManager() response = http.request('GET', shapepointsUrl) data = json.loads(response.data.decode('utf-8')) path = [] for i in range(len(data['routes'])): for j in range(len(data['routes'][i]['legs'])): for k in range(len(data['routes'][i]['legs'][j]['steps'])): for m in range(len(data['routes'][i]['legs'][j]['steps'][k]['intersections'])): path.append([data['routes'][i]['legs'][j]['steps'][k]['intersections'][m]['location'][1], data['routes'][i]['legs'][j]['steps'][k]['intersections'][m]['location'][0]]) totalTimeInSecond = data['routes'][0]['duration'] [timeInSeconds, distInMeters] = distributeTimeDist(path, totalTimeInSecond) except: print ("Message: OSRM is currently not available, please try again later.") return [path, timeInSeconds, distInMeters]
def privGetShapepoints2D( odID=1, objectID=None, modelFile=None, startLoc=None, endLoc=None, startTimeSec=0.0, expDurationSec=None, routeType='euclidean2D', speedMPS=None, leafletColor=config['VRV_DEFAULT_LEAFLETARCCOLOR'], leafletWeight=config['VRV_DEFAULT_LEAFLETARCWEIGHT'], leafletStyle=config['VRV_DEFAULT_LEAFLETARCSTYLE'], leafletOpacity=config['VRV_DEFAULT_LEAFLETARCOPACITY'], leafletCurveType=config['VRV_DEFAULT_ARCCURVETYPE'], leafletCurvature=config['VRV_DEFAULT_ARCCURVATURE'], useArrows=True, modelScale=config['VRV_DEFAULT_CESIUMMODELSCALE'], modelMinPxSize=config['VRV_DEFAULT_CESIUMMODELMINPXSIZE'], cesiumColor=config['VRV_DEFAULT_CESIUMPATHCOLOR'], cesiumWeight=config['VRV_DEFAULT_CESIUMPATHWEIGHT'], cesiumStyle=config['VRV_DEFAULT_CESIUMPATHSTYLE'], cesiumOpacity=config['VRV_DEFAULT_CESIUMPATHOPACITY'], ganttColor=config['VRV_DEFAULT_GANTTCOLOR'], popupText=None, dataProvider=None, dataProviderArgs=None): # Replace backslash modelFile = replaceBackslashToSlash(modelFile) # Ensure leading slash modelFile = addHeadSlash(modelFile) try: dataProvider = dataProvider.lower() except: pass try: routeType = routeType.lower() except: pass if (startLoc != endLoc): extras = {} if (routeType == 'euclidean2d'): [path, time, dist] = _eucGetShapepointsTimeDist(startLoc, endLoc, speedMPS, expDurationSec) elif (routeType == 'manhattan'): [path, time, dist] = _manGetShapepointsTimeDist(startLoc, endLoc, speedMPS, expDurationSec) elif (routeType == 'fastest' and dataProviderDictionary[dataProvider] == 'pgrouting'): databaseName = dataProviderArgs['databaseName'] [path, time, dist] = pgrGetShapepointsTimeDist(startLoc, endLoc, databaseName) elif (routeType == 'fastest' and dataProviderDictionary[dataProvider] == 'osrm-online'): [path, time, dist] = osrmGetShapepointsTimeDist(startLoc, endLoc) elif (routeType in ['fastest', 'shortest', 'pedestrian'] and dataProviderDictionary[dataProvider] == 'mapquest'): APIkey = dataProviderArgs['APIkey'] [path, time, dist] = mqGetShapepointsTimeDist(startLoc, endLoc, routeType, APIkey) elif (routeType in ['fastest', 'pedestrian', 'cycling', 'truck', 'wheelchair'] and dataProviderDictionary[dataProvider] == 'ors-online'): APIkey = dataProviderArgs['APIkey'] if ('requestExtras' in dataProviderArgs.keys()): requestExtras = dataProviderArgs['requestExtras'] else: requestExtras = True [path, extras, time, dist] = orsGetShapepointsTimeDist(startLoc, endLoc, routeType, APIkey, requestExtras) elif (routeType in ['fastest', 'pedestrian', 'cycling', 'truck'] and dataProviderDictionary[dataProvider] == 'ors-local'): port = dataProviderArgs['port'] if ('requestExtras' in dataProviderArgs.keys()): requestExtras = dataProviderArgs['requestExtras'] else: requestExtras = True [path, extras, time, dist] = orsLocalGetShapepointsTimeDist(startLoc, endLoc, routeType, port, requestExtras) else: return # Check if the original point is too far away from the actual start point of the shapepoints from query distOri = geoDistance2D(startLoc, path[0]) if (distOri >= config['VRV_DEFAULT_DISTANCE_ERROR_TOLERANCE'] ): # Go back to 10m after testing print( "Message: The origin point (lat: %s, lon: %s) is %.1f meters away from the road. You might find a gap between the origin point and the route." % (startLoc[0], startLoc[1], distOri)) # Check if the actual end point is too far away from destination point distDes = geoDistance2D(path[-1], endLoc) if (distDes >= config['VRV_DEFAULT_DISTANCE_ERROR_TOLERANCE'] ): # Go back to 10m after testing print( "Message: The destination point (lat: %s, lon: %s) is %.1f meters away from the road. You might find a gap between destination point and the route." % (endLoc[0], endLoc[1], distDes)) # convert distance to accumulated distance accDist = [] accDist.append(0) for i in range(1, len(dist)): accDist.append(accDist[i - 1] + dist[i]) # If `expDurationSec` is provided, override `speedMPS` and datasource, otherwise, if `speedMPS` is provided, override datasource if (expDurationSec != None): [newTime, newDist] = distributeTimeDist(path, expDurationSec) time = newTime dist = newDist elif (speedMPS != None and expDurationSec == None): newExpDurationSec = accDist[len(accDist) - 1] / speedMPS [newTime, newDist] = distributeTimeDist(path, newExpDurationSec) time = newTime dist = newDist # convert time to accumulated time accTime = [] accTime.append(startTimeSec) for i in range(1, len(dist)): accTime.append(accTime[i - 1] + time[i]) # For maintainability, convert locs into dictionary dicPath = locs2Dict(path) # shapepoint dataframe assignments = privInitDataframe('Assignments') # generate assignments for i in range(1, len(path)): if (i - 1) in extras: startElev = extras[i - 1]['elev'] if 'elev' in extras[i - 1] else None wayname = extras[i]['wayname'] if 'wayname' in extras[ i] else None waycategory = extras[i][ 'waycategory'] if 'waycategory' in extras[i] else None surface = extras[i]['surface'] if 'surface' in extras[ i] else None waytype = extras[i]['waytype'] if 'waytype' in extras[ i] else None steepness = extras[i]['steepness'] if 'steepness' in extras[ i] else None tollway = extras[i]['tollway'] if 'tollway' in extras[ i] else None else: startElev = None wayname = None waycategory = None surface = None waytype = None steepness = None tollway = None if i in extras: endElev = extras[i]['elev'] if 'elev' in extras[i] else None else: endElev = None assignments = assignments.append( { 'odID': odID, 'objectID': objectID, 'modelFile': modelFile, 'startTimeSec': accTime[i - 1], 'startLat': dicPath[i - 1]['lat'], 'startLon': dicPath[i - 1]['lon'], 'startAltMeters': dicPath[i - 1]['alt'], 'endTimeSec': accTime[i], 'endLat': dicPath[i]['lat'], 'endLon': dicPath[i]['lon'], 'endAltMeters': dicPath[i]['alt'], 'leafletColor': leafletColor, 'leafletWeight': leafletWeight, 'leafletStyle': leafletStyle, 'leafletCurveType': leafletCurveType, 'leafletCurvature': leafletCurvature, 'useArrows': useArrows, 'leafletOpacity': leafletOpacity, 'modelScale': modelScale, 'modelMinPxSize': modelMinPxSize, 'cesiumColor': stripCesiumColor(cesiumColor), 'cesiumWeight': cesiumWeight, 'cesiumStyle': cesiumStyle, 'cesiumOpacity': cesiumOpacity, 'ganttColor': ganttColor, 'popupText': popupText, 'startElevMeters': startElev, 'endElevMeters': endElev, 'wayname': wayname, 'waycategory': waycategory, 'surface': surface, 'waytype': waytype, 'steepness': steepness, 'tollway': tollway }, ignore_index=True) else: # For maintainability, convert locs into dictionary dicStartLoc = loc2Dict(startLoc) if (dataProviderDictionary[dataProvider] == 'ors-online'): [[lat, lon, elev]] = orsGetElevation([startLoc], dataProviderArgs['APIkey']) else: elev = None assignments = privInitDataframe('Assignments') assignments = assignments.append( { 'odID': odID, 'objectID': objectID, 'modelFile': modelFile, 'startTimeSec': startTimeSec, 'startLat': dicStartLoc['lat'], 'startLon': dicStartLoc['lon'], 'startAltMeters': dicStartLoc['alt'], 'endTimeSec': expDurationSec + startTimeSec if (expDurationSec is not None) else startTimeSec, 'endLat': dicStartLoc['lat'], 'endLon': dicStartLoc['lon'], 'endAltMeters': dicStartLoc['alt'], 'leafletColor': leafletColor, 'leafletWeight': leafletWeight, 'leafletStyle': leafletStyle, 'leafletCurveType': leafletCurveType, 'leafletCurvature': leafletCurvature, 'useArrows': useArrows, 'leafletOpacity': leafletOpacity, 'modelScale': modelScale, 'modelMinPxSize': modelMinPxSize, 'cesiumColor': stripCesiumColor(cesiumColor), 'cesiumWeight': cesiumWeight, 'cesiumStyle': cesiumStyle, 'cesiumOpacity': cesiumOpacity, 'ganttColor': ganttColor, 'popupText': popupText, 'startElevMeters': elev, 'endElevMeters': elev, 'wayname': None, 'waycategory': None, 'surface': None, 'waytype': None, 'steepness': None, 'tollway': None }, ignore_index=True) return assignments
def privGetShapepoints2D(odID=1, objectID=None, modelFile=None, startLoc=None, endLoc=None, startTimeSec=0.0, expDurationSec=None, routeType='euclidean2D', speedMPS=None, leafletColor=VRV_DEFAULT_LEAFLETARCCOLOR, leafletWeight=VRV_DEFAULT_LEAFLETARCWEIGHT, leafletStyle=VRV_DEFAULT_LEAFLETARCSTYLE, leafletOpacity=VRV_DEFAULT_LEAFLETARCOPACITY, useArrows=True, modelScale=VRV_DEFAULT_CESIUMMODELSCALE, modelMinPxSize=VRV_DEFAULT_CESIUMMODELMINPXSIZE, cesiumColor=VRV_DEFAULT_CESIUMPATHCOLOR, cesiumWeight=VRV_DEFAULT_CESIUMPATHWEIGHT, cesiumStyle=VRV_DEFAULT_CESIUMPATHSTYLE, cesiumOpacity=VRV_DEFAULT_CESIUMPATHOPACITY, dataProvider=None, dataProviderArgs=None): # Replace backslash modelFile = replaceBackslashToSlash(modelFile) try: dataProvider = dataProvider.lower() except: pass try: routeType = routeType.lower() except: pass if (startLoc != endLoc): if (routeType == 'euclidean2d'): [path, time, dist] = _eucGetShapepointsTimeDist(startLoc, endLoc, speedMPS, expDurationSec) elif (routeType == 'manhattan'): [path, time, dist] = _manGetShapepointsTimeDist(startLoc, endLoc, speedMPS, expDurationSec) elif (routeType == 'fastest' and dataProviderDictionary[dataProvider] == 'pgrouting'): databaseName = dataProviderArgs['databaseName'] [path, time, dist] = pgrGetShapepointsTimeDist(startLoc, endLoc, databaseName) elif (routeType == 'fastest' and dataProviderDictionary[dataProvider] == 'osrm-online'): [path, time, dist] = osrmGetShapepointsTimeDist(startLoc, endLoc) elif (routeType in ['fastest', 'shortest', 'pedestrian'] and dataProviderDictionary[dataProvider] == 'mapquest'): APIkey = dataProviderArgs['APIkey'] [path, time, dist] = mqGetShapepointsTimeDist(startLoc, endLoc, routeType, APIkey) elif (routeType in ['fastest', 'pedestrian', 'cycling', 'truck'] and dataProviderDictionary[dataProvider] == 'ors-online'): APIkey = dataProviderArgs['APIkey'] [path, time, dist] = orsGetShapepointsTimeDist(startLoc, endLoc, routeType, APIkey) else: return # Check if the original point is too far away from the actual start point of the shapepoints from query distOri = geoDistance2D(startLoc, path[0]) if (distOri >= VRV_DEFAULT_DISTANCE_ERROR_TOLERANCE ): # Go back to 10m after testing print( "Message: The origin point (lat: %s, lon: %s) is %.1f meters away from the road. You might find a gap between the origin point and the route." % (startLoc[0], startLoc[1], distOri)) # Check if the actual end point is too far away from destination point distDes = geoDistance2D(path[-1], endLoc) if (distDes >= VRV_DEFAULT_DISTANCE_ERROR_TOLERANCE ): # Go back to 10m after testing print( "Message: The destination point (lat: %s, lon: %s) is %.1f meters away from the road. You might find a gap between destination point and the route." % (endLoc[0], endLoc[1], distDes)) # convert distance to accumulated distance accDist = [] accDist.append(0) for i in range(1, len(dist)): accDist.append(accDist[i - 1] + dist[i]) # If `expDurationSec` is provided, override `speedMPS` and datasource, otherwise, if `speedMPS` is provided, override datasource if (expDurationSec != None): [newTime, newDist] = distributeTimeDist(path, expDurationSec) time = newTime dist = newDist elif (speedMPS != None and expDurationSec == None): newExpDurationSec = accDist[len(accDist) - 1] / speedMPS [newTime, newDist] = distributeTimeDist(path, newExpDurationSec) time = newTime dist = newDist # convert time to accumulated time accTime = [] accTime.append(startTimeSec) for i in range(1, len(dist)): accTime.append(accTime[i - 1] + time[i]) # For maintainability, convert locs into dictionary dicPath = locs2Dict(path) # shapepoint dataframe assignments = initDataframe('Assignments') # generate assignments for i in range(1, len(path)): assignments = assignments.append( { 'odID': odID, 'objectID': objectID, 'modelFile': modelFile, 'startTimeSec': accTime[i - 1], 'startLat': dicPath[i - 1]['lat'], 'startLon': dicPath[i - 1]['lon'], 'startAltMeters': dicPath[i - 1]['alt'], 'endTimeSec': accTime[i], 'endLat': dicPath[i]['lat'], 'endLon': dicPath[i]['lon'], 'endAltMeters': dicPath[i]['alt'], 'leafletColor': leafletColor, 'leafletWeight': leafletWeight, 'leafletStyle': leafletStyle, 'useArrows': useArrows, 'leafletOpacity': leafletOpacity, 'modelScale': modelScale, 'modelMinPxSize': modelMinPxSize, 'cesiumColor': cesiumColor, 'cesiumWeight': cesiumWeight, 'cesiumStyle': cesiumStyle, 'cesiumOpacity': cesiumOpacity }, ignore_index=True) else: # For maintainability, convert locs into dictionary dicStartLoc = loc2Dict(startLoc) assignments = initDataframe('Assignments') assignments = assignments.append( { 'odID': odID, 'objectID': objectID, 'modelFile': modelFile, 'startTimeSec': startTimeSec, 'startLat': dicStartLoc['lat'], 'startLon': dicStartLoc['lon'], 'startAltMeters': dicStartLoc['alt'], 'endTimeSec': expDurationSec + startTimeSec if (expDurationSec is not None) else startTimeSec, 'endLat': dicStartLoc['lat'], 'endLon': dicStartLoc['lon'], 'endAltMeters': dicStartLoc['alt'], 'leafletColor': leafletColor, 'leafletWeight': leafletWeight, 'leafletStyle': leafletStyle, 'useArrows': useArrows, 'leafletOpacity': leafletOpacity, 'modelScale': modelScale, 'modelMinPxSize': modelMinPxSize, 'cesiumColor': cesiumColor, 'cesiumWeight': cesiumWeight, 'cesiumStyle': cesiumStyle, 'cesiumOpacity': cesiumOpacity }, ignore_index=True) return assignments
def mqGetShapepointsTimeDist(startLoc, endLoc, routeType='fastest', APIkey=None): """ A function to get a list of shapepoints from start coordinate to end coordinate Parameters ---------- startLoc: list, Required Start location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] endLoc: list, Required End location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] routeType: string, Optional, default as 'fastest' Route type of MapQuest query APIkey: string, Required Enables us to access to MapQuest server Returns ------- path: list of lists A list of coordinates in sequence that shape the route from startLoc to endLoc time: float time between current shapepoint and previous shapepoint, the first element should be 0 dist: float distance between current shapepoint and previous shapepoint, the first element should be 0 """ try: routeType = routeType.lower() except: pass dicStartLoc = loc2Dict(startLoc) dicEndLoc = loc2Dict(endLoc) shapepointsUrl = ( 'http://www.mapquestapi.com/directions/v2/route?key=%s&from=%s,%s&to=%s,%s&fullShape=true&routeType=%s' ) % (APIkey, dicStartLoc['lat'], dicStartLoc['lon'], dicEndLoc['lat'], dicEndLoc['lon'], routeType) data = [] try: http = urllib3.PoolManager() response = http.request('GET', shapepointsUrl) data = json.loads(response.data.decode('utf-8')) path = [] totalTimeInSeconds = data['route']['time'] maneuverIndexes = data['route']['shape']['maneuverIndexes'] rawShapepoints = data['route']['shape']['shapePoints'] for i in range(int(len(rawShapepoints) / 2)): if (len(path) > 0): if (rawShapepoints[i * 2] != path[-1][0] and rawShapepoints[i * 2 + 1] != path[-1][1]): path.append( [rawShapepoints[i * 2], rawShapepoints[i * 2 + 1]]) else: path.append([rawShapepoints[0], rawShapepoints[1]]) [timeSecs, distMeters] = distributeTimeDist(path, totalTimeInSeconds) except: print( "Message: Unable to connect MapQuest, the most common causes are 1) that your computer isn't connected to the network; 2) an invalid key is provided." ) return [path, timeSecs, distMeters]
def orsLocalGetShapepointsTimeDist(startLoc, endLoc, travelMode='fastest', port=8081, requestExtras=True): """ A function to get a list of shapepoints from start coordinate to end coordinate. Parameters ---------- startLoc: list Start location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] endLoc: list End location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] travelMode: string, {fastest} Optional, default as 'fastest'. Choose a travel mode as a parameter for ORS Returns ------- path: list of lists A list of coordinates in sequence that shape the route from startLoc to endLoc extras: dictionary of dictionaries Describes extra information, such as waynames, waytypes, elevation, etc. timeInSeconds: list time between current shapepoint and previous shapepoint, the first element should be 0 distInMeters: list distance between current shapepoint and previous shapepoint, the first element should be 0 """ dicStartLoc = loc2Dict(startLoc) dicEndLoc = loc2Dict(endLoc) """ The following "profile" options are available in ORS: 'driving-car' ('fastest') 'driving-hgv' ('truck' - fastest) 'cycling-regular' ('cycling') 'cycling-road' 'cycling-mountain' 'cycling-electric' 'foot-walking' 'foot-hiking' 'wheelchair' """ units = 'm' preference = 'fastest' try: travelMode = travelMode.lower() except: pass if (travelMode == 'fastest'): profile = 'driving-car' elif (travelMode == 'shortest'): profile = 'driving-car' preference = 'shortest' elif (travelMode == 'pedestrian'): profile = 'foot-walking' elif (travelMode == 'cycling'): profile = 'cycling-road' elif (travelMode == 'truck'): profile = 'driving-hgv' # elif (travelMode == 'wheelchair'): # profile = 'wheelchair' else: print("Error: Invalid travelMode.") return spUrl = ('http://localhost:%s/ors/directions?profile=%s' % (port, profile)) spUrl += '&coordinates=%s,%s|%s,%s' % (dicStartLoc['lon'], dicStartLoc['lat'], dicEndLoc['lon'], dicEndLoc['lat']) spUrl += '&geometry_format=geojson' if (requestExtras): spUrl += '&extra_info=steepness|surface|waycategory|waytype|tollways' elevation = "true" else: elevation = "false" spUrl += '&elevation=%s' % (elevation) spUrl += '&radiuses=-1|-1' spUrl += '&units=m' spUrl += '&instructions=true' spUrl += '&preference=%s' % (preference) try: http = urllib3.PoolManager() response = http.request('GET', spUrl) data = json.loads(response.data.decode('utf-8')) http_status = response.status if (http_status == 200): # OK # ORS uses [lon, lat] order: path = [] extras = {} timeInSeconds = [] distInMeters = [] for i in range(len(data['routes'][0]['geometry']['coordinates'])): path.append([ data['routes'][0]['geometry']['coordinates'][i][1], data['routes'][0]['geometry']['coordinates'][i][0] ]) if (requestExtras): extras[i] = {} if (len(data['routes'][0]['geometry']['coordinates'][i]) >= 2): extras[i]['elev'] = data['routes'][0]['geometry'][ 'coordinates'][i][2] else: extras[i]['elev'] = None segs = data['routes'][0]['segments'] for i in range(len(segs)): for j in range(len(segs[i]['steps'])): # Find arrival times for each shapepoint location. # ORS gives times for groups of waypoints...we need more granularity. subpathTimeSec = segs[i]['steps'][j]['duration'] wpStart = segs[i]['steps'][j]['way_points'][0] wpEnd = segs[i]['steps'][j]['way_points'][1] [tmpTimeSec, tmpDistMeters ] = distributeTimeDist(path[wpStart:wpEnd + 1], subpathTimeSec) if (len(timeInSeconds) == 0): timeInSeconds += tmpTimeSec distInMeters += tmpDistMeters else: timeInSeconds += tmpTimeSec[1:] distInMeters += tmpDistMeters[1:] if (requestExtras): if (wpStart == 0): extras[0]['wayname'] = segs[i]['steps'][j]['name'] for k in range(wpStart + 1, wpEnd + 1): extras[k]['wayname'] = segs[i]['steps'][j]['name'] if (requestExtras): ex = data['routes'][0]['extras'] if ('waycategory' in ex): for [wpStart, wpEnd, val] in ex['waycategory']['values']: if (wpStart == 0): extras[0]['waycategory'] = bitFieldDecomp( val, orsWaycategoryDict) for i in range(wpStart + 1, wpEnd + 1): extras[i]['waycategory'] = bitFieldDecomp( val, orsWaycategoryDict) if ('surface' in ex): for [wpStart, wpEnd, val] in ex['surface']['values']: if (wpStart == 0): extras[0]['surface'] = orsSurfaceDict[ val] if val in orsSurfaceDict else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['surface'] = orsSurfaceDict[ val] if val in orsSurfaceDict else None if ('waytypes' in ex): for [wpStart, wpEnd, val] in ex['waytypes']['values']: if (wpStart == 0): extras[0]['waytype'] = orsWaytypeDict[ val] if val in orsWaytypeDict else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['waytype'] = orsWaytypeDict[ val] if val in orsWaytypeDict else None if ('steepness' in ex): for [wpStart, wpEnd, val] in ex['steepness']['values']: if (wpStart == 0): extras[0]['steepness'] = val for i in range(wpStart + 1, wpEnd + 1): extras[i]['steepness'] = val if ('tollways' in ex): for [wpStart, wpEnd, val] in ex['tollways']['values']: if (wpStart == 0): extras[0]['tollway'] = bool( val) if type(val) is bool else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['tollway'] = bool( val) if type(val) is bool else None # Just for fun, let's print some other info we got (but didn't save): # print("ascent: {}".format(data['features'][0]['properties']['ascent'])) # print("descent: {}".format(data['features'][0]['properties']['descent'])) return [path, extras, timeInSeconds, distInMeters] else: # Error of some kind http_status_description = responses[http_status] print("Error Code %s: %s" % (http_status, http_status_description)) return except: print("Error: ", sys.exc_info()[1]) raise
def orsGetShapepointsTimeDist(startLoc, endLoc, travelMode='fastest', APIkey=None, requestExtras=True): """ A function to get a list of shapepoints from start coordinate to end coordinate. Parameters ---------- startLoc: list Start location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] endLoc: list End location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] travelMode: string, {fastest} Optional, default as 'fastest'. Choose a travel mode as a parameter for ORS Returns ------- path: list of lists A list of coordinates in sequence that shape the route from startLoc to endLoc extras: dictionary of dictionaries Describes extra information, such as waynames, waytypes, elevation, etc. timeInSeconds: list time between current shapepoint and previous shapepoint, the first element should be 0 distInMeters: list distance between current shapepoint and previous shapepoint, the first element should be 0 """ dicStartLoc = loc2Dict(startLoc) dicEndLoc = loc2Dict(endLoc) """ The following "profile" options are available in ORS: 'driving-car' ('fastest') 'driving-hgv' ('truck' - fastest) 'cycling-regular' ('cycling') 'cycling-road' 'cycling-mountain' 'cycling-electric' 'foot-walking' 'foot-hiking' 'wheelchair' There is no "shortest" option """ preference = 'fastest' try: travelMode = travelMode.lower() except: pass if (travelMode == 'fastest'): profile = 'driving-car' elif (travelMode == 'shortest'): profile = 'driving-car' preference = 'shortest' elif (travelMode == 'pedestrian'): profile = 'foot-walking' elif (travelMode == 'cycling'): profile = 'cycling-road' elif (travelMode == 'truck'): profile = 'driving-hgv' elif (travelMode == 'wheelchair'): profile = 'wheelchair' else: print("Error: Invalid travelMode.") return shapepointsUrl = ( 'https://api.openrouteservice.org/v2/directions/%s/geojson' % (profile)) headers = { 'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8', 'Authorization': APIkey, 'Content-Type': 'application/json' } try: # ORS uses [lon, lat] order: coordinates = [[dicStartLoc['lon'], dicStartLoc['lat']], [dicEndLoc['lon'], dicEndLoc['lat']]] units = 'm' radiuses = [-1, -1] if (requestExtras): elevation = "true" extra_info = [ "steepness", "surface", "waycategory", "waytype", "tollways" ] else: elevation = "false" extra_info = [] encoded_body = json.dumps({ "coordinates": coordinates, "elevation": elevation, "extra_info": extra_info, "instructions": "true", "preference": preference, "radiuses": radiuses, "units": units }) http = urllib3.PoolManager() response = http.request('POST', shapepointsUrl, headers=headers, body=encoded_body) data = json.loads(response.data.decode('utf-8')) http_status = response.status if (http_status == 200): # OK # ORS uses [lon, lat] order: path = [] extras = {} timeInSeconds = [] distInMeters = [] for i in range(len( data['features'][0]['geometry']['coordinates'])): path.append([ data['features'][0]['geometry']['coordinates'][i][1], data['features'][0]['geometry']['coordinates'][i][0] ]) if (requestExtras): extras[i] = {} if (len(data['features'][0]['geometry']['coordinates'][i]) >= 2): extras[i]['elev'] = data['features'][0]['geometry'][ 'coordinates'][i][2] else: extras[i]['elev'] = None segs = data['features'][0]['properties']['segments'] for i in range(len(segs)): for j in range(len(segs[i]['steps'])): # Find arrival times for each shapepoint location. # ORS gives times for groups of waypoints...we need more granularity. subpathTimeSec = segs[i]['steps'][j]['duration'] wpStart = segs[i]['steps'][j]['way_points'][0] wpEnd = segs[i]['steps'][j]['way_points'][1] [tmpTimeSec, tmpDistMeters ] = distributeTimeDist(path[wpStart:wpEnd + 1], subpathTimeSec) if (len(timeInSeconds) == 0): timeInSeconds += tmpTimeSec distInMeters += tmpDistMeters else: timeInSeconds += tmpTimeSec[1:] distInMeters += tmpDistMeters[1:] if (requestExtras): if (wpStart == 0): extras[0]['wayname'] = segs[i]['steps'][j]['name'] for k in range(wpStart + 1, wpEnd + 1): extras[k]['wayname'] = segs[i]['steps'][j]['name'] if (requestExtras): ex = data['features'][0]['properties']['extras'] if ('waycategory' in ex): for [wpStart, wpEnd, val] in ex['waycategory']['values']: if (wpStart == 0): extras[0]['waycategory'] = bitFieldDecomp( val, orsWaycategoryDict) for i in range(wpStart + 1, wpEnd + 1): extras[i]['waycategory'] = bitFieldDecomp( val, orsWaycategoryDict) if ('surface' in ex): for [wpStart, wpEnd, val] in ex['surface']['values']: if (wpStart == 0): extras[0]['surface'] = orsSurfaceDict[ val] if val in orsSurfaceDict else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['surface'] = orsSurfaceDict[ val] if val in orsSurfaceDict else None if ('waytypes' in ex): for [wpStart, wpEnd, val] in ex['waytypes']['values']: if (wpStart == 0): extras[0]['waytype'] = orsWaytypeDict[ val] if val in orsWaytypeDict else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['waytype'] = orsWaytypeDict[ val] if val in orsWaytypeDict else None if ('steepness' in ex): for [wpStart, wpEnd, val] in ex['steepness']['values']: if (wpStart == 0): extras[0]['steepness'] = val for i in range(wpStart + 1, wpEnd + 1): extras[i]['steepness'] = val if ('tollways' in ex): for [wpStart, wpEnd, val] in ex['tollways']['values']: if (wpStart == 0): extras[0]['tollway'] = bool( val) if type(val) is bool else None for i in range(wpStart + 1, wpEnd + 1): extras[i]['tollway'] = bool( val) if type(val) is bool else None # Just for fun, let's print some other info we got (but didn't save): # print("ascent: {}".format(data['features'][0]['properties']['ascent'])) # print("descent: {}".format(data['features'][0]['properties']['descent'])) return [path, extras, timeInSeconds, distInMeters] else: # Error of some kind http_status_description = responses[http_status] print("Error Code %s: %s" % (http_status, http_status_description)) return except: print("Error: ", sys.exc_info()[1]) raise
def orsGetShapepointsTimeDist(startLoc, endLoc, travelMode='fastest', APIkey=None): """ A function to get a list of shapepoints from start coordinate to end coordinate. Parameters ---------- startLoc: list Start location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] endLoc: list End location. The format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt] travelMode: string, {fastest} Optional, default as 'fastest'. Choose a travel mode as a parameter for ORS Returns ------- path: list of lists A list of coordinates in sequence that shape the route from startLoc to endLoc timeInSeconds: double FIXME???? time between current shapepoint and previous shapepoint, the first element should be 0 FIXME??? distInMeters: double FIXME??? distance between current shapepoint and previous shapepoint, the first element should be 0 FIXME??? """ dicStartLoc = loc2Dict(startLoc) dicEndLoc = loc2Dict(endLoc) """ The following "profile" options are available in ORS: 'driving-car' ('fastest') 'driving-hgv' ('truck' - fastest) 'cycling-regular' ('cycling') 'cycling-road' 'cycling-mountain' 'cycling-electric' 'foot-walking' 'foot-hiking' 'wheelchair' There is no "shortest" option """ try: travelMode = travelMode.lower() except: pass if (travelMode == 'fastest'): profile = 'driving-car' elif (travelMode == 'pedestrian'): profile = 'foot-walking' elif (travelMode == 'cycling'): profile = 'cycling-road' elif (travelMode == 'truck'): profile = 'driving-hgv' else: print("Error: Invalid travelMode.") return # ORS uses [lon, lat] order: shapepointsUrl = ( 'https://api.openrouteservice.org/v2/directions/%s?api_key=%s&start=%s,%s&end=%s,%s' % (profile, APIkey, dicStartLoc['lon'], dicStartLoc['lat'], dicEndLoc['lon'], dicEndLoc['lat'])) try: http = urllib3.PoolManager() response = http.request('GET', shapepointsUrl) data = json.loads(response.data.decode('utf-8')) http_status = response.status if (http_status == 200): # OK # ORS uses [lon, lat] order: path = [] timeInSeconds = [] distInMeters = [] for i in range(len( data['features'][0]['geometry']['coordinates'])): path.append([ data['features'][0]['geometry']['coordinates'][i][1], data['features'][0]['geometry']['coordinates'][i][0] ]) for i in range(len(data['features'][0]['properties']['segments'])): for j in range( len(data['features'][0]['properties']['segments'][i] ['steps'])): # Find arrival times for each shapepoint location. # ORS gives times for groups of waypoints...we need more granularity. subpathTimeSec = data['features'][0]['properties'][ 'segments'][i]['steps'][j]['duration'] wpStart = data['features'][0]['properties']['segments'][i][ 'steps'][j]['way_points'][0] wpEnd = data['features'][0]['properties']['segments'][i][ 'steps'][j]['way_points'][1] [tmpTimeSec, tmpDistMeters ] = distributeTimeDist(path[wpStart:wpEnd + 1], subpathTimeSec) if (len(timeInSeconds) == 0): timeInSeconds += tmpTimeSec distInMeters += tmpDistMeters else: timeInSeconds += tmpTimeSec[1:] distInMeters += tmpDistMeters[1:] return [path, timeInSeconds, distInMeters] else: # Error of some kind http_status_description = responses[http_status] print("Error Code %s: %s" % (http_status, http_status_description)) return except: print("Error: ", sys.exc_info()[1]) raise