Why?

I like data and cannot lie

Summary

Objective: Find new cafes around Montreal to try out

Problem statement: Finding cafes randomly can be tedious, and blog sites often repeat known cafes.

Solution: Using Google Place API with a modern data stack to fetch and filter out cafes to an updating list of cafes based on Google Reviews and recent review activity to find trending places.

Tools Used

Google Sheet, App Script, BigQuery, Google Place API, ChatGPT/Gemini, Cloudflare

MVP

To validate that my idea would work, I started with what I know best: Google Sheets and Apps Script. I had to create a new API Key within my GCP with access to the Google Place API, plus a few geo functions as I needed to determine the latitude and longitude for my search.

API challenges

Google Place API has two important restrictions that made it hard to search for all cafes in the city.

  • Limit of 60 results per API call
  • Limit of 5 reviews per place

Initially, I focused API calls on individual neighborhoods using text search. Even then, some areas were too large. Switching to Forward Sortation Area (first 3 characters of postal codes) with custom radius helped stay under limits, producing ~650 cafes. Downtown dense areas required multiple smaller grids (250m radius) and deduplication downstream.

For reviews, since only 5 per place were accessible, I fetch daily snapshots to accumulate data over time. This helps track trending places by short-term review spikes.

Map Grid Coverage

To visualize the search grid coverage, I plotted existing data with lat/long and search radius.

Map Grid Visualization

Billing challenges

Accidentally exceeded the free tier twice while testing, requiring minor payments and a Google billing adjustment. Switching from Google Maps to Leaflet reduced billing risk while retaining visualization capabilities.

Data Flow

Below is the data architecture representation for the data sync pipelines:

Data Diagram

The Open Data Evolution: Leaving Google Places for OpenStreetMap

While the initial prototype relied on the Google Places API, maintaining a proprietary commercial API pipeline for community discovery presented severe architectural compromises:

  • Aggressive Billing & Complex SKUs: Google's Atmosphere data SKU (ratings and review volume) carried significant recurring cost risks without adding curated value.
  • Arbitrary Query Caps: Google's API returned a maximum of 20 to 60 places per query radius, necessitating fragile grid workarounds and deduplication logic.
  • Commercial Bias & Tracking: Proprietary place APIs favor promoted venues, enforce tracking SDKs, and prohibit permanent caching or data ownership.

The Solution: 100% Community-Driven OpenStreetMap

We rebuilt the entire catalog on community-sourced, verified OpenStreetMap data across Montreal Island:

  • 648 Independent Spots: Directly mapped from OSM nodes and ways across 41 Montreal neighbourhoods, vetted to exclude global corporate fast-food chains.
  • Zero API Calls or Tracking: No billable Google Places API requests, zero tracking scripts, and zero rate-limiting choke points.
  • Open Mapping with CARTO Voyager: High-performance, clean vector/raster tiles powered by OSM contributors rendered seamlessly via Leaflet.
  • Editorial Focus: In place of volatile star ratings, we focus on what truly matters to coffee enthusiasts: neighbourhood context, verified operating hours, micro-roastery status, outdoor terraces, and guest Wi-Fi.

Pourquoi ?

J'aime les données et je ne peux pas mentir

Résumé

Objectif : Trouver de nouveaux cafés à essayer autour de Montréal

Problématique : Trouver des cafés au hasard peut être factidieux, et les blogs répètent souvent les mêmes adresses connues.

Solution : Utiliser l'API Google Places avec une pile de données moderne pour récupérer et filtrer les cafés afin d'obtenir une liste mise à jour basée sur les avis Google et l'activité récente des avis pour trouver les endroits tendance.

Outils utilisés

Google Sheet, App Script, BigQuery, Google Place API, ChatGPT/Gemini, Cloudflare

MVP (Produit minimum viable)

Pour valider le fonctionnement de mon idée, j'ai commencé avec ce que je connais le mieux : Google Sheets et Apps Script. J'ai dû créer une nouvelle clé API dans mon GCP avec accès à l'API Google Places, ainsi que quelques fonctions géographiques car je devais déterminer la latitude et la longitude pour ma recherche.

Défis de l'API

L'API Google Places comporte deux restrictions importantes qui ont rendu difficile la recherche de tous les cafés de la ville.

  • Limite de 60 résultats par appel API
  • Limite de 5 avis par établissement

Initialement, j'ai ciblé les appels API sur des quartiers individuels à l'aide de la recherche textuelle. Même à ce moment-là, certaines zones étaient trop grandes. Passer à la RTA (région de tri d'acheminement - 3 premiers caractères des codes postaux) avec un rayon personnalisé a permis de rester sous les limites, produisant environ 650 cafés. Les zones denses du centre-ville ont nécessité plusieurs grilles plus petites (rayon de 250m) et une déduplication en aval.

Pour les avis, comme seulement 5 par lieu étaient accessibles, je récupère des instantanés quotidiens pour accumuler des données au fil du temps. Cela aide à suivre les endroits tendance grâce aux pics d'avis à court terme.

Couverture de la grille cartographique

Pour visualiser la couverture de la grille de recherche, j'ai tracé les données existantes avec la latitude/longitude et le rayon de recherche.

Map Grid Visualization

Défis de facturation

J'ai accidentellement dépassé la tranche gratuite à deux reprises lors des tests, ce qui a nécessité des paiements mineurs et un ajustement de facturation Google. Passer de Google Maps à Leaflet a réduit le risque de facturation tout en conservant les capacités de visualisation.

Flux de données

Ci-dessous se trouve la représentation de l'architecture des données pour les pipelines de synchronisation :

Data Diagram

L'évolution vers les données ouvertes : De Google Places à OpenStreetMap

Bien que le prototype initial reposait sur l'API Google Places, maintenir un pipeline commercial propriétaire pour un guide communautaire posait de lourds compromis d'architecture :

  • Risque de facturation et SKUs coûteux : La tarification des données d'ambiance (notes et volume d'avis) représentait des coûts récurrents sans réelle valeur ajoutée pour les cafés de quartier.
  • Plafonds arbitraires : L'API limitait les retours à 20-60 résultats par rayon de recherche, imposant des découpages en grille fragiles et de la déduplication complexe.
  • Biais commercial et pistage : Les APIs propriétaires favorisent les chaînes payantes, imposent des traceurs publicitaires et interdisent la conservation pérenne des données.

La solution : OpenStreetMap, 100 % ouvert et communautaire

Nous avons entièrement reconstruit le répertoire à partir des données ouvertes d'OpenStreetMap sur l'ensemble de l'île de Montréal :

  • 648 cafés indépendants : Extraits directement des nœuds et chemins OSM à travers 41 quartiers montréalais, filtrés pour exclure les grandes chaînes industrielles.
  • Zéro appel API et aucun pistage : Plus aucune requête payante Google Places, aucun traceur tiers et aucune limite d'utilisation.
  • Cartographie libre avec CARTO Voyager : Des tuiles cartographiques fluides et élégantes propulsées par la communauté OSM via Leaflet.
  • Approche éditoriale : Plutôt que des notes en étoiles fluctuantes, nous privilégions les caractéristiques essentielles : quartier, horaires vérifiés, torréfaction artisanale, terrasses et accès Wi-Fi.
API Request Type Free Tier Paid Pricing (After Free Tier)
Basic Data (Nearby/Text Search) ✅ 1000 free requests per month $7 per 1000 requests
Atmosphere Data (rating, user_ratings_total) ❌ No free tier $14 per 1000 requests
Place Details (Basic Info) ✅ 1000 free requests per month $17 per 1000 requests
Place Details (Premium: Website, Phone) ❌ No free tier $34 per 1000 requests
Type de requête API Tranche gratuite Tarification payante (après tranche gratuite)
Données de base (Recherche à proximité/textuelle) ✅ 1000 requêtes gratuites par mois 7 $ par 1000 requêtes
Données d'ambiance (note, nombre total d'avis) ❌ Aucune tranche gratuite 14 $ par 1000 requêtes
Détails du lieu (Infos de base) ✅ 1000 requêtes gratuites par mois 17 $ par 1000 requêtes
Détails du lieu (Premium : site Web, téléphone) ❌ Aucune tranche gratuite 34 $ par 1000 requêtes

Note: Google has updated the Places API abilities and pricing, and each search point is now limited to 20 results instead of 60. I'm working on refining the search pattern to ensure full coverage of Montreal cafes while staying within API limits.

Remarque : Google a mis à jour les fonctionnalités et la tarification de l'API Places, et chaque point de recherche est désormais limité à 20 résultats au lieu de 60. Je travaille à affiner le modèle de recherche pour assurer une couverture complète des cafés montréalais tout en restant dans les limites de l'API.