เติมข้อความอัตโนมัติ (ใหม่)

เลือกแพลตฟอร์ม: Android iOS JavaScript เว็บเซอร์วิส

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

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

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

คำขอที่เติมข้อความอัตโนมัติ (ใหม่)

แอปของคุณรับรายการชื่อสถานที่และ/หรือที่อยู่ซึ่งคาดการณ์ได้จาก autocomplete API ได้โดยเรียกใช้ PlacesClient.findAutocompletePredictions() แล้วส่งออบเจ็กต์ FindAutocompletePredictionsRequest ตัวอย่างด้านล่างแสดงการเรียกใช้ PlacesClient.findAutocompletePredictions() ที่สมบูรณ์

Places.initializeWithNewPlacesApiEnabled(context, apiKey);
final List<Field> placeFields = getPlaceFields();
LatLng center = new LatLng(37.7749, -122.4194);
CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000);
final FindAutocompletePredictionsRequest autocompletePlacesRequest =
    FindAutocompletePredictionsRequest.builder()
            .setQuery("Sicilian piz")
            .setRegionCode("ES")
            .setLocationRestriction(circle)
            .build());
placesClient.findAutocompletePredictions(autoCompletePlacesRequest)
    .addOnSuccessListener(
        (response) -> {
            List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions();
          }
    ).addOnFailureListener(
        exception -> {
            Log.e(TAG, "some exception happened" + exception.getMessage());
        })
    );

การตอบกลับแบบเติมข้อความอัตโนมัติ (ใหม่)

API จะแสดงผล FindAutocompletePredictionsResponse ใน Task รายการ FindAutocompletePredictionsResponse มีรายการAutocompletePrediction วัตถุสูงสุด 5 รายการที่แสดงสถานที่ที่คาดการณ์ รายการอาจว่างเปล่าหากไม่มีสถานที่ที่รู้จักซึ่งตรงกับการค้นหาและเกณฑ์ตัวกรอง

สําหรับสถานที่ที่คาดการณ์แต่ละแห่ง คุณสามารถเรียกใช้เมธอดต่อไปนี้เพื่อดึงรายละเอียดสถานที่

  • getFullText(CharacterStyle) แสดงผลข้อความแบบเต็มของคำอธิบายสถานที่ ข้อความนี้เป็นการผสมผสานระหว่างข้อความหลักและข้อความรอง ตัวอย่างเช่น "หอไอเฟล, ถนน Anatole France, ปารีส, ฝรั่งเศส" นอกจากนี้ วิธีนี้ยังให้คุณไฮไลต์ส่วนของคำอธิบายที่ตรงกับการค้นหาด้วยสไตล์ที่คุณต้องการได้โดยใช้ CharacterStyle คุณจะใช้พารามิเตอร์ CharacterStyle หรือไม่ก็ได้ ตั้งค่าเป็น Null หากไม่ต้องการไฮไลต์
  • getPrimaryText(CharacterStyle) แสดงผลข้อความหลักที่อธิบายสถานที่ โดยปกติแล้วจะเป็นชื่อสถานที่ เช่น "หอไอเฟล" และ "123 Pitt Street"
  • getSecondaryText(CharacterStyle) แสดงผลข้อความเสริมของคำอธิบายสถานที่ ซึ่งมีประโยชน์ เช่น ใช้เป็นบรรทัดที่สองเมื่อแสดงการคาดคะเนการเติมข้อความอัตโนมัติ ตัวอย่างเช่น "Avenue Anatole France, Paris, France" และ "Sydney, New South Wales"
  • getPlaceId() แสดงผลรหัสสถานที่ของสถานที่ที่คาดการณ์ รหัสสถานที่คือตัวระบุที่เป็นข้อความซึ่งระบุสถานที่อย่างเจาะจง ซึ่งคุณใช้เพื่อเรียกPlace ออบเจ็กต์นั้นอีกครั้งในภายหลังได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับรหัสสถานที่ในฟีเจอร์เติมข้อความอัตโนมัติได้ที่รายละเอียดสถานที่ (ใหม่) ดูข้อมูลทั่วไปเกี่ยวกับรหัสสถานที่ได้ที่ภาพรวมรหัสสถานที่
  • getTypes() แสดงรายการประเภทสถานที่ที่เชื่อมโยงกับสถานที่นี้
  • getDistanceMeters() แสดงผลระยะทางตรงเป็นเมตรระหว่างสถานที่นี้กับต้นทางที่ระบุในคำขอ

พารามิเตอร์ที่จำเป็น

  • การค้นหา

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

    หากต้องการตั้งค่าพารามิเตอร์การค้นหา ให้เรียกใช้เมธอด setQuery() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

พารามิเตอร์ที่ไม่บังคับ

  • ประเภทหลัก

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

    สถานที่หนึ่งๆ อาจมีประเภทหลักได้เพียงประเภทเดียวจากประเภท Table A หรือ Table B ที่เชื่อมโยงอยู่ เช่น ประเภทหลักอาจเป็น "mexican_restaurant" หรือ "steak_house"

    คำขอจะถูกปฏิเสธพร้อมข้อผิดพลาด INVALID_REQUEST ในกรณีต่อไปนี้

    • ระบุมากกว่า 5 ประเภท
    • ระบุประเภทที่ไม่รู้จัก

    หากต้องการตั้งค่าพารามิเตอร์ประเภทหลัก ให้เรียกใช้เมธอด setTypesFilter() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

  • ประเทศ

    รวมเฉพาะผลการค้นหาจากรายการประเทศที่ระบุ ซึ่งระบุเป็นรายการค่า 2 อักขระ ccTLD ("โดเมนระดับบนสุด") สูงสุด 15 รายการ หากไม่ระบุ ระบบจะไม่ใช้ข้อจำกัดกับการตอบกลับ ตัวอย่างเช่น หากต้องการจํากัดภูมิภาคเป็นเยอรมนีและฝรั่งเศส ให้ทำดังนี้

    หากคุณระบุทั้ง locationRestriction และ includedRegionCodes ผลการค้นหาจะอยู่ในบริเวณที่ตัดกันของการตั้งค่าทั้ง 2 รายการ

    หากต้องการตั้งค่าพารามิเตอร์ประเทศ ให้เรียกใช้เมธอด setCountries() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

  • ออฟเซ็ตอินพุต

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

    หากต้องการตั้งค่าพารามิเตอร์ออฟเซตอินพุต ให้เรียกใช้เมธอด setInputOffset() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

  • ความลำเอียงด้านสถานที่หรือการจํากัดสถานที่

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

    • ความลำเอียงตามสถานที่ตั้ง

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

      หากต้องการตั้งค่าพารามิเตอร์ความลำเอียงตามสถานที่ ให้เรียกใช้เมธอด setLocationBias() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

    • ข้อจำกัดด้านสถานที่ตั้ง

      ระบุพื้นที่ที่จะค้นหา ระบบจะไม่แสดงผลลัพธ์ที่อยู่นอกพื้นที่ที่ระบุ

      หากต้องการตั้งค่าพารามิเตอร์การจํากัดสถานที่ ให้เรียกใช้เมธอด setLocationRestriction() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

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

    • วงกลมจะกำหนดโดยจุดศูนย์กลางและรัศมีเป็นเมตร รัศมีต้องอยู่ระหว่าง 0.0 ถึง 50000.0 ค่าเริ่มต้นคือ 0.0 สำหรับข้อจำกัดด้านสถานที่ ต้องกำหนดรัศมีเป็นค่าที่มากกว่า 0.0 มิฉะนั้น คำขอจะไม่แสดงผลลัพธ์

    • สี่เหลี่ยมผืนผ้าคือวิวพอร์ตละติจูด-ลองจิจูด ซึ่งแสดงเป็นจุด low และ high ที่ตรงข้ามกันตามแนวทแยงมุม วิวพอร์ตถือเป็นภูมิภาคแบบปิด ซึ่งหมายความว่าจะมีขอบเขตด้วย ขอบเขตละติจูดต้องอยู่ในช่วง -90 ถึง 90 องศา และขอบเขตลองจิจูดต้องอยู่ในช่วง -180 ถึง 180 องศา

      • หาก low = high วิวพอร์ตจะประกอบด้วยจุดเดียวนั้น
      • หาก low.longitude > high.longitude ระบบจะกลับช่วงลองจิจูด (วิวพอร์ตตัดเส้นลองจิจูด 180 องศา)
      • หาก low.longitude = -180 องศาและ high.longitude = 180 องศา วิวพอร์ตจะรวมลองจิจูดทั้งหมด
      • หาก low.longitude = 180 องศาและ high.longitude = -180 องศา ช่วงนี้ลองจิจูดจะว่างเปล่า

      ต้องป้อนข้อมูลทั้ง low และ high และช่องที่แสดงต้องไม่ว่างเปล่า วิวพอร์ตว่างเปล่าจะทำให้เกิดข้อผิดพลาด

  • Origin

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

    หากต้องการตั้งค่าพารามิเตอร์ต้นทาง ให้เรียกใช้เมธอด setOrigin() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

  • รหัสภูมิภาค

    รหัสภูมิภาคที่ใช้จัดรูปแบบคำตอบ ซึ่งรวมถึงการจัดรูปแบบที่อยู่ โดยระบุเป็นค่า 2 อักขระccTLD ("โดเมนระดับบนสุด") รหัส ccTLD ส่วนใหญ่จะเหมือนกับรหัส ISO 3166-1 โดยมีข้อยกเว้นบางประการ ตัวอย่างเช่น ccTLD ของสหราชอาณาจักรคือ "uk" (.co.uk) ส่วนรหัส ISO 3166-1 คือ "gb" (ในทางเทคนิคสำหรับนิติบุคคล "สหราชอาณาจักรบริเตนใหญ่และไอร์แลนด์เหนือ")

    หากคุณระบุรหัสภูมิภาคที่ไม่ถูกต้อง API จะแสดงINVALID_ARGUMENTข้อผิดพลาด พารามิเตอร์นี้อาจส่งผลต่อผลลัพธ์ตามกฎหมายที่เกี่ยวข้อง

    หากต้องการตั้งค่าพารามิเตอร์รหัสภูมิภาค ให้เรียกใช้เมธอด setRegionCode() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

  • โทเค็นเซสชัน

    โทเค็นเซสชันคือสตริงที่ผู้ใช้สร้างขึ้นซึ่งติดตามการเรียกใช้ฟีเจอร์เติมข้อความอัตโนมัติ (ใหม่) เป็น "เซสชัน" ฟีเจอร์เติมข้อความอัตโนมัติใช้โทเค็นเซสชันเพื่อจัดกลุ่มระยะการค้นหาและการเลือกของผู้ใช้ในการค้นหาแบบเติมข้อความอัตโนมัติไว้ในเซสชันแยกต่างหากเพื่อวัตถุประสงค์ในการเรียกเก็บเงิน เซสชันจะเริ่มต้นเมื่อผู้ใช้เริ่มพิมพ์ข้อความค้นหา และสิ้นสุดเมื่อผู้ใช้เลือกสถานที่ เซสชันแต่ละรายการอาจมีคำค้นหาหลายรายการ ตามด้วยการเลือกสถานที่ 1 แห่ง เมื่อเซสชันสิ้นสุดลง โทเค็นจะใช้งานไม่ได้อีกต่อไป แอปของคุณจึงต้องสร้างโทเค็นใหม่สำหรับแต่ละเซสชัน เราขอแนะนำให้ใช้โทเค็นเซสชันสำหรับเซสชันการเติมข้อความอัตโนมัติแบบเป็นโปรแกรมทั้งหมด (เมื่อคุณฝังข้อมูลโค้ดหรือเปิดการเติมข้อความอัตโนมัติโดยใช้ Intent ทาง API จะจัดการเรื่องนี้ให้โดยอัตโนมัติ)

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

    หากต้องการตั้งค่าพารามิเตอร์โทเค็นเซสชัน ให้เรียกใช้เมธอด setSessionToken() เมื่อสร้างออบเจ็กต์ FindAutocompletePredictionsRequest

    ดูข้อมูลเพิ่มเติมได้ที่โทเค็นเซสชัน

ตัวอย่างการเติมข้อความอัตโนมัติ (ใหม่)

ใช้การจํากัดตําแหน่งและความลำเอียงด้านตําแหน่ง

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

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

Places.initializeWithNewPlacesApiEnabled(context, apiKey);
final List<Field> placeFields = getPlaceFields();

LatLng center = new LatLng(37.7749, -122.4194);
CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000);

final FindAutocompletePredictionsRequest autocompletePlacesRequest =
    FindAutocompletePredictionsRequest.builder()
            .setQuery("Amoeba")
            .setLocationRestriction(circle)
            .build());
placesClient.findAutocompletePredictions(autoCompletePlacesRequest)
    .addOnSuccessListener(
        (response) -> {
            List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions();
          }
    ).addOnFailureListener(
        exception -> {
            Log.e(TAG, "some exception happened" + exception.getMessage());
        })
    );

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

Places.initializeWithNewPlacesApiEnabled(context, apiKey);
final List<Field> placeFields = getPlaceFields();

LatLng center = new LatLng(37.7749, -122.4194);
CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000);

final FindAutocompletePredictionsRequest autocompletePlacesRequest =
    FindAutocompletePredictionsRequest.builder()
            .setQuery("Amoeba")
            .setLocationBias(circle)
            .build());
placesClient.findAutocompletePredictions(autoCompletePlacesRequest)
    .addOnSuccessListener(
        (response) -> {
            List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions();
          }
    ).addOnFailureListener(
        exception -> {
            Log.e(TAG, "some exception happened" + exception.getMessage());
        })
    );

ใช้ประเภทหลัก

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

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

Places.initializeWithNewPlacesApiEnabled(context, apiKey);
final List<Field> placeFields = getPlaceFields();

final List<Place.Field> primaryTypes = Arrays.asList("sporting_goods_store");

LatLng center = new LatLng(37.7749, -122.4194);
CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000);

final FindAutocompletePredictionsRequest autocompletePlacesRequest =
    FindAutocompletePredictionsRequest.builder()
            .setQuery("Soccer")
            .setIncludedPrimaryTypes(primaryTypes)
            .setLocationBias(circle)
            .build());
placesClient.findAutocompletePredictions(autoCompletePlacesRequest)
    .addOnSuccessListener(
        (response) -> {
            List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions();
          }
    ).addOnFailureListener(
        exception -> {
            Log.e(TAG, "some exception happened" + exception.getMessage());
        })
    );

หากคุณละเว้นพารามิเตอร์ประเภทหลัก ผลการค้นหาอาจรวมสถานที่ตั้งประเภทที่คุณอาจไม่ต้องการ เช่น "athletic_field"

ใช้ต้นทาง

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

Places.initializeWithNewPlacesApiEnabled(context, apiKey);
final List<Field> placeFields = getPlaceFields();

LatLng center = new LatLng(37.7749, -122.4194);
CircularBounds circle = CircularBounds.newInstance(center, /* radius = */ 5000);

final FindAutocompletePredictionsRequest autocompletePlacesRequest =
    FindAutocompletePredictionsRequest.builder()
            .setQuery("Amoeba")
            .setOrigin(center)
            .setLocationRestriction(circle)
            .build());
placesClient.findAutocompletePredictions(autoCompletePlacesRequest)
    .addOnSuccessListener(
        (response) -> {
            List<AutocompletePrediction> predictions = response.getResult().getAutocompletePredictions();
          }
    ).addOnFailureListener(
        exception -> {
            Log.e(TAG, "some exception happened" + exception.getMessage());
        })
    );

การระบุแหล่งที่มา

คุณใช้ฟีเจอร์เติมข้อความอัตโนมัติ (ใหม่) ได้โดยไม่ต้องมีแผนที่ หากแสดงแผนที่ ต้องเป็นแผนที่ของ Google เมื่อแสดงการคาดคะเนจากบริการการเติมข้อความอัตโนมัติ (ใหม่) ที่ไม่มีแผนที่ คุณต้องใส่โลโก้ Google ที่แสดงในบรรทัดเดียวกับช่องค้นหา/ผลการค้นหา ดูข้อมูลเพิ่มเติมได้ที่การแสดงโลโก้ Google และการระบุแหล่งที่มา