עוגנים גיאו-מרחביים הם סוג של עוגן שמאפשר להציב תוכן תלת-ממדי בעולם האמיתי.
סוגים של עוגנים גיאו-מרחביים
קיימים שלושה סוגים של עוגנים גיאו-מרחביים, שכל אחד מהם מטפל בגובה באופן שונה:
עוגני WGS84:
עוגנים של WGS84 מאפשרים להציב תוכן בתלת-ממד בכל קו רוחב, קו אורך וגובה נתונים.עוגנים לפני השטח:
עוגנים לפני השטח מאפשרים להציב תוכן רק באמצעות קווי אורך ורוחב, עם גובה ביחס לפני השטח במיקום הזה. הגובה נקבע ביחס לקרקע או לרצפה, שנקרא על ידי VPS.דיגנים לגגות:
דיבלים לגג מאפשרים להציב תוכן רק לפי קווי אורך ורוחב, בגובה ביחס לגג המבנה במיקום הזה. הגובה נקבע ביחס לחלק העליון של המבנה, כפי שמוכר באמצעות גיאומטריה של Streetscape. כאשר אינה ממוקמת על מבנה, ברירת המחדל של ההגדרה הזו היא גובה פני השטח.
WGS84 | פני השטח | גג רכב | |
---|---|---|---|
מיקום אופקי | קו רוחב, קו אורך | קו רוחב, קו אורך | קו רוחב, קו אורך |
מיקום אנכי | ביחס לגובה WGS84 | ביחס לרמת פני השטח הנקבעת על ידי מפות Google | יחסית לרמת הגג הנקבעת על ידי מפות Google |
צריך לפתור בעיה בשרת? | לא | כן | כן |
דרישות מוקדמות
לפני שממשיכים, חשוב להפעיל את ה-Geospatial API.
מיקום עוגנים גיאו-מרחביים
לכל סוג עוגן יש ממשקי API ייעודיים שנועדו ליצור אותם. מידע נוסף זמין במאמר סוגים של עוגנים גיאו-מרחביים.
יצירת עוגן מבדיקה של היט
אפשר גם ליצור עוגן גיאו-מרחבי מתוצאת בדיקת ההיט.
משתמשים בפונקציה Pose מבדיקת ההיט וממירים אותה ל-GeospatialPose
. ניתן להשתמש בו כדי למקם כל אחד מ-3 סוגי העוגנים שמתוארים.
קבלת תנוחה גיאו-מרחבית מתנוחת AR
AREarthManager.Convert(Pose)
מספק דרך נוספת לקביעת קווי האורך והרוחב על ידי המרה של תנוחת AR לתנוחה גיאו-מרחבית.
קבלת תנוחת AR מתנוחה גיאו-מרחבית
AREarthManager.Convert(GeospatialPose)
ממירה מיקום אופקי, גובה וסיבוב רבעים שצוינו על-ידי כדור הארץ ביחס למסגרת קואורדינטית ממזרח-לדרום לתנוחת AR ביחס לקואורדינטה העולמית GL.
בחירת השיטה המתאימה לתרחיש לדוגמה
לכל שיטה ליצירת עוגן יש תוספות שחשוב לזכור:
- כשמשתמשים בגיאומטריה של Streetscape, כדאי להשתמש ב-hit-test כדי לצרף תוכן לבניין.
- יש עדיפות לעוגנים בפני שטח או לגג על פני עוגנים מסוג WGS84, מאחר שהם משתמשים בערכי גובה שנקבעים על ידי מפות Google.
קביעת קווי האורך והרוחב של מיקום
יש שלוש דרכים שבאמצעותן אפשר לחשב את קווי האורך והרוחב של מיקום:
- אפשר להשתמש ב-Geospatial Creator כדי להציג ולהעשיר את העולם באמצעות תוכן בתלת-ממד, מבלי להגיע פיזית למיקום. כך ניתן למקם תוכן תלת-ממדי עשיר באופן חזותי באמצעות מפות Google בעורך Unity. קו הרוחב, קו האורך, הסיבוב והגובה של התוכן יחושבו בשבילכם באופן אוטומטי.
- שימוש במפות Google
- שימוש ב-Google Earth. חשוב לשים לב שהשגת קואורדינטות אלה באמצעות Google Earth, בניגוד למפות Google, תספק מרווח שגיאה של עד כמה מטרים.
- מעבר למיקום הפיזי
שימוש במפות Google
כדי לקבל את קווי האורך והרוחב של מיקום באמצעות מפות Google:
נכנסים למפות Google במחשב.
מנווטים אל שכבות > עוד.
משנים את סוג המפה ללוויין ומנקים את תיבת הסימון תצוגת כדור הארץ בפינה הימנית התחתונה של המסך.
כך תכפה פרספקטיבה דו-ממדית ותבטל שגיאות אפשריות שעשויות להגיע מתצוגה תלת-ממדית בזווית.
במפה, לוחצים לחיצה ימנית על המיקום ובוחרים את קו האורך/רוחב כדי להעתיק אותו ללוח.
שימוש ב-Google Earth
אפשר לחשב את קווי האורך והרוחב של מיקום מסוים ב-Google Earth על ידי לחיצה על מיקום בממשק המשתמש וקריאת הנתונים מפרטי הסמן.
כדי לקבל את קווי האורך והרוחב של מיקום מסוים באמצעות Google Earth:
עוברים אל Google Earth במחשב.
מנווטים לתפריט ההמבורגר ובוחרים באפשרות סגנון המפה.
מעבירים את המתג בניינים בתלת-ממד למצב מושבת.
לאחר השבתת המתג בניינים בתלת-ממד, לוחצים על סמל הסיכה כדי להוסיף סמן במיקום שנבחר.
מציינים את הפרויקט שרוצים להכיל את הסמן ולוחצים על Save (שמירה).
בשדה כותרת של הסמן, נותנים שם לסמן.
לוחצים על החץ חזרה בחלונית הפרויקט ובוחרים בתפריט פעולות נוספות.
בתפריט, בוחרים באפשרות ייצוא כקובץ KML.
קובץ ה-KLM מדווח את קווי הרוחב, קווי האורך והגובה של סמן בתג <coordinates>
כשהם מופרדים בפסיקים, באופן הבא:
<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>
אין להשתמש בקווי הרוחב והאורך שמופיעים בתגי <LookAt>
, שמציינים את מיקום המצלמה, ולא את המיקום.
מעבר למיקום הפיזי
ניתן לחשב את הגובה של מיקום מסוים על ידי הגעה אליו פיזית ותצפית מקומית.
מקבלים את הקווטרניון הסיבובי
GeospatialPose.EunRotation
שולפת את הכיוון מתנוחה גיאו-מרחבית ומפיקה רבועה שמייצגת את מטריצת הסיבוב ומשנה וקטור מהיעד למערכת הקואורדינטות של מזרח-צפון-צפון (EUN). +X נקודות לכיוון מזרח, Y+ נקודות למעלה מכוח הכבידה ו-Z+ נקודות צפונה.
עוגנים ל-WGS84
עוגן WGS84 הוא סוג של עוגן שמאפשר למקם תוכן בתלת-ממד בכל קו רוחב, קו אורך וגובה נתונים. כדי למקם אותו בעולם האמיתי, הוא מסתמך על תנוחה ועל כיוון. המיקום מורכב מקווי רוחב, קווי אורך וגובה, שמצוינים במערכת הקואורדינטות WGS84. הכיוון כולל סיבוב קווטרניון.
הגובה מדווח במטרים מעל לאליפסואיד WGS84 שאליו מתייחסים פני הקרקע לא באפס. האפליקציה שלך אחראית לספק את הקואורדינטות האלה עבור כל עוגן שנוצר.
מציבים עוגן WGS84 בעולם האמיתי
איך לקבוע את הגובה של מיקום מסוים
יש כמה דרכים לקבוע את הגובה של מיקום כדי למקם בו עוגנים:
- אם מיקום העוגן נמצא פיזית בקרבת המשתמש, אפשר להשתמש בגובה שדומה לגובה המכשיר של המשתמש.
- אחרי שמזינים את קווי האורך והרוחב, משתמשים ב-Elevation API כדי לקבל גובה לפי המפרט של EGM96. צריך להמיר את הגובה EGM96 של ה-API של מפות Google ל-WGS84 לצורך השוואה מול הגובה
GeospatialPose
. אפשר לראות את ה-GeoidEval שכולל גם שורת פקודה וגם ממשק HTML. ה-API של מפות Google מדווח על קווי אורך ורוחב בהתאם למפרט WGS84, ללא אריזה. - את קו הרוחב, קו האורך והגובה של מיקום מסוים אפשר לקבל מ-Google Earth. כך מתקבל מרווח שגיאה של עד כמה מטרים. בקובץ ה-KML יש להשתמש בקווי אורך ורוחב מתגי
<coordinates>
, ולא מתגי<LookAt>
. - אם עוגן קיים נמצא בקרבת מקום וגם אם אתם לא על שיפוע תלול, ייתכן שתוכלו להשתמש בגובה מה
GeospatialPose
של המצלמה בלי להשתמש במקור אחר, כמו ה-API של מפות Google.
יצירת מודעות עוגן
אחרי שמזינים את קווי הרוחב, קו האורך, הגובה והסיבוב, משתמשים ב-ARAnchorManagerExtensions.AddAnchor()
כדי לעגן תוכן לקואורדינטות הגיאוגרפיות שבחרתם.
if (earthTrackingState == TrackingState.Tracking)
{
var anchor =
AnchorManager.AddAnchor(
latitude,
longitude,
altitude,
quaternion);
var anchoredAsset = Instantiate(GeospatialAssetPrefab, anchor.transform);
}
דיבלים לשטח
עוגן פני שטח הוא סוג של עוגן שמאפשר למקם אובייקטים ב-AR רק לפי קווי רוחב ואורך, תוך מינוף מידע מ-VPS כדי למצוא את הגובה המדויק מעל פני הקרקע.
במקום להזין את הגובה הרצוי, תציג את הגובה מעל לפני השטח. כשהערך הוא אפס, העוגן יהיה ישר מול פני השטח.
הגדרה של מצב חיפוש המטוס
חיפוש מישור הוא אופציונלי ולא נדרש כדי להשתמש בעוגנים. הערה: נעשה שימוש רק במישורים אופקיים. מישורים אופקיים יעזרו ליישור דינמי של עוגנים לפנים.
חשוב לשים לב שהעוגנים בפני השטח מושפעים מ-Horizontal
ומ-Horizontal | Vertical
משתמשים בתפריט הנפתח מצב זיהוי כדי להגדיר את מצב הזיהוי:
יצירת עוגן לפני שטח באמצעות Async API החדש
כדי ליצור עוגן ולמקם אותו, יש להתקשר אל ARAnchorManagerExtensions.resolveAnchorOnTerrainAsync()
.
העוגן לא יהיה מוכן מיד וצריך להיפתר. לאחר פתרון הבעיה, היא תהיה זמינה בResolveAnchorOnTerrainPromise
.
public GameObject TerrainAnchorPrefab;
public void Update()
{
ResolveAnchorOnTerrainPromise terrainPromise =
AnchorManager.ResolveAnchorOnTerrainAsync(
latitude, longitude, altitudeAboveTerrain, eunRotation);
// The anchor will need to be resolved.
StartCoroutine(CheckTerrainPromise(terrainPromise));
}
private IEnumerator CheckTerrainPromise(ResolveAnchorOnTerrainPromise promise)
{
yield return promise;
var result = promise.Result;
if (result.TerrainAnchorState == TerrainAnchorState.Success &&
result.Anchor != null)
{
// resolving anchor succeeded
GameObject anchorGO = Instantiate(TerrainAnchorPrefab,
result.Anchor.gameObject.transform);
anchorGO.transform.parent = result.Anchor.gameObject.transform;
}
else
{
// resolving anchor failed
}
yield break;
}
בדיקת מצב ההבטחה
להבטחה יהיה PromiseState
משויך.
ארץ | התיאור |
---|---|
Pending |
הפעולה עדיין בהמתנה. |
Done |
הפעולה הושלמה והתוצאה זמינה. |
Cancelled |
הפעולה בוטלה. |
בדיקת מצב העוגן של פני השטח בתוצאת Promise
הערך TerrainAnchorState
שייך לפעולה האסינכרונית והוא חלק מתוצאת ההבטחה הסופית.
switch (result.TerrainAnchorState)
{
case TerrainAnchorState.Success:
// Anchor has successfully resolved
break;
case TerrainAnchorState.ErrorUnsupportedLocation:
// The requested anchor is in a location that isn't supported by the Geospatial API.
break;
case TerrainAnchorState.ErrorNotAuthorized:
// An error occurred while authorizing your app with the ARCore API. See
// https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
// for troubleshooting steps.
break;
case TerrainAnchorState.ErrorInternal:
// The Terrain anchor could not be resolved due to an internal error.
break;
default:
break;
}
דיבלים לגגות
דיבלים לגגות הם סוג של עיגון ודומים מאוד לעוגנים לגג שצוינו למעלה. ההבדל הוא שתספק את הגובה מעל הגג ולא את הגובה מעל פני השטח.
יצירת עוגן בגג באמצעות ה-Async API החדש
העוגן לא יהיה מוכן מיד וצריך להיפתר.
כדי ליצור עוגן בגג ולהציב אותו, יש להפעיל את המספר ARAnchorManagerExtensions.resolveAnchorOnRooftopAsync()
. באופן דומה לעוגנים בפני שטח, ניתן לגשת גם אל PromiseState
של Promise. לאחר מכן תוכלו לבדוק את תוצאת ההבטחה כדי לגשת ל-RooftopAnchorState
.
public GameObject RooftopAnchorPrefab;
public void Update()
{
ResolveAnchorOnRooftopPromise rooftopPromise =
AnchorManager.ResolveAnchorOnRooftopAsync(
latitude, longitude, altitudeAboveRooftop, eunRotation);
// The anchor will need to be resolved.
StartCoroutine(CheckRooftopPromise(rooftopPromise));
}
private IEnumerator CheckRooftopPromise(ResolveAnchorOnTerrainPromise promise)
{
yield return promise;
var result = promise.Result;
if (result.RooftopAnchorState == RooftopAnchorState.Success &&
result.Anchor != null)
{
// resolving anchor succeeded
GameObject anchorGO = Instantiate(RooftopAnchorPrefab,
result.Anchor.gameObject.transform);
anchorGO.transform.parent = result.Anchor.gameObject.transform;
}
else
{
// resolving anchor failed
}
yield break;
}
בדיקת מצב ההבטחה
ל-Promise יהיה PromiseState
משויך, ראו טבלה למעלה.
בדיקת מצב העוגן בגג של התוצאה Promise
הערך RooftopAnchorState
שייך לפעולה האסינכרונית והוא חלק מתוצאת ההבטחה הסופית.
switch (result.RooftopAnchorState)
{
case TerrainAnchorState.Success:
// Anchor has successfully resolved
break;
case RooftopAnchorState.ErrorUnsupportedLocation:
// The requested anchor is in a location that isn't supported by the Geospatial API.
break;
case RooftopAnchorState.ErrorNotAuthorized:
// An error occurred while authorizing your app with the ARCore API. See
// https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#terrainanchorstate_errornotauthorized
// for troubleshooting steps.
break;
case RooftopAnchorState.ErrorInternal:
// The Rooftop anchor could not be resolved due to an internal error.
break;
default:
break;
}
המאמרים הבאים
- חשוב לוודא שהבנתם את מכסת השימוש ב-API גיאו-מרחבית.