ใช้ Geospatial Anchor เพื่อกำหนดตำแหน่งเนื้อหาในโลกจริงบน Android NDK

หมุดตำแหน่งทางภูมิศาสตร์เป็นหมุดประเภทหนึ่งที่ให้คุณวางเนื้อหา 3 มิติในโลกแห่งความเป็นจริงได้

ประเภทของหมุดยึดเชิงพื้นที่

หมุดยึดเชิงพื้นที่มี 3 ประเภท ซึ่งแต่ละประเภทจัดการระดับความสูงแตกต่างกันไป ดังนี้

  1. หมุด WGS84:
    หมุด WGS84 ช่วยให้คุณวางเนื้อหา 3 มิติที่ละติจูด ลองจิจูด และระดับความสูงที่ต้องการได้

  2. หมุดเทอร์เรน:
    หมุดเทอร์เรนช่วยให้คุณวางเนื้อหาได้โดยใช้เพียงละติจูดและลองจิจูดที่มีความสูงสัมพันธ์กับภูมิประเทศ ณ ตำแหน่งนั้น ระดับความสูงจะกำหนดตามพื้นดินหรือพื้นตามที่ VPS ทราบ

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

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

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

โปรดตรวจสอบว่าคุณได้เปิดใช้ Geospatial API แล้วก่อนดำเนินการต่อ

วางหมุดภูมิสารสนเทศ

หมุดแต่ละประเภทมี API เฉพาะสำหรับสร้าง โปรดดูข้อมูลเพิ่มเติมที่ประเภทของหมุดพิกัดภูมิศาสตร์

สร้างจุดยึดจากการทดสอบการคลิก

นอกจากนี้ คุณยังสร้างหมุดตำแหน่งทางภูมิศาสตร์จากผลการทดสอบ Hit Test ได้ด้วย ใช้ท่าทางจาก Hit-Test และแปลงเป็น ArGeospatialPose ใช้เพื่อวางจุดยึด 1 ใน 3 ประเภทที่อธิบายไว้

รับท่าทางภูมิสารสนเทศจากท่าทาง AR

ArEarth_getGeospatialPose() มีวิธีเพิ่มเติมในการระบุละติจูดและลองจิจูดโดยการแปลงท่าทาง AR เป็นท่าทางภูมิสารสนเทศ

รับท่าทาง AR จากท่าทางภูมิสารสนเทศ

ArEarth_getPose() จะแปลงตำแหน่งแนวนอน ระดับความสูง และการหมุนควอร์เทอร์ไบน์ที่ระบุโดยโลกตามกรอบพิกัดตะวันออก-ขึ้น-ใต้เป็นท่าทาง AR ตามพิกัดโลก GL

เลือกวิธีการที่เหมาะกับกรณีการใช้งานของคุณ

การสร้างหมุดแต่ละวิธีมีข้อดีข้อเสียที่ควรทราบดังนี้

  • เมื่อใช้เรขาคณิตของภาพถนน ให้ใช้ Hit-Test เพื่อแนบเนื้อหากับอาคาร
  • แนะนำให้ใช้จุดยึดบนพื้นดินหรือบนหลังคาแทนจุดยึด WGS84 เนื่องจากใช้ค่าระดับความสูงที่ Google Maps กำหนด

ระบุละติจูดและลองจิจูดของสถานที่

คุณสามารถคํานวณละติจูดและลองจิจูดของสถานที่ได้ 3 วิธีดังนี้

  • ใช้ Geospatial Creator เพื่อดูและเพิ่มประสิทธิภาพโลกด้วยเนื้อหา 3 มิติโดยไม่ต้องไปที่สถานที่จริง ซึ่งช่วยให้คุณวางเนื้อหา 3 มิติที่สมจริงได้โดยใช้ภาพจาก Google Maps ใน Unity Editor ระบบจะคำนวณละติจูด ลองจิจูด การหมุน และระดับความสูงของเนื้อหาให้คุณโดยอัตโนมัติ
  • ใช้ Google Maps
  • ใช้ Google Earth โปรดทราบว่าการหาพิกัดเหล่านี้โดยใช้ Google Earth แทน Google Maps จะมีความคลาดเคลื่อนได้สูงสุดหลายเมตร
  • ไปที่สถานที่ตั้งจริง

ใช้ Google Maps

วิธีรับละติจูดและลองจิจูดของสถานที่โดยใช้ Google Maps

  1. ไปที่ Google Maps ในคอมพิวเตอร์เดสก์ท็อป

  2. ไปที่เลเยอร์ > เพิ่มเติม

  3. เปลี่ยนประเภทแผนที่เป็นดาวเทียม แล้วยกเลิกการเลือกช่องทำเครื่องหมายมุมมองโลกที่มุมซ้ายล่างของหน้าจอ

    ซึ่งจะบังคับใช้มุมมอง 2 มิติและขจัดข้อผิดพลาดที่อาจเกิดขึ้นจากมุมมอง 3 มิติที่เอียง

  4. คลิกขวาที่ตำแหน่งในแผนที่ แล้วเลือกลองจิจูด/ละติจูดเพื่อคัดลอกไปยังคลิปบอร์ด

ใช้ Google Earth

คุณสามารถคํานวณละติจูดและลองจิจูดของสถานที่จาก Google Earth ได้โดยคลิกสถานที่ใน UI และอ่านข้อมูลจากรายละเอียดจุดสังเกต

วิธีรับละติจูดและลองจิจูดของสถานที่โดยใช้ Google Earth

  1. ไปที่ Google Earth ในคอมพิวเตอร์เดสก์ท็อป

  2. ไปที่เมนูแฮมเบอร์เกอร์ แล้วเลือกรูปแบบแผนที่

  3. สลับสวิตช์สิ่งปลูกสร้าง 3 มิติเป็นปิด

  4. เมื่อปิดสวิตช์อาคาร 3 มิติแล้ว ให้คลิกไอคอนหมุด เพื่อเพิ่มหมุดหมาย ณ ตำแหน่งที่เลือก

  5. ระบุโปรเจ็กต์ที่จะใส่หมุด แล้วคลิกบันทึก

  6. ป้อนชื่อหมุดในช่องชื่อของหมุด

  7. คลิกลูกศรย้อนกลับ ในแผงโปรเจ็กต์ แล้วเลือกเมนู การดำเนินการเพิ่มเติม

  8. เลือกส่งออกเป็นไฟล์ KML จากเมนู

ไฟล์ KLM จะรายงานละติจูด ลองจิจูด และระดับความสูงของจุดสังเกตในแท็ก <coordinates> โดยคั่นด้วยคอมมา ดังนี้

<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>

อย่าใช้ละติจูดและลองจิจูดจากแท็ก <LookAt> ซึ่งระบุตำแหน่งของกล้อง ไม่ใช่ตำแหน่ง

ไปที่สถานที่ตั้งจริง

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

รับควอร์เทอร์ไบน์การหมุน

ArGeospatialPose_getEastUpSouthQuaternion() ดึงข้อมูลการวางแนวจากท่าทางเชิงพื้นที่และแสดงผลควอร์เทอร์ไบน์ที่แสดงถึงเมทริกซ์การหมุนที่เปลี่ยนเวกเตอร์จากเป้าหมายไปยังระบบพิกัดตะวันออก-ขึ้น-ใต้ (EUS) X+ จะชี้ไปทางตะวันออก Y+ จะชี้ขึ้น และ Z+ จะชี้ไปทางใต้ ค่าจะเขียนตามลําดับ {x, y, z, w}

จุดยึด WGS84

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

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

วางหมุด WGS84 ในโลกแห่งความเป็นจริง

ระบุระดับความสูงของสถานที่

การกำหนดระดับความสูงของสถานที่เพื่อวางจุดยึดทำได้หลายวิธี ดังนี้

  • หากตำแหน่งของจุดยึดอยู่ใกล้กับผู้ใช้ คุณสามารถใช้ระดับความสูงที่คล้ายกับระดับความสูงของอุปกรณ์ของผู้ใช้
  • เมื่อทราบละติจูดและลองจิจูดแล้ว ให้ใช้ Elevation API เพื่อรับระดับความสูงตามข้อกำหนด EGM96 คุณต้องแปลงระดับความสูง EGM96 ของ Maps API เป็น WGS84 เพื่อเปรียบเทียบกับระดับความสูง ArGeospatialPose ดู GeoidEval ที่มีทั้งบรรทัดคำสั่งและอินเทอร์เฟซ HTML Maps API จะรายงานละติจูดและลองจิจูดตามข้อกำหนด WGS84 โดยค่าเริ่มต้น
  • คุณดูละติจูด ลองจิจูด และระดับความสูงของสถานที่ได้จาก Google Earth ซึ่งจะทำให้คุณมีข้อผิดพลาดได้สูงสุดหลายเมตร ใช้ละติจูด ลองจิจูด และระดับความสูงจากแท็ก <coordinates> ไม่ใช่แท็ก <LookAt> ในไฟล์ KML
  • หากจุดยึดที่มีอยู่อยู่ใกล้และถ้าคุณไม่ได้อยู่บนแนวเอียง คุณอาจใช้ระดับความสูงจาก ArGeospatialPose ของกล้อง โดยไม่ต้องใช้แหล่งข้อมูลอื่น เช่น Maps API

สร้าง Anchor

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

float eus_quaternion_4[4] = {qx, qy, qz, qw};
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArAnchor* earth_anchor = NULL;
    ArStatus status = ArEarth_acquireNewAnchor(ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude,
        eus_quaternion_4, &earth_anchor);

    // Attach content to the anchor specified by geodetic location and
    // pose.
  }
}

จุดยึดภูมิประเทศ

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

คุณต้องระบุระดับความสูงเหนือภูมิประเทศแทนการป้อนระดับความสูงที่ต้องการ เมื่อค่านี้เป็น 0 หมุดยึดจะอยู่ในระดับเดียวกับภูมิประเทศ

ตั้งค่าโหมดการค้นหาเครื่องบิน

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

ใช้ ArPlaneFindingMode เพื่อเลือกวิธีที่แอปจะตรวจหาเครื่องบิน

สร้างหมุดเทอร์เรนโดยใช้ Async API ใหม่

หากต้องการสร้างและวางจุดยึดภูมิประเทศ ให้กด ArEarth_resolveAnchorOnTerrainAsync()

หมุดจะไม่พร้อมใช้งานในทันทีและจำเป็นต้องแก้ไข เมื่อแก้ไขแล้ว รายการดังกล่าวจะพร้อมใช้งานใน ArResolveAnchorOnTerrainFuture

ตรวจสอบสถานะจุดยึดของภูมิประเทศโดยใช้ ArResolveAnchorOnTerrainFuture_getResultTerrainAnchorState() รับหมุดที่แก้ไขแล้วโดยใช้ ArResolveAnchorOnTerrainFuture_acquireResultAnchor()

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnTerrainCallback callback = NULL;
ArResolveAnchorOnTerrainFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnTerrainAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_terrain, eus_quaternion_4,
        context, callback, &future);
  }
}

ดู "สถานะของอนาคต"

อนาคตจะมี ArFutureState ที่เชื่อมโยงอยู่

รัฐ คำอธิบาย
AR_FUTURE_STATE_PENDING การดำเนินการยังอยู่ระหว่างรอดำเนินการ
AR_FUTURE_STATE_DONE การดำเนินการเสร็จสมบูรณ์และผลลัพธ์พร้อมใช้งาน
AR_FUTURE_STATE_CANCELLED การดำเนินการถูกยกเลิกแล้ว

ตรวจสอบสถานะการยึดตามภูมิประเทศของผลลัพธ์ในอนาคต

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

switch (terrain_anchor_state) {
  case AR_TERRAIN_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_INTERNAL:
    // The Terrain anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

หมุดยึดบนหลังคา

รูปภาพหลักของจุดยึดบนหลังคา

จุดยึดบนหลังคาเป็นจุดยึดประเภทหนึ่งและคล้ายกับจุดยึดบนพื้นด้านบนมาก ความแตกต่างคือคุณจะต้องระบุระดับความสูงเหนือดาดฟ้าแทนระดับความสูงเหนือภูมิประเทศ

สร้างหมุดบนหลังคาโดยใช้ Async API ใหม่

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

หากต้องการสร้างและวางหมุดยึดบนหลังคา ให้โทรหา ArEarth_resolveAnchorOnRooftopAsync() คุณจะเข้าถึง ArFutureState ของอนาคตได้ด้วย ซึ่งคล้ายกับจุดยึดของภูมิประเทศ จากนั้นตรวจสอบผลลัพธ์ในอนาคตเพื่อเข้าถึง ArRooftopAnchorState

ใช้ ArEarth_resolveAnchorOnRooftopAsync() เพื่อสร้าง ArResolveAnchorOnRooftopFuture

ตรวจสอบสถานะจุดยึดบนหลังคาโดยใช้ ArResolveAnchorOnRooftopFuture_getResultRooftopAnchorState()

รับหมุดที่แก้ไขแล้วโดยใช้ ArResolveAnchorOnRooftopFuture_acquireResultAnchor()

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnRooftopCallback callback = NULL;
ArResolveAnchorOnRooftopFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnRooftopAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_rooftop, eus_quaternion_4,
        context, callback, &future);
  }
}

ดู "สถานะของอนาคต"

อนาคตจะมี ArFutureState ที่เชื่อมโยงกัน โปรดดูตารางด้านบน

ตรวจสอบสถานะการยึดบนหลังคาของผลลัพธ์ในอนาคต

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

switch (rooftop_anchor_state) {
  case AR_ROOFTOP_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_INTERNAL:
    // The Rooftop anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

ขั้นตอนถัดไป