I am trying to make an app that can display places of interest by inputting a location, radius of search, type of location to search and an optional keyword to qualify the location type to search. It uses the Google Places API, which accepts only GPS coordinates as the location input, it cannot accept the location name as input. However, as most people don’t know the GPS coordinates of a location, I want to also give them the ability to search for the GPS coordinates of a location by inputting the location name. Then, using these location coordinates and the other 3 inputs that the user will enter next, I will display a map in the dcc.Graph area below.
Following is my code which displays the GPS coordinates of an input location. Now, I want to make it such that if the user inputs a location name, then the returned GPS coordinates should get automatically put into the input textboxes for latitude and longitude below. How do I do that?
import dash
from dash.dependencies import Output, Input, State
import dash_core_components as dcc
import dash_html_components as html
import requests, json
app = dash.Dash()
app.layout = html.Div(children=[
html.H3(children="Please input the GPS coordinates (i.e., latitude and longitude), radius of search (in metres), location type and keyword (option) to search for interesting places nearby. If you don't know the GPS coordinates, please enter the name of the location, and we'll help you find it.", style={'height':'8vh'}),
html.Div([
dcc.Input(id='input_loc_name', placeholder='Enter location name (like, Mountain View, CA)', type='text', style={'width': '20%', 'display': 'inline-block'}),
html.Button('Submit', id='submit_loc_name'),
html.H6(id='coordinates_display', style={'height':'6vh', 'font-size':'1.15em'}),
]),
html.Div([
dcc.Input(id='input_lat', placeholder='Enter a latitude', type='text', style={'width': '10%', 'display': 'inline-block'}),
dcc.Input(id='input_lon', placeholder='Enter a longitude', type='text', style={'width': '10%', 'display': 'inline-block'}),
dcc.Input(id='input_radius', placeholder='Enter radius (in metres)', type='text', style={'width': '10%', 'display': 'inline-block'}),
dcc.Input(id='input_type', placeholder='Enter type of location', type='text', style={'width': '10%', 'display': 'inline-block'}),
dcc.Input(id='input_key', placeholder='Enter keyword (optional)', type='text', style={'width': '10%', 'display': 'inline-block'}),
]),
html.Button('Submit', id='submit_button'),
html.Div([
html.H3(id='output_text'),
html.Div([dcc.Graph(id='output_graph')]),
])
])
google_API_key = "API_key"
def return_lat_lon(location_name):
req = requests.get('https://maps.googleapis.com/maps/api/geocode/json?address='+location_name+'&key='+google_API_key)
res = req.json()
result = res['results'][0]
lat = result['geometry']['location']['lat']
lon = result['geometry']['location']['lng']
return lat, lon
@app.callback(
Output('coordinates_display', 'children'),
[Input('submit_loc_name', 'n_clicks')],
[State('input_loc_name', 'value')])
def display_gps_coordinatates(n_clicks, input_loc_name):
if n_clicks:
if input_loc_name:
lat, lon = return_lat_lon(input_loc_name)
return "The GPS coordinates (latitude, longitude) of '{}' are: {}, {}".format(input_loc_name, lat, lon)
else:
return dash.no_update
if __name__ == '__main__':
app.run_server(debug=True)
My callback function for making the map is as follows:
@app.callback(
Output('output_graph', 'figure'),
[Input('submit_button', 'n_clicks')],
[State('input_lat', 'value'),
State('input_lon', 'value'),
State('input_radius', 'value'),
State('input_type', 'value'),
State('input_key', 'value')])
def update_output(n_clicks, lat_, lon_, radius, loc_type, keyword):
if n_clicks:
### code to construct the map
So, I think I just need to figure out a way to add the first callback’s output as one of the inputs to the second callback. But assuming I find a way to do that, I fear it would throw error in the case that the user did not inout any location name in the textbox (as they knew what coordinates they wanted to input). So, how do I do this?