Ejemplo n.º 1
0
def osrmGetTimeDistOnePair(startLoc, endLoc):
	"""
	A function to get a total time and total distance between two given coordinates

	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
	-------
	timeSeconds: double
		time between current shapepoint and previous shapepoint, the first element should be 0
	distMeters: double
		distance between current shapepoint and previous shapepoint, the first element should be 0
	"""

	dicStartLoc = loc2Dict(startLoc)
	dicEndLoc = loc2Dict(endLoc)
	timeDistUrl = ('http://router.project-osrm.org/route/v1/driving/%s,%s;%s,%s') % (dicStartLoc['lon'], dicStartLoc['lat'], dicEndLoc['lon'], dicEndLoc['lat']) # OSRM use lon/lat
	data = []

	try:
		http = urllib3.PoolManager()
		response = http.request('GET', timeDistUrl)
		data = json.loads(response.data.decode('utf-8'))

		timeSeconds = data['routes'][0]['duration']
		distMeters = data['routes'][0]['distance']
	except:
		print ("Message: OSRM is currently not available, please try again later.")

	return [timeSeconds, distMeters]
Ejemplo n.º 2
0
def osrmGetSnapToRoadLatLon(loc):
	"""
	A function to get snapped latlng for one coordinate using OSRM

	Parameters
	----------
	loc: list
		The location to be snapped to road

	Returns
	-------
	list
		A snapped locations in the format of [lat, lon], notice that this function will lost the info of altitude of the location.
	"""

	dicLoc = loc2Dict(loc)
	snapToRoadUrl = ('http://router.project-osrm.org/nearest/v1/driving/%s,%s') % (dicLoc['lon'], dicLoc['lat']) # OSRM use lon/lat
	data = []

	try:
		http = urllib3.PoolManager()
		response = http.request('GET', snapToRoadUrl)
		data = json.loads(response.data.decode('utf-8'))

		snapLoc = [data['waypoints'][0]['location'][1], data['waypoints'][0]['location'][0]] # OSRM use lon/lat
	except:
		print ("Message: OSRM is currently not available, please try again later.")

	return snapLoc
Ejemplo n.º 3
0
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]
Ejemplo n.º 4
0
def privAddStaticAssignment(initAssignments=None,
                            odID=1,
                            objectID=None,
                            modelFile=None,
                            modelScale=VRV_DEFAULT_CESIUMMODELSCALE,
                            modelMinPxSize=VRV_DEFAULT_CESIUMMODELMINPXSIZE,
                            loc=None,
                            startTimeSec=None,
                            endTimeSec=None):

    # Replace backslash
    modelFile = replaceBackslashToSlash(modelFile)

    # assignment dataframe
    assignments = initDataframe('Assignments')

    dicLoc = loc2Dict(loc)

    assignments = assignments.append(
        {
            'odID': odID,
            'objectID': objectID,
            'modelFile': modelFile,
            'modelScale': modelScale,
            'modelMinPxSize': modelMinPxSize,
            'startTimeSec': startTimeSec,
            'startLat': dicLoc['lat'],
            'startLon': dicLoc['lon'],
            'startAltMeters': dicLoc['alt'],
            'endTimeSec': endTimeSec,
            'endLat': dicLoc['lat'],
            'endLon': dicLoc['lon'],
            'endAltMeters': dicLoc['alt'],
            'leafletColor': None,
            'leafletWeight': None,
            'leafletStyle': None,
            'leafletOpacity': None,
            'cesiumColor': None,
            'cesiumWeight': None,
            'cesiumStyle': None,
            'cesiumOpacity': None,
            'useArrows': None
        },
        ignore_index=True,
        sort=False)

    if (type(initAssignments) is pd.core.frame.DataFrame):
        assignments = pd.concat([initAssignments, assignments],
                                ignore_index=True)

    return assignments
Ejemplo n.º 5
0
def orsLocalGetSnapToRoadLatLon(loc, port):
    """
	A function to get snapped latlng for one coordinate using ORS
	Parameters
	----------
	loc: list
		The location to be snapped to road
	Returns
	-------
	list
		A snapped location in the format of [lat, lon].  Note that this function will lose the info of altitude of the location.
	"""

    # There is no function in ORS that snaps to a road.
    # Instead, issue a driving request from a location to itself.
    dicLoc = loc2Dict(loc)

    # ORS uses [lon, lat] order:
    snapToRoadUrl = (
        'http://localhost:%s/ors/directions?profile=driving-car&geometry_format=geojson&coordinates=%s,%s|%s,%s&elevation=false'
        % (port, dicLoc['lon'], dicLoc['lat'], dicLoc['lon'], dicLoc['lat']))

    try:
        http = urllib3.PoolManager()
        response = http.request('GET', snapToRoadUrl)
        data = json.loads(response.data.decode('utf-8'))

        http_status = response.status

        if (http_status == 200):
            # OK
            # ORS uses [lon, lat] order:
            snapLoc = [
                data['routes'][0]['geometry']['coordinates'][0][1],
                data['routes'][0]['geometry']['coordinates'][0][0]
            ]

            return snapLoc
        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
Ejemplo n.º 6
0
def pgrGetSnapToRoadLatLon(gid, loc, databaseName):
    """
	A function to get snapped latlng for one coordinate using pgRouting

	Parameters
	----------
	gid: int
		The gid of the street in pgRouting database
	loc: list
		The location to be snapped to road
	databaseName: string, Require
		If you are hosting a data provider on your local machine (e.g., pgRouting), you'll need to specify the name of the local database.

	Returns
	-------
	list
		A snapped locations in the format of [lat, lon], notice that this function will lost the info of altitude of the location.
	"""

    conn = psycopg2.connect(
        "dbname='%s' user='******' host='%s' password='******'" %
        (databaseName, config['VRV_SETTING_PGROUTING_USERNAME'],
         config['VRV_SETTING_PGROUTING_HOST'],
         config['VRV_SETTING_PGROUTING_PASSWORD']))
    cur = conn.cursor()

    # For maintainability
    dicLoc = loc2Dict(loc)

    sqlCommand = " select ST_X(point), ST_Y(point)"
    sqlCommand += " from ("
    sqlCommand += " 	select ST_ClosestPoint("
    sqlCommand += " 		ST_GeomFromEWKT(CONCAT('SRID=4326; LINESTRING(',x1,' ',y1,', ',x2,' ',y2,')')),"
    sqlCommand += " 		ST_GeomFromEWKT('SRID=4326;POINT(%s %s)')) as point" % (
        dicLoc['lon'], dicLoc['lat'])  # Be very careful about lon and lat
    sqlCommand += " 	from ways"
    sqlCommand += " 	where gid=%s" % (gid)
    sqlCommand += " ) a;"
    cur.execute(sqlCommand)
    row = cur.fetchone()
    snapLoc = [row[1], row[0]]

    conn.close()

    return snapLoc
Ejemplo n.º 7
0
def mqGetSnapToRoadLatLon(loc, APIkey):
    """
	A function to get snapped latlng for one coordinate using MapQuest

	Parameters
	----------
	loc: list
		The location to be snapped to road
	APIkey: string, Required
		Enables us to access to MapQuest server

	Returns
	-------
	list
		A snapped locations in the format of [lat, lon], notice that this function will lost the info of altitude of the location.
	"""

    dicLoc = loc2Dict(loc)

    snapToRoadUrl = (
        'http://www.mapquestapi.com/geocoding/v1/batch?key=%s&thumbMaps=false&outFormat=json&location=%s,%s'
    ) % (APIkey, dicLoc['lat'], dicLoc['lon'])
    data = []
    try:
        http = urllib3.PoolManager()
        response = http.request('GET', snapToRoadUrl)
        data = json.loads(response.data.decode('utf-8'))

        snapLoc = [
            data['results'][0]['locations'][0]['latLng']['lat'],
            data['results'][0]['locations'][0]['latLng']['lng']
        ]
    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 snapLoc
Ejemplo n.º 8
0
def pgrGetNearestStreet(loc, databaseName):
	"""
	A function to return the details of the nearest street given a known coordinate

	Parameters
	----------
	loc: list
		The locationi that trying to find the nearest street of
	databaseName: string, Require
		If you are hosting a data provider on your local machine (e.g., pgRouting), you'll need to specify the name of the local database.

	Returns
	-------
	gid: int
		gid from Ways table, identifier for street
	sourceVid: int
		sourceVid from Ways table, identifier for source vertice
	targetVid: int
		targetVid from Ways table, identifier for target vertice
	sourceLat: int
		sourceLat from Ways table, latitude for source vertice
	sourceLon: int
		sourceLon from Ways table, longitude for source vertice
	targetLat: int
		targetLat from Ways table, latitude for target vertice
	targetLon: int
		targetLon from Ways table, longitude for target vertice
	cost_s: int
		cost_s from Ways table, time needs from source to target
	reverse_cost_s: int
		reverse_cost_s from Ways table, time needs from target to source
	one_way: int
		one_way from Ways table, indicate if it is one way street
	"""
	conn = psycopg2.connect("dbname='%s' user='******' host='%s' password='******'" % (
		databaseName, 
		VRV_SETTING_PGROUTING_USERNAME, 
		VRV_SETTING_PGROUTING_HOST, 
		VRV_SETTING_PGROUTING_PASSWORD))
	cur = conn.cursor()

	# For maintainability
	dicLoc = loc2Dict(loc)

	try:
		sqlCommand  = " select gid, source, target, y1, x1, y2, x2, cost_s, reverse_cost_s, one_way"
		sqlCommand += " from "
		sqlCommand += " 	ways"
		sqlCommand += "	where"
		sqlCommand += "		x1 >= %s - 0.01 and x1 <= %s + 0.01" % (dicLoc['lon'], dicLoc['lon']) # Eliminate most of the ways there
		sqlCommand += " order by"
		sqlCommand += " 	ST_Distance("
		sqlCommand += "			ST_GeogFromText('SRID=4326; POINT(%s %s)')," % (dicLoc['lon'], dicLoc['lat'])  # Be very careful about lon and lat
		sqlCommand += "			ST_GeogFromText(CONCAT('SRID=4326; LINESTRING(',x1,' ',y1,', ',x2,' ',y2,')')))"
		sqlCommand += "	limit 1;"
		cur.execute(sqlCommand)
		row = cur.fetchone()
		street = {
			"gid" : int(row[0]),
			"source" : int(row[1]),
			"target" : int(row[2]),
			"sourceLoc" : [row[3], row[4]],
			"targetLoc" : [row[5], row[6]],
			"cost_s" : row[7],
			"reverse_cost_s" : row[8],
			"one_way" : row[9]
		}

	except:
		sqlCommand  = " select gid, source, target, y1, x1, y2, x2, length_m, cost_s, reverse_cost_s, one_way"
		sqlCommand += " from "
		sqlCommand += " 	ways"
		sqlCommand += " order by"
		sqlCommand += " 	ST_Distance("
		sqlCommand += "			ST_GeogFromText('SRID=4326; POINT(%s %s)')," % (dicLoc['lon'], dicLoc['lat'])  # Be very careful about lon and lat
		sqlCommand += "			ST_GeogFromText(CONCAT('SRID=4326; LINESTRING(',x1,' ',y1,', ',x2,' ',y2,')')))"
		sqlCommand += "	limit 1;"
		cur.execute(sqlCommand)
		row = cur.fetchone()
		street = {
			"gid" : int(row[0]),
			"source" : int(row[1]),
			"target" : int(row[2]),
			"sourceLoc" : [row[3], row[4]],
			"targetLoc" : [row[5], row[6]],
			"cost_s" : row[7],
			"reverse_cost_s" : row[8],
			"one_way" : row[9]
		}

	conn.close()

	return street
Ejemplo n.º 9
0
def pgrGetTimeDist(fromLocs, toLocs, databaseName):
	"""
	This function generated time and distance matrix using pgRouting

	Parameters
	----------
	fromLoc: list, Conditional
		Used in 'one2many' mode. To state the coordinate of the starting node
	locs: list of lists
		Used in 'all2all', 'one2many', 'many2one' modes. A list of coordinates, in the format of [[lat1, lon1], [lat2, lon2], ...]
	toLoc: list, Conditional
		Used in 'many2one' mode. To state the coordinate of the ending node
	databaseName: string	
		If you are hosting a data provider on your local machine (e.g., pgRouting), you'll need to specify the name of the local database. 

	Returns
	-------
	timeSecs: dictionary
		The key of each item in this dictionary is in (coordID1, coordID2) format, the travelling time from first entry to second entry, the units are seconds
	distMeters: dictionary
		The key of each item in this dictionary is in (coordID1, coordID2) format, the travelling distance from first entry to second entry, the units are meters
	"""

	conn = psycopg2.connect("dbname='%s' user='******' host='%s' password='******'" % (
		databaseName, 
		VRV_SETTING_PGROUTING_USERNAME, 
		VRV_SETTING_PGROUTING_HOST, 
		VRV_SETTING_PGROUTING_PASSWORD))
	conn.autocommit = True
	cur = conn.cursor()

	dummyClassID = 821 # Hard-coded number, no specific meaning
	# FIXME! For database security reason, we need to testify if class_id = 821 is not used in the original database	

	sqlCommand  = " select max(id) from ways_vertices_pgr;"
	cur.execute(sqlCommand)
	row = cur.fetchone()
	newlyInsertVidNum = int(row[0]) + 1

	locs = fromLocs.copy()
	for i in range(len(toLocs)):
		try:
			locs.index(toLocs[i])
		except ValueError:
			locs.append(toLocs[i])

	startVidList = []
	endVidList = []
	for i in range(len(fromLocs)):
		startVidList.append(newlyInsertVidNum + locs.index(fromLocs[i]))
	for i in range(len(toLocs)):
		endVidList.append(newlyInsertVidNum + locs.index(toLocs[i]))

	for i in range(len(locs)):
		# Add dummy vertices
		street = pgrGetNearestStreet(locs[i], databaseName)
		snapLoc = pgrGetSnapToRoadLatLon(street['gid'], locs[i], databaseName)
		dicSnapLoc = loc2Dict(snapLoc)
		sqlCommand	= "	insert into ways_vertices_pgr (id, lon, lat) values (%s, %s, %s);" % (
			newlyInsertVidNum + locs.index(locs[i]),
			dicSnapLoc['lon'],
			dicSnapLoc['lat'])
		cur.execute(sqlCommand)

		# Add four two road segments
		distSource2Snapped = geoDistance2D(street['sourceLoc'], snapLoc)
		distSnapped2Target = geoDistance2D(snapLoc, street['targetLoc'])
		ratio = distSource2Snapped / (distSource2Snapped + distSnapped2Target)
		dicSourceLoc = loc2Dict(street['sourceLoc'])
		dicTargetLoc = loc2Dict(street['targetLoc'])
		sqlCommand  = "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
			dummyClassID, 
			street['source'],
			newlyInsertVidNum + locs.index(locs[i]),
			distSource2Snapped,
			dicSourceLoc['lon'],
			dicSourceLoc['lat'],
			dicSnapLoc['lon'],
			dicSnapLoc['lat'],
			street['cost_s'] * ratio,
			street['reverse_cost_s'] * ratio)
		cur.execute(sqlCommand)
		sqlCommand  = "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
			dummyClassID, 
			newlyInsertVidNum + locs.index(locs[i]),
			street['target'],
			distSnapped2Target,
			dicSnapLoc['lon'],
			dicSnapLoc['lat'],
			dicTargetLoc['lon'],
			dicTargetLoc['lat'],
			street['cost_s'] * (1 - ratio),
			street['reverse_cost_s'] * (1 - ratio))
		cur.execute(sqlCommand)

	sqlCommand  = "	select " 
	sqlCommand += "		start_vid as start_node, "
	sqlCommand += "		end_vid as end_node, "
	sqlCommand += "		sum(cost) as time, "
	sqlCommand += "		sum(length_m) as distance "
	sqlCommand += "	from ("
	sqlCommand += "		select "
	sqlCommand += "			a.*, "
	sqlCommand += "			b.length_m"
	sqlCommand += "		from pgr_dijkstra("
	sqlCommand += "			'select gid as id, source, target, cost_s as cost, reverse_cost_s as reverse_cost from ways', "
	sqlCommand += "			ARRAY%s, " % (startVidList)
	sqlCommand += "			ARRAY%s, " % (endVidList)
	sqlCommand += "			directed := true) a "
	sqlCommand += "		left join "
	sqlCommand += "			ways b "
	sqlCommand += "		on "
	sqlCommand += "			a.edge = b.gid "
	sqlCommand += "		order by "
	sqlCommand += "			a.path_seq"
	sqlCommand += "		) x "
	sqlCommand += "	group by "
	sqlCommand += "		start_vid, "
	sqlCommand += "		end_vid;"
	cur.execute(sqlCommand)
	row = cur.fetchall()

	for i in range(len(startVidList)):
		sqlCommand  = "	delete from ways_vertices_pgr where id = %s;" % (startVidList[i])
		cur.execute(sqlCommand)
	for i in range(len(endVidList)):
		sqlCommand  = "	delete from ways_vertices_pgr where id = %s;" % (endVidList[i])
		cur.execute(sqlCommand)
	sqlCommand  = "	delete from ways where class_id = %s;" % (dummyClassID)
	cur.execute(sqlCommand)

	conn.close()

	rawDist = {}
	rawTime = {}
	for i in range(len(row)):
		rawTime[row[i][0], row[i][1]] = row[i][2]
		rawDist[row[i][0], row[i][1]] = row[i][3]
	distMeters = {}
	timeSecs = {}

	for i in range(len(fromLocs)):
		for j in range(len(toLocs)):
			try:
				distMeters[i, j] = rawDist[startVidList[i], endVidList[j]]
			except:
				distMeters[i, j] = 0
			try:
				timeSecs[i, j] = rawTime[startVidList[i], endVidList[j]]
			except:
				timeSecs[i, j] = 0

	return [timeSecs, distMeters]
Ejemplo n.º 10
0
def pgrGetShapepointsTimeDist(startLoc, endLoc, databaseName):
	"""
	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]
	endLat: float
		Required, latitude of end coordinate
	endLon: float
		Required, longitude of end coordinate
	databaseName: string, Require
		If you are hosting a data provider on your local machine (e.g., pgRouting), you'll need to specify the name of the local database.

	Returns
	-------
	path: list of lists
		A list of coordinates in sequence that shape the route from startLoc to endLoc
	timeSecs: list
		time between current shapepoint and previous shapepoint, the first element should be 0
	distMeters: list
		distance between current shapepoint and previous shapepoint, the first element should be 0
	"""

	conn = psycopg2.connect("dbname='%s' user='******' host='%s' password='******'" % (
		databaseName, 
		VRV_SETTING_PGROUTING_USERNAME, 
		VRV_SETTING_PGROUTING_HOST, 
		VRV_SETTING_PGROUTING_PASSWORD))
	conn.autocommit = True
	cur = conn.cursor()

	# Calculate the distance between snapped location and source/target of closest street for the START coordinate
	startStreet = pgrGetNearestStreet(startLoc, databaseName)
	snapStartLoc = pgrGetSnapToRoadLatLon(startStreet['gid'], startLoc, databaseName)
	dicSnapStartLoc = loc2Dict(snapStartLoc)
	distSnapStart2Source = geoDistance2D(snapStartLoc, startStreet['sourceLoc'])
	distSnapStart2Target = geoDistance2D(snapStartLoc, startStreet['targetLoc'])

	# Calculate the distance between snapped location and source/target of closest street for the END coordinate
	endStreet = pgrGetNearestStreet(endLoc, databaseName)
	snapEndLoc = pgrGetSnapToRoadLatLon(endStreet['gid'], endLoc, databaseName)
	dicSnapEndLoc = loc2Dict(snapEndLoc)
	distSnapEnd2Source = geoDistance2D(snapEndLoc, endStreet['sourceLoc'])
	distSnapEnd2Target = geoDistance2D(snapEndLoc, endStreet['targetLoc'])

	# Find the number of vertices in the pgRouting database
	sqlCommand  = "	select count(*) from ways_vertices_pgr;"
	cur.execute(sqlCommand)
	row = cur.fetchone()
	newlyInsertVidNum = int(row[0]) + 1

	# Testify and find a dummyClassID to put temp vertices and segments
	dummyClassID = 821 # Hard-coded number, no specific meaning
	# FIXME! For database security reason, we need to testify if class_id = 821 is not used in the original database

	# insert the snapped location for START coordinate, and two segments from the coordinate to source/target of the closest street
	sqlCommand  = "	insert into ways_vertices_pgr (id, lon, lat) values (%s, %s, %s);" % (
		newlyInsertVidNum, 
		dicSnapStartLoc['lon'], 
		dicSnapStartLoc['lat'])
	sqlCommand += "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
		dummyClassID, 
		newlyInsertVidNum, 
		startStreet['target'], 
		distSnapStart2Target, 
		dicSnapStartLoc['lon'],
		dicSnapStartLoc['lat'],
		startStreet['targetLoc'][1], 
		startStreet['targetLoc'][0], 
		startStreet['cost_s'] * distSnapStart2Target / (distSnapStart2Target + distSnapStart2Source), 
		startStreet['reverse_cost_s'] * distSnapStart2Target / (distSnapStart2Target + distSnapStart2Source))
	sqlCommand += "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
		dummyClassID, 
		startStreet['source'], 
		newlyInsertVidNum, 
		distSnapStart2Source, 
		startStreet['sourceLoc'][1], 
		startStreet['sourceLoc'][0], 
		dicSnapStartLoc['lon'],
		dicSnapStartLoc['lat'],
		startStreet['cost_s'] * distSnapStart2Source / (distSnapStart2Target + distSnapStart2Source), 
		startStreet['reverse_cost_s'] * distSnapStart2Source / (distSnapStart2Target + distSnapStart2Source))

	# insert the snapped location for END coordinate, and two segments from the coordinate to source/target of the closest street
	sqlCommand += "	insert into ways_vertices_pgr (id, lon, lat) values (%s, %s, %s);" % (
		newlyInsertVidNum + 1, 
		dicSnapEndLoc['lon'], 
		dicSnapEndLoc['lat'])
	sqlCommand += "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
		dummyClassID, 
		newlyInsertVidNum + 1, 
		endStreet['target'], 
		distSnapEnd2Target, 
		dicSnapEndLoc['lon'],
		dicSnapEndLoc['lat'],
		endStreet['targetLoc'][1], 
		endStreet['targetLoc'][0], 
		endStreet['cost_s'] * distSnapEnd2Target / (distSnapEnd2Target + distSnapEnd2Source), 
		endStreet['reverse_cost_s'] * distSnapEnd2Target / (distSnapEnd2Target + distSnapEnd2Source))
	sqlCommand += "	insert into ways (class_id, source, target, length_m, x1, y1, x2, y2, cost_s, reverse_cost_s) values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s);" % (
		dummyClassID, 
		endStreet['source'], 
		newlyInsertVidNum + 1, 
		distSnapEnd2Source, 
		endStreet['sourceLoc'][1], 
		endStreet['sourceLoc'][0], 
		dicSnapEndLoc['lon'],
		dicSnapEndLoc['lat'],
		endStreet['cost_s'] * distSnapEnd2Source / (distSnapEnd2Target + distSnapEnd2Source), 
		endStreet['reverse_cost_s'] * distSnapEnd2Source / (distSnapEnd2Target + distSnapEnd2Source))

	# Do dijstra algorithm to find shortest path
	sqlCommand += " select b.gid as gid, b.y1 as lats1, b.x1 as lons1, b.y2 as lats2, b.x2 as lons2, a.cost as secs, b.length_m as dist "
	sqlCommand += "	from "
	sqlCommand += "		pgr_dijkstra("
	sqlCommand += "			'select gid as id, source, target, cost_s as cost, reverse_cost_s as reverse_cost from ways',"
	sqlCommand += "			%s," % (newlyInsertVidNum)
	sqlCommand += "			%s," % (newlyInsertVidNum + 1)
	sqlCommand += "			directed := true"
	sqlCommand += "		) a"
	sqlCommand += "	left join"
	sqlCommand += "		ways b"
	sqlCommand += "	on a.edge = b.gid"
	sqlCommand += "	order by a.path_seq"

	# Return the shapepoint result from dijstra algorithm
	cur.execute(sqlCommand)
	row = cur.fetchall()
	summary = pd.DataFrame(row, columns=['gid', 'lats1', 'lons1', 'lats2', 'lons2', 'secs', 'dist'])
	
	# Delete the temp data
	sqlCommand  = "	delete from ways_vertices_pgr where id = (%s);" % (newlyInsertVidNum)
	sqlCommand += "	delete from ways_vertices_pgr where id = (%s);" % (newlyInsertVidNum + 1)
	sqlCommand += "	delete from ways where class_id = %s;" % (dummyClassID)
	cur.execute(sqlCommand)

	# The last row is junk info, drop it
	summary.drop(summary.index[len(summary) - 1], inplace = True)

	# Sorting the coordinates so that they can be linked to each other
	lats1 = summary['lats1'].tolist()
	lons1 = summary['lons1'].tolist()
	lats2 = summary['lats2'].tolist()
	lons2 = summary['lons2'].tolist()
	path = []
	path.append(startLoc)
	for i in range(1, len(lats1)):
		if (lats1[i] != lats1[i - 1] and lats1[i] != lats2[i - 1]):
			path.append([lats1[i], lons1[i]])
		else:
			path.append([lats2[i], lons2[i]])
	timeSecs = summary['secs'].tolist()
	distMeters = summary['dist'].tolist()

	conn.close()

	return [path, timeSecs, distMeters]
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
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]
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
def privAddStaticAssignment(
        initAssignments=None,
        odID=1,
        objectID=None,
        modelFile=None,
        modelScale=config['VRV_DEFAULT_CESIUMMODELSCALE'],
        modelMinPxSize=config['VRV_DEFAULT_CESIUMMODELMINPXSIZE'],
        loc=None,
        startTimeSec=None,
        endTimeSec=None,
        ganttColor=config['VRV_DEFAULT_GANTTCOLOR'],
        popupText=None):

    # Replace backslash
    modelFile = replaceBackslashToSlash(modelFile)

    # Ensure leading slash
    modelFile = addHeadSlash(modelFile)

    # assignment dataframe
    assignments = privInitDataframe('Assignments')

    dicLoc = loc2Dict(loc)

    assignments = assignments.append(
        {
            'odID': odID,
            'objectID': objectID,
            'modelFile': modelFile,
            'modelScale': modelScale,
            'modelMinPxSize': modelMinPxSize,
            'startTimeSec': startTimeSec,
            'startLat': dicLoc['lat'],
            'startLon': dicLoc['lon'],
            'startAltMeters': dicLoc['alt'],
            'endTimeSec': endTimeSec,
            'endLat': dicLoc['lat'],
            'endLon': dicLoc['lon'],
            'endAltMeters': dicLoc['alt'],
            'ganttColor': ganttColor,
            'popupText': popupText,
            'leafletColor': None,
            'leafletWeight': None,
            'leafletStyle': None,
            'leafletOpacity': None,
            'leafletCurveType': None,
            'leafletCurvature': None,
            'cesiumColor': None,
            'cesiumWeight': None,
            'cesiumStyle': None,
            'cesiumOpacity': None,
            'useArrows': None,
            'startElevMeters': None,
            'endElevMeters': None,
            'wayname': None,
            'waycategory': None,
            'surface': None,
            'waytype': None,
            'steepness': None,
            'tollway': None
        },
        ignore_index=True,
        sort=False)

    if (type(initAssignments) is pd.core.frame.DataFrame):
        assignments = pd.concat([initAssignments, assignments],
                                ignore_index=True)

    return assignments
Ejemplo n.º 16
0
def _buildFlightProfile(startLoc, cruiseAltMetersAGL, endLoc, takeoffSpeedMPS,
                        rateOfClimbMPS, cruiseSpeedMPS, landSpeedMPS,
                        rateOfDescentMPS):
    """
	Build a flight profile, by profile, it means it has take_off/cruise/loiter(mission)/landing phase, if we want to construct a customized profile, use _buildFlightPath

	Parameters
	----------
	startLoc: list
		Start location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt].
	cruiseAltMetersAGL: float
		Cruise altitude, meters above sea level.
	endLoc: list
		End location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt].
	rateOfClimbMPS: float
		Rate of climb of the aircraft, it is a vertical speed.
	climbGradientInDegree: float
		Climb gradient, the unit is degree, horizontal as zero, minimal value as 0, maximum value as 90 (vertical up).
	cruiseSpeedMPS: float
		Speed of cruise, in the unit of meters/second.
	rateOfDescentMPS: float
		Rate of descent, vertical speed.
	descentGradientInDegree: float
		Descent gradient, the unit is degree, horizontal as zero, minimal value as 0, maximum value as 90 (vertical down).
	
	Return
	------
	flight dataframe
		A dataframe to be interpreted into assignments dataframe
	"""

    # Interpret locations into readable dictionary
    dicStartLoc = loc2Dict(startLoc)
    dicEndLoc = loc2Dict(endLoc)

    # Calculate gradients of climbing and landing
    climbGradientInDegree = math.degrees(
        math.asin(rateOfClimbMPS / takeoffSpeedMPS))
    descentGradientInDegree = math.degrees(
        math.asin(rateOfDescentMPS / landSpeedMPS))

    # calculate the ideal takeoff/landing time/ground distance
    idealTakeoffTimeSec = (cruiseAltMetersAGL -
                           dicStartLoc['alt']) / rateOfClimbMPS
    idealTakeoffGroundDistance = (cruiseAltMetersAGL -
                                  dicStartLoc['alt']) / math.tan(
                                      math.radians(climbGradientInDegree))
    idealLandingTimeSec = (cruiseAltMetersAGL -
                           dicEndLoc['alt']) / rateOfDescentMPS
    idealLandingGroundDistance = (cruiseAltMetersAGL -
                                  dicEndLoc['alt']) / math.tan(
                                      math.radians(descentGradientInDegree))

    # including start and end, takeoffAt and arrivalAt are not included in here
    markPath = [startLoc, endLoc]

    # Total ground distance
    totalGroundDistance = geoDistancePath2D(markPath)

    # Flight Profile dataframe
    flight = pd.DataFrame(columns=[
        'lat', 'lon', 'altAGL', 'accuGroundDistance', 'description',
        'loiterTime'
    ])

    # For the first location, add one row
    flight = flight.append(
        {
            'lat': dicStartLoc['lat'],
            'lon': dicStartLoc['lon'],
            'altAGL': dicStartLoc['alt'],
            'accuGroundDistance': 0.0,
            'description': "beforeTakeoff",
            'loiterTime': 0.0
        },
        ignore_index=True)

    # Check if distance is enough for taking off and landing
    if (totalGroundDistance >
            idealTakeoffGroundDistance + idealLandingGroundDistance):
        # if can reach cruise altitude, everything is ideal
        takeoffMileage = geoMileageInPath2D(markPath,
                                            idealTakeoffGroundDistance)
        landingMileage = geoMileageInPath2D(
            markPath, totalGroundDistance - idealLandingGroundDistance)

        # if can cruise, it means we need two locations
        flight = flight.append(
            {
                'lat': takeoffMileage['loc'][0],
                'lon': takeoffMileage['loc'][1],
                'altAGL': cruiseAltMetersAGL,
                'accuGroundDistance': idealTakeoffGroundDistance,
                'description': "takeoffAtAlt",
                'loiterTime': 0.0
            },
            ignore_index=True)
        flight = flight.append(
            {
                'lat': landingMileage['loc'][0],
                'lon': landingMileage['loc'][1],
                'altAGL': cruiseAltMetersAGL,
                'accuGroundDistance':
                totalGroundDistance - idealLandingGroundDistance,
                'description': "arrivalAtAlt",
                'loiterTime': 0.0
            },
            ignore_index=True)
    else:
        # if can not reach cruise altitude, the profile is "triangle", i.e. the takeoffAt position are the same as arrivalAt position
        deltaAGLTakeoffLanding = dicStartLoc['alt'] - dicEndLoc['alt']
        deltaAGLCruiseTakeoff = (
            (totalGroundDistance - deltaAGLTakeoffLanding /
             math.tan(math.radians(descentGradientInDegree))) *
            (math.tan(math.radians(climbGradientInDegree)) +
             math.tan(math.radians(descentGradientInDegree))))
        deltaAGLCruiseLanding = deltaAGLCruiseTakeoff + deltaAGLTakeoffLanding
        takeoffGroundDistance = deltaAGLCruiseTakeoff / math.tan(
            math.radians(climbGradientInDegree))
        landingGroundDistance = deltaAGLCruiseLanding / math.tan(
            math.radians(descentGradientInDegree))

        takeoffMileage = geoMileageInPath2D(markPath, takeoffGroundDistance)

        flight = flight.append(
            {
                'lat': takeoffMileage['loc'][0],
                'lon': takeoffMileage['loc'][1],
                'altAGL': deltaAGLCruiseTakeoff + dicStartLoc['alt'],
                'accuGroundDistance': takeoffGroundDistance,
                'description': "takeoffAtAlt and arrivalAtAlt",
                'loiterTime': 0.0
            },
            ignore_index=True)

    # For the last location, add one row
    flight = flight.append(
        {
            'lat': dicEndLoc['lat'],
            'lon': dicEndLoc['lon'],
            'altAGL': dicEndLoc['alt'],
            'accuGroundDistance': totalGroundDistance,
            'description': "afterArrival",
            'loiterTime': 0.0
        },
        ignore_index=True)

    # Reorder flight in order
    flight = flight.sort_values('accuGroundDistance', ascending=True)
    flight = flight.reset_index(drop=True)

    # Add the 'groundDistance' column to flight dataframe
    groundDistance = [0.0]
    for i in range(1, len(flight)):
        groundDistance.append(
            geoDistance2D(
                (flight.iloc[i]['lat'], flight.iloc[i]['lon']),
                (flight.iloc[i - 1]['lat'], flight.iloc[i - 1]['lon'])))
    flight['groundDistance'] = groundDistance

    # Add the 'flightDistance' column to flight dataframe
    flightDistance = [0.0]
    for i in range(1, len(flight)):
        deltaHeight = flight.iloc[i]['altAGL'] - flight.iloc[i - 1]['altAGL']
        groundDistance = flight.iloc[i]['groundDistance']
        flightDistance.append(
            math.sqrt(deltaHeight * deltaHeight +
                      groundDistance * groundDistance))
    flight['flightDistance'] = flightDistance

    # Add the 'accuFlightDistance' column to flight dataframe
    accuFlightDistance = [0.0]
    for i in range(1, len(flight)):
        accuFlightDistance.append(accuFlightDistance[i - 1] +
                                  flight.iloc[i]['flightDistance'])
    flight['accuFlightDistance'] = accuFlightDistance

    # Add the 'time' column to flight dataframe
    duration = [0.0]
    for i in range(1, len(flight)):
        if (flight.iloc[i]['description'] == "takeoffAtAlt"
                or flight.iloc[i]['description']
                == "takeoffAtAlt and arrivalAtAlt"):
            speed = takeoffSpeedMPS
            duration.append(flight.iloc[i]['flightDistance'] / speed)
        elif (flight.iloc[i]['description'] == "arrivalAtAlt"):
            speed = cruiseSpeedMPS
            duration.append(flight.iloc[i]['flightDistance'] / speed)
        elif (flight.iloc[i]['description'] == "afterArrival"):
            speed = landSpeedMPS
            duration.append(flight.iloc[i]['flightDistance'] / speed)
    flight['timeFromPreviousPosition'] = duration

    # Add the 'accuTime' column to flight dataframe
    startTimeSec = []
    endTimeSec = []
    startTimeSec.append(0.0)
    endTimeSec.append(flight.iloc[0]['loiterTime'])
    for i in range(1, len(flight)):
        startTimeSec.append(endTimeSec[i - 1] +
                            flight.iloc[i]['timeFromPreviousPosition'])
        endTimeSec.append(endTimeSec[i - 1] +
                          flight.iloc[i]['timeFromPreviousPosition'] +
                          flight.iloc[i]['loiterTime'])
    flight['pathStartTimeSec'] = startTimeSec
    flight['pathEndTimeSec'] = endTimeSec

    return flight
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
def orsGetSnapToRoadLatLon(loc, APIkey):
    """
	A function to get snapped latlng for one coordinate using ORS
	Parameters
	----------
	loc: list
		The location to be snapped to road
	Returns
	-------
	list
		A snapped location in the format of [lat, lon].  Note that this function will lose the info of altitude of the location.
	"""

    # There is no function in ORS that snaps to a road.
    # Instead, issue a driving request from a location to itself.
    dicLoc = loc2Dict(loc)

    snapToRoadUrl = (
        'https://api.openrouteservice.org/v2/directions/driving-car/geojson')

    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 = [[dicLoc['lon'], dicLoc['lat']],
                       [dicLoc['lon'], dicLoc['lat']]]
        radiuses = [-1, -1]
        elevation = "false"
        extra_info = []

        encoded_body = json.dumps({
            "coordinates": coordinates,
            "elevation": elevation,
            "extra_info": extra_info,
            "instructions": "false",
            "radiuses": radiuses
        })

        http = urllib3.PoolManager()
        response = http.request('POST',
                                snapToRoadUrl,
                                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:
            snapLoc = [
                data['features'][0]['geometry']['coordinates'][0][1],
                data['features'][0]['geometry']['coordinates'][0][0]
            ]

            return snapLoc
        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
Ejemplo n.º 20
0
def buildNoLoiteringFlight(routeType='square',
                           startLoc=None,
                           cruiseAltMetersAGL=None,
                           endLoc=None,
                           takeoffSpeedMPS=None,
                           rateOfClimbMPS=None,
                           cruiseSpeedMPS=None,
                           landSpeedMPS=None,
                           rateOfDescentMPS=None):
    """
	This function generates a flight profile/path given routeType, origin/destinate location and speed of all phase. The profile it generate does not include loiter (i.e. the loiter column is all zero)

	Parameters
	----------
	routeType: string, Optional, default as 'square'
		Type of flight profile/path, options are 'square', 'triangular', 'trapezoidal', 'straight'.
	startLoc: list, Required, default as 'None'
		Start location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt].
	cruiseAltMetersAGL: float, Required, default as 'None'
		Cruise altitude, meters above sea level.
	endLoc: list, Required, default as 'None'
		End location, the format is [lat, lon] (altitude, above sea level, set to be 0) or [lat, lon, alt].
	rateOfClimbMPS: float, Required, default as 'None'
		Rate of climb of the aircraft, it is a vertical speed.
	climbGradientInDegree: float, Required, default as 'None'
		Climb gradient, the unit is degree, horizontal as zero, minimal value as 0, maximum value as 90 (vertical up).
	cruiseSpeedMPS: float, Required, default as 'None'
		Speed of cruise, in the unit of meters/second.
	rateOfDescentMPS: float, Required, default as 'None'
		Rate of descent, vertical speed.
	descentGradientInDegree: float, Required, default as 'None'
		Descent gradient, the unit is degree, horizontal as zero, minimal value as 0, maximum value as 90 (vertical down).

	Return
	------
	flight dataframe
		A dataframe to be interpreted into assignments dataframe
	"""

    try:
        routeType = routeType.lower()
    except:
        pass

    # Generate flight profile without loitering
    if (routeType == 'square'):
        flight = _buildFlightProfile(startLoc=startLoc,
                                     cruiseAltMetersAGL=cruiseAltMetersAGL,
                                     endLoc=endLoc,
                                     takeoffSpeedMPS=takeoffSpeedMPS,
                                     rateOfClimbMPS=takeoffSpeedMPS,
                                     cruiseSpeedMPS=cruiseSpeedMPS,
                                     landSpeedMPS=landSpeedMPS,
                                     rateOfDescentMPS=landSpeedMPS)

    elif (routeType == 'triangular'):
        dicStartLoc = loc2Dict(startLoc)
        dicEndLoc = loc2Dict(endLoc)
        midLoc = [(dicStartLoc['lat'] + dicEndLoc['lat']) / 2,
                  (dicStartLoc['lon'] + dicEndLoc['lon']) / 2,
                  cruiseAltMetersAGL]
        flight = _buildFlightPath(path=[startLoc, midLoc, endLoc],
                                  speedMPS=cruiseSpeedMPS)
        # There will be only three locations
        flight.loc[0, 'description'] = "beforeDeparture"
        flight.loc[1, 'description'] = "takeoffAtAlt and arrivalAtAlt"
        flight.loc[2, 'description'] = "afterArrival"

    elif (routeType == 'trapezoidal'):
        flight = _buildFlightProfile(startLoc=startLoc,
                                     cruiseAltMetersAGL=cruiseAltMetersAGL,
                                     endLoc=endLoc,
                                     takeoffSpeedMPS=takeoffSpeedMPS,
                                     rateOfClimbMPS=rateOfClimbMPS,
                                     cruiseSpeedMPS=cruiseSpeedMPS,
                                     landSpeedMPS=landSpeedMPS,
                                     rateOfDescentMPS=rateOfDescentMPS)

    elif (routeType == 'straight'):
        flight = _buildFlightPath(path=[startLoc, endLoc],
                                  speedMPS=cruiseSpeedMPS)
        # There will be only two locations
        flight.loc[0, 'description'] = "beforeDeparture"
        flight.loc[1, 'description'] = "afterArrival"

    return flight