این سند توضیح میدهد که حصار جغرافیایی سمت کلاینت چیست، چه زمانی باید از آن استفاده کرد و چگونه میتوان آن را در موارد استفاده در یک برنامه تلفن همراه به کار برد. همچنین نحوه پیادهسازی یک مثال در اندروید با استفاده از Google Navigation SDK را نشان میدهد.

شرکتها اغلب نیاز دارند بدانند که یک دستگاه تلفن همراه چه زمانی وارد یا از یک منطقه خاص خارج میشود. این کار با حفظ مرزهای جغرافیایی مجازی یا ژئوفنسها انجام میشود که به نرمافزار امکان میدهد هنگام عبور دستگاه از یک مرز، رویدادها را فعال کند.
درک اینکه چه زمانی یک وسیله نقلیه خاص از یک مرز عبور میکند، برای موارد استفاده متعددی مانند موارد زیر مهم است:
- تعامل با مشتری : کسبوکارها میتوانند از حصار جغرافیایی برای ارسال اعلانهای فوری به کاربران نهایی در مورد پیشنهادات ویژه، رویدادها یا محصولات جدید استفاده کنند.
- امنیت و ایمنی : کسبوکارها میتوانند از حصار جغرافیایی برای ایجاد محیطهای مجازی در اطراف مناطق حساس، مانند مراکز داده یا انبارها، استفاده کنند و در صورت ورود یا خروج کسی از منطقه، به پرسنل امنیتی هشدار دهند.
- حمل و نقل : مشاغل میتوانند از حصار جغرافیایی برای ردیابی موقعیت مکانی وسایل نقلیه و بهینهسازی مسیرها و برنامهها استفاده کنند.
بنابراین مهم است که بدانید چگونه آن مناطق (چندضلعیها) را در یک برنامهی رو به روی کلاینت نمایش دهید. این برنامه باید موقعیت مکانی دستگاه را ردیابی کند و بررسی کند که آیا از یک محدودهی جغرافیایی خاص عبور کرده است یا خیر.
محدوده
این سند بر پیادهسازی حصار جغرافیایی (geofencing) در سمت کلاینت تمرکز دارد. این بدان معناست که برنامه کلاینت باید موارد زیر را داشته باشد:
- چندضلعیهایی که باید برای بررسی وجود نقص در آنها بررسی شوند؛
- موقعیت مکانی کاربر در لحظه
- منطقی برای بررسی اینکه آیا مکان فعلی داخل یا خارج از هر یک از چندضلعیها است.
این راهنما شامل مثالهایی در اندروید است، اما روشهای معادلی برای انجام این کار در iOS وجود دارد. سرویس موقعیت مکانی اندروید یک پیادهسازی داخلی برای حصارهای جغرافیایی دایرهای دارد که میتوانید اینجا مشاهده کنید. کد مرجع و توضیحات زیر نقطه شروعی برای پیادهسازیهای پیچیدهتر است.
SDK ناوبری
کیت توسعه نرمافزار ناوبری (Navigation SDK) یک کتابخانه بومی اندروید/iOS است که به اپلیکیشن راننده اضافه شده است. این کیت مسئول موارد زیر است:
- دریافت مکانهای ثبتشده از جادهها از طریق برنامهای که آن را اجرا میکند. این روش دقیقتر از FusedLocationProvider (FLP) اندروید است، زیرا از شبکه جادهای گوگل برای ثبت مکانها به نزدیکترین بخش جاده استفاده میکند که ETA و سایر اطلاعات را از FLP بسیار دقیقتر میکند.
- تجربهای گام به گام که به رانندگان اجازه میدهد با در نظر گرفتن ترافیک لحظهای و سایر محدودیتهای مسیر، به طور مؤثر از نقطه A به نقطه B برسند.
- اجرای رویدادها از طریق شنوندههای رویداد و فراخوانیهای ثبتشده.
شنوندگان
کیت توسعه نرمافزار ناوبری (Navigation SDK) شنوندههای زیادی دارد که میتوانید از آنها استفاده کنید. به چند مورد اشاره میکنم:
- تغییرات مکان از طریق ارائهدهنده RoadSnappedLocation .
- رویدادهای تغییر مسیر (کاربر چرخش U، چرخش به چپ و غیره را از دست میدهد و از مسیر پیشنهادی منحرف میشود) را از طریق ReroutingListener تغییر مسیر دهید.
- رویدادهای ورود (رسیدن کاربر به مقصد برنامهریزیشده) از طریق ArrivalListener .
- رویدادهای مسافت باقیمانده و زمان رسیدن به مقصد (زمان رسیدن راننده به مقصد بر اساس متر و زمان رسیدن راننده به مقصد بر اساس زمان) هر دو از طریق .RemainingTimeOrDistanceChangedListener قابل دسترسی هستند.
در این راهنما فقط از RoadSnappedLocation Provider و LocationListener آن استفاده شده است.
راهکار تعیین محدوده جغرافیایی سمت کلاینت
حالا بیایید ساخت قابلیت تعیین محدوده جغرافیایی (geofencing) سمت کلاینت را شروع کنیم. در مثال زیر، ما Navigation SDK را داریم که در حالت نوبتی عمل میکند و یک چندضلعی در مسیر تعریف شده است که نشاندهنده محدوده جغرافیایی ما است.
- Geofenceها در BigQuery ذخیره میشوند و توسط backend شما دریافت میشوند.
- بخش مدیریت به صورت دورهای، حصارهای جغرافیایی را به برنامههای درایو ارسال میکند.
- درایور پیمایش میکند و اپلیکیشن درایور مرتباً در حال بررسی محدودههای جغرافیایی برای یافتن محرک است.
- اپلیکیشن درایور، بکاند را از وقوع یک رویداد آگاه میکند تا بتواند اقدام کند.
همزمان با حرکت وسیله نقلیه در طول مسیر، برنامه مرتباً بررسی میکند که آیا چندضلعی نقض شده است یا خیر. وقتی برنامه تشخیص میدهد که از یک حصار جغرافیایی عبور کرده است، پیامی در رابط کاربری نمایش داده میشود که میگوید: حصار جغرافیایی نقض شد .
پیکربندی وابستگیها برای Android-Maps-Utils
این راهکار از Android-Maps-Utils، یک کتابخانه متنباز حاوی ابزارهایی که برای طیف وسیعی از برنامههای کاربردی با استفاده از Google Maps Android API مفید هستند، استفاده میکند.
این کتابخانه عمومی است و در گیتهاب میزبانی میشود و از طریق آدرس زیر قابل دسترسی است:
- اندروید : https://github.com/googlemaps/android-maps-utils
- آیاواس : https://github.com/googlemaps/google-maps-ios-utils
برای گنجاندن این کتابخانه در برنامه اندروید خود (محدوده این سند)، باید فایل build.gradle خود را برای گنجاندن آن تغییر دهید. توجه داشته باشید که این فایل build.gradle برای ماژول (برنامهای) است که در حال ساخت آن هستید، نه در سطح پروژه.
dependencies {
...
// Utilities for Maps SDK for Android (requires Google Play Services)
implementation 'com.google.maps.android:android-maps-utils:2.3.0'
}
سپس، پس از همگامسازی Gradle با آخرین فایل build.gradle خود، میتوانید com.google.maps.android.PolyUtil را در فایل جاوا خود وارد کنید:
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.maps.android.PolyUtil;
حصارهای جغرافیایی خود را تعریف کنید
توجه داشته باشید که در اینجا PolygonOptions نیز وارد میشود. دلیل این امر این است که این چیزی است که برای نمایش چندضلعی استفاده میشود:
mPolygonOptions = new PolygonOptions()
.add(new LatLng(29.4264525,-98.4948758))
.add(new LatLng(29.4267029,-98.4948758))
.add(new LatLng(29.4273742,-98.4945822))
.add(new LatLng(29.4264562,-98.4943592))
.fillColor(0x0000ff36)
.strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
.strokeColor(Color.BLUE)
.strokeWidth(5);
همانطور که در بالا میبینید، در اینجا ما یک چندضلعی ثابت با مختصات از پیش تعیینشده - (طول و عرض جغرافیایی) - تعریف میکنیم. با این حال، در سناریوهای واقعی، این مختصات و تعاریف چندضلعی اغلب از یک نقطه پایانی backend میآیند و احتمالاً از راه دور دریافت میشوند. این بدان معناست که چندضلعیها باید توسط برنامه به صورت آنی ایجاد شوند.
برای جزئیات بیشتر در مورد آنچه میتوان در PolygonOptions مشخص کرد، لطفاً اینجا را بررسی کنید.
شما باید چندضلعیها را در حین ایجاد فرگمنت یا اکتیویتی خود تعریف کنید. برای مثال:
protected void onCreate(Bundle savedInstanceState) {
...
mPolygonOptions = new PolygonOptions()
.add(new LatLng(29.4264525,-98.4948758))
.add(new LatLng(29.4267029,-98.4948758))
.add(new LatLng(29.4273742,-98.4945822))
.add(new LatLng(29.4264562,-98.4943592))
.fillColor(0x0000ff36)
.strokePattern(Arrays.asList(new Dash(45.0f), new Gap(10.0f)))
.strokeColor(Color.BLUE)
.strokeWidth(5);
...// more code here
}
به بهروزرسانیهای موقعیت مکانی گوش دهید
پس از تعریف geofence های خود، فقط باید یک شنونده بهروزرسانی موقعیت مکانی ایجاد کنید تا در رویداد فوقالذکر در Navigation SDK با نام RoadSnappedLocationProvider مشترک شود که آخرین موقعیت مکانی دستگاه را برمیگرداند.
mLocListener = new RoadSnappedLocationProvider.LocationListener() {
@Override
public void onLocationChanged(Location snapped) {
LatLng snappedL = new LatLng(snapped.getLatitude(), snapped.getLongitude());
if(PolyUtil.containsLocation(snappedL, mPolygonOptions.getPoints(), true) && !mGeofenceBreached){
Log.d("Geofence", "Vehicle has breached the polygon");
}
}
@Override
public void onRawLocationUpdate(Location location) {
}
};
با استفاده از Android-Maps-Utils میتوانید از PolyUtil.containsLocation برای بررسی اینکه آیا مکان دریافتی درون چندضلعی از پیش تعریف شده قرار دارد یا خیر، استفاده کنید. در مثال زیر از چندضلعی از پیش تعریف شده که نشان دهنده geofence است، استفاده شده است، اما در عمل ممکن است چندین چندضلعی داشته باشید و به یک حلقه نیاز باشد.
یک رویکرد جایگزین
این سند بر روی یک برنامهی سمت کلاینت تمرکز دارد که نقض geofence (چندضلعی) سفارشی را بررسی میکند. با این حال، سناریوهایی وجود دارد که ممکن است بخواهید چنین بررسیهایی را در backend خود انجام دهید.
این یعنی برنامه، بهروزرسانیهای موقعیت مکانی را به یک backend گزارش میدهد و این backend سپس بررسی میکند که آیا آن وسیله نقلیه از یک چندضلعی خاص عبور کرده است یا خیر، بنابراین برای انجام اعتبارسنجی به برنامه کلاینت وابسته نیست.
یک راه حل ممکن به شرح زیر خواهد بود:
[محیط اجرا] معماری تعیین محدوده جغرافیایی سمت سرور
یک معماری نمونه که رویکرد سمت سرور به حصار جغرافیایی را نشان میدهد.

- اپلیکیشن راننده، با استفاده از Driver SDK، بهروزرسانیهای موقعیت مکانی را به Fleet Engine ارسال میکند. بهروزرسانیهای موقعیت مکانی و ناوبری درونبرنامهای از طریق Navigation SDK انجام میشود.
- موتور ناوگان، این بهروزرسانیها را در Cloud Logging یا Pub/Sub خروجی میدهد.
- بخش پشتی، آن سیگنالهای موقعیت مکانی را جمعآوری میکند.
- حصارهای جغرافیایی (Geofences) برای تجزیه و تحلیل توسط backend در Big Query ذخیره میشوند.
- پس از فعال شدن ژئوفنس، هشدارهایی به اپلیکیشن درایور ارسال میشود.
در این معماری، از Driver SDK و Fleet Engine استفاده شده است. Fleet Engine میتواند بهروزرسانیهای PubSub را منتشر کند و ورودیهای لاگ را در Cloud Logging ایجاد کند. در هر دو مورد، مکان خودرو قابل بازیابی است.
سپس، بکاند میتواند صف PubSub را رصد کند یا گزارشها را بخواند و بهروزرسانیهای خودرو را زیر نظر داشته باشد. سپس، هر زمان که بهروزرسانیای اتفاق میافتد (یا هر چند ثانیه، چند دقیقه، بسته به اهمیت آن)، بکاند میتواند توابع BigQuery GIS را فراخوانی کند تا مشخص شود که آیا یک وسیله نقلیه خاص داخل یا خارج از محدودههای جغرافیایی قرار دارد یا خیر. در صورتی که یک یا چند محدوده جغرافیایی نقض شده باشد، بکاند میتواند وارد عمل شود و خطوط لوله داخلی یا سایر گردشهای کاری مرتبط را فعال کند.
نتیجهگیری
حصار جغرافیایی ابزاری قدرتمند است که میتواند برای اهداف مختلفی مورد استفاده قرار گیرد. مشاغل میتوانند از حصار جغرافیایی برای هدف قرار دادن کاربران نهایی با تبلیغات و آگهیهای مرتبط، ارائه خدمات مبتنی بر مکان و بهبود امنیت و ایمنی استفاده کنند.
کیت توسعه نرمافزار ناوبری (Navigation SDK) شنوندههای رویداد (event listeners) مفیدی را ارائه میدهد که میتوانند لحظات مهم بسیاری را در طول یک سفر تشخیص دهند. شرکتها اغلب برای موارد استفاده خاص به حصارهای جغرافیایی سفارشی نیاز دارند. در این سند، ما راهی برای دستیابی به این هدف نشان دادیم، اما امکانات بیپایان هستند. مشتاقانه منتظر دیدن ایدههای شما هستیم.
اقدامات بعدی
- وبینار « کاوش کنید، یاد بگیرید و از امکانات پلتفرم نقشههای گوگل الهام بگیرید» را تماشا کنید.
پیشنهاد مطالعه بیشتر: