ย้ายข้อมูลจาก Geocoding v3 ไปยัง v4

นักพัฒนาซอฟต์แวร์ในเขตเศรษฐกิจยุโรป (EEA)

Geocoding API v4 เปิดตัวเมธอดใหม่หลายรายการที่แทนที่ฟังก์ชันการทำงานใน API เวอร์ชัน 3 คู่มือนี้จะแสดงวิธีย้ายข้อมูลแอปเพื่อใช้เมธอด v4 ใหม่

คุณใช้คีย์ API ที่มีอยู่กับเมธอด v4 ใหม่ได้ อย่างไรก็ตาม หากคุณได้ขอเพิ่มโควต้าใน API เวอร์ชัน 3 คุณต้องขอเพิ่มโควต้าใน API เวอร์ชัน 4 ใหม่

ย้ายข้อมูลจากการเข้ารหัสพิกัดภูมิศาสตร์แบบส่งต่อ v3

หากใช้ v3 Geocoding เพื่อ เข้ารหัสพิกัดภูมิศาสตร์ของที่อยู่ คุณควรย้ายข้อมูลไปยังเมธอด Geocode an address v4 ซึ่งยอมรับคำขอ GET

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

ขอเปลี่ยนแปลงพารามิเตอร์

พารามิเตอร์ v3 พารามิเตอร์ v4 หมายเหตุ
address, components address ตอนนี้ระบบจะส่งที่อยู่ที่ไม่มีโครงสร้าง (v3 address) ในเส้นทาง URL คุณสามารถส่งคอมโพเนนต์ของที่อยู่ที่จัดโครงสร้าง (v3 components) เป็นพารามิเตอร์การค้นหา address.* ได้ ดูสร้างตัวกรองคอมโพเนนต์ v3 ขึ้นมาใหม่
bounds locationBias.rectangle เปลี่ยนชื่อแล้ว โครงสร้างเปลี่ยนเป็นออบเจ็กต์
language languageCode เปลี่ยนชื่อแล้ว หากไม่ระบุ v3 จะใช้ส่วนหัว Accept-Language หรือค่าเริ่มต้นเป็น en ส่วน v4 จะใช้ค่าเริ่มต้นเป็นภาษาท้องถิ่นและสคริปต์ของสถานที่ตั้ง
region regionCode เปลี่ยนชื่อแล้ว เมื่อละเว้น v3 จะมีค่าเริ่มต้นเป็น us ส่วน v4 จะไม่มีค่าเริ่มต้น
extra_computations นำออกแล้ว แทนที่ด้วยเมธอด SearchDestinations

การเปลี่ยนแปลงช่องคําตอบ

ช่อง v3 ช่อง v4 หมายเหตุ
status, error_message นำออกแล้ว v4 ใช้รหัสสถานะ HTTP และเนื้อหาข้อผิดพลาด
results.address_components.long_name / results.address_components.short_name results.addressComponents.longText / results.addressComponents.shortText เปลี่ยนชื่อแล้ว
results.geometry.location_type results.granularity เปลี่ยนชื่อแล้ว
results.geometry.location results.location ชื่อฟิลด์: lat/lng -> latitude/longitude
results.geometry.viewport results.viewport ชื่อฟิลด์: northeast/southwest -> high/low
results.postcode_localities results.postalCodeLocalities เปลี่ยนชื่อแล้ว ตอนนี้แสดงผลสำหรับท้องถิ่นอย่างน้อย 1 แห่ง (v3 ต้องมีมากกว่า 1 รายการ)
results.partial_match นำออกแล้ว
ใหม่ results.addressComponents.languageCode ภาษาของคอมโพเนนต์ที่อยู่เฉพาะ
ใหม่ results.bounds ขอบเขตที่ชัดเจนโดยใช้ high/low
ใหม่ results.place ชื่อทรัพยากรของสถานที่
ใหม่ results.postalAddress ออบเจ็กต์ PostalAddress ที่มีโครงสร้าง

จำลองตัวกรองคอมโพเนนต์ v3

การเข้ารหัสพิกัดภูมิศาสตร์แบบส่งต่อใน Geocoding v3 มีพารามิเตอร์ components ที่เปิดใช้การกรองผลลัพธ์อย่างเข้มงวดสำหรับคอมโพเนนต์ที่เฉพาะเจาะจง (เช่น components=country:US) การเข้ารหัสพิกัดภูมิศาสตร์แบบส่งต่อใน v4 ไม่รองรับการกรองอย่างเข้มงวดประเภทนี้ในพารามิเตอร์คำขอ ใน v4 คุณสามารถระบุข้อมูลที่อยู่เป็นสตริงที่ไม่มีโครงสร้างรายการเดียวในเส้นทาง หรือเป็นพารามิเตอร์การค้นหาที่มีโครงสร้าง เช่น address.addressLines, address.locality, address.administrativeArea, address.postalCode และ address.regionCode พารามิเตอร์ที่มีโครงสร้างไม่ได้ทำหน้าที่เป็นตัวกรองแบบเข้มงวด แต่จะรวมคอมโพเนนต์ทั้งหมดที่ระบุไว้เพื่อสร้างที่อยู่ที่สมบูรณ์ซึ่ง API จะพยายามเข้ารหัสพิกัดภูมิศาสตร์ API จะค้นหารายการที่ตรงกับที่อยู่ทั้งหมดที่ระบุในทุกคอมโพเนนต์มากที่สุด การระบุองค์ประกอบในลักษณะที่มีโครงสร้างจะช่วยให้ API เข้าใจความตั้งใจได้ดีขึ้น โดยเฉพาะอย่างยิ่งเมื่อมีการรวบรวมข้อมูลที่อยู่จากช่องแบบฟอร์มที่แยกต่างหาก ซึ่งจะช่วยให้ API จัดการกับการพิมพ์ผิดเล็กน้อยหรือความกำกวมภายในคอมโพเนนต์แต่ละรายการได้ เนื่องจากประเภทข้อมูลในแต่ละฟิลด์มีความชัดเจน

หากต้องการให้ทำงานคล้ายกับตัวกรองคอมโพเนนต์แบบเข้มงวดของ v3 คุณต้องใช้การกรองฝั่งไคลเอ็นต์ในอาร์เรย์ results ที่ API v4 แสดงผลตามออบเจ็กต์ postalAddress และ addressComponents ในการตอบกลับ

ตารางต่อไปนี้แสดงการจับคู่ที่ดีที่สุดระหว่างตัวกรอง components ของ v3 กับช่อง postalAddress ของ v4

ตัวกรองคอมโพเนนต์ v3 ช่องการตอบกลับ v4
country postalAddress.regionCode
postal_code postalAddress.postalCode
administrative_area postalAddress.administrativeArea หรือ addressComponents

ตัวอย่างการกรองฝั่งไคลเอ็นต์

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

กรองตามประเทศ

จับคู่ address.regionCode จากคำขอของคุณกับ postalAddress.regionCode ในผลการค้นหาแต่ละรายการ โปรดทราบว่าแม้ว่า API จะยอมรับรหัสภูมิภาคที่เป็นตัวพิมพ์เล็กในคำขอ แต่จะแสดงผลเป็นตัวพิมพ์ใหญ่เสมอในการตอบกลับ ดังนั้นคุณต้องปรับอินพุตให้เป็นตัวพิมพ์ใหญ่ก่อนทำการเปรียบเทียบ

ตัวอย่างโค้ด Python
def filter_by_country(results, region_code):
    return [
        res for res in results
        if res.get('postalAddress', {}).get('regionCode') == region_code.upper()
    ]

# Example usage:
# v4_response = ... # API call response
# filtered = filter_by_country(v4_response.get('results', []), 'US')
ตัวอย่างโค้ด Node.js
function filterByCountry(results, regionCode) {
    return results.filter(res => res.postalAddress?.regionCode === regionCode.toUpperCase());
}

// Example usage:
// const v4Response = ... # API call response
// const filtered = filterByCountry(v4Response.results, 'US');
กรองตามเขตบริหาร

จับคู่ address.administrativeArea จากคำขอของคุณกับ postalAddress.administrativeArea ในผลการค้นหาแต่ละรายการ คุณควรปรับอินพุตให้เป็นตัวพิมพ์ใหญ่ก่อนการเปรียบเทียบ เช่นเดียวกับรหัสประเทศ วิธีนี้จะเชื่อถือได้ก็ต่อเมื่อ administrativeArea ในคำขอของคุณมีตัวย่อ 2 ตัวอักษรมาตรฐาน postalAddress.administrativeArea ในการตอบกลับอาจไม่ตรงกับคำต่อท้ายรหัส ISO 3166-2 โดยตรงเนื่องจากสาเหตุหลายประการ ประการแรก ในบางพื้นที่ เขตปกครองย่อยที่สอดคล้องกับรหัส ISO 3166-2 ไม่ได้เป็นส่วนหนึ่งของการแสดงที่อยู่ทางไปรษณีย์ตามมาตรฐาน ตัวอย่างเช่น ในสเปน เขตบริหารระดับ 1 (เช่น "CN" สำหรับกานาเรียส) อาจแสดงใน addressComponents แต่ postalAddress.administrativeArea อาจมีพื้นที่ระดับ 2 (เช่น "ซานตากรุซเดเตเนริเฟ") ประการที่ 2 ในบางพื้นที่ ตัวย่อของเขตย่อยไม่เป็นที่ใช้กันโดยทั่วไปและจะแสดงใน postalAddress.administrativeArea ด้วยชื่อที่ยาวกว่า (ด้วยเหตุผลที่คล้ายกัน addressComponents.shortText สำหรับคอมโพเนนต์ที่อยู่ซึ่งสอดคล้องกับเขตย่อยอาจไม่ตรงกับส่วนต่อท้ายรหัส ISO 3166-2 ของเขตย่อย) นอกจากนี้ ในบางกรณีอาจมีการแสดงเขตย่อยที่คอมโพเนนต์ที่อยู่สำหรับ administrative_area_level_n โดยที่ n มากกว่า 1 เพื่อให้ได้ผลลัพธ์ที่ครอบคลุมที่สุด คุณควรตรวจสอบการจับคู่ทั้งใน postalAddress.administrativeArea และ addressComponents ที่มีประเภท administrative_area_level_n (เช่น administrative_area_level_1)

ตัวอย่างโค้ด Python
def filter_by_admin_area(results, admin_area):
    target = admin_area.upper()
    filtered = []
    for res in results:
        # Check postalAddress
        pa_aa = res.get('postalAddress', {}).get('administrativeArea', '')
        if pa_aa == target:
            filtered.append(res)
            continue
        # Check all administrative area levels in addressComponents
        for comp in res.get('addressComponents', []):
            is_admin_level = any(t.startswith('administrative_area_level_')
                               for t in comp.get('types', []))
            if is_admin_level:
                short = comp.get('shortText', '')
                if short == target:
                    filtered.append(res)
                    break
    return filtered

# Example usage:
# filtered = filter_by_admin_area(v4_response.get('results', []), 'CA')
ตัวอย่างโค้ด Node.js
function filterByAdminArea(results, adminArea) {
    const target = adminArea.toUpperCase();
    return results.filter(res => {
        // Check postalAddress.administrativeArea
        if (res.postalAddress?.administrativeArea === target) {
            return true;
        }
        // Check addressComponents for any administrative area level
        return res.addressComponents?.some(c => {
            const isAdmin = c.types?.some(t => t.startsWith('administrative_area_level_'));
            return isAdmin && c.shortText === target;
        });
    });
}

// Example usage:
// const filtered = filterByAdminArea(v4Response.results, 'CA');
กรองตามรหัสไปรษณีย์

จับคู่ address.postalCode จากคำขอของคุณกับ postalAddress.postalCode ในผลการค้นหาแต่ละรายการ คุณต้องปรับทั้งรหัสไปรษณีย์ที่ป้อนและรหัสไปรษณีย์ที่เป็นผลลัพธ์ให้เป็นมาตรฐานก่อนเปรียบเทียบ ตรรกะการปรับมาตรฐานจะขึ้นอยู่กับภูมิภาคเป็นอย่างมาก แนวทางพื้นฐานคือการนำเว้นวรรคและขีดกลางออก แล้วแปลงเป็นตัวพิมพ์ที่สอดคล้องกัน

อาจต้องใช้การปรับมาตรฐานขั้นสูงขึ้นเพื่อจัดการคำนำหน้ารหัสไปรษณีย์ (เช่น "L2" ในสหราชอาณาจักร) หรือคำต่อท้าย (เช่น "+4" ในรหัสไปรษณีย์ของสหรัฐอเมริกา) ตรรกะการปรับมาตรฐานที่เฉพาะเจาะจงที่จำเป็นจะแตกต่างกันไปตามประเทศและรูปแบบของรหัสไปรษณีย์ที่เกี่ยวข้อง คุณอาจต้องปรับฟังก์ชันการปรับมาตรฐานที่ระบุหรือใช้ตรรกะที่ซับซ้อนมากขึ้นสำหรับภูมิภาคที่คุณกำหนดเป้าหมาย

ตัวอย่างที่ระบุจะจัดการรหัสไปรษณีย์ของสหรัฐอเมริกาและอนุญาตให้จับคู่กับฐาน 5 หลักได้แม้ว่าจะมีการระบุหรือแสดงผล ZIP+4 ก็ตาม

ตัวอย่างโค้ด Python (เน้นรหัสไปรษณีย์ของสหรัฐอเมริกา)
import re

def normalize_postal_code_us(pc):
    # Basic normalization for US: uppercase, alphanumeric only
    if not pc:
        return ""
    normalized = re.sub(r'[^A-Z0-9]', '', pc.upper())
    # Return only the first 5 digits for US ZIP codes
    return normalized[:5]

def filter_by_postal_code_us(results, postal_code):
    normalized_input = normalize_postal_code_us(postal_code)
    if not normalized_input:
        return []
    filtered_results = []
    for res in results:
        pa_pc = res.get('postalAddress', {}).get('postalCode', '')
        if normalize_postal_code_us(pa_pc) == normalized_input:
            filtered_results.append(res)
    return filtered_results

# Example usage:
# Matches '94043', '94043-1351', '940431351'
# filtered = filter_by_postal_code_us(v4_response.get('results', []), '94043')
# filtered = filter_by_postal_code_us(v4_response.get('results', []), '94043-1234')
ตัวอย่างโค้ด Node.js (เน้นรหัสไปรษณีย์ของสหรัฐอเมริกา)
function normalizePostalCodeUs(pc) {
    // Basic normalization for US: uppercase, alphanumeric only
    const normalized = (pc || '').toUpperCase().replace(/[^A-Z0-9]/g, '');
    // Return only the first 5 digits for US ZIP codes
    return normalized.substring(0, 5);
}

function filterByPostalCodeUs(results, postalCode) {
    const normalizedInput = normalizePostalCodeUs(postalCode);
    if (!normalizedInput) {
        return [];
    }
    return results.filter(res => {
        const paPc = res.postalAddress?.postalCode || '';
        return normalizePostalCodeUs(paPc) === normalizedInput;
    });
}

// Example usage:
// Matches '94043', '94043-1351', '940431351'
// const filtered = filterByPostalCodeUs(v4Response.results, '94043');
// const filtered = filterByPostalCodeUs(v4Response.results, '94043-1234');

ย้ายข้อมูลจากการเข้ารหัสพิกัดภูมิศาสตร์แบบย้อนกลับ v3

หากคุณใช้การเข้ารหัสพิกัดภูมิศาสตร์แบบย้อนกลับ v3 เพื่อเปลี่ยนพิกัดเป็นที่อยู่ คุณควรย้ายข้อมูลไปยังเมธอดการเข้ารหัสพิกัดภูมิศาสตร์แบบย้อนกลับของสถานที่ v4 ซึ่งยอมรับคำขอ GET

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

ขอเปลี่ยนแปลงพารามิเตอร์

พารามิเตอร์ v3 พารามิเตอร์ v4 หมายเหตุ
language languageCode เปลี่ยนชื่อแล้ว หากไม่ระบุ v3 จะใช้ส่วนหัว Accept-Language หรือค่าเริ่มต้นเป็น en ส่วน v4 จะใช้ค่าเริ่มต้นเป็นภาษาท้องถิ่นและสคริปต์ของสถานที่ตั้ง
region regionCode เปลี่ยนชื่อแล้ว เมื่อละเว้น v3 จะมีค่าเริ่มต้นเป็น us ส่วน v4 จะไม่มีค่าเริ่มต้น
result_type types เปลี่ยนชื่อแล้ว โดยใช้พารามิเตอร์การค้นหาซ้ำ
location_type granularity เปลี่ยนชื่อแล้ว โดยใช้พารามิเตอร์การค้นหาซ้ำ
extra_computations นำออกแล้ว แทนที่ด้วยเมธอด SearchDestinations

การเปลี่ยนแปลงช่องคําตอบ

ช่อง v3 ช่อง v4 หมายเหตุ
status, error_message นำออกแล้ว v4 ใช้รหัสสถานะ HTTP และเนื้อหาข้อผิดพลาด
results.address_components.long_name / results.address_components.short_name results.addressComponents.longText / results.addressComponents.shortText เปลี่ยนชื่อแล้ว
results.geometry.location_type results.granularity เปลี่ยนชื่อแล้ว
results.geometry.location results.location ชื่อฟิลด์: lat/lng -> latitude/longitude
results.geometry.viewport results.viewport ชื่อฟิลด์: northeast/southwest -> high/low
ใหม่ results.addressComponents.languageCode ภาษาของคอมโพเนนต์ที่อยู่เฉพาะ
ใหม่ results.bounds ขอบเขตที่ชัดเจนโดยใช้ high/low
ใหม่ results.place ชื่อทรัพยากรของสถานที่
ใหม่ results.postalAddress ออบเจ็กต์ PostalAddress ที่มีโครงสร้าง

ย้ายข้อมูลจากตัวบ่งชี้ที่อยู่ v3

ใน Geocoding API v3 การส่ง extra_computations=ADDRESS_DESCRIPTORS จะแสดงผลออบเจ็กต์ address_descriptor ที่มี landmarks[] และ areas[] ใน Geocoding API v4 ความสามารถนี้จะแทนที่ด้วยเมธอด SearchDestinations (POST /v4/geocode/destinations) ซึ่งจะแสดงผลบริบทเชิงพื้นที่ที่สมบูรณ์ภายในออบเจ็กต์ Destination แต่ละรายการโดยตรง

ตารางต่อไปนี้จะแมปช่อง address_descriptor ของ v3 เดิมกับช่อง SearchDestinations ของ v4 ที่เทียบเท่า

ฟิลด์ address_descriptor v3 ฟิลด์ SearchDestinations v4 หมายเหตุเกี่ยวกับการย้ายข้อมูล
landmarks[] destinations[].landmarks[] ขอ destinations.landmarks ใน X-Goog-FieldMask
landmarks[].place_id landmarks[].place.placeId รวมอยู่ในออบเจ็กต์ place (PlaceView)
landmarks[].display_name landmarks[].place.displayName ข้อความที่แปลแล้ว (text และ languageCode)
landmarks[].types landmarks[].place.types อาร์เรย์ของสตริงประเภทสถานที่
landmarks[].spatial_relationship landmarks[].relationalDescription v4 จะแสดงผลวลีที่แปลแล้วและมนุษย์อ่านได้ (เช่น "Across from Central Park") แทนที่จะเป็น Enum ดิบ (ACROSS_THE_ROAD, AROUND_THE_CORNER)
landmarks[].straight_line_distance_meters landmarks[].straightLineDistanceMeters เปลี่ยนชื่อเป็นรูปแบบ lower camelCase แล้ว
landmarks[].travel_distance_meters landmarks[].travelDistanceMeters เปลี่ยนชื่อเป็นรูปแบบ lower camelCase แล้ว
areas[] (containment enum) destinations[].containingPlaces[] และ subDestinations[] รายการที่เทียบเท่าที่ใกล้เคียงที่สุดสำหรับลำดับชั้นเชิงโครงสร้าง: ระบบจะแสดงผลคอมเพล็กซ์ วิทยาเขต ห้างสรรพสินค้า และอาคารที่ล้อมรอบเป็นออบเจ็กต์ PlaceView ที่มีโครงสร้างใน containingPlaces[] และ subDestinations[] (โดยตั้งค่า structureType เป็น GROUNDS หรือ BUILDING และโครงร่าง displayPolygon ที่ไม่บังคับ) โปรดทราบว่าไม่มีการแทนที่แบบ 1:1 โดยตรงสำหรับพื้นที่ใกล้เคียงย่าน/เขตหรือ enum containment ของ v3 (NEAR, WITHIN, OUTSKIRTS)

ย้ายข้อมูลจากการเข้ารหัสพิกัดภูมิศาสตร์ของสถานที่ v3

หากคุณใช้ place_id เพื่อรับที่อยู่สำหรับรหัสสถานที่ที่เฉพาะเจาะจงด้วย Geocoding v3 คุณต้องย้ายข้อมูลไปยังเมธอด Place Geocoding v4 ซึ่งยอมรับคำขอ GET

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

ขอเปลี่ยนแปลงพารามิเตอร์

พารามิเตอร์ v3 พารามิเตอร์ v4 หมายเหตุ
place_id ฟิลด์ place ในโปรโตคำขอ ตอนนี้ระบบจะระบุรหัสสถานที่ตั้งเป็นพารามิเตอร์เส้นทาง places/{place} เช่น https://geocode.googleapis.com/v4/geocode/places/ChIJj61dQgK6j4AR4GeTYWZsKWw ซึ่งจะแมปกับช่องสถานที่ในคำขอที่เกี่ยวข้อง
language languageCode เปลี่ยนชื่อแล้ว หากไม่ระบุ v3 จะใช้ส่วนหัว Accept-Language หรือค่าเริ่มต้นเป็น en ส่วน v4 จะใช้ค่าเริ่มต้นเป็นภาษาท้องถิ่นและสคริปต์ของสถานที่ตั้ง
region regionCode เปลี่ยนชื่อแล้ว เมื่อละเว้น v3 จะมีค่าเริ่มต้นเป็น us ส่วน v4 จะไม่มีค่าเริ่มต้น

การเปลี่ยนแปลงช่องคําตอบ

ช่อง v3 ช่อง v4 หมายเหตุ
status, error_message นำออกแล้ว v4 ใช้รหัสสถานะ HTTP และเนื้อหาข้อผิดพลาด
results (root) v4 จะแสดงผลออบเจ็กต์ผลลัพธ์รายการเดียว ไม่ใช่ results อาร์เรย์
results.address_components.long_name / results.address_components.short_name addressComponents.longText / addressComponents.shortText เปลี่ยนชื่อแล้ว
results.geometry.location_type granularity เปลี่ยนชื่อแล้ว
results.geometry.location location ชื่อฟิลด์: lat/lng -> latitude/longitude
results.geometry.viewport viewport ชื่อฟิลด์: northeast/southwest -> high/low
results.postcode_localities postalCodeLocalities เปลี่ยนชื่อแล้ว ตอนนี้แสดงผลสำหรับท้องถิ่นอย่างน้อย 1 แห่ง (v3 ต้องมีมากกว่า 1 รายการ)
ใหม่ addressComponents.languageCode ภาษาของคอมโพเนนต์ที่อยู่เฉพาะ
ใหม่ bounds ขอบเขตที่ชัดเจนโดยใช้ high/low
ใหม่ place ชื่อทรัพยากรของสถานที่
ใหม่ postalAddress ออบเจ็กต์ PostalAddress ที่มีโครงสร้าง

ย้ายข้อมูลจากข้อมูลเจาะจงเฉพาะพื้นที่ของการเข้ารหัสพิกัดภูมิศาสตร์ไปยังปลายทาง

ฟีเจอร์ต่อไปนี้ใน Geocoding API v3 จะถูกแทนที่ด้วยเมธอด SearchDestinations ของ Geocoding API v4

  • การเข้าชม
  • จุดนำทาง
  • เค้าโครงอาคาร
  • ค่าเข้า

หากคุณใช้ Geocoding API v3 สำหรับฟีเจอร์ข้างต้น ให้ใช้เอกสารนี้เพื่อช่วยคุณใช้เมธอด SearchDestinations แทนเพื่อรับฟีเจอร์เหล่านี้ เอกสารนี้อธิบายตำแหน่งที่จะค้นหาฟีเจอร์เหล่านี้ในการตอบกลับจาก SearchDestinations และความแตกต่างในการแสดงฟีเจอร์เหล่านี้ในการตอบกลับจาก API ระหว่าง Geocoding API v3 กับเมธอด SearchDestinations ของ Geocoding API v4

การเข้าชม

หากต้องการดูทางเข้าที่เชื่อมโยงกับ destination ให้ใช้ช่อง destination.entrances

entrance แต่ละรายการใน destination.entrances มีฟิลด์ต่อไปนี้ (แทนที่สคีมา buildings.entrances เวอร์ชัน 3 เดิม)

  • displayName - ฟิลด์ใหม่ที่ไม่บังคับซึ่งมีชื่อที่มนุษย์อ่านได้สำหรับทางเข้า เช่น "Gate B"
  • location - สถานที่ตั้งประเภท LatLng โดยใช้ latitude และ longitude (แทนที่ lat/lng ของ v3)
  • tags - เหมือนกับช่อง tags จากทางเข้า Geocoding API v3 (เช่น PREFERRED)
  • place - ชื่อทรัพยากรของสถานที่ (เช่น places/ChIJ...) แทนที่ช่อง building_place_id จาก Geocoding API v3 ใน v4 สถานที่นี้สามารถแสดงโครงสร้างปลายทางใดก็ได้ (อาคาร วิทยาเขต หรือสวนสาธารณะ) ไม่ใช่แค่อาคารเท่านั้น

หากต้องการดูจุดนำทางที่เชื่อมโยงกับ destination ให้ใช้ช่อง destination.navigationPoints

navigationPoint แต่ละรายการใน destination.navigationPoints มีฟิลด์ต่อไปนี้ (แทนที่สคีมา navigation_points เวอร์ชัน 3 เดิม)

  • navigationPointToken - สตริงโทเค็นที่เข้ารหัสซึ่งใช้เพื่อกำหนดเส้นทางไปยังจุดนำทางที่เฉพาะเจาะจงนี้ในเมธอด ComputeRoutes (Waypoint.navigationPointToken) ของ Routes API ดูเส้นทางโดยใช้โทเค็นจุดนำทาง
  • displayName - ฟิลด์ตัวเลือกใหม่ที่มีชื่อที่มนุษย์อ่านได้สำหรับจุดนำทาง เช่น "5th Ave"
  • location - สถานที่ตั้งประเภท LatLng โดยใช้ latitude และ longitude
  • travelModes - คล้ายกับช่อง restricted_travel_modes จาก Geocoding API v3 ยกเว้นว่า v4 จะระบุรูปแบบการเดินทางที่ยอมรับได้ (DRIVE, WALK) แทนรูปแบบการเดินทางที่ถูกจำกัด
  • usage - ช่องใหม่ที่ระบุกรณีการใช้งานการมาถึงที่รองรับสำหรับจุดนำทาง (เช่น PICKUP, DROPOFF หรือ PARKING)

เค้าโครงอาคาร

หากต้องการดูเค้าโครงอาคารที่เชื่อมโยงกับ destination ให้ใช้ช่อง displayPolygon ของออบเจ็กต์ placeView ใน destination ที่แสดงถึงอาคาร (แทนที่อาร์เรย์ buildings.building_outlines เวอร์ชัน 3 เดิม) สำหรับ placeView แต่ละรายการ ให้ตรวจสอบว่าเป็นอาคารที่มีช่อง placeView.structureType หรือไม่ หากประเภทโครงสร้างเป็น BUILDING คุณจะดูโครงร่างได้จากช่อง placeView.displayPolygon placeView จะมีช่องเพิ่มเติมสำหรับอาคารที่ไม่ได้อยู่ใน Geocoding API v3 ด้วย

destination สามารถมีออบเจ็กต์ placeView ที่แสดงถึงอาคารในช่องต่อไปนี้

  • destination.primary - สถานที่หลักของจุดหมาย
  • destination.containingPlaces - ฟิลด์ที่ซ้ำได้ซึ่งมีสถานที่ขนาดใหญ่กว่าที่ "มี" สถานที่หลัก เช่น หากสถานที่หลักคือ subpremise โดยปกติแล้ว containingPlaces จะมี placeView ที่แสดงถึงอาคาร
  • destination.subDestinations - ฟิลด์ที่ซ้ำได้ซึ่งมีจุดหมายย่อยของสถานที่หลัก (เช่น ห้องชุดหรือห้องสวีทแต่ละห้องภายในอาคาร)

โปรดทราบว่ารูปแบบของ placeView.displayPolygon ตรงกับรูปแบบโครงร่างอาคารใน Geocoding API v3 ซึ่งเป็นรูปแบบ GeoJSON โดยใช้รูปแบบ RFC 7946

ค่าเข้า

เช่นเดียวกับโครงร่างอาคาร หากต้องการดูพื้นที่ที่เชื่อมโยงกับ destination ให้ใช้ช่อง displayPolygon ของออบเจ็กต์ placeView ใน destination ที่แสดงพื้นที่ (แทนที่อาร์เรย์ grounds เวอร์ชัน 3 เดิม) สำหรับ placeView แต่ละรายการ ให้ตรวจสอบว่าเป็นรูปหลายเหลี่ยมของพื้นที่ที่มีช่อง placeView.structureType หรือไม่ หากประเภทโครงสร้างเป็น GROUNDS คุณจะดูโครงร่างได้จากช่อง placeView.displayPolygon placeView จะมีช่องเพิ่มเติมสำหรับพื้นที่ที่ไม่ได้อยู่ใน Geocoding API v3 ด้วย

destination สามารถมีออบเจ็กต์ placeView ที่แสดงถึงเหตุผลในช่องต่อไปนี้

  • destination.primary
  • destination.containingPlaces
  • destination.subDestinations

โปรดทราบว่ารูปแบบของ placeView.displayPolygon ตรงกับรูปแบบโครงร่างพื้นที่ใน Geocoding API v3 ซึ่งเป็นรูปแบบ GeoJSON โดยใช้รูปแบบ RFC 7946

ความแม่นยำของผลลัพธ์

ใน Geocoding API v3 ช่อง location_type ในเรขาคณิตการตอบกลับจะระบุความแม่นยำของผลลัพธ์ และไคลเอ็นต์บางรายจะจัดอันดับหรือกรองผลลัพธ์ตามค่าเหล่านี้ (ROOFTOP, RANGE_INTERPOLATED, GEOMETRIC_CENTER และ APPROXIMATE) ในการย้ายข้อมูล Geocoding API v4 มาตรฐาน ช่องนี้จะเปลี่ยนชื่อเป็น granularity

ใน Destinations API (v4 SearchDestinations) จะไม่มีช่อง location_type แต่จะจัดการข้อมูลเชิงพื้นที่แตกต่างออกไป ดังนี้

  • ไม่จำเป็นต้องกรองฝั่งไคลเอ็นต์ด้วยตนเอง: แม้ว่าการเข้ารหัสพิกัดภูมิศาสตร์มาตรฐานจะให้ผลลัพธ์หลายรายการในระดับความละเอียดที่แตกต่างกัน แต่วิธี SearchDestinations จะช่วยลดความกำกวมด้วยการแปลงเป็นปลายทางเดียวที่เพิ่มประสิทธิภาพเมื่อเป็นไปได้ ซึ่งช่วยให้ลูกค้าไม่ต้องกรองตามประเภทสถานที่เพื่อพิจารณาว่าผลลัพธ์ใดดีที่สุด
  • ข้อมูลเชิงพื้นที่ที่แสดงตามประเภทโครงสร้างและรูปหลายเหลี่ยมที่แสดง: เรขาคณิตและโครงสร้างเชิงพื้นที่จะระบุโดยสิ่งต่อไปนี้
    • displayPolygon (สำหรับเรขาคณิตที่แน่นอน)
    • ช่อง structureType ภายในออบเจ็กต์ placeView
  • การแมปประเภทโครงสร้าง
    • โดยทั่วไปแล้ว structureType ของ POINT, BUILDING หรือ SECTION จะสอดคล้องกับสิ่งที่เรียกว่า ROOFTOP ก่อนหน้านี้
    • โดยทั่วไปแล้ว structureType ที่มีค่า GROUNDS จะสอดคล้องกับ GEOMETRIC_CENTER

ใช้มาสก์ฟิลด์เพื่อขอฟีเจอร์เหล่านี้

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

curl -X POST -d '{"place": "places/ChIJG3kh4hq6j4AR_XuFQnV0_t8"}' \
  -H "X-Goog-Api-Key: API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Goog-FieldMask: destinations.entrances,destinations.navigationPoints,destinations.primary,destinations.containingPlaces,destinations.subDestinations" \
  https://geocode.googleapis.com/v4/geocode/destinations

สูตรการย้ายข้อมูลและรูปแบบโค้ดที่พบบ่อย

เมื่อย้ายข้อมูลเวิร์กโฟลว์ที่ซับซ้อนจาก Geocoding v3 หรือ Geocoding++ ไปยัง SearchDestinations ให้ใช้สูตรโค้ดต่อไปนี้เพื่อดึงข้อมูลโครงสร้างเชิงพื้นที่และที่อยู่ทั่วไป

ดึงข้อมูลรูปหลายเหลี่ยมของอาคารที่ดีที่สุด

หากต้องการแสดงผลรอยเท้าอาคารสำหรับสถานที่หรือจุดหมาย ให้ทำดังนี้

  1. ตรวจสอบว่าสถานที่ primary มี structureType === 'BUILDING' และมี displayPolygon หรือไม่
  2. หากไม่ ให้ตรวจสอบ containingPlaces เพื่อค้นหาอาคารที่ล้อมรอบ (มีประโยชน์เมื่อปลายทางหลักเป็นปลายทางย่อยของอาคารขนาดใหญ่)
  3. หากไม่พบอาคารที่ล้อมรอบ ให้ตรวจสอบ subDestinations เพื่อดูว่ามีการระบุอาคารแต่ละหลังไว้หรือไม่
ตัวอย่างโค้ด Python
def get_best_building_polygon(destination):
    primary = destination.get('primary', {})
    if primary.get('structureType') == 'BUILDING' and 'displayPolygon' in primary:
        return primary['displayPolygon']

    # Check containing places for the parent building
    for place in destination.get('containingPlaces', []):
        if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place:
            return place['displayPolygon']

    # Fallback to sub-destinations if available
    for place in destination.get('subDestinations', []):
        if place.get('structureType') == 'BUILDING' and 'displayPolygon' in place:
            return place['displayPolygon']

    return None
ตัวอย่างโค้ด Node.js
function getBestBuildingPolygon(destination) {
    const { primary = {}, containingPlaces = [], subDestinations = [] } = destination;

    if (primary.structureType === 'BUILDING' && primary.displayPolygon) {
        return primary.displayPolygon;
    }

    const parentBuilding = containingPlaces.find(
        p => p.structureType === 'BUILDING' && p.displayPolygon
    );
    if (parentBuilding) {
        return parentBuilding.displayPolygon;
    }

    const subBuilding = subDestinations.find(
        p => p.structureType === 'BUILDING' && p.displayPolygon
    );
    return subBuilding?.displayPolygon || null;
}

โครงร่างของพื้นที่สกัดกาแฟ

หากต้องการขอบเขตของอพาร์ตเมนต์คอมเพล็กซ์ วิทยาเขตของบริษัท ศูนย์การค้า หรือสวนสาธารณะ ให้ทำดังนี้

  1. หากสถานที่ primary แสดงถึงทั้งอาคาร (structureType === 'GROUNDS') ให้ใช้ primary.displayPolygon
  2. หากสถานที่ primary เป็นอาคารหรือทางเข้าที่ตั้งอยู่ภายในอาคารที่ใหญ่กว่า ให้ค้นหาพื้นที่โดยรอบใน containingPlaces
ตัวอย่างโค้ด Python
def get_grounds_polygon(destination):
    primary = destination.get('primary', {})
    if primary.get('structureType') == 'GROUNDS' and 'displayPolygon' in primary:
        return primary['displayPolygon']

    for place in destination.get('containingPlaces', []):
        if place.get('structureType') == 'GROUNDS' and 'displayPolygon' in place:
            return place['displayPolygon']

    return None
ตัวอย่างโค้ด Node.js
function getGroundsPolygon(destination) {
    const { primary = {}, containingPlaces = [] } = destination;

    if (primary.structureType === 'GROUNDS' && primary.displayPolygon) {
        return primary.displayPolygon;
    }

    const groundsPlace = containingPlaces.find(
        p => p.structureType === 'GROUNDS' && p.displayPolygon
    );
    return groundsPlace?.displayPolygon || null;
}

เลือกจุดสังเกตสำหรับการแสดงที่อยู่เทียบกับการมาถึงจุดหมายปลายทาง

การเข้ารหัสพิกัดภูมิศาสตร์ v3 address_descriptor แสดงผล enum spatial_relationship (WITHIN, BESIDE, BEHIND, NEAR, ACROSS_THE_ROAD, AROUND_THE_CORNER) ใน SearchDestinations:

  • ไม่มี enum ความสัมพันธ์แบบข้อมูลดิบ แต่ให้ใช้ relationalDescription.text โดยตรงแทน ซึ่งมีวลีที่แปลแล้วและพร้อมแสดง เช่น "Across from Central Park" หรือ "Behind the convention center" อย่าใส่ "Near " ไว้ด้านหน้าด้วยตนเอง
  • ใช้ tags เพื่อเลือกจุดสังเกตที่เหมาะกับกรณีการใช้งานของคุณ ดังนี้
    • ARRIVAL: จุดสังเกตที่เจาะจงเฉพาะพื้นที่ซึ่งอยู่ติดกับจุดหมาย อยู่ตรงข้าม หรืออยู่ฝั่งตรงข้ามถนนจากจุดหมาย (โดยทั่วไปจะอยู่ภายในระยะ 50-100 เมตร) เหมาะที่สุดสำหรับการแสดงเวลาที่คนขับจะมาถึงแบบเรียลไทม์ การยืนยันการจัดส่งของบริษัทจัดส่ง หรือการ์ดแสดงเวลาที่คนขับจะมาถึงในแอป
    • ADDRESS: จุดสังเกตที่โดดเด่นในพื้นที่ภายในย่านใกล้เคียง (โดยทั่วไปไม่เกิน 100-500 เมตร) เหมาะที่สุดสำหรับการชำระเงินที่แสดงต่อลูกค้า การตรวจสอบคำสั่งซื้อ หรือการจำแนกปลายทางก่อนการเดินทาง
    • หากจุดสังเกตมีทั้งแท็ก ADDRESS และ ARRIVAL แสดงว่าจุดสังเกตนั้นเป็นที่รู้จักกันดีในละแวกใกล้เคียงและอยู่ติดกับจุดหมายปลายทางโดยตรง
ตัวอย่างโค้ด Python
def get_best_relational_landmark(destination, is_last_mile=True):
    """Select the best landmark based on user context.

    Args:
        destination: Destination object from SearchDestinations.
        is_last_mile: True for arrival and delivery guidance (prefers ARRIVAL tags).
                      False for address display and disambiguation (prefers ADDRESS tags).

    Returns:
        Dict with landmark description, distances, tags, and placeId, or None.
    """
    landmarks = destination.get('landmarks', [])
    if not landmarks:
        return None

    target_tag = 'ARRIVAL' if is_last_mile else 'ADDRESS'

    # Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag.
    for lm in landmarks:
        tags = lm.get('tags', [])
        if target_tag in tags or ('ARRIVAL' in tags and 'ADDRESS' in tags):
            description = lm.get('relationalDescription', {}).get('text')
            if description:
                return {
                    'description': description,
                    'travelDistanceMeters': lm.get('travelDistanceMeters'),
                    'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'),
                    'tags': tags,
                    'placeId': lm.get('place', {}).get('placeId')
                }

    # Fallback to the first available landmark with a relational description if no tagged match is found
    for lm in landmarks:
        description = lm.get('relationalDescription', {}).get('text')
        if description:
            return {
                'description': description,
                'travelDistanceMeters': lm.get('travelDistanceMeters'),
                'straightLineDistanceMeters': lm.get('straightLineDistanceMeters'),
                'tags': lm.get('tags', []),
                'placeId': lm.get('place', {}).get('placeId')
            }

    return None
ตัวอย่างโค้ด Node.js
/**
 * Select the best landmark based on user context.
 *
 * @param {Object} destination Destination object from SearchDestinations.
 * @param {boolean} [isLastMile=true] True for arrival and delivery guidance
 *        (prefers ARRIVAL tags). False for address display and disambiguation
 *        (prefers ADDRESS tags).
 * @return {Object|null}
 */
function getBestRelationalLandmark(destination, isLastMile = true) {
    const landmarks = destination.landmarks || [];
    if (!landmarks.length) return null;

    const targetTag = isLastMile ? 'ARRIVAL' : 'ADDRESS';

    // Landmarks are ranked by relevance and proximity. Select the first candidate matching the target tag.
    const match = landmarks.find((lm) => {
        const tags = lm.tags || [];
        return (tags.includes(targetTag) || (tags.includes('ARRIVAL') && tags.includes('ADDRESS'))) &&
               lm.relationalDescription?.text;
    }) || landmarks.find((lm) => lm.relationalDescription?.text);

    if (match) {
        return {
            description: match.relationalDescription.text,
            travelDistanceMeters: match.travelDistanceMeters,
            straightLineDistanceMeters: match.straightLineDistanceMeters,
            tags: match.tags || [],
            placeId: match.place?.placeId || null,
        };
    }

    return null;
}

เส้นทางไปยังจุดนำทางของยานพาหนะและทางเข้าที่ต้องการ

เวิร์กโฟลว์การจัดส่งและการมาถึงในขั้นตอนสุดท้ายจะรวมจุดเข้าถึงเชิงพื้นที่ 2 ประเภทที่ส่งเสริมกันเข้าด้วยกัน ดังนี้

  • การขับขี่แบบเลี้ยวต่อเลี้ยว: กำหนดเส้นทางให้ยานพาหนะไปยังจุดส่งผู้โดยสารบนถนนที่กำหนดโดยใช้ navigationPoints จุดนำทางจะได้รับการจัดอันดับล่วงหน้าตามความใกล้เคียงและความเกี่ยวข้อง ดังนั้นจุดแรกที่ตรงกับรูปแบบการเดินทางที่ต้องการ (เช่น 'DRIVE') และแท็กการใช้งาน (เช่น 'DROPOFF' หรือ 'PICKUP') จะเป็นจุดอ้างอิงที่เหมาะสมที่สุดสำหรับยานพาหนะ ส่ง navigationPointToken ไปยังเมธอด ComputeRoutes (Waypoint.navigationPointToken) ของ Routes API หรือ Navigation SDK หากไม่มีจุดขับรถที่สแนปกับถนน ให้ใช้ทางเข้าอาคารหรือเซนทรอยด์หลักแทน
  • การเข้าถึงประตูทางเข้าจริง: นำทางผู้จัดส่งที่เดินเท้าหรือผู้โดยสารไปยังทางเข้าอาคารโดยใช้ destinations.entrances ตรวจสอบ tags เพื่อหา 'PREFERRED' เพื่อค้นหาทางเข้าที่น่าจะให้สิทธิ์เข้าถึงทางกายภาพโดยตรง หากไม่มีข้อมูลทางเข้า ให้ใช้จุดนำทางสำหรับคนเดินเท้า (travelModes รวมถึง 'WALK') หรือเซนทรอยด์หลัก
ตัวอย่างโค้ด Python
def get_routing_and_arrival_points(destination, usage_tag=None):
    navigation_points = destination.get('navigationPoints', [])
    entrances = destination.get('entrances', [])
    primary_location = destination.get('primary', {}).get('location')

    # 1. Doorstep / Physical Entrance
    # Prefer PREFERRED entrance -> any entrance -> WALK nav point -> primary location
    preferred_entrance = None
    for ent in entrances:
        if 'PREFERRED' in ent.get('tags', []):
            preferred_entrance = ent
            break
    if not preferred_entrance and entrances:
        preferred_entrance = entrances[0]

    walk_nav_point = None
    for np in navigation_points:
        if 'WALK' in np.get('travelModes', []):
            walk_nav_point = np
            break

    if preferred_entrance:
        doorstep_location = preferred_entrance.get('location')
    elif walk_nav_point:
        doorstep_location = walk_nav_point.get('location')
    else:
        doorstep_location = primary_location

    # 2. Vehicle Routing Waypoint
    # Find a driving navigation point. If usage_tag (such as 'DROPOFF' or 'PICKUP')
    # is specified, prioritize a candidate with that usage tag; otherwise fall back
    # to the first available driving point.
    drive_nav_point = None
    fallback_drive_point = None
    for np in navigation_points:
        if 'DRIVE' in np.get('travelModes', []):
            if usage_tag and usage_tag in np.get('usages', []):
                drive_nav_point = np
                break  # Exact match for desired usage tag
            elif fallback_drive_point is None:
                fallback_drive_point = np  # First driving point as fallback

    if not drive_nav_point:
        drive_nav_point = fallback_drive_point

    if drive_nav_point:
        vehicle_location = drive_nav_point.get('location')
        nav_token = drive_nav_point.get('navigationPointToken')
    elif preferred_entrance:
        vehicle_location = preferred_entrance.get('location')
        nav_token = None
    else:
        vehicle_location = primary_location
        nav_token = None

    return {
        'vehicleRoutingWaypoint': {
            'navigationPointToken': nav_token,
            'location': vehicle_location,
        },
        'doorstepLocation': doorstep_location,
    }
ตัวอย่างโค้ด Node.js
function getRoutingAndArrivalPoints(destination, usageTag = null) {
    const navigationPoints = destination.navigationPoints || [];
    const entrances = destination.entrances || [];
    const primaryLocation = destination.primary?.location || null;

    // 1. Doorstep / Physical Entrance
    const preferredEntrance = entrances.find(ent => ent.tags?.includes('PREFERRED'))
        || entrances[0]
        || null;

    const walkNavPoint = navigationPoints.find(np => np.travelModes?.includes('WALK'))
        || null;

    const doorstepLocation = preferredEntrance?.location
        || walkNavPoint?.location
        || primaryLocation;

    // 2. Vehicle Routing Waypoint
    // Find a driving navigation point. If usageTag (such as 'DROPOFF' or 'PICKUP')
    // is specified, prioritize a candidate with that usage tag; otherwise fall back
    // to the first available driving point.
    const driveNavPoint = (usageTag && navigationPoints.find(np => np.travelModes?.includes('DRIVE') && np.usages?.includes(usageTag)))
        || navigationPoints.find(np => np.travelModes?.includes('DRIVE'))
        || null;

    let vehicleLocation = primaryLocation;
    let navToken = null;
    if (driveNavPoint) {
        vehicleLocation = driveNavPoint.location;
        navToken = driveNavPoint.navigationPointToken;
    } else if (preferredEntrance) {
        vehicleLocation = preferredEntrance.location;
    }

    return {
        vehicleRoutingWaypoint: {
            navigationPointToken: navToken,
            location: vehicleLocation,
        },
        doorstepLocation: doorstepLocation,
    };
}

ข้อควรพิจารณาด้านความปลอดภัย

Geocoding API v4 ออกแบบมาเป็น API แบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ ไม่มีเส้นทางการย้ายข้อมูลโดยตรงสำหรับผู้ใช้ JavaScript จาก v3 ไปยัง v4 การเรียกใช้เมธอด v4 โดยตรงจาก JavaScript ฝั่งไคลเอ็นต์ (เช่น ในเบราว์เซอร์) โดยใช้คีย์ API จะทำให้คีย์ API มีความเสี่ยงสูงต่อการถูกขโมยและการใช้ในทางที่ผิด

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

วิธีที่แนะนำในการใช้ Geocoding API v4 คือใช้จากเซิร์ฟเวอร์แบ็กเอนด์ของคุณเอง แอปพลิเคชันไคลเอ็นต์ควรส่งคำขอไปยังเซิร์ฟเวอร์สื่อกลางนี้ ซึ่งจะเรียกใช้ Google API อย่างปลอดภัยโดยใช้คีย์ API ที่ได้รับการปกป้อง (เช่น คีย์ที่จัดเก็บไว้ในตัวแปรสภาพแวดล้อมหรือ Secret Manager) วิธีนี้ช่วยให้มั่นใจได้ว่าคีย์ API จะไม่แสดงในโค้ดฟรอนท์เอนด์

ทางเลือกสำหรับความต้องการฝั่งไคลเอ็นต์

หากคุณมีความต้องการฝั่งไคลเอ็นต์ที่ต้องใช้การเข้ารหัสพิกัดภูมิศาสตร์ ให้พิจารณาใช้โซลูชันฝั่งไคลเอ็นต์ที่มีอยู่รายการใดรายการหนึ่งต่อไปนี้