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

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

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

PlaceSearchElement คืออะไร

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

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

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

รูปภาพ

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

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

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

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

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

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

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

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

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

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

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

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

  1. ใช้gmp-map เว็บ คอมโพเนนต์ HTML
  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 } เพื่อให้แน่ใจว่า Listener จะเริ่มทำงานสำหรับผลการค้นหาปัจจุบันเท่านั้น

// 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 แสดง

รูปภาพ

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

เพิ่ม HTML ของ Place Details Compact Element ลงในโค้ด เช่น

<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 เพื่อเก็บการอ้างอิงไปยัง Place Details Compact Element และแสดงตัวแปรนี้ในโค้ดการเริ่มต้นใช้งาน เช่น

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

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

เมื่อดำเนินการเสร็จแล้ว ระบบจะเปิด Info Window เพื่อแสดง Place Details Compact Element ซึ่งยึดตามเครื่องหมาย

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

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

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

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

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

แอปพลิเคชันจะมีลักษณะดังนี้

รูปภาพ

บทสรุป

PlaceSearchElement เมื่อใช้ร่วมกับ Place Details Compact Element จะเป็นวิธีที่คล่องตัวในการเพิ่มฟีเจอร์การค้นหาสถานที่ที่สมบูรณ์ลงในแอปพลิเคชัน Google Maps Platform

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

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

Henrik Valve | DevX วิศวกร