Using Google Places API

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 and inputUrl. 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.

sample output

Implement Google Places Api in Website

From the errors you are getting, it looks like you should:

  1. 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.
  2. 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,
Sample Image

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:

  1. Use use-places-autocomplete to provide place suggestion when searching for a place. This library have a GetGeocode and a GetLatLng that you can use to get the coordinates of the chosen place.
  2. 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.
  3. 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



Leave a reply



Submit