Reputation: 43
The title already gives it away. I want to get a list of all restaurants in my area. Google Places limits "NearbySearch" requests to a maximum of 20 (60 with pagination). What approach would you guys use to get more than 60 results.
I'm currently thinking about something like this:
const searchRadius = 5000;
const center = { lat: 50.262, lng: 10.970 };
const step = 0.05;
const searches = [];
for (let latOffset = -0.2; latOffset <= 0.2; latOffset += step) {
for (let lngOffset = -0.2; lngOffset <= 0.2; lngOffset += step) {
searches.push({
location: { lat: center.lat + latOffset, lng: center.lng + lngOffset },
radius: searchRadius,
});
}
}
And then sort the request by distance with a very small radius. However, this feels kind of hacky. I know this topic has been discussed alot and there are a lot of other threads, but it has been years since the last post so I was wondering if there is maybe anything new. I couldn't find anything after hours of going through Googles Documentation and stackoverflow, but I thought I'd give it a shot.
Edit:
I wrote this code, which basically uses the grid approach I already posted, but I enhanced it a bit. I made it so that if the request actually returns more than the limit, the step is repeated but smaller.
async function fetchAllPages(dbConnection, params) {
let nextPageToken = null;
let totalResults = 0;
let anyInGermany = false;
do {
try {
if (nextPageToken) {
await new Promise((resolve) => setTimeout(resolve, 2000));
params.pagetoken = nextPageToken;
}
const response = await client.placesNearby({params});
const results = response.data.results;
totalResults += results.length;
for (const place of results) {
const details = await getPlaceDetails(place.place_id);
if (details && details.address.includes('Germany')) {
anyInGermany = true;
await saveToDatabase(dbConnection, details);
} else {
console.log(`Übersprungen (nicht in Deutschland): ${place.name}, ${details.address}`);
}
}
nextPageToken = response.data.next_page_token || null;
} catch (error) {
console.error(`Fehler beim Abrufen von Seiten:`, error.message);
nextPageToken = null;
}
} while (nextPageToken);
if(!anyInGermany)
await saveInvalidCoordinate(dbConnection, params.location.lat, params.location.lng)
return totalResults;
}
async function requestWithDynamicStep(dbConnection, lat, lng, step) {
let currentStep = step;
let totalResults = 0;
while (currentStep >= MIN_STEP) {
const coordKey = `${lat},${lng}`;
if (invalidCoordinatesCache.has(coordKey)) {
console.log(`Überspringe ungültige Koordinaten: ${lat}, ${lng}`);
return;
}
console.log(`Suche Orte bei Lat: ${lat}, Lng: ${lng}, Schrittweite: ${currentStep}...`);
const params = {
location: {lat, lng},
rankby: 'distance',
type: 'restaurant',
key: apiKey,
};
totalResults = await fetchAllPages(dbConnection, params);
if (totalResults >= MAX_RESULTS) {
console.log(`Limit erreicht (${totalResults} Treffer). Schrittweite verkleinern...`);
currentStep /= 2;
} else if (totalResults === 0) {
} else {
break;
}
}
if (currentStep < MIN_STEP) {
console.log(`Minimale Schrittweite erreicht bei Lat: ${lat}, Lng: ${lng}`);
}
}
async function searchPlacesAcrossGermany() {
const dbConnection = await mysql.createConnection(dbConfig);
await loadInvalidCoordinates(dbConnection);
for (let lat = GERMANY_BOUNDS.south; lat <= GERMANY_BOUNDS.north; lat += initialStep) {
for (let lng = GERMANY_BOUNDS.west; lng <= GERMANY_BOUNDS.east; lng += initialStep) {
await requestWithDynamicStep(dbConnection, lat, lng, initialStep);
}
}
await dbConnection.end();
console.log('Fertig mit der Suche und Speicherung!');
}
Upvotes: 1
Views: 81
Reputation: 4865
The Places APIs were never provided to get a list of all restaurants (or any other type of place) in my area (or anywhere). If you are interested, there is a feature request for this in https://issuetracker.google.com/35826799
However, in the meantime, Google did recently launch a new Places Insights API which may be a better (or good enough) fit for this or similar purposes.
Upvotes: 0