סיכומים מבוססי-AI

קוד מקור מלא לדוגמה

מחפשים מקומות כדי לראות את הסיכומים מבוססי ה-AI. הנה כמה הצעות לחיפוש:

  • "מלון" לסיכומים של שכונות.
  • "תחנת טעינה לרכב חשמלי" לסיכומי שירותים של EVCS.
  • כל מסעדה או עסק, כדי לקבל סיכומים של המקום ושל הביקורות.

TypeScript

// Define DOM elements.
const mapElement = document.querySelector('gmp-map')!;
const placeAutocomplete = document.querySelector('gmp-place-autocomplete')!;
const summaryPanel = document.getElementById('summary-panel')!;
const placeName = document.getElementById('place-name')!;
const placeAddress = document.getElementById('place-address')!;
const tabContainer = document.getElementById('tab-container')!;
const summaryContent = document.getElementById('summary-content')!;
const aiDisclosure = document.getElementById('ai-disclosure')!;
const flagContentLink = document.getElementById(
    'flag-content-link'
) as HTMLAnchorElement;

let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;

async function init(): Promise<void> {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

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

    // Bind autocomplete bounds to map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds()!;
    });

    // Create the marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    // Handle selection of an autocomplete result.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();

            // Fetch all summary fields.
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'generativeSummary',
                    'neighborhoodSummary',
                    'reviewSummary',
                    'evChargeAmenitySummary',
                ],
            });

            // Update the map viewport and position the marker.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location!);
                innerMap.setZoom(17);
            }
            marker.position = place.location;

            // Update the panel UI.
            updateSummaryPanel(place);
        }
    );
}

function updateSummaryPanel(place: google.maps.places.Place) {
    // Reset UI
    summaryPanel.classList.remove('hidden');
    tabContainer.innerHTML = ''; // innerHTML is OK here since we're clearing known child elements.
    summaryContent.textContent = '';
    aiDisclosure.textContent = '';

    placeName.textContent = place.displayName || '';
    placeAddress.textContent = place.formattedAddress || '';

    let firstTabActivated = false;

    /**
     * Safe Helper: Accepts either a text string or a DOM Node (like a div or DocumentFragment).
     */
    const createTab = (
        label: string,
        content: string | Node,
        disclosure: string | null,
        flagUrl: string | null
    ) => {
        const btn = document.createElement('button');
        btn.className = 'tab-button';
        btn.textContent = label;

        btn.onclick = () => {
            // Do nothing if the tab is already active.
            if (btn.classList.contains('active')) {
                return;
            }

            // Manage the active class state.
            document.querySelectorAll('.tab-button').forEach((b) => {
                b.classList.remove('active');
            });
            btn.classList.add('active');

            if (typeof content === 'string') {
                summaryContent.textContent = content;
            } else {
                summaryContent.replaceChildren(content.cloneNode(true));
            }

            // Set the disclosure text.
            aiDisclosure.textContent = disclosure || 'AI-generated content.';

            // Add the content flag URI.
            if (flagUrl) {
                flagContentLink.href = flagUrl;
                flagContentLink.textContent = 'Report an issue';
            }
        };

        tabContainer.appendChild(btn);

        // Auto-select the first available summary.
        if (!firstTabActivated) {
            btn.click();
            firstTabActivated = true;
        }
    };

    // --- 1. Generative Summary (Place) ---
    if (place.generativeSummary?.overview) {
        createTab(
            'Overview',
            place.generativeSummary.overview,
            place.generativeSummary.disclosureText,
            place.generativeSummary.flagContentURI
        );
    }

    // --- 2. Review Summary ---
    if (place.reviewSummary?.text) {
        createTab(
            'Reviews',
            place.reviewSummary.text,
            place.reviewSummary.disclosureText,
            place.reviewSummary.flagContentURI
        );
    }

    // --- 3. Neighborhood Summary ---
    if (place.neighborhoodSummary?.overview?.content) {
        createTab(
            'Neighborhood',
            place.neighborhoodSummary.overview.content,
            place.neighborhoodSummary.disclosureText,
            place.neighborhoodSummary.flagContentURI
        );
    }

    // --- 4. EV Amenity Summary (uses content blocks)) ---
    if (place.evChargeAmenitySummary) {
        const evSummary = place.evChargeAmenitySummary;
        const evContainer = document.createDocumentFragment();

        // Helper to build a safe DOM section for EV categories.
        const createSection = (title: string, text: string) => {
            const wrapper = document.createElement('div');
            wrapper.style.marginBottom = '15px'; // Or use a CSS class

            const titleEl = document.createElement('strong');
            titleEl.textContent = title;

            const textEl = document.createElement('div');
            textEl.textContent = text;

            wrapper.appendChild(titleEl);
            wrapper.appendChild(textEl);
            return wrapper;
        };

        // Check and append each potential section
        if (evSummary.overview?.content) {
            evContainer.appendChild(
                createSection('Overview', evSummary.overview.content)
            );
        }
        if (evSummary.coffee?.content) {
            evContainer.appendChild(
                createSection('Coffee', evSummary.coffee.content)
            );
        }
        if (evSummary.restaurant?.content) {
            evContainer.appendChild(
                createSection('Food', evSummary.restaurant.content)
            );
        }
        if (evSummary.store?.content) {
            evContainer.appendChild(
                createSection('Shopping', evSummary.store.content)
            );
        }

        // Only add the tab if the container has children
        if (evContainer.hasChildNodes()) {
            createTab(
                'EV Amenities',
                evContainer, // Passing a Node instead of string
                evSummary.disclosureText,
                evSummary.flagContentURI
            );
        }
    }

    // Safely handle the empty state.
    if (!firstTabActivated) {
        const msg = document.createElement('em');
        msg.textContent =
            'No AI summaries are available for this specific location.';
        summaryContent.replaceChildren(msg);
        aiDisclosure.textContent = '';
    }
}

void init();

JavaScript

// Define DOM elements.
const mapElement = document.querySelector('gmp-map');
const placeAutocomplete = document.querySelector('gmp-place-autocomplete');
const summaryPanel = document.getElementById('summary-panel');
const placeName = document.getElementById('place-name');
const placeAddress = document.getElementById('place-address');
const tabContainer = document.getElementById('tab-container');
const summaryContent = document.getElementById('summary-content');
const aiDisclosure = document.getElementById('ai-disclosure');
const flagContentLink = document.getElementById('flag-content-link');

let innerMap;
let marker;

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

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

    // Bind autocomplete bounds to map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });

    // Create the marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    // Handle selection of an autocomplete result.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();

            // Fetch all summary fields.
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'generativeSummary',
                    'neighborhoodSummary',
                    'reviewSummary',
                    'evChargeAmenitySummary',
                ],
            });

            // Update the map viewport and position the marker.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location);
                innerMap.setZoom(17);
            }
            marker.position = place.location;

            // Update the panel UI.
            updateSummaryPanel(place);
        }
    );
}

function updateSummaryPanel(place) {
    // Reset UI
    summaryPanel.classList.remove('hidden');
    tabContainer.innerHTML = ''; // innerHTML is OK here since we're clearing known child elements.
    summaryContent.textContent = '';
    aiDisclosure.textContent = '';

    placeName.textContent = place.displayName || '';
    placeAddress.textContent = place.formattedAddress || '';

    let firstTabActivated = false;

    /**
     * Safe Helper: Accepts either a text string or a DOM Node (like a div or DocumentFragment).
     */
    const createTab = (label, content, disclosure, flagUrl) => {
        const btn = document.createElement('button');
        btn.className = 'tab-button';
        btn.textContent = label;

        btn.onclick = () => {
            // Do nothing if the tab is already active.
            if (btn.classList.contains('active')) {
                return;
            }

            // Manage the active class state.
            document.querySelectorAll('.tab-button').forEach((b) => {
                b.classList.remove('active');
            });
            btn.classList.add('active');

            if (typeof content === 'string') {
                summaryContent.textContent = content;
            } else {
                summaryContent.replaceChildren(content.cloneNode(true));
            }

            // Set the disclosure text.
            aiDisclosure.textContent = disclosure || 'AI-generated content.';

            // Add the content flag URI.
            if (flagUrl) {
                flagContentLink.href = flagUrl;
                flagContentLink.textContent = 'Report an issue';
            }
        };

        tabContainer.appendChild(btn);

        // Auto-select the first available summary.
        if (!firstTabActivated) {
            btn.click();
            firstTabActivated = true;
        }
    };

    // --- 1. Generative Summary (Place) ---
    if (place.generativeSummary?.overview) {
        createTab(
            'Overview',
            place.generativeSummary.overview,
            place.generativeSummary.disclosureText,
            place.generativeSummary.flagContentURI
        );
    }

    // --- 2. Review Summary ---
    if (place.reviewSummary?.text) {
        createTab(
            'Reviews',
            place.reviewSummary.text,
            place.reviewSummary.disclosureText,
            place.reviewSummary.flagContentURI
        );
    }

    // --- 3. Neighborhood Summary ---
    if (place.neighborhoodSummary?.overview?.content) {
        createTab(
            'Neighborhood',
            place.neighborhoodSummary.overview.content,
            place.neighborhoodSummary.disclosureText,
            place.neighborhoodSummary.flagContentURI
        );
    }

    // --- 4. EV Amenity Summary (uses content blocks)) ---
    if (place.evChargeAmenitySummary) {
        const evSummary = place.evChargeAmenitySummary;
        const evContainer = document.createDocumentFragment();

        // Helper to build a safe DOM section for EV categories.
        const createSection = (title, text) => {
            const wrapper = document.createElement('div');
            wrapper.style.marginBottom = '15px'; // Or use a CSS class

            const titleEl = document.createElement('strong');
            titleEl.textContent = title;

            const textEl = document.createElement('div');
            textEl.textContent = text;

            wrapper.appendChild(titleEl);
            wrapper.appendChild(textEl);
            return wrapper;
        };

        // Check and append each potential section
        if (evSummary.overview?.content) {
            evContainer.appendChild(
                createSection('Overview', evSummary.overview.content)
            );
        }
        if (evSummary.coffee?.content) {
            evContainer.appendChild(
                createSection('Coffee', evSummary.coffee.content)
            );
        }
        if (evSummary.restaurant?.content) {
            evContainer.appendChild(
                createSection('Food', evSummary.restaurant.content)
            );
        }
        if (evSummary.store?.content) {
            evContainer.appendChild(
                createSection('Shopping', evSummary.store.content)
            );
        }

        // Only add the tab if the container has children
        if (evContainer.hasChildNodes()) {
            createTab(
                'EV Amenities',
                evContainer, // Passing a Node instead of string
                evSummary.disclosureText,
                evSummary.flagContentURI
            );
        }
    }

    // Safely handle the empty state.
    if (!firstTabActivated) {
        const msg = document.createElement('em');
        msg.textContent =
            'No AI summaries are available for this specific location.';
        summaryContent.replaceChildren(msg);
        aiDisclosure.textContent = '';
    }
}

void init();

CSS

/* Reuse existing map height */
gmp-map {
    height: 100%;
}

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

/* Existing Autocomplete Card Style */
.place-autocomplete-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 2px;
    font-family: Roboto, sans-serif;
    font-size: 1rem;
}

gmp-place-autocomplete {
    width: 330px;
}

/* New: Summary Panel Styles */
.summary-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 0; /* Padding handled by children */
    font-family: Roboto, sans-serif;
    width: 350px;
    max-height: 80vh; /* Prevent overflow on small screens */
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.hidden {
    display: none;
}

#place-header {
    padding: 15px;
    background-color: #f8f9fa;
    border-bottom: 1px solid #ddd;
}

#place-header h2 {
    margin: 0 0 5px 0;
    font-size: 1.2rem;
}

#place-address {
    margin: 0;
    color: #555;
    font-size: 0.9rem;
}

/* Tab Navigation */
.tab-container {
    display: flex;
    border-bottom: 1px solid #ddd;
    background-color: #fff;
}

.tab-button {
    flex: 1;
    background: none;
    border: none;
    padding: 10px;
    cursor: pointer;
    font-weight: 500;
    color: #555;
    border-bottom: 3px solid transparent;
}

.tab-button:hover {
    background-color: #f1f1f1;
}

.tab-button.active {
    font-weight: bold;
    border-bottom: 3px solid #000000;
}

.tab-button.active:hover {
    background-color: #ffffff;
    cursor: default;
}

/* Content Area */
.content-area {
    padding: 15px;
    line-height: 1.5;
    font-size: 0.95rem;
    color: #333;
}

.disclosure-footer {
    font-size: 0.75rem;
    color: #666;
    padding: 10px 15px;
    border-top: 1px solid #eee;
    font-style: italic;
}

.flag-content-link {
    font-size: 0.75rem;
    color: #666;
    padding: 10px 15px;
    border-top: 1px solid #eee;
}

HTML

<html>
    <head>
        <title>AI Place Summaries</title>
        <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: "GOOGLE_MAPS_API_KEY"
            });
        </script>
    </head>
    <body>
        <gmp-map center="37.80, -122.425" zoom="14" map-id="DEMO_MAP_ID">
            <!-- Search Input Card -->
            <div
                class="place-autocomplete-card"
                slot="control-inline-start-block-start">
                <gmp-place-autocomplete
                    placeholder="Find places with AI summaries"></gmp-place-autocomplete>
            </div>

            <!-- Summary text panel (initially hidden) -->
            <div
                id="summary-panel"
                class="summary-card hidden"
                slot="control-inline-end-block-start">
                <div id="place-header">
                    <h2 id="place-name"></h2>
                    <p id="place-address"></p>
                </div>

                <!-- Tabs for toggling summary types -->
                <div class="tab-container" id="tab-container"></div>

                <!-- Content display area -->
                <div id="summary-content" class="content-area"></div>

                <!-- Legal/AI Disclosure -->
                <div id="ai-disclosure" class="disclosure-footer"></div>

                <!-- Flag content link -->
                <a id="flag-content-link" class="flag-content-link"></a>
            </div>
        </gmp-map>
    </body>
</html>

סיכומים מבוססי-AI הם סקירות כלליות של מקום או אזור, שמספקות תובנות מועילות לגבי מקומות ספציפיים, האזור שסביב מקום מסוים וביקורות שקשורות למקום. יש שלושה סוגים שונים של סיכומים מבוססי-AI:

  • סיכום מקום: סקירה קצרה של 100 תווים שספציפית למזהה מקום נתון, שמשלבת סוגים רבים ושונים של נתונים לתמונת מצב כללית של מקום.

  • סיכום של ביקורות: סיכום שנוצר על מקום מסוים, שמבוסס רק על ביקורות של משתמשים.

  • סיכום האזור: סיכום שנוצר לגבי האזור שמסביב למקום, ומספק הקשר נוסף, כולל נקודות עניין בקרבת מקום. יש שני סוגים של סיכומי אזורים:

    • סיכום השכונה: סקירה כללית של נקודות עניין בקרבת מקום, למקומות מהסוגים premise, street_address וכל הסוגים בקטגוריות דיור ולינה.

    • סיכום השירותים של תחנת טעינה לרכב חשמלי: סקירה כללית של נקודות עניין בקרבת מקום למקומות מהסוג electric_vehicle_charging_station.

אחזור סיכומים מבוססי-AI

כדי לאחזר ולהציג סיכומים מבוססי-AI, פועלים לפי השלבים הבאים:

  1. טוענים את הספרייה Places.

    const { Place } = await google.maps.importLibrary("places");
  2. מקבלים מופע של Place. בקטע הקוד הבא אפשר לראות איך יוצרים מופע של Place ממזהה מקום:

    const place = new Place("ChIJaYaXFTqq3oARNy537Kb_W_c");
  3. בקריאה ל-place.fetchFields(), מציינים את השדות של סוגי הסיכומים שבהם רוצים להשתמש. בקטע הקוד הבא, כל שדות הסיכום נדרשים:

    await place.fetchFields({
      fields: [
        'generativeSummary',
        'neighborhoodSummary',
        'reviewSummary',
        'evChargeAmenitySummary'
        // Include other fields as needed.
      ]
    });
              
  4. אחזור נתוני הסיכום באמצעות גישה למאפיינים generativeSummary,‏ neighborhoodSummary,‏ reviewSummary ו-evChargeAmenitySummary, בהתאמה. בקטע הקוד הבא אפשר לראות איך מאחזרים את הסקירה הכללית מ-generativeSummary.

    const summaryText = place.generativeSummary.overview;
            

לא לכל המקומות יש סיכומים מבוססי-AI, לכן חשוב לבדוק אם הנתונים הדרושים קיימים לפני שמציגים אותם למשתמשים. בקטע הקוד הבא, משתמשים בהצהרת if כדי לבדוק אם יש generativeSummary:

if (place.generativeSummary) {
  overviewText = place.generativeSummary.overview;
} else {
  overviewText = 'No summary is available.';
}
    

אפשר גם להשתמש באופרטור nullish כדי לבדוק בקצרה אם יש סיכום:

const overviewText = place.generativeSummary.overview ?? 'No summary is available.';
    

הצגת השיוכים הנדרשים

כל הסיכומים מבוססי ה-AI שמוצגים באפליקציה חייבים לכלול שיוך מתאים בהתאם למדיניות ולסטנדרטים של Google. מידע נוסף זמין במאמר מדיניות וייחוסים ב-Maps JavaScript API.

תקצירי מקומות

סיכומי מקומות הם סקירות כלליות קצרות באורך 100 תווים שספציפיות למזהה מקום נתון, כדי לספק תמונת מצב ברמה גבוהה של מקום. סיכומי המקומות יכולים להדגיש מאכלים, שירותים או מוצרים פופולריים שאפשר לרכוש במיקום מסוים:

  • "מסעדה במרכז הקניות Forum Shops שמגישים בה מנות גדולות של אוכל איטלקי מסורתי באווירה נינוחה"

  • "מספרה אופנתית שמציעה תספורות, צביעת שיער ופן".

  • "חנות גדולה עם הרבה מוכרים שמציעים מגוון פריטי עיצוב, ריהוט ובגדים בסגנון וינטג'".

סיכומי מקומות זמינים לסוגי המקומות שמוצגים בקטע סוגים נתמכים בקטגוריות תרבות, בידור ופנאי, אוכל ושתייה, קניות, שירותים וספורט.

אפשר לקבל סיכומי מקומות על נקודות עניין בשפות ובאזורים הבאים:

שפה אזור
אנגלית

הודו

ארצות הברית

בקשת סיכום על מקום

כדי לבקש סיכום של מקום שנוצר על ידי AI, צריך לכלול את השדה generativeSummary כששולחים קריאה ל-fetchFields():

await place.fetchFields({
    fields: [
        'generativeSummary',
        // Include other fields as needed.
    ],
});
    

משתמשים במאפיין generativeSummary כדי לאחזר סיכומי מקומות. קטע הקוד הבא מאחזר את הסקירה הכללית ואת טקסט הגילוי הנאות מ-generativeSummary:

if (place.generativeSummary) {
    console.log("Place Overview:", place.generativeSummary.overview);
    console.log("Disclosure:", place.generativeSummary.disclosureText);
}
    

סיכומים של ביקורות

סיכומי הביקורות נוצרים על סמך ביקורות של משתמשים בלבד. הסיכומים של הביקורות משלבים אלמנטים מרכזיים של ביקורות משתמשים, כמו מאפייני מקומות וסנטימנט של כותבי הביקורות, כדי לספק תובנות ברמה גבוהה ולעזור למשתמשים לקבל החלטות מושכלות.

לדוגמה, סיכום של ביקורות על בניין המעבורת בסן פרנסיסקו כולל מידע על אוכל, קניות, נופים ואווירה:

"מבקרים אומרים שהאתר ההיסטורי הזה מציע מבחר מגוון של חנויות, מסעדות ושוק איכרים, ורבים משבחים את הנופים של המפרץ והעיר. הם גם מדגישים את האווירה התוססת, את הגישה הנוחה למעבורת ליעדים אחרים ואת ההזדמנות ליהנות מעסקים מקומיים".

סיכומים של ביקורות זמינים לנקודות עניין בשפות ובאזורים הבאים:

שפה אזור
אנגלית ארגנטינה, בוליביה, ברזיל, צ'ילה, קולומביה, קוסטה ריקה, הרפובליקה הדומיניקנית, אקוודור, גואטמלה, הודו, יפן, מקסיקו, פרגוואי, פרו, בריטניה, ארצות הברית, אורוגוואי, ונצואלה
יפנית יפן
פורטוגזית ברזיל
ספרדית ארגנטינה, בוליביה, צ'ילה, קולומביה, קוסטה ריקה, הרפובליקה הדומיניקנית, אקוודור, גואטמלה, מקסיקו, פרגוואי, פרו, ארצות הברית, אורוגוואי, ונצואלה

בקשת סיכום של ביקורות

כדי לבקש סיכום של ביקורות, צריך לכלול את השדה reviewSummary כששולחים קריאה ל-fetchFields():

await place.fetchFields({
    fields: [
        'reviewSummary',
        // Include other fields as needed.
    ],
});
  

משתמשים במאפיין reviewSummary כדי לאחזר סיכום של ביקורות. כדי לאחזר סיכומים של ביקורות, ניגשים למאפיין reviewSummary.text. קטע הקוד הבא מאחזר את הטקסט מ-reviewSummary.

if (place.reviewSummary) {
    console.log("Place Review Summary:", place.reviewSummary.text);
}
  

סיכומי אזורים

סיכומי האזור נוצרים עבור האזור שמסביב למקום. סיכומי אזורים מספקים הקשר נוסף למיקום, כולל נקודות עניין בקרבת מקום, כדי שהמשתמשים יוכלו לקבל החלטה מושכלת יותר לגבי המקום שאליו הם רוצים להגיע ומה לעשות כשהם מגיעים לשם. לדוגמה, כשמבקרים בעיר חדשה, אפשר לראות סיכום שנוצר על השכונה שבה נמצא המלון כדי לקבל מידע נוסף על האזור:

  • "האזור התוסס הזה בסן פרנסיסקו, שמשלב את נורת' ביץ' וצ'יינהטאון, נמצא מצפון-מערב לרובע הפיננסי וכולל אתרים ספרותיים, אטרקציות תרבותיות ייחודיות ומגוון מסעדות. בין המקומות הבולטים: חנות הספרים המפורסמת City Lights, מוזיאון הרכבל המרתק והרחובות ההומים של צ'יינהטאון".

אם אתם שוקלים לטעון רכב חשמלי, אתם יכולים לעיין בסיכום שנוצר לגבי תחנת טעינה לרכב חשמלי כדי לקבל מידע נוסף על האזור שמסביב:

  • "באזור הזה יש מגוון אפשרויות לסעודה במרחק של 9 דקות הליכה, כולל סטארבקס, סושי ג'ין וסייפוויי".

בנוסף לתיאור של האזור, התגובה מכילה גם רשימה של מופעי Place למקומות שמוזכרים בתיאור. צריך להפעיל את fetchFields() במופעי Place האלה כדי לבקש פרטים נוספים על כל מקום.

יש שני סוגים של סיכומי אזורים מבוססי-AI:

  • סיכום השכונה: סקירה כללית ברמה גבוהה של נקודות עניין בקרבת מקום, למקומות מהסוגים premise, street_address וכל הסוגים בקטגוריות דיור ולינה.

  • סיכום השירותים של תחנת טעינה לרכב חשמלי: סקירה כללית של נקודות עניין בקרבת מקומות מהסוג electric_vehicle_charging_station.

אפשר לקבל סיכומי אזורים לנקודות עניין בשפות ובאזורים הבאים:

שפה אזור
אנגלית ארצות הברית

בקשת סיכום של שכונה

אפשר לבקש סיכומים של שכונות למקומות מהסוגים premise, street_address וכל הסוגים בקטגוריות דיור ולינה. כדי לבקש סיכום של השכונה, צריך לכלול את השדה neighborhoodSummary כששולחים קריאה ל-fetchFields():

await place.fetchFields({
    fields: [
        'neighborhoodSummary',
        // Include other fields as needed.
    ],
});
  

משתמשים במאפיין neighborhoodSummary כדי לאחזר סיכומים של שכונות. כדי לאחזר סיכומים של שכונות, צריך לגשת למאפיין neighborhoodSummary.content כדי לקבל את הטקסט.

בקטע הקוד הבא אפשר לראות איך מאחזרים את התוכן של neighborhoodSummary:

if (place.neighborhoodSummary) {
    console.log("Place Neighborhood Summary:", place.neighborhoodSummary.overview.content);
}
  

בקשת סיכום של שירותי תחנת טעינה לרכב חשמלי

אפשר לבקש סיכומים של שירותי תחנות טעינה לרכב חשמלי במקומות מהסוג electric_vehicle_charging_station. הסיכום של שירותי תחנת הטעינה לרכב חשמלי מציע ארבעה סוגים של סיכומים: overview, ‏ coffee, ‏ restaurant ו-store. לכן, מבנה הנתונים הוא מערך של אובייקטים, שכל אחד מהם מכיל סיכום. כדי לבקש סיכום של שירותי תחנת הטעינה לרכב חשמלי, צריך לכלול את השדה evChargeAmenitySummary כששולחים קריאה ל-fetchFields():

await place.fetchFields({
    fields: [
        'evChargeAmenitySummary',
        // Include other fields as needed.
    ],
});
  

משתמשים במאפיין evChargeAmenitySummary כדי לאחזר סיכומים של שירותי תחנות טעינה לרכב חשמלי. כדי לאחזר טקסט מהסיכומים, צריך לגשת למאפיין content של המאפיינים evChargeAmenitySummary.overview,‏ evChargeAmenitySummary.coffee,‏ evChargeAmenitySummary.restaurant ו-evChargeAmenitySummary.store.

בקטע הקוד הבא אפשר לראות איך מאחזרים את התוכן של evChargeAmenitySummary:

// overview, coffee, restaurant, store.
if (place.evChargeAmenitySummary) {
    console.log("Place EVCS Amenity Summary:", place.evChargeAmenitySummary.overview.content);
    console.log("Coffee:", place.evChargeAmenitySummary.coffee.content);
    console.log("Restaurants:", place.evChargeAmenitySummary.restaurant.content);
    console.log("Stores:", place.evChargeAmenitySummary.store.content);
}