Gate Nama Sebelum Gambar di Grid Budaya
Foto Maps gampang diambil, susah dipertanggungjawabkan. Gate nama entitas, cek naturalWidth, dan dump sebelum perubahan massal.
Ringkasan
Grid budaya di portal budaya punya masalah. Kartunya kosong tanpa gambar. Saya ambil gambar dari Google Maps.
Grid /kebudayaan di portal budaya KotaPortal sudah lama punya masalah yang tidak kelihatan di API: judul ada, entitas ada, tapi separuh kartunya kosong tanpa gambar. Saya buka halaman itu di browser, hitung kartunya satu per satu, dan masalahnya murni pasokan gambar. Data entity sehat. Yang tidak ada hanya fotonya. Pemilik venue sebenarnya punya foto di Google Maps, jadi jalan tercepat terlihat jelas: buka halaman Maps mereka, ambil gambar hero pertama, unduh versi =w1200, simpan ke api/uploads/2026/10/26/budaya-<slug>.jpg, lalu isi kolom gambar. Satu sore, kira-kira begitu perkiraan saya.
Tebakan pertama meleset di nama, bukan di gambar
Perkiraan itu bertahan sampai saya mengerjakan task ini. Di tengah proses saya menemukan beberapa entitas budaya yang fotonya ternyata toko furniture di Jepara, interior sebuah mal, dan satu foto dari kota yang salah. Nama tempatnya mirip saat dicari, tapi halamannya jelas bukan entitas yang saya maksud. Kalau lolos, pembaca akan percaya pada grid yang rapi sambil menerima informasi yang salah tanpa pernah tahu.
Jadi gerbang pertama yang saya pasang bukan soal gambar, tapi soal identitas. Halaman Maps hanya boleh menyumbang foto kalau judul halamannya (h1) cocok dengan nama entitas di basis data. Terdengar kaku, tapi salah petakan jauh lebih mahal daripada kartu yang tetap kosong. Dari 12 entitas yang saya kerjakan, 7 lolos dan disimpan, 5 dikembalikan ke keadaan tanpa gambar karena tidak bisa diverifikasi: 415 Vadya, 416 Puspa Natya, 423 Mustika Jati, 500 Stasiun Citayam, dan 505 Barongsai. Satu di antaranya, entitas 601, tadinya salah kota dan berhasil dipulihkan lewat query ulang. Pada ronde ketiga Google mulai membatasi laju permintaan saya. Batas itu saya baca sebagai tanda untuk berhenti menebak.
Setelah lolos gerbang nama, pemeriksaan teknisnya cuma satu sinyal: naturalWidth === 0. Properti naturalWidth mengembalikan lebar intrinsik gambar dalam piksel [4], dan nilainya nol ketika data gambarnya tidak tersedia. Pemeriksaan itu harus dijalankan setelah event load atau error selesai, bukan saat gambar masih dimuat, kalau tidak gambar lambat akan salah dicap rusak. Thumbnail grid juga saya beri loading="lazy": sumber daya non-kritis ditunda sampai mendekati viewport [2], jadi 12 kartu tidak berarti 12 unduhan di detik pertama.
URL Google itu pipa, bukan gudang
Asumsi kedua yang runtuh: URL foto Google bersifat permanen. Kanal resminya sendiri menolak asumsi itu. photo_reference tidak boleh di-cache dan bisa kedaluwarsa [3]. Artinya URL foto Google adalah pipa tampilan, bukan penyimpanan.
Bagian yang paling jujur untuk diakui: menyimpan salinan lokal foto Maps berarti mengekstrak konten dari layanan mereka. Ketentuan penggunaan menyebutnya lugas, "Customer will not export, extract, or otherwise scrape Google Maps Content for use outside the Services" [1]. Google bahkan menyediakan sinyal visual soal asal foto: nama atau ikon atribusi membedakan foto milik Google dari foto kontributor eksternal [5]. Kebijakan konten kiriman pengguna bukan lisensi untuk memakai ulang. Praktisnya, foto hasil backfill seperti ini adalah jembatan darurat, bukan aset permanen. Gantinya bertahap dengan foto resmi dari pemilik venue lewat CMS, dan status lisensinya dicatat apa adanya di jurnal kerja.
Perubahan massal butuh rem
Mengisi belasan baris data dalam satu sesi adalah operasi massal, dan operasi massal tanpa rem hanya menunggu waktu menjadi cerita buruk. Saya pasang tiga lapis rem. Pertama, dump SQL sebelum eksekusi, 261026_pre-budaya-grid-photos_backup.sql, jalur rollback yang bisa dibaca manusia dan dipulihkan tanpa membaca log. Kedua, hitung ulang lewat API sesudahnya: 7 entitas membawa gambar, sisanya kembali ke keadaan tanpa gambar. Ketiga, verifikasi visual per kartu, memastikan nama di layar cocok dengan isi fotonya, satu per satu, bukan sekadar memastikan ada gambar.
Satu jebakan kecil yang hampir lolos: payload list API menaruh gambar di field thumbnail, bukan di field gambar utama. Konsumen API berikutnya yang mengira sebaliknya akan menggambar grid kosong, persis masalah yang memulai pekerjaan ini.
Foto pihak ketiga memang murah sampai salah satunya keliru. Gerbang validasi, nama dulu, gambar diperiksa setelah selesai dimuat, kembalikan kalau ragu, dump sebelum eksekusi massal, bukan upacara tambahan. Itu harga murah untuk grid yang bisa dipercaya, jauh lebih murah daripada satu pagi penuh menelusuri foto yang salah dari awal.
Sumber
- Google Maps Platform, Terms of Service, diakses 26 Oktober 2026.
- MDN Web Docs, Lazy loading, diakses 26 Oktober 2026.
- Google Maps Platform, Place Photos (Legacy), diakses 26 Oktober 2026.
- MDN Web Docs, HTMLImageElement.naturalWidth, diakses 26 Oktober 2026.
- Google Maps Platform, User Contributed Content Policy, diakses 26 Oktober 2026.