از لنگرهای Geospatial برای قرار دادن محتوای واقعی در Android NDK استفاده کنید

لنگرهای جغرافیایی نوعی لنگر هستند که به شما امکان می دهند محتوای سه بعدی را در دنیای واقعی قرار دهید.

انواع لنگرهای جغرافیایی

سه نوع لنگر ژئوفضایی وجود دارد که هر کدام به طور متفاوتی ارتفاع را کنترل می کنند:

  1. لنگرهای WGS84 :
    لنگرهای WGS84 به شما امکان می دهند محتوای سه بعدی را در هر عرض جغرافیایی، طول جغرافیایی و ارتفاع مشخصی قرار دهید.

  2. لنگرهای زمین :
    لنگرهای زمین به شما امکان می دهند محتوا را فقط با استفاده از طول و عرض جغرافیایی با ارتفاع نسبت به زمین در آن موقعیت قرار دهید. ارتفاع نسبت به همکف یا طبقه که توسط VPS شناخته می شود تعیین می شود.

  3. لنگرهای پشت بام :
    لنگرهای پشت بام به شما امکان می دهند محتوا را فقط با استفاده از طول و عرض جغرافیایی با ارتفاع نسبت به پشت بام ساختمان در آن موقعیت قرار دهید. ارتفاع نسبت به بالای یک ساختمان که توسط Streetscape Geometry شناخته می شود تعیین می شود. زمانی که روی ساختمان قرار نگیرد، به طور پیش‌فرض ارتفاع زمین را نشان می‌دهد.

WGS84 زمین پشت بام
موقعیت افقی طول جغرافیایی عرض جغرافیایی طول جغرافیایی عرض جغرافیایی طول جغرافیایی عرض جغرافیایی
موقعیت عمودی نسبت به ارتفاع WGS84 نسبت به سطح زمین تعیین شده توسط Google Maps نسبت به سطح پشت بام تعیین شده توسط Google Maps
نیاز به حل و فصل سرور دارد؟ خیر آره آره

پیش نیازها

قبل از ادامه، مطمئن شوید که Geospatial API را فعال کرده اید.

لنگرهای جغرافیایی را قرار دهید

هر نوع لنگر دارای APIهای اختصاصی برای ایجاد آنها است. برای اطلاعات بیشتر به انواع لنگرهای جغرافیایی مراجعه کنید.

یک لنگر از یک تست ضربه ایجاد کنید

شما همچنین می توانید یک لنگر Geospatial از یک نتیجه تست ضربه ایجاد کنید. از Pose از تست ضربه استفاده کنید و آن را به ArGeospatialPose تبدیل کنید. از آن برای قرار دادن هر یک از 3 نوع لنگر شرح داده شده استفاده کنید.

از یک ژست AR یک ژئوفضایی بگیرید

ArEarth_getGeospatialPose() یک راه اضافی برای تعیین طول و عرض جغرافیایی با تبدیل یک Pose AR به یک Pose Geospatial ارائه می دهد.

یک ژست واقعیت افزوده از یک موقعیت جغرافیایی

ArEarth_getPose() یک موقعیت افقی، ارتفاع و چرخش ربعانی مشخص شده توسط زمین را با توجه به یک قاب مختصات شرق به بالا به جنوب به یک وضعیت AR با توجه به مختصات جهان GL تبدیل می کند.

انتخاب کنید کدام روش مناسب مورد استفاده شما است

هر روش ایجاد یک لنگر دارای معاوضه هایی است که باید به خاطر داشته باشید:

  • هنگام استفاده از Streetscape Geometry ، از تست ضربه برای پیوست کردن محتوا به ساختمان استفاده کنید.
  • لنگرهای زمینی یا پشت بام را به لنگرهای WGS84 ترجیح دهید زیرا از مقادیر ارتفاع تعیین شده توسط Google Maps استفاده می کنند.

طول و عرض جغرافیایی یک مکان را تعیین کنید

سه روش برای محاسبه طول و عرض جغرافیایی یک مکان وجود دارد:

  • از Geospatial Creator برای مشاهده و تقویت جهان با محتوای سه بعدی بدون نیاز به رفتن فیزیکی به مکانی استفاده کنید. این به شما امکان می دهد محتوای سه بعدی همه جانبه را به صورت بصری با استفاده از نقشه های گوگل در ویرایشگر Unity قرار دهید. طول و عرض جغرافیایی، چرخش و ارتفاع محتوا به طور خودکار برای شما محاسبه می شود.
  • از نقشه های گوگل استفاده کنید
  • از Google Earth استفاده کنید. توجه داشته باشید که به دست آوردن این مختصات با استفاده از گوگل ارث، بر خلاف نقشه گوگل، تا چندین متر حاشیه خطا برای شما ایجاد می کند.
  • به مکان فیزیکی بروید

از نقشه های گوگل استفاده کنید

برای دریافت طول و عرض جغرافیایی یک مکان با استفاده از Google Maps:

  1. در رایانه رومیزی خود به Google Maps بروید.

  2. به لایه ها > بیشتر بروید.

  3. نوع Map را به Satellite تغییر دهید و تیک Globe View را در گوشه سمت چپ پایین صفحه پاک کنید.

    این کار باعث می شود که یک چشم انداز دوبعدی ایجاد شود و خطاهای احتمالی که می تواند از نمای سه بعدی زاویه دار ایجاد شود را حذف می کند.

  4. روی نقشه، روی مکان کلیک راست کرده و طول جغرافیایی/طول جغرافیایی را انتخاب کنید تا آن را در کلیپ بورد خود کپی کنید.

از Google Earth استفاده کنید

می‌توانید با کلیک کردن روی یک مکان در رابط کاربری و خواندن داده‌ها از جزئیات مکان‌نما، طول و عرض جغرافیایی یک مکان را از Google Earth محاسبه کنید.

برای دریافت طول و عرض جغرافیایی یک مکان با استفاده از Google Earth:

  1. در رایانه رومیزی خود به Google Earth بروید.

  2. به منوی همبرگر بروید و Map Style را انتخاب کنید.

  3. سوئیچ ساختمان های سه بعدی را خاموش کنید.

  4. هنگامی که سوئیچ ساختمان های سه بعدی خاموش شد، روی نماد پین کلیک کنید برای اضافه کردن یک مکان در مکان انتخاب شده.

  5. پروژه ای را مشخص کنید که نشان مکان شما را داشته باشد و روی ذخیره کلیک کنید.

  6. در قسمت عنوان برای نشان مکان، یک نام برای نشان مکان وارد کنید.

  7. روی فلش عقب کلیک کنید در پنجره پروژه و انتخاب کنید منوی اقدامات بیشتر .

  8. از منو Export as file KML را انتخاب کنید.

فایل KLM طول، طول و ارتفاع را برای یک مکان در تگ <coordinates> که با کاما از هم جدا شده است، به شرح زیر گزارش می دهد:

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

از طول و عرض جغرافیایی تگ های <LookAt> که موقعیت دوربین را مشخص می کنند، نه مکان را استفاده نکنید .

به مکان فیزیکی بروید

شما می توانید ارتفاع یک مکان را با رفتن به آنجا به صورت فیزیکی و انجام یک مشاهده محلی محاسبه کنید.

کواترنیون چرخش را بدست آورید

ArGeospatialPose_getEastUpSouthQuaternion() جهت گیری را از یک Pose Geospatial استخراج می کند و یک کواترنیون را خروجی می دهد که نشان دهنده ماتریس چرخش است که یک بردار را از هدف به سیستم مختصات شرق به بالا به جنوب (EUS) تبدیل می کند. X+ به شرق، Y+ به سمت بالا و Z+ به سمت جنوب اشاره می کند. مقادیر به ترتیب {x, y, z, w} نوشته می‌شوند.

لنگر WGS84

لنگر WGS84 نوعی لنگر است که به شما امکان می دهد محتوای سه بعدی را در هر عرض جغرافیایی، طول و ارتفاع معین قرار دهید. برای قرار گرفتن در دنیای واقعی به پوز و جهت گیری متکی است. این موقعیت شامل یک عرض جغرافیایی، طول جغرافیایی و ارتفاع است که در سیستم مختصات WGS84 مشخص شده است. جهت گیری از یک چرخش کواترنیونی تشکیل شده است.

ارتفاع بر حسب متر بالاتر از بیضی مرجع WGS84 گزارش شده است به طوری که سطح زمین در صفر نیست . برنامه شما مسئول ارائه این مختصات برای هر لنگر ایجاد شده است.

یک لنگر WGS84 را در دنیای واقعی قرار دهید

ارتفاع یک مکان را تعیین کنید

چند راه برای تعیین ارتفاع مکان برای قرار دادن لنگر وجود دارد:

  • اگر مکان لنگر از نظر فیزیکی نزدیک کاربر است، می‌توانید از ارتفاعی مشابه ارتفاع دستگاه کاربر استفاده کنید.
  • هنگامی که طول و عرض جغرافیایی را دارید، از Elevation API برای بدست آوردن ارتفاع بر اساس مشخصات EGM96 استفاده کنید. برای مقایسه با ارتفاع ArGeospatialPose باید ارتفاع Maps API EGM96 را به WGS84 تبدیل کنید. GeoidEval را ببینید که دارای خط فرمان و رابط HTML است. Maps API طول و عرض جغرافیایی را مطابق با مشخصات WGS84 از جعبه گزارش می دهد.
  • می‌توانید طول، طول و ارتفاع یک مکان را از Google Earth دریافت کنید. این به شما یک حاشیه خطا تا چند متر می دهد. از طول، طول و ارتفاع از تگ های <coordinates> استفاده کنید، نه تگ های <LookAt> را در فایل KML.
  • اگر یک لنگر موجود نزدیک است و اگر در شیب تند نیستید، ممکن است بتوانید از ارتفاع ArGeospatialPose دوربین بدون استفاده از منبع دیگری مانند Maps API استفاده کنید.

لنگر را ایجاد کنید

هنگامی که ربع طول جغرافیایی، طول جغرافیایی، ارتفاع و چرخش را دارید، از 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 برای یافتن ارتفاع دقیق از سطح زمین استفاده کنید.

به جای اینکه ارتفاع مورد نظر را وارد کنید، ارتفاع بالای زمین را ارائه می دهید. هنگامی که این صفر باشد، لنگر هم سطح با زمین خواهد بود.

حالت هواپیمایابی را تنظیم کنید

پیدا کردن هواپیما اختیاری است و برای استفاده از لنگرها لازم نیست. توجه داشته باشید که فقط از صفحات افقی استفاده می شود. هواپیماهای افقی به هم ترازی پویا لنگرهای زمین در زمین کمک خواهند کرد.

از ArPlaneFindingMode برای انتخاب نحوه شناسایی هواپیماها توسط برنامه استفاده کنید.

با استفاده از Async API جدید یک لنگر Terrain ایجاد کنید

برای ایجاد و قرار دادن لنگر Terrain، 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 متعلق به عملیات ناهمزمان است و بخشی از نتیجه نهایی Future است.

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

لنگرهای پشت بام

پشت بام لنگر قهرمان

لنگرهای پشت بام نوعی لنگر هستند و بسیار شبیه به لنگرهای Terrain در بالا هستند. تفاوت این است که شما به جای ارتفاع بالای زمین، ارتفاع بالای پشت بام را ارائه می دهید.

یک لنگر پشت بام با استفاده از Async API جدید ایجاد کنید

لنگر بلافاصله آماده نخواهد شد و باید حل شود.

برای ایجاد و قرار دادن یک لنگر پشت بام، ArEarth_resolveAnchorOnRooftopAsync() را فراخوانی کنید. مشابه لنگرهای Terrain، به ArFutureState of the Future نیز دسترسی خواهید داشت. سپس می توانید نتیجه Future را برای دسترسی به 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);
  }
}

وضعیت آینده را بررسی کنید

Future یک ArFutureState مرتبط خواهد داشت، جدول بالا را ببینید.

وضعیت لنگر پشت بام نتیجه آینده را بررسی کنید

ArRooftopAnchorState به عملیات ناهمزمان تعلق دارد و بخشی از نتیجه نهایی Future است.

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

بعدش چی