Place Photos ti consente di aggiungere contenuti fotografici di alta qualità alle tue pagine web. Accedi a milioni di foto archiviate nel database di Places e ottieni immagini ridimensionabili utilizzando Trova luogo, Ricerca nelle vicinanze, Ricerca di testo, Completamento automatico e Dettagli luogo.
Visualizza il codice sorgente dell'esempio completo
Questa demo mostra una foto casuale di una delle cinque città e le attribuzioni dell'autore richieste nell'angolo in basso a destra della foto.
TypeScript
const CITIES = [ { name: 'New York', id: 'ChIJOwg_06VPwokRYv534QaPC8g' }, { name: 'London', id: 'ChIJdd4hrwug2EcRmSrV3Vo6llI' }, { name: 'Paris', id: 'ChIJD7fiBh9u5kcRYJSMaMOCCwQ' }, { name: 'Tokyo', id: 'ChIJ51cu8IcbXWARiRtXIothAS4' }, { name: 'Rome', id: 'ChIJu46S-ZZhLxMROG5lkwZ3D7k' }, ]; async function init() { const { Place } = await google.maps.importLibrary('places'); const heading = document.getElementById('heading')!; const summary = document.getElementById('summary')!; const expandedImageDiv = document.getElementById('expanded-image')!; const randomizeBtn = document.getElementById( 'randomize-btn' ) as HTMLButtonElement; async function showRandomCityPhoto() { randomizeBtn.disabled = true; // Pick a random city const city = CITIES[Math.floor(Math.random() * CITIES.length)]; try { const place = new Place({ id: city.id }); await place.fetchFields({ fields: ['displayName', 'photos', 'editorialSummary'], }); heading.textContent = place.displayName ?? city.name; summary.textContent = place.editorialSummary ?? ''; expandedImageDiv.innerHTML = ''; if (place.photos && place.photos.length > 0) { // Pick one of the first 10 photos const maxPhotos = Math.min(10, place.photos.length); const randomIndex = Math.floor(Math.random() * maxPhotos); const photo = place.photos[randomIndex]; const img = document.createElement('img'); img.alt = `Photo of ${place.displayName ?? city.name}`; img.src = photo.getURI({ maxHeight: 800 }); expandedImageDiv.appendChild(img); if (photo.authorAttributions.length) { expandedImageDiv.appendChild( createAttribution(photo.authorAttributions[0]) ); } } else { expandedImageDiv.textContent = 'No photos available for this location.'; } } catch (error) { console.error('Failed to fetch place details:', error); summary.textContent = 'Failed to load data.'; } // Re-enable button after 2 seconds setTimeout(() => { randomizeBtn.disabled = false; }, 2000); } // Helper function to create attribution DIV. function createAttribution( attribution: google.maps.places.AuthorAttribution ) { const attributionLabel = document.createElement('a'); attributionLabel.classList.add('attribution-label'); attributionLabel.textContent = attribution.displayName; attributionLabel.href = attribution.uri!; attributionLabel.target = '_blank'; attributionLabel.rel = 'noopener noreferrer'; return attributionLabel; } randomizeBtn.addEventListener('click', () => void showRandomCityPhoto()); // Initial load void showRandomCityPhoto(); } void init();
JavaScript
const CITIES = [ { name: 'New York', id: 'ChIJOwg_06VPwokRYv534QaPC8g' }, { name: 'London', id: 'ChIJdd4hrwug2EcRmSrV3Vo6llI' }, { name: 'Paris', id: 'ChIJD7fiBh9u5kcRYJSMaMOCCwQ' }, { name: 'Tokyo', id: 'ChIJ51cu8IcbXWARiRtXIothAS4' }, { name: 'Rome', id: 'ChIJu46S-ZZhLxMROG5lkwZ3D7k' }, ]; async function init() { const { Place } = await google.maps.importLibrary('places'); const heading = document.getElementById('heading'); const summary = document.getElementById('summary'); const expandedImageDiv = document.getElementById('expanded-image'); const randomizeBtn = document.getElementById('randomize-btn'); async function showRandomCityPhoto() { randomizeBtn.disabled = true; // Pick a random city const city = CITIES[Math.floor(Math.random() * CITIES.length)]; try { const place = new Place({ id: city.id }); await place.fetchFields({ fields: ['displayName', 'photos', 'editorialSummary'], }); heading.textContent = place.displayName ?? city.name; summary.textContent = place.editorialSummary ?? ''; expandedImageDiv.innerHTML = ''; if (place.photos && place.photos.length > 0) { // Pick one of the first 10 photos const maxPhotos = Math.min(10, place.photos.length); const randomIndex = Math.floor(Math.random() * maxPhotos); const photo = place.photos[randomIndex]; const img = document.createElement('img'); img.alt = `Photo of ${place.displayName ?? city.name}`; img.src = photo.getURI({ maxHeight: 800 }); expandedImageDiv.appendChild(img); if (photo.authorAttributions.length) { expandedImageDiv.appendChild( createAttribution(photo.authorAttributions[0]) ); } } else { expandedImageDiv.textContent = 'No photos available for this location.'; } } catch (error) { console.error('Failed to fetch place details:', error); summary.textContent = 'Failed to load data.'; } // Re-enable button after 2 seconds setTimeout(() => { randomizeBtn.disabled = false; }, 2000); } // Helper function to create attribution DIV. function createAttribution(attribution) { const attributionLabel = document.createElement('a'); attributionLabel.classList.add('attribution-label'); attributionLabel.textContent = attribution.displayName; attributionLabel.href = attribution.uri; attributionLabel.target = '_blank'; attributionLabel.rel = 'noopener noreferrer'; return attributionLabel; } randomizeBtn.addEventListener('click', () => void showRandomCityPhoto()); // Initial load void showRandomCityPhoto(); } void init();
CSS
/* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; font-family: 'Inter', sans-serif; background: linear-gradient(135deg, #1e1e2f, #252540); display: flex; align-items: center; justify-content: center; } #container { display: flex; background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 20px; padding: 30px; max-width: 900px; width: 100%; box-sizing: border-box; box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3); color: white; } .place-overview { flex: 1; display: flex; flex-direction: column; justify-content: center; margin-right: 40px; } #info { position: relative; } #heading { font-size: 2.5rem; font-weight: 700; margin-top: 0; margin-bottom: 15px; background: linear-gradient(90deg, #fff, #a5b4fc); -webkit-background-clip: text; -webkit-text-fill-color: transparent; } #summary { font-size: 1.1rem; line-height: 1.6; color: #cbd5e1; } #expanded-image { position: relative; width: 400px; height: 400px; border-radius: 16px; overflow: hidden; box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4); transform: perspective(1000px) rotateY(-5deg); transition: transform 0.5s ease; } #expanded-image:hover { transform: perspective(1000px) rotateY(0deg) scale(1.02); } #expanded-image img { width: 100%; height: 100%; object-fit: contain; } #randomize-btn { margin-top: 20px; padding: 12px 24px; font-size: 1.1rem; font-weight: bold; color: white; background: linear-gradient(90deg, #4f46e5, #3b82f6); border: none; border-radius: 12px; cursor: pointer; transition: transform 0.2s, background 0.3s; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); font-family: 'Inter', sans-serif; align-self: flex-start; } #randomize-btn:hover:not(:disabled) { transform: scale(1.05); } #randomize-btn:disabled { background: #475569; cursor: not-allowed; opacity: 0.7; } .attribution-label { position: absolute; bottom: 10px; right: 10px; background-color: rgba(0, 0, 0, 0.6); color: white; padding: 6px 12px; border-radius: 20px; font-size: 0.8rem; text-decoration: none; backdrop-filter: blur(4px); transition: background-color 0.3s; } .attribution-label:hover { background-color: rgba(0, 0, 0, 0.8); }
HTML
<html lang="en">
<head>
<title>Place Photos</title>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8"
});
</script>
</head>
<body>
<div id="container">
<div class="place-overview">
<div id="info">
<h1 id="heading"></h1>
<div id="summary"></div>
</div>
<button id="randomize-btn">Random City Photo</button>
</div>
<div id="expanded-image"></div>
</div>
</body>
</html>Prova campione
Scarica le foto
Per ottenere le foto di un luogo, includi il campo
photos
nei parametri della richiesta
fetchFields(). L'istanza Place risultante contiene un array di
fino a 10 oggetti Photo, da cui puoi accedere alle immagini e alle informazioni di attribuzione richieste.
Chiama getURI()
per restituire l'URI della foto sorgente, utilizzando
PhotoOptions
per impostare l'altezza e/o la larghezza massime dell'immagine restituita. Se specifichi un valore sia per
maxHeight sia per maxWidth, il servizio fotografico ridimensionerà l'immagine in base
alla più piccola delle due dimensioni, mantenendo le proporzioni originali. Se non viene specificata alcuna dimensione, verrà restituita l'immagine a grandezza naturale.
La classe Photo
espone le seguenti proprietà:
authorAttributions: un array di oggettiAuthorAttributioncontenenti il testo e gli URL di attribuzione richiesti.flagContentURI: un link in cui l'utente può segnalare un problema con la foto.googleMapsURI: un link per mostrare la foto su Google Maps.heightPx: l'altezza della foto in pixel.widthPx: la larghezza della foto in pixel.
L'esempio seguente mostra come effettuare una richiesta Place Details per le foto, chiamando getURI()
su un'istanza di foto per restituire l'URI di origine dell'immagine, quindi aggiungendo il primo risultato della foto a
un elemento img (le attribuzioni sono omesse per brevità):
const { Place } = await google.maps.importLibrary('places'); // Use a place ID to create a new Place instance. const place = new Place({ id: 'ChIJydSuSkkUkFQRsqhB-cEtYnw', // Woodland Park Zoo, Seattle WA }); // Call fetchFields, passing the desired data fields. await place.fetchFields({ fields: ['photos'] }); // Add the first photo to an img element. const photoImg = document.getElementById('image-container'); photoImg.src = place.photos[0].getURI({maxHeight: 400});
Attribuzioni degli autori
Quando visualizzi una foto, devi mostrare anche le attribuzioni dell'autore. Utilizza la classe
AuthorAttribution
per restituire le attribuzioni. Un'attribuzione include il nome dell'autore (displayName), un URI per il suo profilo Google Maps (uri) e un URI per la foto dell'autore (photoURI). Il seguente snippet mostra la restituzione di displayName, uri e photoURI per una foto del luogo.
let name = place.photos[0].authorAttributions[0].displayName; let url = place.photos[0].authorAttributions[0].uri; let authorPhoto = place.photos[0].authorAttributions[0].photoURI;