示例#1
0
def privGetShapepoints3D(
        odID=1,
        objectID=None,
        modelFile=None,
        startTimeSec=0.0,
        startLoc=None,
        endLoc=None,
        takeoffSpeedMPS=None,
        cruiseSpeedMPS=None,
        landSpeedMPS=None,
        cruiseAltMetersAGL=None,
        routeType='square',
        climbRateMPS=None,
        descentRateMPS=None,
        earliestLandTime=-1,
        loiterPosition='arrivalAtAlt',
        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'],
        ganttColorLoiter=config['VRV_DEFAULT_GANTTCOLORLOITER'],
        popupText=None):

    # Replace backslash
    modelFile = replaceBackslashToSlash(modelFile)

    # Ensure leading slash
    modelFile = addHeadSlash(modelFile)

    # Generate flight profile without loitering
    flight = buildNoLoiteringFlight(routeType, startLoc, cruiseAltMetersAGL,
                                    endLoc, takeoffSpeedMPS, climbRateMPS,
                                    cruiseSpeedMPS, landSpeedMPS,
                                    descentRateMPS)

    # Calculate loiter time
    [totalTime, groundDistance, flightDistance] = getTimeDistFromFlight(flight)
    remainLoiterTime = 0
    if (earliestLandTime - startTimeSec > totalTime):
        remainLoiterTime = earliestLandTime - startTimeSec - totalTime
    else:
        remainLoiterTime = 0

    # Add loiter given loiter position
    flight = addLoiterTimeToFlight(flight=flight,
                                   loiterPosition=loiterPosition,
                                   loiterTime=remainLoiterTime)

    # Build assignments dataframe
    assignments = privInitDataframe('assignments')
    for i in range(1, len(flight)):
        # For all segments in flight profile, loitering happens AFTER arrival at that position
        assignments = assignments.append(
            {
                'odID': odID,
                'objectID': objectID,
                'modelFile': modelFile,
                'startTimeSec':
                startTimeSec + flight.iloc[i - 1]['pathEndTimeSec'],
                'startLat': flight.iloc[i - 1]['lat'],
                'startLon': flight.iloc[i - 1]['lon'],
                'startAltMeters': flight.iloc[i - 1]['altAGL'],
                'endTimeSec':
                startTimeSec + flight.iloc[i]['pathStartTimeSec'],
                'endLat': flight.iloc[i]['lat'],
                'endLon': flight.iloc[i]['lon'],
                'endAltMeters': flight.iloc[i]['altAGL'],
                'leafletColor': leafletColor,
                'leafletWeight': leafletWeight,
                'leafletStyle': leafletStyle,
                'leafletOpacity': leafletOpacity,
                'leafletCurveType': leafletCurveType,
                'leafletCurvature': leafletCurvature,
                'useArrows': useArrows,
                'modelScale': modelScale,
                'modelMinPxSize': modelMinPxSize,
                'cesiumColor': stripCesiumColor(cesiumColor),
                'cesiumWeight': cesiumWeight,
                'cesiumStyle': cesiumStyle,
                'cesiumOpacity': cesiumOpacity,
                'ganttColor': ganttColor,
                'popupText': popupText,
                'startElevMeters': None,
                'endElevMeters': None,
                'wayname': None,
                'waycategory': None,
                'surface': None,
                'waytype': None,
                'steepness': None,
                'tollway': None
            },
            ignore_index=True)

        # If they need loitering, add the line of loitering
        if (flight.iloc[i]['loiterTime'] != 0):
            assignments = assignments.append(
                {
                    'odID':
                    odID,
                    'objectID':
                    objectID,
                    'modelFile':
                    modelFile,
                    'startTimeSec':
                    startTimeSec + flight.iloc[i]['pathStartTimeSec'],
                    'startLat':
                    flight.iloc[i]['lat'],
                    'startLon':
                    flight.iloc[i]['lon'],
                    'startAltMeters':
                    flight.iloc[i]['altAGL'],
                    'endTimeSec':
                    startTimeSec + flight.iloc[i]['pathEndTimeSec'],
                    'endLat':
                    flight.iloc[i]['lat'],
                    'endLon':
                    flight.iloc[i]['lon'],
                    'endAltMeters':
                    flight.iloc[i]['altAGL'],
                    'leafletColor':
                    leafletColor,
                    'leafletWeight':
                    leafletWeight,
                    'leafletStyle':
                    leafletStyle,
                    'leafletOpacity':
                    leafletOpacity,
                    'leafletCurveType':
                    leafletCurveType,
                    'leafletCurvature':
                    leafletCurvature,
                    'useArrows':
                    useArrows,
                    'modelScale':
                    modelScale,
                    'modelMinPxSize':
                    modelMinPxSize,
                    'cesiumColor':
                    stripCesiumColor(cesiumColor),
                    'cesiumWeight':
                    cesiumWeight,
                    'cesiumStyle':
                    cesiumStyle,
                    'cesiumOpacity':
                    cesiumOpacity,
                    'ganttColor':
                    ganttColorLoiter,
                    'popupText':
                    popupText,
                    'startElevMeters':
                    None,
                    'endElevMeters':
                    None,
                    'wayname':
                    None,
                    'waycategory':
                    None,
                    'surface':
                    None,
                    'waytype':
                    None,
                    'steepness':
                    None,
                    'tollway':
                    None
                },
                ignore_index=True)

    return assignments
示例#2
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
def deconstructAssignments(assignments=None,
                           includeStationaryFlag=False,
                           includeVerticalFlag=False):
    """
	Given an Assignments dataframe, according to objectID and odID, separate it into a set of routes

	Parameters
	----------
	assignments: :ref:`Assignments`, Required
		Assignments dataframe, to be converted and separated by `odID`
	includeStationaryFlag: boolean, Optional, default as False
		Decide whether we includes the "routes" that have the same origin and destination
	includeVerticalFlag: boolean, Optional, default as False
		Decide whether we includes the "routes" that is vertical to the ground
	
	Return
	------
	list
		It is a list of assignment dataframes, each dataframe is a route or a period of stationary 'movement'
	"""
    lstSubAssignments = []

    # If we need to include all stationary rows, find all stationary, each row becomes a new dataframe
    if (includeStationaryFlag):
        stationaryRows = assignments.loc[
            (assignments['startLat'] == assignments['endLat'])
            & (assignments['startLon'] == assignments['endLon']) &
            (assignments['startAltMeters'] == assignments['endAltMeters'])]
        stationaryRows = stationaryRows.reset_index(drop=True)
        for i in range(0, len(stationaryRows)):
            lstSubAssignments.append(stationaryRows.loc[i:i, :].copy())

    # If we need to include all vertical rows, find all vertical, each row becomes a new dataframe
    if (includeVerticalFlag):
        verticalRows = assignments.loc[
            (assignments['startLat'] == assignments['endLat'])
            & (assignments['startLon'] == assignments['endLon']) &
            (assignments['startAltMeters'] != assignments['endAltMeters'])]
        verticalRows = verticalRows.reset_index(drop=True)
        for i in range(0, len(verticalRows)):
            lstSubAssignments.append(verticalRows.loc[i:i, :].copy())

    collection = assignments.loc[
        (assignments['startLat'] != assignments['endLat']) |
        (assignments['startLon'] != assignments['endLon'])]
    if (len(collection) > 0):
        collection = collection.sort_values(
            by=['objectID', 'startTimeSec', 'modelFile', 'odID'],
            ascending=True)
        collection = collection.reset_index(drop=True)

        # Find consecutive routes
        tmpSubAssignment = privInitDataframe('Assignments')
        for i in range(len(collection)):
            if (len(tmpSubAssignment) == 0):
                tmpSubAssignment = pd.concat(
                    [tmpSubAssignment, collection.loc[i:i, :].copy()],
                    ignore_index=True,
                    sort=True)
            else:
                if (tmpSubAssignment.iloc[len(tmpSubAssignment) - 1]['endLat']
                        == collection.iloc[i]['startLat']
                        and tmpSubAssignment.iloc[len(tmpSubAssignment) -
                                                  1]['endLon']
                        == collection.iloc[i]['startLon']
                        and tmpSubAssignment.iloc[len(tmpSubAssignment) -
                                                  1]['endAltMeters']
                        == collection.iloc[i]['startAltMeters']
                        and tmpSubAssignment.iloc[len(tmpSubAssignment) -
                                                  1]['endTimeSec']
                        == collection.iloc[i]['startTimeSec']
                        and tmpSubAssignment.iloc[len(tmpSubAssignment) -
                                                  1]['odID']
                        == collection.iloc[i]['odID']):
                    tmpSubAssignment = pd.concat(
                        [tmpSubAssignment, collection.loc[i:i, :].copy()],
                        ignore_index=True,
                        sort=True)
                else:
                    lstSubAssignments.append(tmpSubAssignment.copy())
                    tmpSubAssignment = privInitDataframe('Assignments')
                    tmpSubAssignment = pd.concat(
                        [tmpSubAssignment, collection.loc[i:i, :].copy()],
                        ignore_index=True,
                        sort=True)
        lstSubAssignments.append(tmpSubAssignment.copy())

    # Re-index odID for lstRoutes
    for i in range(0, len(lstSubAssignments)):
        lstSubAssignments[i] = lstSubAssignments[i].reset_index(drop=True)
        lstSubAssignments[i]['odID'] = i

    return lstSubAssignments
def privCreateArcsFromLocSeq(
        locSeq=None,
        initArcs=None,
        startArc=1,
        objectID=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,
        cesiumColor=config['VRV_DEFAULT_CESIUMPATHCOLOR'],
        cesiumWeight=config['VRV_DEFAULT_CESIUMPATHWEIGHT'],
        cesiumStyle=config['VRV_DEFAULT_CESIUMPATHSTYLE'],
        cesiumOpacity=config['VRV_DEFAULT_CESIUMPATHOPACITY'],
        popupText=None):
    """
	See createArcsFromLocSeq for docstring
	"""

    # Number of arcs
    numArcs = len(locSeq)

    # Define odIDs
    if (type(initArcs) is pd.core.frame.DataFrame):
        if (len(initArcs) > 0):
            maxOdID = max(initArcs['odID'])
            startArc = max(maxOdID + 1, startArc)
    odIDs = [n for n in range(startArc, startArc + numArcs)]

    # arc dataframe
    arcs = privInitDataframe('Arcs')

    # generate arcs
    for i in range(len(locSeq) - 1):
        arcs = arcs.append(
            {
                'odID': odIDs[i],
                'objectID': objectID,
                'startLat': locSeq[i][0],
                'startLon': locSeq[i][1],
                'endLat': locSeq[i + 1][0],
                'endLon': locSeq[i + 1][1],
                'leafletColor': leafletColor,
                'leafletWeight': leafletWeight,
                'leafletStyle': leafletStyle,
                'leafletOpacity': leafletOpacity,
                'leafletCurveType': leafletCurveType,
                'leafletCurvature': leafletCurvature,
                'cesiumColor': stripCesiumColor(cesiumColor),
                'cesiumWeight': cesiumWeight,
                'cesiumStyle': cesiumStyle,
                'cesiumOpacity': cesiumOpacity,
                'useArrows': useArrows,
                'popupText': popupText,
                'startElevMeters': None,
                'endElevMeters': None
            },
            ignore_index=True)

    # if the user provided an initNode dataframe, add the new points after it
    if (type(initArcs) is pd.core.frame.DataFrame):
        arcs = pd.concat([initArcs, arcs], ignore_index=True)

    return arcs
def privCreateNodesFromLocs(
        locs=None,
        initNodes=None,
        nodeType=None,
        nodeName=None,
        startNode=1,
        incrementName=False,
        incrementStart=1,
        snapToRoad=False,
        dataProvider=None,
        dataProviderArgs=None,
        popupText=None,
        leafletIconPrefix=config['VRV_DEFAULT_LEAFLETICONPREFIX'],
        leafletIconType=config['VRV_DEFAULT_LEAFLETICONTYPE'],
        leafletColor=config['VRV_DEFAULT_LEAFLETICONCOLOR'],
        leafletIconText=None,
        cesiumIconType=config['VRV_DEFAULT_CESIUMICONTYPE'],
        cesiumColor=config['VRV_DEFAULT_CESIUMICONCOLOR'],
        cesiumIconText=None):
    """
	Given a set of nodes lats and lons, return a node dataframe

	Parameters
	----------
	locs: list of lists, Required, default as None
		A list of locations, in the form of [[lat, lon, alt], [lat, lon, alt], ...] or [[lat, lon], [lat, lon], ...]
	initNodes: :ref:`Nodes`, Optional, default as None
		A dataframe containing an existing set of nodes. If `initNodes` is provided, this function will extend to that dataframe.
	nodeType: string, Optional, default as None
		A user-defined text field that can be used to classify nodes. This field is to categorize a batch of nodes (e.g., "restaurants"). If provided, all nodes generated by the `generateNodes()` function call will be given this value. The nodeType is not used by VeRoViz explicitly. 
	nodeName: string, Optional, default as None
		The name of all nodes that are to be generated by this function call. This field is a more detailed description (e.g., "pizza" or "steakhouse"). The nodeName is not used by VeRoViz explicitly. 
	startNode: int, Optional, default as 1
		The starting node number will be the maximum of startNode and any id values contained in the initNodes dataframe (if provided).  
	incrementName: boolean, Optional, default as False
		Toggle to choose if we add increment after nodeName, e.g. 'customer1', 'customer2',...
	incrementStart: int, Optional, default as 1
		The starting number of the increment.
	popupText: string, Optional, default as None
		Text (or HTML) that will be displayed when a user clicks on the node in either Leaflet or Cesium.  A value of None will result in the node ID being auto-populated in the `popupText` column of the nodes dataframe.
	leafletIconPrefix: string, Optional, default as "glyphicon"
		The collection of Leaflet icons.  Options are "glyphicon", "fa", or "custom". See :ref:`Leaflet style`
	leafletIconType: string, Optional, default as "info-sign"
		The specific icon to be used for all generated nodes.  The list of available options depends on the choice of the leafletIconType. See :ref:`Leaflet style`
	leafletColor: string, Optional, default as "blue"
		The icon color of the generated nodes when displayed in Leaflet. One of a collection of pre-specified colors. See :ref:`Leaflet style`
	leafletIconText: string, Optional, default as None
		Text that will be displayed within the node on a Leaflet map.  This text will only be shown if `leafletIconPrefix` is 'custom' and `leafletIconType` includes a font color and font size.  A value of None will result in the node ID being displayed in the node.  See :ref:`Leaflet style`.
	cesiumIconType: string, Optional, default as "pin"
		'pin' is the only option right now. See :ref:`Cesium style`
	cesiumColor: string, Optional, default as "blue"
		The color of the generated nodes when displayed in Cesium.  One of a collection of pre-specified colors. See :ref:`Cesium style`
	cesiumIconText: string, Optional, default as None
		Text that will be displayed within the node on a Cesium map. See :ref:`Cesium style`

	Return
	------
	:ref:`Nodes`
		A Nodes dataframe with given list of coordinates
	"""

    # Number of nodes
    numNodes = len(locs)

    # Define ids and nodeNames
    if (type(initNodes) is pd.core.frame.DataFrame):
        if (len(initNodes) > 0):
            maxID = max(initNodes['id'])
            startNode = max([maxID + 1, startNode])

    ids = [n for n in range(startNode, startNode + numNodes)]
    if (incrementName):
        nodeNames = [(nodeName + "%s" % (n))
                     for n in range(incrementStart, incrementStart + numNodes)]
    else:
        nodeNames = [nodeName] * numNodes

    # Snap to road
    # FIXME! - Issue #28 - Multiple nodes might be snapped to the same location
    if (snapToRoad):
        locs = privGetSnapLocBatch(locs=locs,
                                   dataProvider=dataProvider,
                                   dataProviderArgs=dataProviderArgs)

    # node dataframe
    nodes = privInitDataframe('Nodes')

    # generate nodes
    dicLocs = locs2Dict(locs)
    for i in range(len(locs)):
        nodes = nodes.append(
            {
                'id':
                ids[i],
                'lat':
                dicLocs[i]['lat'],
                'lon':
                dicLocs[i]['lon'],
                'altMeters':
                dicLocs[i]['alt'],
                'nodeName':
                nodeNames[i],
                'nodeType':
                nodeType,
                'popupText':
                popupText if (popupText != None) else ids[i],
                'leafletIconPrefix':
                leafletIconPrefix,
                'leafletIconType':
                leafletIconType,
                'leafletColor':
                leafletColor,
                'leafletIconText':
                leafletIconText if (leafletIconText != None) else ids[i],
                'cesiumIconType':
                cesiumIconType,
                'cesiumColor':
                stripCesiumColor(cesiumColor),
                'cesiumIconText':
                cesiumIconText if (cesiumIconText != None) else ids[i],
                'elevMeters':
                None
            },
            ignore_index=True)

    # if the user provided an initNode dataframe, add the new points after it
    if (type(initNodes) is pd.core.frame.DataFrame):
        nodes = pd.concat([initNodes, nodes], ignore_index=True)

    return nodes
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