pub struct Client {
pub key: String,
pub rate_limit: RequestRate,
pub reqwest_client: Client,
}Expand description
Use the GoogleMapsClient struct’s implemented methods to set your Google
API key and other settings such as: rate limiting, maxium retries, &
retry delay times for your requests.
This structure contains your API key - the preferred way for authenticating with the Google Maps Platform APIs, your request rate limit settings, and your automatic retry settings.
How to use this structure’s methods in a builder pattern:
let mut my_settings = google_maps::Client::try_new(YOUR_GOOGLE_API_KEY_HERE)
.with_max_delay(std::time::Duration::from_secs(32))
.with_max_retries(10)
.with_rate(&Api::All, 1, std::time::Duration::from_secs(2))
.build();Fields§
§key: StringYour application’s API key. This key identifies your application for purposes of quota management. Learn how to get a key.
rate_limit: RequestRateRate limits for each of the Google Cloud Maps Platform APIs.
reqwest_client: ClientAllows you to optionally provide your own pre-configured reqwest client that will be used by the Google Maps client.
Implementations§
Source§impl Client
impl Client
Sourcepub fn new(key: impl Into<String>) -> Self
👎Deprecated since 3.4.2: use try_new instead
pub fn new(key: impl Into<String>) -> Self
try_new insteadInitialize the settings needed for a Google Cloud Maps API transaction.
§Arguments
key‧ Your application’s API key. This key identifies your application for purposes of quota management. Learn how to get a key.
§Panics
- This function will panic if the
reqwestclient builder chain fails. Realistically this shouldn’t happen. However you may want to usetry_newto instantiate a newGoogleMapsClientinstead.
Sourcepub fn directions(
&self,
origin: impl Into<Location>,
destination: impl Into<Location>,
) -> Request<'_>
pub fn directions( &self, origin: impl Into<Location>, destination: impl Into<Location>, ) -> Request<'_>
The Directions API is a service that calculates directions between locations. You can search for directions for several modes of transportation, including transit, driving, walking, or cycling.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let directions = google_maps_client.directions(
// Origin: Canadian Museum of Nature
Location::from_address("240 McLeod St, Ottawa, ON K2P 2R1"),
// Destination: Canada Science and Technology Museum
Location::try_from_f32(45.403_509, -75.618_904)?,
)Sourcepub fn distance_matrix<C, W>(&self, origins: C, destinations: C) -> Request<'_>
pub fn distance_matrix<C, W>(&self, origins: C, destinations: C) -> Request<'_>
The Distance Matrix API is a service that provides travel distance and time for a matrix of origins and destinations, based on the recommended route between start and end points.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let distances = google_maps_client.distance_matrix(
// Origins
vec![
// Microsoft
Waypoint::from_address("One Microsoft Way, Redmond, WA 98052, United States"),
// Cloudflare
Waypoint::from_address("101 Townsend St, San Francisco, CA 94107, United States"),
],
// Destinations
vec![
// Google
Waypoint::from_place_id("ChIJj61dQgK6j4AR4GeTYWZsKWw"),
// Mozilla
Waypoint::try_from_f32(37.387_316, -122.060_008)?,
],
)§Generics
This method uses generics to improve ergonomics. The C generic is
intended to represent any collection that can be iterated over, and the
W generic is for any type that can be converted to a Waypoint type.
Sourcepub const fn elevation(&self) -> Request<'_>
pub const fn elevation(&self) -> Request<'_>
The Elevation API provides elevation data for all locations on the surface of the earth, including depth locations on the ocean floor (which return negative values).
§Arguments
This method accepts no arguments, it initiates a builder pattern. Use the methods of the resulting type to set the parameters.
Sourcepub const fn geocoding(&self) -> ForwardRequest<'_>
pub const fn geocoding(&self) -> ForwardRequest<'_>
The Geocoding API is a service that provides geocoding and reverse geocoding of addresses. Geocoding is the process of converting addresses (like a street address) into geographic coordinates (like latitude and longitude), which you can use to place markers on a map, or position the map.
§Arguments
This method accepts no arguments, it initiates a builder pattern. Use the methods of the resulting type to set the parameters.
Sourcepub fn reverse_geocoding(
&self,
location: impl Into<LatLng>,
) -> ReverseRequest<'_>
pub fn reverse_geocoding( &self, location: impl Into<LatLng>, ) -> ReverseRequest<'_>
The Geocoding API is a service that provides geocoding and reverse geocoding of addresses. Reverse geocoding is the process of converting geographic coordinates into a human-readable address.
§Arguments
latlng‧ The latitude and longitude values specifying the location for which you wish to obtain the closest, human-readable address.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let address = google_maps_client.reverse_geocoding(
// 10 Downing St, Westminster, London
LatLng::try_from_dec(dec!(51.503_364), dec!(-0.127_625))?,
)Sourcepub fn time_zone(
&self,
location: impl Into<LatLng>,
timestamp: impl Into<DateTime<Utc>>,
) -> Request<'_>
pub fn time_zone( &self, location: impl Into<LatLng>, timestamp: impl Into<DateTime<Utc>>, ) -> Request<'_>
The Time Zone API provides time offset data for locations on the surface of the earth. You request the time zone information for a specific latitude/longitude pair and date. The API returns the name of that time zone, the time offset from UTC, and the daylight savings offset.
§Arguments
-
location‧ Latitude & longitude of the desired time zone location. -
timestamp‧ Time is used to determine if Daylight Savings is applicable.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let time_zone = google_maps_client.time_zone(
// St. Vitus Cathedral in Prague, Czechia
LatLng::try_from_dec(dec!(50.090_903), dec!(14.400_512))?,
// Tuesday February 23, 2020 @ 6:00:00 pm
NaiveDate::from_ymd_opt(2020, 2, 23)
.unwrap()
.and_hms_opt(18, 00, 0)
.unwrap()
.and_utc()
)Sourcepub fn snap_to_roads<C, L>(&self, path: C) -> Request<'_>
pub fn snap_to_roads<C, L>(&self, path: C) -> Request<'_>
The Roads API Snap To Roads service takes up to 100 GPS points collected along a route, and returns a similar set of data, with the points snapped to the most likely roads the vehicle was traveling along. Optionally, you can request that the points be interpolated, resulting in a path that smoothly follows the geometry of the road.
§Arguments
path‧ The path to be snapped. Note: The snapping algorithm works best for points that are not too far apart. If you observe odd snapping behavior, try creating paths that have points closer together. To ensure the best snap-to-road quality, you should aim to provide paths on which consecutive pairs of points are within 300m of each other. This will also help in handling any isolated, long jumps between consecutive points caused by GPS signal loss, or noise.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let snapped_points = google_maps_client.snap_to_roads(vec![
LatLng::try_from_dec(dec!(-35.27801), dec!(149.12958))?,
LatLng::try_from_dec(dec!(-35.28032), dec!(149.12907))?,
LatLng::try_from_dec(dec!(-35.28099), dec!(149.12929))?,
LatLng::try_from_dec(dec!(-35.28144), dec!(149.12984))?,
LatLng::try_from_dec(dec!(-35.28194), dec!(149.13003))?,
LatLng::try_from_dec(dec!(-35.28282), dec!(149.12956))?,
LatLng::try_from_dec(dec!(-35.28302), dec!(149.12881))?,
LatLng::try_from_dec(dec!(-35.28473), dec!(149.12836))?,
])
.with_interpolation(true)
.execute()
.await?;§Generics
This method uses generics to improve ergonomics. The C generic is
intended to represent any collection that can be iterated over, and the
L generic is for any type that can be converted to LatLng
coordinates.
Sourcepub fn nearest_roads<C, L>(&self, points: C) -> Request<'_>
pub fn nearest_roads<C, L>(&self, points: C) -> Request<'_>
The Roads API Nearest Roads service returns individual road segments for a given set of GPS coordinates. This services takes up to 100 GPS points and returns the closest road segment for each point. The points passed do not need to be part of a continuous path.
If you are working with sequential GPS points, use Nearest Roads.
§Arguments
points‧ The points to be snapped. The points parameter accepts a list of latitude/longitude pairs.
§Basic usage
use google_maps::prelude::*;
use rust_decimal_macros::dec;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let snapped_points = google_maps_client.nearest_roads(vec![
LatLng::try_from_dec(dec!(-35.27801), dec!(149.12958))?,
LatLng::try_from_dec(dec!(60.170880), dec!(24.942795))?,
LatLng::try_from_dec(dec!(60.170879), dec!(24.942796))?,
LatLng::try_from_dec(dec!(60.170877), dec!(24.942796))?,
]).execute().await?;§Generics
This method uses generics to improve ergonomics. The C generic is
intended to represent any collection that can be iterated over, and the
L generic is for any type that can be converted to LatLng
coordinates.
Sourcepub fn validate_address(&self) -> RequestBuilder<'_, SetClient>
pub fn validate_address(&self) -> RequestBuilder<'_, SetClient>
The Address Validation API Address Validation service validates an address and its components, standardize the address for mailing, and determine the best known geocode for it.
§Address Validation API coverage details
The Google Maps Platform team is constantly working to improve international coverage for our API services. The following list shows the latest coverage details, on a country-by-country basis, for the Address Validation API. Data quality can vary by country.
https://developers.google.com/maps/documentation/address-validation/coverage
§Basic usage
use google_maps::prelude::*;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
let postal_address = PostalAddress::builder()
.region_code("US")
.address_lines(vec![
"1600 Amphitheatre Pkwy",
"Mountain View, CA, 94043"
])
.build();
let address_validation_response = google_maps_client
.validate_address()
.address(postal_address)
.build()
.execute()
.await?;Sourcepub fn provide_validation_feedback(&self) -> RequestBuilder<'_, SetClient>
pub fn provide_validation_feedback(&self) -> RequestBuilder<'_, SetClient>
The Address Validation API Provide Validation Feedback service
feedback about the outcome of the sequence of validation attempts. This
should be the last call made after a sequence of validation calls for
the same address, and should be called once the transaction is
concluded. This should only be sent once for the sequence of
validate_address requests needed to validate an address fully.
§Basic usage
use google_maps::prelude::*;
let google_maps_client = Client::try_new("YOUR_GOOGLE_API_KEY_HERE");
google_maps_client
.provide_validation_feedback()
.conclusion(ValidationConclusion::Unused)
.response_id(address_validation_response.response_id())
.build()
.execute()
.await?;Source§impl Client
impl Client
Sourcepub fn with_rate(
&mut self,
api: &Api,
requests: u16,
per_duration: Duration,
) -> &mut Self
pub fn with_rate( &mut self, api: &Api, requests: u16, per_duration: Duration, ) -> &mut Self
Sets the rate limit for the specified API.
§Arguments
-
api‧ Which Google Maps API are you setting the rate limit for? For example,Api::Directions,Api::DistanceMatrix,Api::Elevation,Api::Geocoding,Api::TimeZone, and so on. TheApi::Allrate limit is applied to all Google Maps API requests in addition to the per-API rate limits. -
requests‧ The number of requests the client library is attempting to target. For example, 2 requests per 1 hour. -
duration‧ The duration for the targeted request rate. For example, 1 request per 1 minute. This can be defined using thestd::time::Durationmethods.
§Examples:
The following examples show how one might try to limit the request rate to achieve maximum throughput while minimizing charges by Google.
The following rates are subject to change by Google. Please review the current Google Maps Platform billing rates.
This Google client library’s rate limiting is not persistent. If your program is often restarted, it is easily possible to exceed Google’s monthly free credit. These are approximations and examples.
To accurately minimize billing charges by Google, please use the Google Cloud Platform Console IAM & admin to set quotas for each API on the server’s side.
You are responsible for all charges. Use with care.
// Assumptions:
// - $200.00 USD monthly free credit from Google. Thanks, guys!
// - 2,629,746 seconds in a month.
const GOOGLE_CREDIT: f64 = 200.0;
const SECONDS_PER_MONTH: u64 = 2_629_746;- Directions API. You are billed for this SKU when your request does not use live traffic information, arrival or departure times, < 10 waypoints, and no waypoint optimization, $0.005 USD per request.
with_rate(Api::Directions, (GOOGLE_CREDIT / 0.005) as u16, Duration::from_secs(SECONDS_PER_MONTH))- Directions Advanced API. You are billed for this SKU when your request requires live traffic information, > 10 waypoints, and/or waypoint optimization, $0.01 per request.
with_rate(Api::Directions, (GOOGLE_CREDIT / 0.01) as u16, Duration::from_secs(SECONDS_PER_MONTH))- Distance Matrix API. You are billed for this SKU when your requests do not require live traffic information, $0.005 per element. The below rate assumes an average of 10 elements per request.
with_rate(
Api::DistanceMatrix,
(GOOGLE_CREDIT / (0.005 * 10.0)) as u16,
Duration::from_secs(SECONDS_PER_MONTH)
)- Distance Matrix Advanced API. You are billed for this SKU when your requests require live traffic information, $0.01 USD per element. The below rate assumes an average of 10 elements per request.
with_rate(
Api::DistanceMatrix,
(GOOGLE_CREDIT / (0.01 * 10.0)) as u16,
Duration::from_secs(SECONDS_PER_MONTH)
)- Elevation API. $0.005 USD per request.
with_rate(Api::Elevation, (GOOGLE_CREDIT / 0.005) as u16, Duration::from_secs(SECONDS_PER_MONTH))- Geocoding API. $0.005 USD per request.
with_rate(Api::Geocoding, (GOOGLE_CREDIT / 0.005) as u16, Duration::from_secs(SECONDS_PER_MONTH))- Time Zone API. $0.005 USD per request.
with_rate(Api::TimeZone, (GOOGLE_CREDIT / 0.005) as u16, Duration::from_secs(SECONDS_PER_MONTH))Source§impl Client
impl Client
Sourcepub fn autocomplete(
&self,
input: impl Into<String>,
) -> RequestWithClientBuilder<'_, SetInput<SetClient>>
pub fn autocomplete( &self, input: impl Into<String>, ) -> RequestWithClientBuilder<'_, SetInput<SetClient>>
The Places API Place Autocomplete service returns place predictions.
Autocomplete (New) is a web service that returns place predictions and query predictions in response to an HTTP request. In the request, specify a text search string and geographic bounds that controls the search area.
Autocomplete (New) can match on full words and substrings of the input, resolving place names, addresses, and plus codes. Applications can therefore send queries as the user types, to provide on-the-fly place and query predictions.
The response from Autocomplete (New) can contain two types of predictions:
-
Place predictions: Places, such as businesses, addresses and points of interest, based on the specified input text string and search area. Place predictions are returned by default.
-
Query predictions: Query strings matching the input text string and search area. Query predictions are not returned by default. Use the
.include_query_predictions(true)request parameter to add query predictions to the response.
For example, you call Autocomplete (New) using as input a string that contains a partial user input, “Sicilian piz”, with the search area limited to San Francisco, CA. The response then contains a list of place predictions that match the search string and search area, such as the restaurant named “Sicilian Pizza Kitchen”, along with details about the place.
The returned place predictions are designed to be presented to the user to aid them in selecting the intended place. You can make a Place Details (New) request to get more information about any of the returned place predictions.
The response can also contain a list of query predictions that match the search string and search area, such as “Sicilian Pizza & Pasta”. Each query prediction in the response includes the text field containing a recommended text search string. Use that string as an input to Text Search (New) to perform a more detailed search.
The APIs Explorer lets you make live requests so that you can get familiar with the API and the API options: https://developers.google.com/maps/documentation/places/web-service/place-autocomplete#try_it
§Arguments
input· The text string on which to search.
§Examples
use google_maps::places_new::PlaceType;
let google_maps_client = google_maps::Client::try_new("YOUR_API_KEY_HERE")?;
// Start a new autocomplete session
let response = google_maps_client
.autocomplete("pizza")
.included_primary_types(vec![PlaceType::Restaurant])
.execute()
.await?;
// Display suggestions with HTML highlighting
for suggestion in &response.suggestions {
println!("{}", suggestion.to_html("mark"));
}
// Output:
// <mark>Pizza</mark> By The Bay, Marine Drive, Churchgate, Mumbai, Maharashtra, India
// <mark>Pizza</mark> 4P's Indiranagar, 12th Main Road, HAL 2nd Stage, Bengaluru, Karnataka, India
// <mark>Pizza</mark> Culture Napoletana, Edmonton Trail, Calgary, AB, Canada
Sourcepub async fn next_autocomplete(
&self,
input: impl Into<String>,
previous: ResponseWithContext,
) -> Result<ResponseWithContext, Error>
pub async fn next_autocomplete( &self, input: impl Into<String>, previous: ResponseWithContext, ) -> Result<ResponseWithContext, Error>
Continue a Place Autocomplete session with new input.
Reuses the session token and all other parameters from the previous response, only updating the input text. This maintains session continuity for Google’s billing model and ensures consistent relevance scoring across the autocomplete interaction.
This method immediately executes the request with the preserved parameters. If you need to
modify parameters before the next request, update the ResponseWithContext first:
§Arguments
input· The new text string on which to search.previous· The previous response context containing the session state to continue.
§Examples
use google_maps::places_new::PlaceType;
let google_maps_client = google_maps::Client::try_new("YOUR_API_KEY_HERE")?;
// Initial autocomplete request
let response = google_maps_client
.autocomplete("pizza")
.included_primary_types(vec![PlaceType::Restaurant])
.execute()
.await?;
for suggestion in &response.suggestions {
println!("{}", suggestion.to_html("mark"));
}
// Output:
// <mark>Pizza</mark> By The Bay, Marine Drive, Churchgate, Mumbai, Maharashtra, India
// <mark>Pizza</mark> 4P's Indiranagar, 12th Main Road, HAL 2nd Stage, Bengaluru, Karnataka, India
// Continue the session as the user types more
let response = google_maps_client
.next_autocomplete("pizza sicilian", response)
.await?;
for suggestion in &response.suggestions {
println!("{}", suggestion.to_html("b"));
}
// Output:
// <b>Pizza Sicilian</b>a, Rue Sully Prudhomme, Châtillon, France
// <b>Pizza Sicilian</b>a, 6a Avenida, Puerto Barrios, Guatemala
// <b>Pizza Sicilian</b>a 762, Chiquimula, Guatemala
Source§impl Client
impl Client
Sourcepub fn nearby_search<L>(
&self,
location_restriction: L,
) -> Result<RequestWithClientBuilder<'_, SetLocationRestriction<SetClient>>, Error>
pub fn nearby_search<L>( &self, location_restriction: L, ) -> Result<RequestWithClientBuilder<'_, SetLocationRestriction<SetClient>>, Error>
Searches for places within a geographic area.
The Google Maps Places API Nearby Search (New) service finds places within a specified circular area, optionally filtered by place type.
Unlike Text Search which uses text queries, Nearby Search focuses purely on location-based discovery - perfect for “what’s nearby” functionality or finding specific types of places within a radius.
Results can be ranked by distance (closest first) or popularity (most relevant first). This endpoint does not support pagination - the maximum 20 results per request is a hard limit.
Use field masking to control which place data is returned and manage API costs, as you’re charged based on the fields requested. Different field groups trigger different pricing SKUs (Pro, Enterprise, Enterprise + Atmosphere).
§Location Restriction
The location must be specified as a circle (center point + radius). You can provide this as:
- A 3-tuple:
(latitude, longitude, radius_meters) - A
Circlestruct - A
LocationRestriction::Circleenum variant
Note: Nearby Search only supports circular search areas. Rectangle/viewport restrictions will fail validation.
§Examples
Basic nearby search using tuple syntax:
use google_maps::places_new::{Field, PlaceType};
// Find restaurants within 5km of San Francisco
let response = google_maps_client
.nearby_search((37.7749, -122.4194, 5000.0))?
.field_mask([
Field::PlacesDisplayName,
Field::PlacesFormattedAddress,
Field::PlacesRating,
])
.included_primary_types(vec![PlaceType::Restaurant])
.execute()
.await?;
for place in &response {
if let Some(name) = place.display_text() {
println!("Found: {}", name);
}
}Rank by distance to find the closest places:
use google_maps::places_new::{Field, RankPreference};
let response = google_maps_client
.nearby_search((40.7128, -74.0060, 2000.0))?
.field_mask([Field::PlacesDisplayName, Field::PlacesLocation])
.rank_preference(RankPreference::Distance)
.execute()
.await?;
println!("Closest {} places:", response.len());Filter by multiple types and exclude specific types:
use google_maps::places_new::{Field, PlaceType};
// Find schools but exclude primary schools
let response = google_maps_client
.nearby_search((35.6762, 139.6503, 3000.0))?
.field_mask([Field::PlacesDisplayName, Field::PlacesPrimaryType])
.included_types(vec![PlaceType::School])
.excluded_types(vec![PlaceType::PrimarySchool])
.max_result_count(10)
.execute()
.await?;Using an explicit Circle for more control:
use google_maps::places_new::{Circle, LatLng, Field};
use rust_decimal_macros::dec;
let center = LatLng::try_from_dec(dec!(51.5074), dec!(-0.1278))?;
let circle = Circle::try_new(center, dec!(1000.0))?;
let response = google_maps_client
.nearby_search(circle)?
.field_mask([Field::PlacesDisplayName])
.execute()
.await?;Source§impl Client
impl Client
Sourcepub fn place_details(
&self,
place_id: impl Into<String>,
) -> Result<RequestBuilder<'_, SetPlaceId<SetClient>>, Error>
pub fn place_details( &self, place_id: impl Into<String>, ) -> Result<RequestBuilder<'_, SetPlaceId<SetClient>>, Error>
Once you have a place ID, you can request more details about a particular establishment or point of interest by initiating a Place Details (New) request.
A Place Details (New) request returns more comprehensive information about the indicated place such as its complete address, phone number, user rating and reviews.
There are many ways to obtain a place ID. You can use:
- Text Search (New) or Nearby Search (New)
- Geocoding API
- Routes API
- Address Validation API
- Autocomplete (New)
Source§impl Client
impl Client
Sourcepub fn place_photos_image<P>(
&self,
photo_request: P,
) -> Result<RequestBuilder<'_, SetSkipHttpRedirect<SetPhotoRequest<SetClient>>>, Error>
pub fn place_photos_image<P>( &self, photo_request: P, ) -> Result<RequestBuilder<'_, SetSkipHttpRedirect<SetPhotoRequest<SetClient>>>, Error>
Downloads a place photo’s image bytes directly from Google’s servers.
The Google Maps Places Place Photos (New) API can return the actual image file rather than
just a URL. This method accepts various input types - photo names, PhotoInfo structs, or
entire Place objects - and returns a builder for configuring size constraints.
Unlike place_photos_uri() which returns a temporary URL, this method returns the actual
image bytes immediately. Use this when you need the image data right away for processing, or
displaying.
You must specify at least one dimension (max_width_px or max_height_px) to control the
image size. Google scales the image while maintaining aspect ratio.
§What You Get Back
Returns a PhotoImage containing:
- The actual image file bytes (JPEG, PNG, or WebP format)
- Photo metadata (dimensions, attributions, links) if provided
- Helper methods for format detection, size display, and orientation
§When to Use This vs place_photos_uri()
Use place_photos_image() when:
- You’re processing the image (resizing, filtering, etc.)
- You want to cache the actual image data
- You need offline access to the image
Use place_photos_uri() when:
- You just need a URL for an
<img>tag - You’re passing the URL to a frontend/mobile app
- You want the client to handle the download
- You need multiple sizes of the same photo
§Input Types Accepted
- Photo name strings -
"places/ChIJ.../photos/ABC"- When you just have the name PhotoInforeferences -&photo_info- Preserves all metadata (dimensions, attributions)Placereferences -&place- Automatically uses the first photo from the place
§Examples
Download and save images for furtherance & display from nearby search:
// Find nearby restaurants and download their photos
let places = client.nearby_search((37.7749, -122.4194, 5000.0))?
.field_mask(FieldMask::specific([Field::PlacesPhotos, Field::PlacesDisplayName]))
.included_primary_types(vec![PlaceType::Restaurant])
.execute()
.await?;
for place in places {
// Download the actual image bytes
let photo = client.place_photos_image(&place)?
.max_width_px(1024)
.execute()
.await?;
// Save to disk
let filename = format!("{}.jpg", place.display_text().unwrap());
std::fs::write(&filename, photo.bytes())?;
println!("Saved {} ({} bytes)", filename, photo.size_bytes());
}Process the image bytes:
let photo = client.place_photos_image(&place)?
.max_width_px(1024)
.execute()
.await?;
// Use with image processing library
let img = image::load_from_memory(&photo)?;
let thumbnail = img.thumbnail(200, 200);
thumbnail.save("thumbnail.jpg")?;
// Or just access the bytes directly
let bytes: &[u8] = &photo; // Via Deref
let bytes: &[u8] = photo.as_ref(); // Via AsRefFrom a photo name string:
// When you just have the name from storage or cache
let photo = client.place_photos_image("places/ChIJ.../photos/ABC")?
.max_width_px(400)
.execute()
.await?;
std::fs::write("photo.jpg", &photo)?;§Dimension Constraints
You must specify at least one dimension:
// Width only - height scales proportionally
.max_width_px(800)
// Height only - width scales proportionally
.max_height_px(600)
// Both - scales to fit within box, maintaining aspect ratio
.max_width_px(800)
.max_height_px(600)Valid range: 1-4800 pixels.
§Important Notes
-
Photo names expire - Always get fresh photo names from recent Place Details, Nearby Search, or Text Search responses. Never cache or hardcode photo names.
-
Field mask required - When fetching places, include
photosin your field mask or you won’t get any photo data. -
Bandwidth usage - This downloads the full image immediately. For large images or many photos, consider using
place_photos_uri()instead to get URLs that clients can download on-demand.
§Errors
Returns an error if:
- The place has no photos (when passing a
Place) - The photo name is invalid or expired
- Dimension constraints are missing or out of range (1-4800)
- Network request fails
- API returns an error response
Source§impl Client
impl Client
Sourcepub fn place_photos_uri<P>(
&self,
photo_request: P,
) -> Result<RequestBuilder<'_, SetSkipHttpRedirect<SetPhotoRequest<SetClient>>>, Error>
pub fn place_photos_uri<P>( &self, photo_request: P, ) -> Result<RequestBuilder<'_, SetSkipHttpRedirect<SetPhotoRequest<SetClient>>>, Error>
Fetches a photo URI from Google’s servers.
The Google Maps Places Place Photos (New) API returns a temporary URL where you can access
a place photo. This method accepts various input types - photo names, PhotoInfo structs,
or entire Place objects - and returns a builder for configuring size constraints.
You must specify at least one dimension (max_width_px or max_height_px) to control the
image size. Google scales the image while maintaining aspect ratio.
§What You Get Back
Returns a PhotoUri containing:
- The temporary photo URL (short-lived, fetch promptly)
- Photo metadata (dimensions, attributions, links)
- Helper methods for HTML generation and image downloading
§Input Types Accepted
- Photo name strings -
"places/ChIJ.../photos/ABC"- When you just have the name PhotoInforeferences -&photo_info- Preserves all metadata (dimensions, attributions)Placereferences -&place- Automatically uses the first photo from the place
§Examples
From a nearby search result:
// Find nearby restaurants and get their first photo
let places = client.nearby_search((37.7749, -122.4194, 5000.0))?
.field_mask(FieldMask::specific([Field::PlacesPhotos, Field::PlacesDisplayName]))
.included_primary_types(vec![PlaceType::Restaurant])
.execute()
.await?;
for place in places {
// Pass the entire place - automatically uses first photo
let photo_uri = client.place_photos_uri(&place)?
.max_width_px(1024)
.execute()
.await?;
println!("{}: {}", place.display_text().unwrap(), photo_uri);
}From a specific PhotoInfo:
// Get place details with photos
let place = client.place_details("ChIJ...")?
.field_mask([Field::PlacesPhotos])
.execute()
.await?;
// Pick a specific photo (not just the first)
if let Some(photo_info) = place.photos().get(2) {
let photo_uri = client.place_photos_uri(photo_info)?
.max_width_px(800)
.max_height_px(600)
.execute()
.await?;
// Metadata is preserved!
println!("Dimensions: {:?}", photo_uri.dimension_description());
println!("By: {:?}", photo_uri.author_attributions());
}From a photo name string:
// When you just have the name from storage or cache
let photo_uri = client.place_photos_uri("places/ChIJ.../photos/ABC")?
.max_width_px(400)
.execute()
.await?;Download the actual image:
let photo_uri = client.place_photos_uri(&place)?
.max_width_px(1024)
.execute()
.await?;
// Download the image bytes
let image_bytes = photo_uri.download_image(&client).await?;
std::fs::write("restaurant.jpg", &image_bytes)?;Generate HTML:
let photo_uri = client.place_photos_uri(&photo_info)?
.max_width_px(800)
.execute()
.await?;
// Create an <img> tag
let html = photo_uri.to_html_img();
// Or a <figure> with attribution caption
let html = photo_uri.to_html_figure();§Dimension Constraints
You must specify at least one dimension:
// Width only - height scales proportionally
.max_width_px(800)
// Height only - width scales proportionally
.max_height_px(600)
// Both - scales to fit within box, maintaining aspect ratio
.max_width_px(800)
.max_height_px(600)Valid range: 1-4800 pixels.
§Important Notes
-
Photo URIs are temporary - They may expire or become rate-limited. Fetch and cache the image data itself, not the URI.
-
Photo names expire too - Always get fresh photo names from recent Place Details, Nearby Search, or Text Search responses. Never cache or hardcode photo names.
-
Field mask required - When fetching places, include
photosin your field mask or you won’t get any photo data.
§Errors
Returns an error if:
- The place has no photos (when passing a
Place) - The photo name is invalid or expired
- Dimension constraints are missing or out of range (1-4800)
- Network request fails
- API returns an error response
§See Also
- [
PhotoUri] - The returned type with helper methods - [
PhotoInfo] - Photo metadata from place responses PhotoRequest- The intermediate request type
Source§impl Client
impl Client
Sourcepub fn text_search(
&self,
text_query: impl Into<String>,
) -> RequestWithClientBuilder<'_, SetTextQuery<SetClient>>
pub fn text_search( &self, text_query: impl Into<String>, ) -> RequestWithClientBuilder<'_, SetTextQuery<SetClient>>
Searches for places based on a text query string.
The Google Maps Places API Text Search (New) service finds places matching a natural language query like “pizza in New York”, “shoe stores near Ottawa”, or specific addresses like “123 Main Street”. This is the most flexible search method, accepting free-form text that can include business names, place types, addresses, or combinations of location and query terms.
Text search supports optional location biasing to prioritize results near a specific area, though the query itself can override this with explicit location references. Results are ranked by relevance to the query text, considering factors like prominence, distance (when location context exists), and how well the place matches the search terms.
Use field masking to control which place data is returned and manage API costs, as you’re
charged based on the fields requested. The response may include a next_page_token for
pagination when more than 20 results are available.
§Examples
Basic text search with specific fields:
use google_maps::places_new::Field;
let response = google_maps_client
.text_search("Spicy Vegetarian Food in Nairobi Kenya")
.field_mask([
Field::PlacesId,
Field::PlacesName,
Field::PlacesDisplayName,
Field::PlacesFormattedAddress,
Field::PlacesGoogleMapsUri,
Field::NextPageToken,
])
.execute()
.await?;
for place in &response.places {
if let Some(name) = place.display_text() {
println!("Found: {}", name);
}
}Search with location biasing:
use google_maps::LatLng;
use google_maps::places_new::{Field, LocationBias};
let response = google_maps_client
.text_search("coffee shops")
.location_bias(LocationBias::circle(
LatLng::try_from_dec(40.7128, -74.0060)?,
2000.0, // 2km radius
))
.field_mask([Field::PlacesDisplayName, Field::PlacesLocation])
.execute()
.await?;Handling pagination:
use google_maps::places_new::Field;
// First page
let response = google_maps_client
.text_search("restaurants in Tokyo")
.field_mask([
Field::PlacesDisplayName,
Field::PlacesRating,
Field::NextPageToken,
])
.execute()
.await?;
println!("Page 1: {} results", response.places.len());
// Get next page if available
if response.has_next_page() {
let next_response = google_maps_client
.next_text_search(response)
.await?;
println!("Page 2: {} results", next_response.places.len());
}Sourcepub async fn next_text_search(
&self,
previous: ResponseWithContext,
) -> Result<ResponseWithContext, Error>
pub async fn next_text_search( &self, previous: ResponseWithContext, ) -> Result<ResponseWithContext, Error>
Retrieves the next page of results from a previous text search.
When a text search returns more than 20 results, Google provides a next_page_token in the
response to retrieve additional results. This method handles pagination by extracting the
token from a previous response and executing a new request with the same search parameters.
The next page request automatically preserves all original search parameters (query, field
mask, location bias, restrictions, etc.) from the initial search. Each page can contain up
to 20 places, and you can continue calling this method as long as the response includes
another next_page_token.
Note that page tokens expire after a short time (typically a few minutes), so pagination should be done in a timely manner. The total number of pages available may be limited by Google’s API even when more results theoretically exist.
§Examples
Collecting all available pages:
use google_maps::places_new::Field;
let mut all_places = Vec::new();
// Get first page
let mut response = google_maps_client
.text_search("hotels in Paris")
.field_mask([
Field::PlacesDisplayName,
Field::PlacesRating,
Field::NextPageToken,
])
.execute()
.await?;
all_places.extend(response.places.clone());
// Get remaining pages
while response.has_next_page() {
response = google_maps_client.next_text_search(response).await?;
all_places.extend(response.places.clone());
}
println!("Found {} total places", all_places.len());§Errors
Returns an error if:
- The page token has expired
- Network connectivity issues occur
- The API returns an error response
- The previous response didn’t contain a
next_page_token
Sourcepub async fn collect_all_text_search_pages(
&self,
initial_response: ResponseWithContext,
) -> Result<Vec<Place>, Error>
pub async fn collect_all_text_search_pages( &self, initial_response: ResponseWithContext, ) -> Result<Vec<Place>, Error>
Collects all remaining pages from a text search into a single vector.
This is a convenience method that automatically handles pagination, collecting all places from the initial response and all subsequent pages into a single vector. Useful when you need the complete result set without manually managing the pagination loop.
The method will continue fetching pages until no next_page_token is available or until
Google’s API stops returning more results. Each page is fetched sequentially to avoid
overwhelming the API.
Note that collecting all pages may take significant time for queries with many results and
will consume API quota for each page fetched. Consider using manual pagination with
next_text_search() if you need more control over the fetching process or want to process
results as they arrive.
§Examples
Collecting all results at once:
use google_maps::places_new::Field;
// Get first page
let response = google_maps_client
.text_search("coffee shops in Seattle")
.field_mask([
Field::PlacesDisplayName,
Field::PlacesLocation,
Field::NextPageToken,
])
.execute()
.await?;
// Collect all remaining pages
let all_places = google_maps_client
.collect_all_text_search_pages(response)
.await?;
println!("Found {} total places", all_places.len());Processing with progress updates:
use google_maps::places_new::Field;
let mut response = google_maps_client
.text_search("restaurants in Tokyo")
.field_mask([Field::PlacesDisplayName, Field::NextPageToken])
.execute()
.await?;
let first_page_count = response.places.len();
println!("Page 1: {} results", first_page_count);
let all_places = google_maps_client
.collect_all_text_search_pages(response)
.await?;
println!("Total: {} results across all pages", all_places.len());§Errors
Returns an error if:
- Any page request fails due to network issues
- The API returns an error response for any page
- A page token expires during collection (pagination should be timely)