Ejemplo n.º 1
0
def _genNodesRoadBased(numNodes=None,
                       boundingRegion=None,
                       distToRoad=None,
                       dataProvider=None,
                       dataProviderArgs=None):
    """
	Generate randomized node using Uniform distribution within a bounding area and close to roads
	
	Note
	----
	This function is an approximation, the error is getting larger when the location is closer to poles

	Parameters
	----------
	numNodes: int, Required
		Number of nodes to be generated
	boudingArea: list, Required
		A defined polygon, nodes are generated within this area
	distToRoad: float, Required
		The maximun distance to road for generated nodes.
	dataProvider: string, Conditional, default as None
		Specifies the data source to be used for generating nodes on a road network. See :ref:`Data Providers` for options and requirements.
	dataProviderArgs: dictionary, Conditional, default as None
		For some data providers, additional parameters are required (e.g., API keys or database names). See :ref:`Data Providers` for the additional arguments required for each supported data provider.
	
	Returns
	-------
	list of lists
		A list of coordinates, within a given distance to its nearest street
	"""

    # Initialize
    locs = []
    holes = []
    goodLocs = []

    # Generate nodes, if it is not close enough, discard and regenerate
    while (len(locs) < numNodes):
        newLocs = _genNodesUniformBounded(numNodes - len(locs), boundingRegion)
        goodLocs = []
        for i in range(len(newLocs)):
            goodFlag = True
            for j in range(len(holes)):
                if (geoDistance2D(newLocs[i], holes[j][0]) < holes[j][1]):
                    goodFlag = False
                    break
            if (goodFlag):
                goodLocs.append(newLocs[i])
        if (len(goodLocs) > 0):
            snapLocs = privGetSnapLocBatch(goodLocs, dataProvider,
                                           dataProviderArgs)
            for i in range(len(snapLocs)):
                dist = geoDistance2D(goodLocs[i], snapLocs[i])
                if (dist > distToRoad):
                    holes.append([goodLocs[i], dist - distToRoad])
                else:
                    locs.append(goodLocs[i])

    return locs
Ejemplo n.º 2
0
def getSnapLocBatch(locs=None, dataProvider=None, dataProviderArgs=None):
    """
	Snap multiple locations, each given by [lat, lon] coordinates, to their nearest locations on a road network.
	

	Parameters
	----------
	locs: list of lists, Required
		A list of GPS coordinates of node locations, in the form of [[lat, lon], [lat, lon], ...]
	dataProvider: string, Conditional, default as None
		Specifies the data source to be used for finding routes or generate nodes on a road network. See :ref:`Data Providers` for options and requirements of options.
	dataProviderArgs: dictionary, Conditional, default as None
		For some data provider, veroviz need some extra parameters such as API keys or database name. See :ref:`Data Providers` for the keys required for different data provider.
	
	Returns
	-------
	list of lists
		A list of snapped locations in the format of [[lat, lon], [lat, lon], ...].  Note: Any altitude values provided as inputs in the `loc` parameter will be lost in the return.

	Example
	-------
	Import veroviz and check if the version is up-to-date:
		>>> import veroviz as vrv
		>>> vrv.checkVersion()

	Also, import os so we can use environment variables for data provider API keys:
		>>> import os

	Snap a given list of location to their nearest streets:
		>>> locs = [
		...     [42.00, -78.00],
		...     [42.10, -78.00],
		...     [42.20, -78.00]]
		>>> snapLocs = vrv.getSnapLocBatch(
		...     locs             = locs,
		...     dataProvider     = 'MapQuest',
		...     dataProviderArgs = {'APIkey': os.environ['MAPQUESTKEY']})
		>>> snapLocs
		[[41.999401, -78.003876], [42.100021, -77.995549], [42.1993, -78.001011]]
	"""

    # validation
    [valFlag, errorMsg,
     warningMsg] = valGetSnapLocBatch(locs, dataProvider, dataProviderArgs)
    if (not valFlag):
        print(errorMsg)
        return
    elif (config['VRV_SETTING_SHOWWARNINGMESSAGE'] and warningMsg != ""):
        print(warningMsg)

    snapLocs = privGetSnapLocBatch(locs, dataProvider, dataProviderArgs)

    return snapLocs
Ejemplo n.º 3
0
def _genNodesRoadBased(numNodes=None,
                       boundingRegion=None,
                       distToRoad=None,
                       dataProvider=None,
                       APIkey=None,
                       databaseName=None):
    """
	Generate randomized node using Uniform distribution within a bounding area and close to roads

	Note
	----
	This function is an approximation, the error is getting larger when the location is closer to poles

	Parameters
	----------
	numNodes: int, Required
		Number of nodes to be generated
	boudingArea: list, Required
		A defined polygon, nodes are generated within this area
	distToRoad: float, Required
		The maximun distance to road for generated nodes.
	dataProvider: string, Conditional, See :ref:`Dataprovider`
		Specifies the data source to be used for generating nodes on a road network.  
	APIkey: string, Conditional, See :ref:`Dataprovider`
		Some data providers require an API key (which you'll need to register for).
	databaseName: string, Conditional, See :ref:`Dataprovider`
		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 of lists
		A list of coordinates, within a given distance to its nearest street
	"""

    # Initialize
    locs = []

    # Generate nodes, if it is not close enough, discard and regenerate
    while (len(locs) < numNodes):
        newLocs = _genNodesUniformBounded(numNodes - len(locs), boundingRegion)
        snapLocs = privGetSnapLocBatch(newLocs, dataProvider, APIkey,
                                       databaseName)
        for i in range(len(snapLocs)):
            if (geoDistance2D(newLocs[i], snapLocs[i]) <= distToRoad):
                locs.append(newLocs[i])

    return locs
Ejemplo n.º 4
0
def privCreateNodesFromLocs(locs=None,
                            initNodes=None,
                            nodeType=None,
                            nodeName=None,
                            startNode=1,
                            incrementName=False,
                            incrementStart=1,
                            snapToRoad=False,
                            dataProvider=None,
                            dataProviderArgs=None,
                            leafletIconPrefix=VRV_DEFAULT_LEAFLETICONPREFIX,
                            leafletIconType=VRV_DEFAULT_LEAFLETICONTYPE,
                            leafletColor=VRV_DEFAULT_LEAFLETICONCOLOR,
                            leafletIconText=None,
                            cesiumIconType=VRV_DEFAULT_CESIUMICONTYPE,
                            cesiumColor=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.
	leafletIconPrefix: string, Optional, default as "glyphicon"
		The collection of Leaflet icons.  Options are "glyphicon" or "fa". 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. 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 "Cesium.Color.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 = initDataframe('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,
                'leafletIconPrefix':
                leafletIconPrefix,
                'leafletIconType':
                leafletIconType,
                'leafletColor':
                leafletColor,
                'leafletIconText':
                leafletIconText if (leafletIconText != None) else ids[i],
                'cesiumIconType':
                cesiumIconType,
                'cesiumColor':
                cesiumColor,
                'cesiumIconText':
                cesiumIconText if (cesiumIconText != None) else ids[i]
            },
            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
Ejemplo n.º 5
0
def snapNodesToRoad(nodes=None, dataProvider=None, dataProviderArgs=None):
    """
	Updates the locations of nodes within a dataframe, such that each node becomes located on a road network.

	Parameters
	----------
	nodes: :ref:`Nodes`, Required, default as None
		A :ref:`Nodes` dataframe containing an existing set of nodes.  
	dataProvider: string, Conditional, default as None
		Specifies the data source to be used for generating nodes on a road network. See :ref:`Data Providers` for options and requirements.
	dataProviderArgs: dictionary, Conditional, default as None
		For some data providers, additional parameters are required (e.g., API keys or database names). See :ref:`Data Providers` for the additional arguments required for each supported data provider.

	Returns
	-------
	:ref:`Nodes` dataframe
		A copy of the input `nodes` dataframe, with updated lat/lon values.	

	Example
	-------
	Import veroviz and check if the version is up-to-date:
		>>> import veroviz as vrv
		>>> vrv.checkVersion()

	Also, import os so we can use environment variables for data provider API keys:
		>>> import os
		
	Create a :ref:`Nodes` dataframe by :meth:`~veroviz.generateNodes.createNodesFromLocs` with two nodes that are off the road network:
		>>> exampleNodes = vrv.createNodesFromLocs(
		...     locs = [[42.80, -78.00],
		...             [42.81, -78.004]],
		...     leafletColor = 'red')


	These nodes are not aligned with the road network.  The following examples demonstrate how to move the nodes to lat/lon locations that correspond to roads.
		>>> # Use OSRM as data provider
		>>> snappedNodes = vrv.snapNodesToRoad(
		...     nodes        = exampleNodes, 
		...     dataProvider = 'OSRM-online')

	Display the original (red) and OSRM-snapped (green) nodes to see the effects of snapping.
		>>> myMap = vrv.createLeaflet(nodes=exampleNodes, mapBackground='Stamen Toner')
		>>> myMap = vrv.createLeaflet(nodes=snappedNodesOSRM, mapObject=myMap)
		>>> myMap	

	We can also use ORS, MapQuest, or pgRouting as the data source.  In these cases, an API key or database name should be provided.
		>>> # Use MapQuest as data provider, and change node colors to purple:
		>>> snappedNodesMQ = vrv.snapNodesToRoad(
		...     nodes            = exampleNodes,
		...     dataProvider     = 'MapQuest',
		...     dataProviderArgs = { 'APIkey' : os.environ['MAPQUESTKEY']})
		>>> snappedNodesMQ['leafletColor'] = 'purple'	
	
		>>> # Add the MapQuest-snapped (purple) nodes to our map:
		>>> myMap = vrv.createLeaflet(nodes=snappedNodesMQ, mapObject=myMap)
		>>> myMap
	
		>>> # Use ORS as data provider, and change node colors to blue:
		>>> snappedNodesORS = vrv.snapNodesToRoad(
		...     nodes            = exampleNodes,
		...     dataProvider     = 'ORS-online',
		...     dataProviderArgs = {'APIkey': os.environ['ORSKEY']})
		>>> snappedNodesORS['leafletColor'] = 'blue'	

		>>> # Add the ORS-snapped (blue) nodes to our map:
		>>> myMap = vrv.createLeaflet(nodes=snappedNodesORS, mapObject=myMap)
		>>> myMap

		>>> # Use pgRouting as data provider, and change node colors to black:
		>>> snappedNodesPGR = vrv.snapNodesToRoad(
		...     nodes        = exampleNodes,
		...     dataProvider = 'pgRouting',
		...     dataProviderArgs = {'databaseName': 'YOUR_DATABASENAME'})
		>>> snappedNodesPGR['leafletColor'] = 'black'	

		>>> # Add the pgRouting-snapped (black) nodes to our map:
		>>> myMap = vrv.createLeaflet(nodes=snappedNodesPGR, mapObject=myMap)
		>>> myMap

	"""

    # validation
    [valFlag, errorMsg,
     warningMsg] = valSnapNodesToRoad(nodes, dataProvider, dataProviderArgs)
    if (not valFlag):
        print(errorMsg)
        return
    elif (config['VRV_SETTING_SHOWWARNINGMESSAGE'] and warningMsg != ""):
        print(warningMsg)

    # List of lat/lon before snapping
    locs = list(zip(nodes['lat'].tolist(), nodes['lon'].tolist()))
    snapNodes = nodes.copy()

    # Find list of snapped coordins
    snapLocs = privGetSnapLocBatch(locs, dataProvider, dataProviderArgs)

    # Make a copy of nodes and replace lat/lon columns withn snapped lat/lon
    snapNodes['lat'] = list(zip(*snapLocs))[0]
    snapNodes['lon'] = list(zip(*snapLocs))[1]

    return snapNodes