การค้นพบสถานที่ด้วย PlaceSearchElement

วัตถุประสงค์

ดูวิธีผสานรวม PlaceSearchElement กับ Google Maps เพื่อช่วยให้ผู้ใช้ค้นหาสถานที่โดยใช้การค้นหาในบริเวณใกล้เคียงหรือการค้นหาข้อความ ซึ่งจะช่วยเพิ่มความสามารถในการสำรวจจุดที่น่าสนใจ ใช้องค์ประกอบรายละเอียดสถานที่แบบกะทัดรัดเพื่อแสดงรายละเอียดเพิ่มเติมเกี่ยวกับสถานที่ที่แสดงในแอปพลิเคชัน

PlaceSearchElement คืออะไร

PlaceSearchElement เป็นส่วนหนึ่งของ Places UI Kit ใน Maps JavaScript API ซึ่งเป็นองค์ประกอบ HTML ที่แสดงผลการค้นหาสถานที่โดยตรงในรูปแบบรายการภายในแอปพลิเคชัน องค์ประกอบนี้ช่วยลดความซับซ้อนของกระบวนการแสดงสถานที่ที่พบโดยใช้การค้นหาในบริเวณใกล้เคียงหรือการค้นหาข้อความ เพื่อมอบประสบการณ์การใช้งานที่ราบรื่นแก่ผู้ใช้ในการค้นหาสถานที่ เมื่อผู้ใช้เลือกสถานที่จากรายการ คุณสามารถแสดงรายละเอียดของสถานที่นั้นบนแผนที่ โดยมักจะใช้หน้าต่างข้อมูลและองค์ประกอบรายละเอียดสถานที่

แสดงภาพการค้นพบสถานที่

รูปภาพต่อไปนี้แสดงตัวอย่างการทำงานของ PlaceSearchElement ทางด้านซ้าย รายชื่อร้านอาหารจะแสดงขึ้น (PlaceSearchElement) เมื่อเลือกร้านอาหาร รายละเอียดจะปรากฏในหน้าต่างข้อมูลบนแผนที่ และแผนที่จะจัดให้อยู่กึ่งกลางตำแหน่งของร้านอาหาร

รูปภาพ

กรณีการใช้งานสำหรับการสำรวจสถานที่

การผสานรวม PlaceSearchElement จะช่วยปรับปรุงแอปพลิเคชันต่างๆ ในอุตสาหกรรมที่หลากหลายได้ ดังนี้

  • การเดินทางและการท่องเที่ยว: ช่วยให้นักท่องเที่ยวค้นหาสถานที่ท่องเที่ยว โรงแรม หรืออาหารประเภทที่ต้องการในพื้นที่ได้
  • อสังหาริมทรัพย์: ช่วยให้ผู้มีโอกาสเป็นผู้ซื้อหรือผู้เช่าค้นหาโรงเรียน ซูเปอร์มาร์เก็ต หรือตัวเลือกขนส่งมวลชนที่อยู่ใกล้เคียงได้
  • โลจิสติกส์และบริการ: ช่วยผู้ขับขี่ค้นหาสถานีชาร์จ EV ปั๊มน้ำมัน หรือศูนย์บริการที่เฉพาะเจาะจง

เวิร์กโฟลว์ของโซลูชัน: การใช้การสำรวจสถานที่

ส่วนนี้จะแนะนำการผสานรวม PlaceSearchElement เพื่อค้นหาสถานที่บนแผนที่ และมีข้อมูลโค้ดสำหรับการโต้ตอบกับ Places UI Kit ดูวิธีเริ่มต้นแผนที่และใช้ทั้งการค้นหาในบริเวณใกล้เคียงและการค้นหาข้อความ สุดท้าย ให้ใช้องค์ประกอบรายละเอียดสถานที่เพื่อแสดงรายละเอียดเพิ่มเติมเกี่ยวกับสถานที่เมื่อผู้ใช้คลิกหมุดบนแผนที่

ข้อกำหนดเบื้องต้น

เราขอแนะนำให้คุณทำความคุ้นเคยกับเอกสารประกอบต่อไปนี้

เปิดใช้ Maps JavaScript API และ Places UI Kit ในโปรเจ็กต์

ตรวจสอบว่าคุณได้โหลด Maps JavaScript API และนำเข้าไลบรารีที่จำเป็นก่อนเริ่มต้นใช้งาน เอกสารนี้ยังถือว่าคุณมีความรู้ด้านการพัฒนาเว็บ ซึ่งรวมถึง HTML, CSS และ JavaScript ด้วย

เพิ่มแผนที่ลงในหน้าเว็บ

ขั้นตอนแรกคือการเพิ่มแผนที่ลงในหน้าเว็บ แผนที่นี้จะใช้เพื่อแสดงผลลัพธ์ PlaceSearchElement เป็นหมุดที่เลือกได้

คุณเพิ่มแผนที่ลงในหน้าเว็บได้ 2 วิธีดังนี้

  1. การใช้คอมโพเนนต์เว็บ HTML gmp-map
  2. การใช้ JavaScript

ข้อมูลโค้ดในหน้านี้สร้างขึ้นโดยใช้แมป JavaScript

แผนที่สามารถจัดให้อยู่กึ่งกลางในตำแหน่งที่คุณต้องการให้ผู้ใช้ค้นหาบริเวณรอบๆ เช่น โรงแรม หรือเริ่มต้นเพื่อขอตำแหน่งปัจจุบันของผู้ใช้เพื่อจัดแผนที่ให้อยู่กึ่งกลาง สำหรับวัตถุประสงค์ของเอกสารนี้ เราจะใช้ตำแหน่งคงที่เพื่อยึดการค้นหา

หากคุณกำลังแสดงภาพสถานที่ใกล้เคียงกับสถานที่ที่แน่นอน เช่น โรงแรม ให้วางเครื่องหมายบนแผนที่เพื่อแสดงสถานที่นี้ เช่น

รูปภาพ

แผนที่อยู่ตรงกลางของซานฟรานซิสโก โดยมีหมุดสีน้ำเงินแสดงสถานที่ที่เรากำลังค้นหาในบริเวณใกล้เคียง มีการปรับแต่งสีหมุดโดยใช้ PinElement การควบคุมประเภทแผนที่ถูกซ่อนจาก UI

ตั้งค่า PlaceSearchElement

ตอนนี้ ให้ตั้งค่า HTML และ CSS เพื่อแสดง PlaceSearchElement ตัวอย่างนี้จะวางองค์ประกอบไว้เหนือด้านซ้ายของแผนที่ แต่คุณสามารถลองใช้เลย์เอาต์อื่นๆ เพื่อให้เหมาะกับแอปพลิเคชันของคุณได้

PlaceSearchElement ใช้วิธีการแบบประกาศ แทนที่จะกำหนดค่าทั้งหมดใน JavaScript คุณสามารถกำหนดประเภทการค้นหาใน HTML ได้โดยตรงด้วยการฝังองค์ประกอบคำขอ เช่น <gmp-place-nearby-search-request> ไว้ในคอมโพเนนต์ <gmp-place-search> หลัก

เริ่มต้นองค์ประกอบ <gmp-place-search> ภายในโค้ด HTML ใช้แอตทริบิวต์ selectable เพื่อเปิดใช้กิจกรรมการคลิกในผลการค้นหา ภายในนั้น ให้เพิ่ม <gmp-place-nearby-search-request> เพื่อระบุว่าจะใช้องค์ประกอบนี้สำหรับการค้นหาในบริเวณใกล้เคียง

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

ในการค้นหาเบื้องต้นและแสดงผลลัพธ์ เราจะใช้ JavaScript เพื่อรับการอ้างอิงไปยังองค์ประกอบคำขอที่ฝังอยู่และตั้งค่าพร็อพเพอร์ตี้ขององค์ประกอบนั้น เริ่มต้น Circle เพื่อใช้เป็น locationRestriction โดยใช้ตำแหน่งเครื่องหมายจากขั้นตอนก่อนหน้าเป็นจุดศูนย์กลาง จากนั้นตั้งค่าพร็อพเพอร์ตี้ locationRestriction และ includedPrimaryTypes ในองค์ประกอบคำขอเพื่อเรียกใช้การค้นหา

ข้อมูลโค้ดสําหรับการดำเนินการนี้มีดังนี้

// Get references to the Place Search and its nested request element
const placeSearchElement = document.querySelector("gmp-place-search");
const placeSearchRequestElement = document.querySelector("gmp-place-nearby-search-request");

// Define the location restriction for the search
const circleRestriction = new Circle({
    center: marker.position,
    radius: 500
});

// Set the properties on the request element to perform an initial search for restaurants.
placeSearchRequestElement.locationRestriction = circleRestriction;
placeSearchRequestElement.includedPrimaryTypes = ['restaurant'];

ตัวอย่างลักษณะของแอปพลิเคชันในขั้นตอนนี้มีดังนี้

รูปภาพ

PlaceSearchElement มีตัวเลือกการค้นหา 2 แบบ ดังนี้

องค์ประกอบเหล่านี้เป็นองค์ประกอบที่ฝังอยู่ภายใน <gmp-place-search> จากนั้นคุณจะเรียกให้แสดงการค้นหาโดยตั้งค่าพร็อพเพอร์ตี้ในองค์ประกอบคำขอที่ฝังนั้นโดยใช้ JavaScript

ส่วนนี้จะอธิบายการใช้ทั้ง 2 วิธี

รูปภาพ

หากต้องการอนุญาตให้ผู้ใช้ทำการค้นหาในบริเวณใกล้เคียง คุณต้องมีองค์ประกอบ UI เพื่อให้ผู้ใช้เลือกประเภทสถานที่ก่อน เลือกวิธีการเลือกที่เหมาะกับแอปพลิเคชันของคุณมากที่สุด เช่น รายการแบบเลื่อนลงที่ป้อนข้อมูลด้วยตัวเลือกประเภทสถานที่

เราขอแนะนำให้เลือกประเภทย่อยที่เกี่ยวข้องกับกรณีการใช้งานของคุณ ตัวอย่างเช่น หากคุณกำลังพัฒนาแอปพลิเคชันเพื่อแสดงให้นักท่องเที่ยวเห็นว่ามีอะไรอยู่ใกล้โรงแรมบ้าง คุณอาจเลือก bakery, coffee_shop, museum, restaurant และ tourist_attraction

HTML ควรมีองค์ประกอบ <gmp-place-search> ที่มี <gmp-place-nearby-search-request> ซ้อนอยู่ภายใน

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

ถัดไป ให้สร้าง Listener ของ JavaScript สำหรับเหตุการณ์ change ในตัวเลือกประเภทสถานที่ Listener นี้จะเรียกใช้ฟังก์ชันที่อัปเดตพร็อพเพอร์ตี้ขององค์ประกอบ <gmp-place-nearby-search-request> ซึ่งจะทริกเกอร์การค้นหาใหม่และอัปเดตรายการโดยอัตโนมัติ

// Get a reference to the nested request element
const placeSearchRequestElement = document.querySelector('gmp-place-nearby-search-request');

// Function to update the place search based on the selected type
function updatePlaceList() {
    const selectedType = placeTypeSelect.value;
    if (!selectedType) {
        // If no type is selected, don't perform a search.
        // You could optionally hide the list or clear previous results here.
        placeSearchElement.style.display = 'none';
        return;
    }
    placeSearchElement.style.display = 'block';

    // Set properties on the request element to trigger a new search
    placeSearchRequestElement.locationRestriction = searchCircle;
    placeSearchRequestElement.maxResultCount = 8;
    placeSearchRequestElement.includedPrimaryTypes = [selectedType];
}

ระบบจะใช้ searchCircle เดียวกันจากขั้นตอนการตั้งค่าสำหรับ locationRestriction ระบบจะตั้งค่าพร็อพเพอร์ตี้ includedPrimaryTypes เป็นค่าจากการเลือกของผู้ใช้ นอกจากนี้ยังมีการตั้งค่า maxResultCount (ไม่บังคับ) เพื่อจำกัดจำนวนผลลัพธ์ด้วย

รูปภาพ

หากต้องการเปิดใช้การค้นหาข้อความ คุณต้องเปลี่ยนการกำหนดค่า HTML คุณฝังองค์ประกอบ <gmp-place-text-search-request> แทนคำขอการค้นหาในบริเวณใกล้เคียง

<gmp-place-search selectable>
  <gmp-place-text-search-request>
  </gmp-place-text-search-request>
</gmp-place-search>

เพิ่มการป้อนข้อความและปุ่มค้นหาลงใน UI สร้าง Listener ของ JavaScript สำหรับเหตุการณ์ click ของปุ่ม เครื่องจัดการเหตุการณ์จะรับอินพุตของผู้ใช้และอัปเดตพร็อพเพอร์ตี้ขององค์ประกอบ <gmp-place-text-search-request> เพื่อทำการค้นหา

// Get a reference to the text search request element
const placeTextSearchRequestElement = document.querySelector('gmp-place-text-search-request');
const textSearchInput = document.getElementById('textSearchInput');
const textSearchButton = document.getElementById('textSearchButton');

textSearchButton.addEventListener('click', performTextSearch);

function performTextSearch() {
    const query = textSearchInput.value.trim();
    if (!query) {
        console.log("Search query is empty.");
        return;
    }
    // Set properties on the request element to trigger a new search
    placeTextSearchRequestElement.textQuery = query;
    placeTextSearchRequestElement.locationBias = map.getBounds();
    placeTextSearchRequestElement.maxResultCount = 8;
}

ในที่นี้ เราตั้งค่าพร็อพเพอร์ตี้ textQuery ด้วยข้อมูลที่ผู้ใช้ป้อน นอกจากนี้ เรายังมี locationBias ที่ใช้ขอบเขตของแผนที่ปัจจุบัน ซึ่งจะบอก API ให้เลือกผลลัพธ์ภายในพื้นที่นั้นโดยไม่จำกัดอย่างเคร่งครัด maxResultCount ที่ไม่บังคับจะจำกัดจำนวนผลลัพธ์ที่แสดง

แสดงหมุดและรายละเอียดของสถานที่

ตอนนี้แอปพลิเคชันจะทำการค้นหาสถานที่และป้อนข้อมูลองค์ประกอบได้แล้ว ในขั้นตอนถัดไป เราจะปรับปรุงฟังก์ชันการทำงานโดยทำดังนี้

  • แสดงหมุดบนแผนที่สำหรับสถานที่แต่ละแห่งที่ป้อนในPlaceSearchElement
  • อนุญาตให้ผู้ใช้คลิกหมุดหรือสถานที่ภายในPlaceSearchElementเพื่อแสดงรายละเอียดเพิ่มเติมเกี่ยวกับสถานที่นั้นๆ

หลักการของขั้นตอนนี้จะเหมือนกันไม่ว่าแอปพลิเคชันจะใช้การค้นหาในบริเวณใกล้เคียงหรือการค้นหาข้อความ

ก่อนอื่น ให้เพิ่มตัวแปรร่วมลงในโค้ด JavaScript เพื่อจัดเก็บเครื่องหมายสถานที่ ซึ่งจะช่วยให้คุณนำออกได้เมื่อการค้นหามีการเปลี่ยนแปลงและจัดการกิจกรรมการคลิก

let markers = {};

สร้างฟังก์ชันเพื่อเพิ่มเครื่องหมายลงในแผนที่ ระบบจะเรียกใช้ฟังก์ชันนี้ เมื่อใดก็ตามที่มีการโหลดผลการค้นหาใหม่ โดยจะดำเนินการต่อไปนี้

  • นำเครื่องหมายสถานที่ที่มีอยู่ออกจากแผนที่
  • วนซ้ำผลลัพธ์จาก PlaceSearchElement และเพิ่มเครื่องหมายสำหรับแต่ละรายการ
  • ปรับขอบเขตของแผนที่เพื่อให้มองเห็นเครื่องหมายใหม่ทั้งหมด

หากต้องการฟังเมื่อมีผลการค้นหา ให้เพิ่ม Listener เหตุการณ์ gmp-load ลงในองค์ประกอบ <gmp-place-search> เหตุการณ์นี้จะเริ่มทำงานหลังจากการค้นหาเสร็จสมบูรณ์และแสดงผลลัพธ์แล้ว

เราจะเพิ่ม Listener ไว้ในฟังก์ชันการค้นหา (เช่น updatePlaceList) และใช้ตัวเลือก { once: true } เพื่อให้แน่ใจว่าจะเริ่มทำงานเฉพาะกับผลลัพธ์ของการค้นหาปัจจุบันเท่านั้น

// In your search function, after setting the request properties:
placeSearchElement.addEventListener('gmp-load', addMarkers, { once: true });

ฟังก์ชัน addMarkers จะมีลักษณะดังนี้

async function addMarkers() {
    const { LatLngBounds } = await google.maps.importLibrary("core");
    const bounds = new LatLngBounds();

    if (placeSearchElement.places.length > 0) {
        // Remove existing markers
        for (const m in markers) {
            markers[m].map = null;
        }
        markers = {};

        // Loop through each place from the search results
        // and add a marker for each one.
        for (const place of placeSearchElement.places) {
            const marker = new google.maps.marker.AdvancedMarkerElement({
                map: map,
                position: place.location,
            });

            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;

            // Add a click listener for each marker.
            marker.addListener('gmp-click', (event) => {
                // The main logic for showing details will go here.
            });
        }
        // Position the map to display all markers.
        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    }
}

เมื่อขั้นตอนนี้เสร็จสมบูรณ์ แอปพลิเคชันจะมีลักษณะดังต่อไปนี้ โดยสามารถแสดงเครื่องหมายสำหรับสถานที่แต่ละแห่งที่ PlaceSearchElement แสดงผลได้

รูปภาพ

เมื่อมีเครื่องหมายบนแผนที่แล้ว ขั้นตอนสุดท้ายคือการจัดการกิจกรรมการคลิกเครื่องหมายและองค์ประกอบเพื่อแสดงหน้าต่างข้อมูลพร้อมรายละเอียดสถานที่ ซึ่งได้จากองค์ประกอบรายละเอียดสถานที่ สำหรับตัวอย่างนี้ เราจะใช้องค์ประกอบรายละเอียดสถานที่แบบกะทัดรัด

เพิ่ม HTML ขององค์ประกอบรายละเอียดสถานที่แบบกะทัดรัดลงในโค้ด เช่น

<gmp-place-details-compact orientation="vertical" style="display: none;">
    <gmp-place-all-content></gmp-place-all-content>
    <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
</gmp-place-details-compact>

style ตั้งค่าเป็น display: none และจะไม่แสดงจนกว่าจะจำเป็นต้องใช้ ระบบจะส่ง gmp-place-all-content เพื่อแสดงผลเนื้อหาเอลิเมนต์ทั้งหมด หากต้องการเลือกเนื้อหาที่จะแสดงผล โปรดดูเอกสารประกอบเกี่ยวกับองค์ประกอบรายละเอียดสถานที่แบบย่อ

สร้างตัวแปรร่วมใน JavaScript เพื่อเก็บข้อมูลอ้างอิงไปยังองค์ประกอบแบบกะทัดรัดของรายละเอียดสถานที่ และป้อนข้อมูลนี้ในโค้ดการเริ่มต้น เช่น

let placeDetailsElement;
...
placeDetailsElement = document.querySelector('gmp-place-details-compact');

ภายในฟังก์ชัน addMarkers ให้เพิ่ม Listener เหตุการณ์ gmp-click ลงในเครื่องหมายแต่ละรายการ และกำหนดค่าองค์ประกอบรายละเอียดสถานที่แบบย่อเพื่อแสดงรายละเอียดสถานที่โดยส่งรหัสสถานที่ของเครื่องหมายปัจจุบัน

เมื่อเสร็จแล้ว หน้าต่างข้อมูลจะเปิดขึ้นเพื่อแสดงองค์ประกอบรายละเอียดสถานที่แบบกะทัดรัดซึ่งยึดอยู่กับเครื่องหมาย

สุดท้าย แผนที่จะอยู่ในตำแหน่งวิวพอร์ตของสถานที่ที่เลือกเพื่อให้มองเห็นได้

async function addMarkers() {
          ...
            marker.addListener('gmp-click', (event) => {
                //Set up Place Details Compact Widget
                placeDetailsElement.style.display = "block";
                // Remove any existing place request element
                const existingPlaceRequest = placeDetailsElement.querySelector('gmp-place-details-place-request');
                if (existingPlaceRequest) {
                    existingPlaceRequest.remove();
                }
                // Create and configure the new place request element
                const placeRequestElement = new google.maps.places.PlaceDetailsPlaceRequestElement({ place: place.id });
                // Prepend the new place request element to the main widget
                placeDetailsElement.prepend(placeRequestElement);
                if (infoWindow.isOpen) {
                    infoWindow.close();
                }
                infoWindow.setOptions({
                    content: placeDetailsElement
                });
                infoWindow.open({
                    anchor: marker,
                    map: map
                });
                // Position the map to show the selected place
                placeDetailsElement.addEventListener('gmp-load', () => {
                    map.fitBounds(place.viewport, { top: 500, left: 400 });
                });
            });
          ...
        });
    }
}

หากต้องการให้ผู้ใช้คลิกสถานที่ในองค์ประกอบรายการสถานที่เพื่อแสดงองค์ประกอบรายละเอียดสถานที่แบบย่อ ให้เพิ่มโค้ดต่อไปนี้ลงในโค้ด JavaScript หลังจากการเรียกใช้ configureFromSearchNearbyRequest

placeSearchElement.addEventListener("gmp-select", ({ place }) => {
    if (markers[place.id]) {
        markers[place.id].click();
    }
});

หลังจากขั้นตอนนี้เสร็จสมบูรณ์ แอปพลิเคชันจะใช้การค้นหาในบริเวณใกล้เคียงหรือการค้นหาข้อความเพื่อสร้างองค์ประกอบรายการสถานที่ได้ ผลลัพธ์ของโค้ดนี้จะแสดงหมุดบนแผนที่ และการคลิกหมุดหรือสถานที่ในองค์ประกอบรายการสถานที่ (Place List Element) จะแสดงหน้าต่างข้อมูลพร้อมรายละเอียดสถานที่ ซึ่งได้มาจากองค์ประกอบรายละเอียดสถานที่แบบย่อ (Place Details Compact Element)

ใบสมัครจะมีลักษณะดังต่อไปนี้

รูปภาพ

บทสรุป

PlaceSearchElement ที่รวมเข้ากับองค์ประกอบรายละเอียดสถานที่แบบกะทัดรัดช่วยให้คุณเพิ่มฟีเจอร์การสำรวจสถานที่ที่สมบูรณ์ลงในแอปพลิเคชัน Google Maps Platform ได้อย่างมีประสิทธิภาพ

ลองใช้ Places UI Kit วันนี้เพื่อช่วยให้ผู้ใช้ค้นหาและสำรวจสถานที่ได้โดยใช้ทั้งการค้นหาสถานที่ใกล้เคียงและการค้นหาข้อความ รวมถึงแสดงรายละเอียดสถานที่ที่สมบูรณ์ ซึ่งจะช่วยปรับปรุงการโต้ตอบกับ Use Case การค้นพบสถานที่

ผู้ร่วมให้ข้อมูล

Henrik Valve | วิศวกร DevX