Place Photos

Entwickler im Europäischen Wirtschaftsraum (EWR)

Mit der Funktion „Place Photos“ können Sie qualitativ hochwertige Fotos auf Ihren Webseiten einbinden. Sie können auf Millionen von Fotos in der Places-Datenbank zugreifen und mit „Find Place“, „Nearby Search“, „Text Search“, „Autocomplete“ und „Place Details“ Bilder in beliebiger Größe abrufen.

Vollständigen Quellcode des Beispiels ansehen

Dieses rudimentäre Fotokarussell zeigt Fotos für den angegebenen Ort, einschließlich der erforderlichen Quellenangaben (oben links auf dem ausgewählten Foto).

TypeScript

async function init() {
    const { Place } = (await google.maps.importLibrary(
        'places'
    )) as google.maps.PlacesLibrary;

    // 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: ['displayName', 'photos', 'editorialSummary'],
    });

    // Get the various HTML elements.
    const heading = document.getElementById('heading') as HTMLElement;
    const summary = document.getElementById('summary') as HTMLElement;
    const gallery = document.getElementById('gallery') as HTMLElement;
    const expandedImageDiv = document.getElementById(
        'expanded-image'
    ) as HTMLElement;

    // Show the display name and summary for the place.
    heading.textContent = place.displayName as string;
    summary.textContent = place.editorialSummary as string;

    // Add photos to the gallery.
    place.photos?.forEach((photo) => {
        const altText = 'Photo of ' + place.displayName;
        const img = document.createElement('img');
        const imgButton = document.createElement('button');
        const expandedImage = document.createElement('img');
        img.src = photo?.getURI({ maxHeight: 380 });
        img.alt = altText;
        imgButton.addEventListener('click', (event) => {
            centerSelectedThumbnail(imgButton);
            event.preventDefault();
            expandedImage.src = img.src;
            expandedImage.alt = altText;
            expandedImageDiv.innerHTML = '';
            expandedImageDiv.appendChild(expandedImage);
            const attributionLabel = createAttribution(
                photo.authorAttributions[0]
            )!;
            expandedImageDiv.appendChild(attributionLabel);
        });

        imgButton.addEventListener('focus', () => {
            centerSelectedThumbnail(imgButton);
        });

        imgButton.appendChild(img);
        gallery.appendChild(imgButton);
    });

    // Display the first photo.
    if (place.photos && place.photos.length > 0) {
        const photo = place.photos[0];
        const img = document.createElement('img');
        img.alt = 'Photo of ' + place.displayName;
        img.src = photo.getURI();
        expandedImageDiv.appendChild(img);

        if (photo.authorAttributions && photo.authorAttributions.length > 0) {
            expandedImageDiv.appendChild(
                createAttribution(photo.authorAttributions[0])
            );
        }
    }

    // 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;
    }

    // Helper function to center the selected thumbnail in the gallery.
    function centerSelectedThumbnail(element: HTMLElement) {
        element.scrollIntoView({
            behavior: 'smooth',
            block: 'center',
            inline: 'center',
        });
    }
}

init();

JavaScript

async function init() {
    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: ['displayName', 'photos', 'editorialSummary'],
    });
    // Get the various HTML elements.
    const heading = document.getElementById('heading');
    const summary = document.getElementById('summary');
    const gallery = document.getElementById('gallery');
    const expandedImageDiv = document.getElementById('expanded-image');
    // Show the display name and summary for the place.
    heading.textContent = place.displayName;
    summary.textContent = place.editorialSummary;
    // Add photos to the gallery.
    place.photos?.forEach((photo) => {
        const altText = 'Photo of ' + place.displayName;
        const img = document.createElement('img');
        const imgButton = document.createElement('button');
        const expandedImage = document.createElement('img');
        img.src = photo?.getURI({ maxHeight: 380 });
        img.alt = altText;
        imgButton.addEventListener('click', (event) => {
            centerSelectedThumbnail(imgButton);
            event.preventDefault();
            expandedImage.src = img.src;
            expandedImage.alt = altText;
            expandedImageDiv.innerHTML = '';
            expandedImageDiv.appendChild(expandedImage);
            const attributionLabel = createAttribution(photo.authorAttributions[0]);
            expandedImageDiv.appendChild(attributionLabel);
        });
        imgButton.addEventListener('focus', () => {
            centerSelectedThumbnail(imgButton);
        });
        imgButton.appendChild(img);
        gallery.appendChild(imgButton);
    });
    // Display the first photo.
    if (place.photos && place.photos.length > 0) {
        const photo = place.photos[0];
        const img = document.createElement('img');
        img.alt = 'Photo of ' + place.displayName;
        img.src = photo.getURI();
        expandedImageDiv.appendChild(img);
        if (photo.authorAttributions && photo.authorAttributions.length > 0) {
            expandedImageDiv.appendChild(createAttribution(photo.authorAttributions[0]));
        }
    }
    // 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;
    }
    // Helper function to center the selected thumbnail in the gallery.
    function centerSelectedThumbnail(element) {
        element.scrollIntoView({
            behavior: 'smooth',
            block: 'center',
            inline: 'center',
        });
    }
}
init();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#container {
    display: flex;
    border: 2px solid black;
    border-radius: 10px;
    padding: 10px;
    max-width: 950px;
    height: 100%;
    max-height: 400px;
    box-sizing: border-box;
}

.place-overview {
    width: 400px;
    height: 380px;
    overflow-x: auto;
    position: relative;
    margin-right: 20px;
}

#info {
    font-family: sans-serif;
    position: sticky;
    position: -webkit-sticky;
    left: 0;
    padding-bottom: 10px;
}

#heading {
    width: 500px;
    font-size: x-large;
    margin-bottom: 20px;
}

#summary {
    width: 100%;
}

#gallery {
    display: flex;
    padding-top: 10px;
}

#gallery img {
    width: 200px;
    height: 200px;
    margin: 10px;
    border-radius: 10px;
    cursor: pointer;
    object-fit: cover; /* fill the area without distorting the image */
}

#expanded-image {
    display: flex;
    height: 370px;
    overflow: hidden;
    background-color: #000;
    border-radius: 10px;
    margin: 0 auto;
}

.attribution-label {
    background-color: rgba(255, 255, 255, 0.7);
    font-size: 10px;
    font-family: sans-serif;
    margin: 2px;
    position: absolute;
}

button {
    display: flex;
    outline: none;
    border: none;
    padding: 0;
    background: none;
    cursor: pointer;
}

button:focus {
    border: 2px solid blue;
    border-radius: 10px;
}

HTML

<html lang="en">
    <head>
        <title>Place Photos</title>

        <link rel="stylesheet" type="text/css" href="./style.css" />
        <script type="module" src="./index.js"></script>
        <!-- prettier-ignore -->
        <script>(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", v: "weekly" });</script>
    </head>
    <body>
        <div id="container">
            <div class="place-overview">
                <div id="info">
                    <h1 id="heading"></h1>
                    <div id="summary"></div>
                </div>
                <div id="gallery"></div>
            </div>
            <div id="expanded-image"></div>
        </div>
    </body>
</html>

Testbeispiel

Fotos herunterladen

Wenn Sie Fotos für einen Ort abrufen möchten, fügen Sie das Feld photos in die Anfrageparameter fetchFields() ein. Die resultierende Place-Instanz enthält ein Array mit bis zu 10 Photo-Objekten, über die Sie auf Bilder und die erforderlichen Quellenangaben zugreifen können. Rufen Sie getURI() auf, um den Quellfoto-URI zurückzugeben. Verwenden Sie PhotoOptions, um die maximale Höhe und/oder Breite des zurückgegebenen Bildes festzulegen. Wenn Sie sowohl für maxHeight als auch für maxWidth einen Wert angeben, wird das Bild vom Fotodienst auf die kleinere der beiden Größen skaliert, wobei das ursprüngliche Seitenverhältnis beibehalten wird. Wenn keine Dimension angegeben ist, wird das Bild in voller Größe zurückgegeben.

Die Klasse Photo stellt die folgenden Eigenschaften bereit:

  • authorAttributions: Ein Array von AuthorAttribution-Objekten mit dem erforderlichen Zuordnungstext und den erforderlichen URLs.
  • flagContentURI: Ein Link, über den der Nutzer ein Problem mit dem Foto melden kann.
  • googleMapsURI: Ein Link, um das Foto in Google Maps zu sehen.
  • heightPx: Die Höhe des Fotos in Pixeln.
  • widthPx: Die Breite des Fotos in Pixeln.

Im folgenden Beispiel wird eine Place Details-Anfrage für Fotos gestellt, getURI() für eine Fotoinstanz aufgerufen, um den Quell-URI für das Bild zurückzugeben, und das erste Fotoergebnis wird einem img-Element hinzugefügt (die Quellenangaben werden aus Gründen der Übersichtlichkeit weggelassen):

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});

Autorenangaben

Wenn Sie ein Foto anzeigen, müssen Sie auch die Autorenangabe für das Foto anzeigen. Verwenden Sie die Klasse AuthorAttribution, um Attributions zurückzugeben. Eine Quellenangabe enthält den Namen des Autors (displayName), einen URI für sein Google Maps-Profil (uri) und einen URI für das Foto des Autors (photoURI). Im folgenden Snippet sehen Sie, wie displayName, uri und photoURI für ein Ortsfoto zurückgegeben werden.

  let name = place.photos[0].authorAttributions[0].displayName;
  let url = place.photos[0].authorAttributions[0].uri;
  let authorPhoto = place.photos[0].authorAttributions[0].photoURI;