فناوری پشت سانداسکیپ
هدف از این صفحه ارائهی درکی کلی از نحوهی کارکرد اپلیکیشن سانداسکیپ در پشتصحنه است. برای استفاده از اپلیکیشن نیازی به خواندن این مطلب ندارید، اما چند دلیل برای نوشتن آن وجود دارد:
- برای کمک به هر تازهواردِ علاقهمند به اپلیکیشن تا محدودیتهای آن را درک کند
- برای اینکه به کاربران ایدهای بدهد که با ویژگیهای جدید چه چیز دیگری ممکن است
- برای ارائهی نمایی کلی از عملکرد اپلیکیشن به توسعهدهندگان
دو فناوری وجود دارند که اپلیکیشن را ممکن میسازند، GPS و دادههای OpenStreetMap. GPS به ما ایدهی خوبی از اینکه گوشی کجاست و کجا بوده است میدهد. سپس میتوان از دادههای OpenStreetMap برای یافتن آنچه در نزدیکی است استفاده کرد و آن را برای کاربر توصیف نمود.
جهتنماهای صوتی
از بسیاری جهات اینها از منظر فناوری سادهترین چیزها برای پیادهسازی هستند. با فرض اینکه موقعیت گوشی و جهتی برای گوشی داریم، میتوانیم صدای جهتنما را تغییر دهیم تا به نظر برسد که از آن جهت میآید. ما از یک کتابخانه از Steam Audio برای انجام موقعیتیابی صوتی استفاده میکنیم که از توابع انتقال مرتبط با سر (head related transfer functions) بهره میبرد تا بهترین موقعیتیابی صوتی ممکن را ارائه دهد. تنها کار دیگری که انجام میدهیم این است که صدای جهتنما را تغییر میدهیم تا بسته به زاویهی میان جهت کاربر و موقعیت جهتنما، صدای متفاوتی پخش شود. این زاویهها بسته به جهتنمای انتخابشده (ضربه، جرقه، زنگ و غیره) متفاوتاند و برخی تعداد بیشتری صدا نسبت به بقیه دارند. و این جهتنماهای صوتی در سادهترین سطح خود است.
تنها پیچیدگی اضافی، فرض دربارهی موقعیت گوشی و جهتی است که کاربر به آن نشانه گرفته است. بیایید اینها را بهنوبت بررسی کنیم.
موقعیت مکانی
موقعیتی که GPS برمیگرداند میتواند خطای نسبتاً بزرگی داشته باشد و این به این بستگی دارد که چه مقدار از آسمان برای GPS گوشی قابلمشاهده است و چه تعداد درخت و ساختمان بلند سیگنال GPS را در مسیر رسیدن به گوشی منعکس میکنند.
رویکردی که ما برای فیلتر کردن موقعیت در پیش گرفتهایم، استفاده از چیزی است که به آن تطبیق نقشه (map matching) گفته میشود. این فرض میکند که کاربر بهاحتمال زیاد در حال حرکت در طول یک مسیر یا جادهی نقشهبرداریشده است - ما از اصطلاح «راه» (Way) برای پوشش همهی جادهها، مسیرها و گذرها استفاده میکنیم. تطبیق نقشه به اینکه کاربر کجا بوده است نگاه میکند و با استفاده از جهت حرکت همراه با دادههای نقشهبرداری محلی، محتملترین موقعیت روی یک راه را انتخاب میکند. این رویکرد نهتنها خطاهای ناشی از GPS را در نظر میگیرد، بلکه خطاهای موجود در دادههای نقشه را نیز لحاظ میکند. همهی راهها بهدقت نقشهبرداری نشدهاند و بنابراین آنها هم خطا دارند. برای تعیین اینکه محتملترین راهی که کاربر روی آن قرار دارد کدام است، الگوریتم این موارد را در نظر میگیرد:
- یک راه چقدر به موقعیت GPS و موقعیتهای GPS پیشین نزدیک است
- جهت حرکت - آیا آنها در همان جهت راه حرکت میکنند
- اینکه آیا امکان رسیدن از آخرین موقعیت تطبیقیافته با نقشه به موقعیت جدید از طریق شبکهی راهها وجود دارد. این برای رد کردن جابهجایی میان راههایی که در واقع به هم متصل نیستند لازم است، مثلاً یکی از روی دیگری با یک پل عبور میکند، یا از زیر آن با یک تونل. تطبیق نقشه ممکن است تصمیم بگیرد که هیچ راه نزدیکی وجود ندارد، یا مطمئن نباشد که کاربر روی کدام یک قرار دارد، و در این حالت بهسادگی منتظر موقعیت GPS بعدی میماند و دوباره تلاش میکند تا زمانی که مطمئن شود.
جهت
چندین جهت وجود دارد که ما در نرمافزار ردیابی میکنیم:
- جهتی که گوشی به آن نشانه گرفته است. ما از این هنگامی که گوشی قفل نیست و اپلیکیشن در حال استفاده است بهره میبریم، اما همچنین زمانی که گوشی قفل است نیز، تا زمانی که گوشی بهصورت افقی نگه داشته شده و صفحهی نمایش رو به آسمان باشد. هنگام گذاشتن گوشی در کیف خود خوب است این را به خاطر داشته باشید. اگر گوشی بهصورت افقی در ته کیفی که عمودی نگه داشته شده گذاشته شود، جهت تصادفیای که کیف شما به آن نشانه گرفته توسط اپلیکیشن استفاده میشود.
- جهتی که گوشی در آن حرکت میکند.
- جهت برگرفته از هدفونهای دارای ردیابی سر. ما در حال حاضر از این استفاده نمیکنیم، هرچند اپلیکیشن iOS از آن پشتیبانی میکرد. ما فناوری لازم را برای افزودن آن در آینده در اختیار داریم.
وقتی گوشی قفل است و در کیف قرار دارد، اپلیکیشن از جهت حرکت استفاده میکند. با این حال، اگر کاربر در حال حرکت نباشد، هیچ جهتی در دسترس نیست. وقتی این اتفاق میافتد، جهتنماهای صوتی آرامتر میشوند تا نشان دهند که دانستن جهت فعلی جهتنما ممکن نیست - کاربر میتواند بدون تغییر موقعیت در حال چرخیدن باشد.
برای برخی کاربردهای جهت در اپلیکیشن، جهت به جهتِ راهِ تطبیقیافته با نقشه «چفت» میشود، بنابراین اگر کاربر تقریباً در جهت راه راه میرود، فرض میشود جهت واقعی راه درست است و در آن محاسبات استفاده میشود.
نتیجهگیری
هرچند در نگاه نخست جهتنماهای صوتی ساده به نظر میرسند، استفاده از تطبیق نقشه برای تلاش جهت حذف خطاهای موقعیت و جهت، مقدار قابلتوجهی پیچیدگی به همراه میآورد.
دادههای نقشه
دادههای نقشهای که اپلیکیشن استفاده میکند تقریباً همگی از پروژهی OpenStreetMap سرچشمه میگیرند. ما سروری را اجرا میکنیم که نقشهی کل جهان را در سطوح بزرگنمایی متعدد در خود دارد. هر سطح بزرگنمایی به کاشیها (tiles) تقسیم میشود. سطح بزرگنمایی ۰ شامل ۱ کاشی است، سطح ۱ شامل ۴ کاشی، سطح ۲ شامل ۱۶ کاشی و همینطور تا سطح ۱۴ که برای پوشش کرهی زمین حدود ۲۶۸ میلیون کاشی دارد. هر کاشی شامل چندین لایه است و هر لایه نقاط، خطوط و چندضلعیهایی دارد که میتوان آنها را برای ساختن یک نقشهی گرافیکی رسم کرد. آن نقشهی گرافیکی همان چیزی است که در رابط کاربری گرافیکی اپلیکیشن به کاربر نشان داده میشود. هر نقطه، خط و چندضلعی فرادادهای دارد که توصیف میکند آن چیست. این بیشتر مستقیماً از دادههای OpenStreetMap است، بنابراین یک خط ممکن است یک footway باشد که یک sidewalk است یا یک road که یک minor است
دادهها از طریق یک «سبک» (style) به نقشهی گرافیکی تبدیل میشوند که قواعدی دربارهی نحوهی رسم نقاط، خطوط و چندضلعیهای مختلف در هر لایه دارد، مثلاً چگونه یک گذر رسم شود، چگونه یک جنگل رسم شود، چگونه یک ایستگاه اتوبوس رسم شود. این قواعد میتوانند بسته به سطح بزرگنمایی متفاوت باشند، به همین دلیل است که با بزرگنمایی، نقاط و خطوط بیشتر و بیشتری قابلمشاهده میشوند که هنگام کوچکنمایی دیده نمیشدند، مثلاً ایستگاههای اتوبوس و گذرها.
با تغییر سبک میتوانیم نحوهی نمایش نقشهی رابط کاربری را تغییر دهیم، که «نقشهی دسترسپذیر»ی که در حال آزمایش آن هستیم از همینجا میآید. هدف آن داشتن کنتراست بیشتر و خطوط و متن پررنگتر است. سبک در خود اپلیکیشن تعبیه شده است، بنابراین برای تغییر ظاهر آن لازم نیست نقشهی روی سرور را تغییر دهیم.
اما چگونه از دادههای نقشه برای صدا استفاده میکنیم؟
استفاده از دادههای نقشه برای صدا
ما در حال حاضر از مقدار نسبتاً کمی از دادههای نقشهبرداری برای تولید رابط کاربری صوتی استفاده میکنیم. تقریباً همهی رابط کاربری صوتی فقط از کاشیهای موجود در بیشترین سطح بزرگنمایی استفاده میکند. اپلیکیشن یک شبکهی ۲ در ۲ از کاشیها را در اطراف محل کاربر به هم میدوزد و سپس فقط به چند مورد از لایهها نگاه میکند:
transportation- برای همهی انواع راهها از جمله جادهها، گذرها، راهآهنها و خطوط تراموا.poi- نقاط مورد علاقه، مثلاً مغازهها، مراکز ورزشی، نیمکتها، صندوقهای پست، ایستگاههای اتوبوس و غیره.building- این برایpoiهایی است که بهصورت بیش از یک نقطه نقشهبرداری شدهاند، مثلاً سوپرمارکتهای بزرگ یا تالارهای شهر.
این اپلیکیشن خطوط و چندضلعیها را در مرزهای کاشیها به هم متصل میکند و همهی راهها را به قطعهراهها (Way segments) و تقاطعهای متصل تبدیل میکند. این مهم است زیرا به ما امکان میدهد در طول یک راه جستوجو کنیم تا دریابیم به کجا میتوانیم برسیم.
همهی دادههای تجزیهشده همچنین در قالبی آسان برای جستوجو قرار داده میشوند تا اپلیکیشن بتواند بهراحتی بیابد کدام ویژگیهای نقشه در نزدیکی هستند. در این مرحله دادهها به دستهها طبقهبندی میشوند. دستههای فعلی عبارتاند از:
- جادهها
- جادهها و گذرها (همهی راهها)
- تقاطعها - نقاطی که راهها در آنها به هم میرسند
- ورودیها - اینها نقاطی روی یک ساختمان هستند که بهعنوان ورودی علامتگذاری شدهاند.
- محلهای عبور - محلهای عبور از عرض جاده
- نقاط مورد علاقه (POI) - همهی نقاط مورد علاقه
- ایستگاههای حملونقل - ایستگاههای اتوبوس، ایستگاههای راهآهن، ایستگاههای تراموا و غیره.
- زیردستههای نقاط مورد علاقه:
- اطلاعات
- شیء
- مکان
- نقطهی شاخص
- تحرک
- ایمنی
- سکونتگاهها و زیردستهها (بخش بعدی را ببینید)
- شهرهای بزرگ
- شهرها
- روستاها
- دهکدهها
با وجود این، اپلیکیشن میتواند برای هر موقعیتی بهراحتی بیابد
- «همهی ایستگاههای حملونقل در فاصلهی ۵۰ متری» یا
- «نزدیکترین تقاطعِ پیش روی من» یا
- «نزدیکترین دهکده، روستا، شهر یا شهر بزرگ»
با وجود این، ساختن اعلانهای صوتی فقط مسئلهی پرسوجوی دادهها بر اساس موقعیت و جهت فعلی است. همانطور که کاربر در سراسر یک شبکهی کاشی حرکت میکند، اپلیکیشن آن را بهروزرسانی میکند تا حول موقعیت فعلی متمرکز شود.
دادههای بیشتر
یکی از مشکلات شبکهی دادههای نقشهی بسیار محلی ما این است که به این معناست که ما میتوانیم حداکثر حدود ۱ کیلومتر در هر جهت را «ببینیم». این برای زمانی که در حال توصیف آنچه در پیش روی ماست هستیم اشکالی ندارد، اما گاهی دوست داریم زمینهی بیشتری بدهیم. مثال اصلی این موضوع زمانی است که از اپلیکیشن استفاده میشود و کاربر در حال راه رفتن نیست.
وقتی اپلیکیشن تشخیص میدهد که کاربر با سرعتی بیش از ۵ متر بر ثانیه در حال حرکت است، نحوهی توصیف جهان را تغییر میدهد. بهجای اعلام هر تقاطع و نقطهی مورد علاقه، کمتر اعلام میکند و فقط جادههای نزدیک را اعلام میکند. مشکل این است که دانستن نام یک جاده اگر ندانید در کدام شهر است چندان مفید نیست.
برای تلاش در رفع این موضوع، ما اکنون دادههای نقشه را در سطح بزرگنمایی پایینتری نیز تجزیه میکنیم و دادهها را از لایهی place استخراج میکنیم. این لایه شامل نام شهرها، شهرهای بزرگ، محلهها، روستاها و غیره است. یکی از مشکلات نقشهبرداری چیزها این است که همیشه مرز آشکاری میان این مکانها وجود ندارد. OpenStreetMap گاهی مرزهای شهر را در پایگاهدادهی خود دارد، اما حتی در این صورت، تا زمانی که به نقشهی کاشیبندیشدهی ما میرسد، آن اطلاعات اغلب از دست میرود. آنچه ما داریم موقعیتی است که نام مکانها روی نقشه رسم میشوند. اینها طبقهبندی میشوند و سپس اپلیکیشن نزدیکترین دهکده، روستا، شهر یا شهر بزرگ به کاربر را مییابد و آن را گزارش میکند.
برای بسیاری از شهرهای بزرگ، نام واقعی شهر هرگز اعلام نخواهد شد، زیرا بیشتر شهرهای بزرگ به بخشهای کوچکتری مانند محلهها تقسیم میشوند، اما همانها زمینهی اضافی میدهند و بسیار مفیدند. فقط به یاد داشته باشید که چون اپلیکیشن گزارش میدهد که شما در نزدیکی خیابانی در یک محلهی خاص هستید، این فقط به این معناست که برچسب آن محله نزدیکترین نقطه است و ممکن است نادرست یا حتی آنسوی یک رودخانه باشد.
زمینهی بیشتر
هرچه زمینهی بیشتری بتوان به توصیفها افزود بهتر است، تا زمانی که مختصر و قابلپیشبینی نگه داشته شود. یکی از مشکلاتی که در توصیف تقاطعها دیدیم این بود که اغلب راههای «بدوننام» دخیل بودند. اینها راههایی هستند که نامی ندارند. در دادههای نقشهبرداری اینها ممکن است فقط یک گذرگاه، یک گذر یا یک جادهی خدماتی باشند، اما بدون زمینهی بیشتر در توصیفهای متنی چندان مفید نیست. خوشبختانه، میتوانیم بهتر عمل کنیم، بنابراین کاری که اپلیکیشن انجام میدهد این است که هرگاه قرار است یک راه بدوننام را اعلام کند، میبیند که آیا میتواند زمینهی بیشتری برای آن پیدا کند.
-
آیا یک پیادهرو است؟ بسیاری از مناطق OpenStreetMap اکنون پیادهروها را جدا از جادهها نقشهبرداری کردهاند. اینها معمولاً با
sidewalkبرچسبگذاری میشوند اما معمولاً نمیگویند جادهای که پیادهرو متعلق به آن است کدام است.وقتی اپلیکیشن به یک پیادهروی بدوننام برمیخورد، به دنبال جادهای میگردد که فکر میکند در کنار آن امتداد دارد و از آن برای نامگذاری پیادهرو استفاده میکند. این موضوع برای اعلانهای ما بسیار مهم از آب درمیآید. بهجای اعلام هر تقاطع پیادهرو، همانطور که در طول یک پیادهرو حرکت میکنیم، اعلانها بهگونهای انجام میشوند که گویی در طول جادهی مرتبط حرکت میکنیم. بهجای «در حال حرکت به سمت غرب در طول گذر» داریم «در حال حرکت به سمت غرب در طول جادهی مور». کاربر روی پیادهروی نقشهبرداریشده است، اما توصیف منطقیتر است.
-
آیا به یک راهِ نامدار ختم میشود؟ اغلب اوقات گذرهای پیادهرویی وجود دارند که دو جاده را به هم متصل میکنند. با نگاه کردن به هر دو انتهای گذر میتوانیم بهراحتی آن زمینه را اضافه کنیم بهطوری که در یک جهت ممکن است «گذر به جادهی مور» و در نزدیکشدن از انتهای دیگر ممکن است «گذر به درایو رزلیا» باشد. این کار فقط جایی انجام میشود که گذر تقسیم نشود، اگر به دو گذر بدوننام تقسیم شود آنگاه تلاش نمیکنیم این زمینه را اضافه کنیم.
-
آیا نزدیک یک نشانه ختم میشود؟ اگر یک راه بدوننام نزدیک یک نشانه آغاز یا ختم شود، از آن برای توصیف آن استفاده میشود، مثلاً «گذر به تقاطع درخت بزرگ». کاربر میتواند نشانهها را هر جا که بخواهد اضافه کند و با افزودن نشانهها در طول شبکههای گذر میتواند به کل یک مسیر زمینه اضافه کند.
-
آیا وارد یک نقطهی مورد علاقه میشود یا از آن خارج میشود؟ اگر یک راه بدوننام بیرون از یک نقطهی مورد علاقه آغاز و داخل آن ختم شود (یا برعکس) آنگاه میتوانیم آن زمینه را اضافه کنیم، مثلاً «گذرگاه به پارک لنوکس».
-
آیا نزدیک یک ورودی ختم میشود؟ اگر یک راه بدوننام نزدیکتر به یک ورودی آغاز یا ختم شود آنگاه میتوانیم آن زمینه را اضافه کنیم، مثلاً «جادهی خدماتی به Best Buy».
-
آیا نزدیک یک نقطهی شاخص یا مکان ختم میشود؟ اگر یک راه بدوننام نزدیکتر به یک نقطهی شاخص آغاز یا ختم شود آنگاه میتوانیم آن زمینه را نیز اضافه کنیم، مثلاً «جادهی خدماتی به کلیسای جامع سنت جایلز».
-
آیا یک بنبست است؟ اپلیکیشن هر راه بدوننامی را که به جایی منتهی نمیشود بهعنوان بنبست علامتگذاری میکند.
-
آیا از کنار هیچ پلهای میگذرد؟ اگر راه بدوننام از روی یک پل، از داخل یک تونل یا بالا/پایین پلهها میگذرد آنگاه این موضوع یادداشت شده و به زمینه افزوده میشود. این جدا از برچسبگذاری مقصد است، بنابراین زمینهای مانند «گذر از روی پل به پارک لنوکس» ممکن است.
این زمینهها به ترتیب افزوده میشوند و بنابراین ممکن است در یک جهت «گذر به پارک لین از طریق پلهها» و در جهت دیگر «گذر به پارک لنوکس از طریق پلهها» داشته باشیم. خیابانِ نامدار هنگام خروج از پارک اولویت میگیرد، اما هنگام ورود به پارک از نام پارک استفاده میشود.
زمینهی آینده
زمینههای اضافی گوناگونی وجود دارند که امیدواریم در آینده اضافه کنیم از جمله:
- زمینه برای راههایی که از عوارض آبی خطی پیروی میکنند، مثلاً «گذر در کنار رودخانهی دی»
- زمینه برای راههایی که از لبهی پیکرههای آبی پیروی میکنند «گذر در کنار مخزن میلنگاوی»
- زمینه برای راههایی که از راهآهنها پیروی میکنند، مثلاً «گذر در کنار راهآهن». این حتی میتواند نام خط راهآهن را نیز در بر گیرد
- افزودن محتوای اضافی به پلها و تونلها، اینکه روی چه چیزی یا زیر چه چیزی هستند، مثلاً «گذر از طریق پل روی راهآهن به جادهی مور»
اعلانهای صوتی
اکنون که دادههای نقشه را در قالبی داریم که میتوانیم بهراحتی از آن استفاده کنیم، تولید اعلانها واقعاً نسبتاً ساده است.
اعلانها هنگام راه رفتن
هنگام راه رفتن، اعلانهای صوتیای که میتوانند رخ دهند (به ترتیب اولویت) عبارتاند از:
- توصیف اینکه مقصد فعلی چقدر دور است
- توصیف یک تقاطع پیشِ رو
- توصیف ۵ نقطهی مورد علاقهی نزدیک
همهی اعلانها محدودیت نرخ دارند تا خیلی پُرتکرار نباشند. اگر کاربر از حرکت بایستد آنگاه اعلانها متوقف میشوند، و حتی هنگام حرکت یک اعلان در هر موقعیت GPS جدید تکرار نمیشود. بسامد، مطابق اپلیکیشن iOS، چنین است:
- هر ۶۰ ثانیه برای مقصد فعلی
- هر ۳۰ ثانیه برای یک تقاطع پیشِ رو
- هر ۶۰ ثانیه برای یک نقطهی مورد علاقه
اعلانها را میتوان از طریق منوی تنظیمات فیلتر کرد و قطعاً جا برای گسترش این رفتار وجود دارد.
اعلانها هنگام حرکت سریعتر
هنگام حرکت با سرعتی بیش از ۵ متر بر ثانیه، اعلانِ مقصد فعلی همچنان انجام میشود، اما اعلانهای تقاطع و نقاط مورد علاقه با اعلانی جایگزین میشوند که تقریباً موقعیت کاربر را توصیف میکند. این یک ایستگاه حملونقل نزدیک، یک نقطهی مورد علاقه که ما را در بر میگیرد مثلاً داخل یک پارک بزرگ، یا یک جاده و سکونتگاه نزدیک را میدهد. اینها از دادههای توصیفشدهی پیشین استفاده میکنند و آشکارا جا برای امکان شخصیسازی این موضوع در آینده وجود دارد.
نشانهها و مسیرها
نشانهها و مسیرها در بیشتر موارد فقط یک ویژگی رابط کاربری هستند که نه به GPS و نه واقعاً به دادههای نقشه متکی است. نشانهها مکانهای نامداری هستند که کاربر میخواهد ذخیره کند و مسیرها یک فهرست مرتبشده از آن نشانهها هستند. رابط کاربری برای ساختن هر دو مستقیماً از نسخهی iOS گرفته شده است.
پخش مسیر
پخش مسیر جایی است که مسیرها جان میگیرند. وقتی یک مسیر پخش میشود، یک جهتنمای صوتی در اولین نشانهی مسیر ایجاد میشود. هنگامی که کاربر به آن نشانه نزدیک میشود، مسیر بهطور خودکار جهتنمای صوتی را به نشانهی بعدی در مسیر منتقل میکند. اگر نشانهی دیگری وجود نداشته باشد، آنگاه پخش مسیر پایان مییابد.
نتیجهگیری
امیدواریم این مطلب بینشی دربارهی نحوهی عملکرد اپلیکیشن داده باشد. اپلیکیشن همواره بر اساس بازخورد کاربران در حال توسعه است، بنابراین لطفاً اگر چیزی هست که فکر میکنید میتوان اضافه کرد با ما تماس بگیرید.