AI-powered summaries (simplified)

This sample demonstrates the use of AI-powered summaries in a simplified format; instead of an interactive UI, it shows the summary in an info window. To view summaries for different places, swap out the Place ID.

Read the documentation.

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap;
let infoWindow;

async function initMap() {
    const { Map, InfoWindow } = (await google.maps.importLibrary(
        'maps'
    )) as google.maps.MapsLibrary;

    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false
    });

    infoWindow = new InfoWindow();
    getPlaceDetails();
}

async function getPlaceDetails() {
    // Request needed libraries.
    const [ {AdvancedMarkerElement}, { Place } ] = await Promise.all([
        google.maps.importLibrary('marker') as Promise<google.maps.MarkerLibrary>,
        google.maps.importLibrary('places') as Promise<google.maps.PlacesLibrary>,
    ]);

    // Use place ID to create a new Place instance.
    const place = new Place({
        id: 'ChIJzzc-aWUM3IARPOQr9sA6vfY', // San Diego Botanic Garden
    });

    // Call fetchFields, passing the needed data fields.
    await place.fetchFields({
        fields: [
            'displayName',
            'formattedAddress',
            'location',
            'generativeSummary',
        ],
    });

    // Add an Advanced Marker
    const marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    });

    // Create a content container.
    const content = document.createElement('div');
    // Populate the container with data.
    const address = document.createElement('div');
    const summary = document.createElement('div');
    const lineBreak = document.createElement('br');
    const attribution = document.createElement('div');

    // Retrieve the textual data (summary, disclosure, flag URI).
    //@ts-ignore
    let overviewText = place.generativeSummary.overview ?? 'No summary is available.';
    //@ts-ignore
    let disclosureText = place.generativeSummary.disclosureText;
    //@ts-ignore
    let reportingUri = place.generativeSummary.flagContentURI;

    // Create HTML for reporting link.
    const reportingLink = document.createElement('a');
    reportingLink.href = reportingUri;
    reportingLink.target = '_blank';
    reportingLink.textContent = "Report a problem."

    // Add text to layout.
    address.textContent = place.formattedAddress ?? '';
    summary.textContent = overviewText;
    attribution.textContent = `${disclosureText}  `;
    attribution.appendChild(reportingLink);

    content.append(address, lineBreak, summary, lineBreak, attribution);

    innerMap.setCenter(place.location);

    // Handle marker click.
    marker.addListener('gmp-click', () => {
        showInfoWindow(marker, place, content);
    });

    // Display the info window at load time.
    showInfoWindow(marker, place, content);
}

function showInfoWindow(marker, place, content) {
    // Display an info window.
    infoWindow.setHeaderContent(place.displayName);
    infoWindow.setContent(content);
    infoWindow.open({
        anchor: marker,
    });
}

initMap();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
let infoWindow;
async function initMap() {
    const { Map, InfoWindow } = (await google.maps.importLibrary('maps'));
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false
    });
    infoWindow = new InfoWindow();
    getPlaceDetails();
}
async function getPlaceDetails() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }, { Place }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);
    // Use place ID to create a new Place instance.
    const place = new Place({
        id: 'ChIJzzc-aWUM3IARPOQr9sA6vfY', // San Diego Botanic Garden
    });
    // Call fetchFields, passing the needed data fields.
    await place.fetchFields({
        fields: [
            'displayName',
            'formattedAddress',
            'location',
            'generativeSummary',
        ],
    });
    // Add an Advanced Marker
    const marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    });
    // Create a content container.
    const content = document.createElement('div');
    // Populate the container with data.
    const address = document.createElement('div');
    const summary = document.createElement('div');
    const lineBreak = document.createElement('br');
    const attribution = document.createElement('div');
    // Retrieve the textual data (summary, disclosure, flag URI).
    //@ts-ignore
    let overviewText = place.generativeSummary.overview ?? 'No summary is available.';
    //@ts-ignore
    let disclosureText = place.generativeSummary.disclosureText;
    //@ts-ignore
    let reportingUri = place.generativeSummary.flagContentURI;
    // Create HTML for reporting link.
    const reportingLink = document.createElement('a');
    reportingLink.href = reportingUri;
    reportingLink.target = '_blank';
    reportingLink.textContent = "Report a problem.";
    // Add text to layout.
    address.textContent = place.formattedAddress ?? '';
    summary.textContent = overviewText;
    attribution.textContent = `${disclosureText}  `;
    attribution.appendChild(reportingLink);
    content.append(address, lineBreak, summary, lineBreak, attribution);
    innerMap.setCenter(place.location);
    // Handle marker click.
    marker.addListener('gmp-click', () => {
        showInfoWindow(marker, place, content);
    });
    // Display the info window at load time.
    showInfoWindow(marker, place, content);
}
function showInfoWindow(marker, place, content) {
    // Display an info window.
    infoWindow.setHeaderContent(place.displayName);
    infoWindow.setContent(content);
    infoWindow.open({
        anchor: marker,
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
    height: 100%;
}

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

HTML

<html>
    <head>
        <title>AI-powered Summaries Basic Sample</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>
        <gmp-map
            center="32.7360353,-117.1509849"
            zoom="14"
            map-id="DEMO_MAP_ID">
        </gmp-map>
    </body>
</html>

Try Sample

Clone Sample

Git and Node.js are required to run this sample locally. Follow these instructions to install Node.js and NPM. The following commands clone, install dependencies and start the sample application.

  git clone https://github.com/googlemaps-samples/js-api-samples.git
  cd samples/ai-powered-summaries-basic
  npm i
  npm start