Using Google Places API
Some points to keep in mind:
- In order to use Google’s Places API, you will need to register and obtain a Google Map’s API Key.
- In class UrlSigner in the tutorial the variable descriptions are:
keyString
=> is your Google Map api key.urlString
is the url you want to sign using the api key. In code you will find
inputKey
andinputUrl
. these 2 variables are just for testing purpose you can omit them if you want. You can directly write code as follows:URL url = new URL(urlString);
UrlSigner signer = new UrlSigner(keyString);
String request = signer.signRequest(url.getPath(),url.getQuery());
System.out.println("Signed URL :" + url.getProtocol() + "://" + url.getHost() + request);
in main method of UrlSigner class.
Using Google Places API in Google Sheets
There is no doubt that the code you copied is working. Upon testing the same exact code you posted to replicate the problems, I only added return
in the function to populate the cell.
See my exact code which worked and returned the data in sheets.
function placesAPI(keyword,latitude,longitude,radius,api_key,depth) {
var output = [ ["Name", "Place ID", "Latitude", "Longitude", "Types"]]
var url = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?types=food&location=51.4977836,-0.1522502&radius=200&key=AIzaSyBtepY6mCTkHr3m4UCacxSkePkli5yEbCM";
var response = UrlFetchApp.fetch(url)
payload = JSON.parse(response);
for (var x = 0; x < payload['results'].length; x++){
var inner = [ payload['results'][x]['name'], payload['results'][x]['place'],payload['results'][x]['latitude'],payload['results'][x]['longitude'],payload['results'][x]['types']]
output.push(inner)}
return(output); // added this code to put the value on the cell
}
In the function call, you need to use the api key in the url first to establish a connection. I have confirmed in my testing that if you used other api keys in the first function call, it will not return anything.
=placesAPI("Golf Course","51.4977836","-0.1522502","20000","AIzaSyBtepY6mCTkHr3m4UCacxSkePkli5yEbCM",20)
After that, it should return the same output below. Same with what we see when visiting the url
manually.
Implement Google Places Api in Website
From the errors you are getting, it looks like you should:
- remove
sensor=false&
from<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=places"></script>
. Having this should not prevent your script from working, but Google recommends that you remove it. - Add an API key to your url with the
key=
parameter if you have one, or create and add one if you do not. This is probably your main issue. You can click the "GET A KEY" link here in the upper right of the page.
Also, you may find the error documentation helpful when debugging these messages.
Integrating Google Places API without using Google Maps API?
Actually, if you want to use just a textfield which return establishments around you as a list you can do it like this using google places auto complete.
Follow those steps,
1) install google places
https://developers.google.com/places/ios-api/start
2) in your main.storyboard add a view controller then create a ViewController.swift file and link it to the storyboard view controller
3) Click on view controller -> go to Editor in menu -> Embed in -> navigation controller. Now you should get a navigation controller linked to your view controller.
4) Copy paste the below codings into ViewController.swift
import UIKit
import GooglePlaces
class ViewController: UIViewController,UISearchBarDelegate{
var resultsViewController: GMSAutocompleteResultsViewController?
var searchController: UISearchController?
override func viewDidLoad() {
super.viewDidLoad()
resultsViewController = GMSAutocompleteResultsViewController()
resultsViewController?.delegate = self
searchController = UISearchController(searchResultsController: resultsViewController)
searchController!.searchResultsUpdater = resultsViewController
// Put the search bar in the navigation bar.
searchController!.searchBar.sizeToFit()
self.navigationItem.titleView = searchController?.searchBar
// When UISearchController presents the results view, present it in
// this view controller, not one further up the chain.
self.definesPresentationContext = true
// Prevent the navigation bar from being hidden when searching.
searchController!.hidesNavigationBarDuringPresentation = false
searchController!.searchBar.keyboardAppearance = UIKeyboardAppearance.Dark
searchController!.searchBar.barStyle = .Black
let filter = GMSAutocompleteFilter()
filter.country = "LK" //put your country here
filter.type = .Establishment
resultsViewController?.autocompleteFilter = filter
searchController?.searchBar.showsCancelButton = true
searchController?.searchBar.delegate = self
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
//self.searchController?.active = true
self.searchController!.searchBar.becomeFirstResponder()
}
func didPresentSearchController(searchController: UISearchController) {
self.searchController!.searchBar.becomeFirstResponder()
}
}
// Handle the user's selection.
extension ViewController: GMSAutocompleteResultsViewControllerDelegate {
func resultsController(resultsController: GMSAutocompleteResultsViewController,didAutocompleteWithPlace place: GMSPlace) {
// Do something with the selected place.
print("Pickup Place name: ", place.name)
print("Pickup Place address: ", place.formattedAddress)
print("Pickup Place attributions: ", place.placeID)
}
func resultsController(resultsController: GMSAutocompleteResultsViewController,
didFailAutocompleteWithError error: NSError){
// TODO: handle the error.
print("Error: ", error.description)
}
// Turn the network activity indicator on and off again.
func didRequestAutocompletePredictionsForResultsController(resultsController: GMSAutocompleteResultsViewController) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}
func didUpdateAutocompletePredictionsForResultsController(resultsController: GMSAutocompleteResultsViewController) {
UIApplication.sharedApplication().networkActivityIndicatorVisible = true
}
}
5) In your app delegate
import GooglePlaces
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
GMSPlacesClient.provideAPIKey(GoogleKey) //add your google key here
return true
}
Hope this helps to you. You can customize colors and all of this. And you can get all the details besides the primary details you getting after selecting a place in this by using the place ID of it.
You will get something like this which is totally customizable,
How to load the Google Places API in React
If you are using useLoadScript
of the @react-google-maps/api library
and use-places-autocomplete
you need to supply the ['places'] as a value of your library to use the Places Autocomplete in your code. Please note that this useLoadScript
will load the Google Maps JavaScript Script tag in your code and you don't need to add the script tag in the html file anymore.
From what I understand, your use case where the user will select a place from the autocomplete dropdown and the nearest hospital should be returned in the map.
To achieve this, you need to have this flow:
- Use
use-places-autocomplete
to provide place suggestion when searching for a place. This library have aGetGeocode
and aGetLatLng
that you can use to get the coordinates of the chosen place. - Once you have the coordinates, you can use Places API Nearby Search, use the keyword
hospital
in your request and define a radius. This will search a list of hospital within the defined radius with the chosen place as the center. - You can loop through the list of result and pin each coordinates as markers in your map.
Here;s the sample code and a code snippet below. Make sure to add your API Key:
Index.js
import React from "react";
import { render } from "react-dom";
import Map from "./Map";
render(<Map />, document.getElementById("root"));
Map.js
/*global google*/
import React from "react";
import { GoogleMap, useLoadScript } from "@react-google-maps/api";
import Search from "./Search";
let service;
const libraries = ["places"];
const mapContainerStyle = {
height: "100vh",
width: "100vw"
};
const options = {
disableDefaultUI: true,
zoomControl: true
};
const center = {
lat: 43.6532,
lng: -79.3832
};
export default function App() {
const { isLoaded, loadError } = useLoadScript({
googleMapsApiKey: "YOUR_API_KEY",
libraries
});
const mapRef = React.useRef();
const onMapLoad = React.useCallback(map => {
mapRef.current = map;
}, []);
const panTo = React.useCallback(({ lat, lng }) => {
mapRef.current.panTo({ lat, lng });
mapRef.current.setZoom(12);
let map = mapRef.current;
let request = {
location: { lat, lng },
radius: "500",
type: ["hospital"]
};
service = new google.maps.places.PlacesService(mapRef.current);
service.nearbySearch(request, callback);
function callback(results, status) {
if (status === google.maps.places.PlacesServiceStatus.OK) {
for (let i = 0; i < results.length; i++) {
let place = results[i];
new google.maps.Marker({
position: place.geometry.location,
map
});
}
}
}
}, []);
return (
<div>
<Search panTo={panTo} />
<GoogleMap
id="map"
mapContainerStyle={mapContainerStyle}
zoom={8}
center={center}
options={options}
onLoad={onMapLoad}
/>
</div>
);
}
Search.js
import React from "react";
import usePlacesAutocomplete, {
getGeocode,
getLatLng
} from "use-places-autocomplete";
export default function Search({ panTo }) {
const {
ready,
value,
suggestions: { status, data },
setValue,
clearSuggestions
} = usePlacesAutocomplete({
requestOptions: {
/* Define search scope here */
},
debounce: 300
});
const handleInput = e => {
// Update the keyword of the input element
setValue(e.target.value);
};
const handleSelect = ({ description }) => () => {
// When user selects a place, we can replace the keyword without request data from API
// by setting the second parameter to "false"
setValue(description, false);
clearSuggestions();
// Get latitude and longitude via utility functions
getGeocode({ address: description })
.then(results => getLatLng(results[0]))
.then(({ lat, lng }) => {
panTo({ lat, lng });
})
.catch(error => {
console.log(" Error: ", error);
});
};
const renderSuggestions = () =>
data.map(suggestion => {
const {
place_id,
structured_formatting: { main_text, secondary_text }
} = suggestion;
return (
<li key={place_id} onClick={handleSelect(suggestion)}>
<strong>{main_text}</strong> <small>{secondary_text}</small>
</li>
);
});
return (
<div>
<input
value={value}
onChange={handleInput}
disabled={!ready}
placeholder="Where are you going?"
/>
{/* We can use the "status" to decide whether we should display the dropdown or not */}
{status === "OK" && <ul>{renderSuggestions()}</ul>}
</div>
);
}
Related Topics
Linkedlist Put into Intent Extra Gets Recast to Arraylist When Retrieving in Next Activity
How to Verify That an Android APK Is Signed with a Release Certificate
Implementing User Choice of Theme
How to Customize Item Background and Item Text Color Inside Navigationview
How to Keep My Android Service Running When the Screen Is Turned Off
Neither User 10102 Nor Current Process Has Android.Permission.Read_Phone_State
Android Setting with Textview for Hebrew Text
Ontaskremoved() Not Getting Called in Huawei and Xiaomi Devices
Proguard Causing Runtimeexception (Unmarshalling Unknown Type Code) in Parcelable Class
Gradle Dsl Method Not Found: 'Runproguard'
How to Lock Orientation During Runtime
How to Set Default App Launcher Programmatically