نقشههای موجود در Maps SDK برای Android را میتوان با حرکات ساده کج کرد و چرخاند و به کاربران این امکان را میدهد که نقشه را با جهتی که برایشان منطقی است تنظیم کنند. در هر سطح بزرگنمایی، میتوانید نقشه را جابهجا کنید، یا پرسپکتیو آن را با تأخیر بسیار کم به لطف ردپای کوچکتر کاشیهای نقشه مبتنی بر برداری تغییر دهید.
نمونه کد
مخزن ApiDemos در GitHub شامل نمونه ای است که ویژگی های دوربین را نشان می دهد:
- CameraDemoActivity - Kotlin : تغییر موقعیت دوربین
- CameraDemoActivity - Java : تغییر موقعیت دوربین
مقدمه
مانند Google Maps در وب، Maps SDK برای Android، سطح جهان (یک کره) را در صفحه دستگاه شما (یک صفحه تخت) با استفاده از طرح ریزی Mercator نشان می دهد. در جهت شرق و غرب، نقشه بی نهایت تکرار می شود، زیرا جهان به طور یکپارچه روی خود می پیچد. در جهت شمال و جنوب نقشه تقریباً به 85 درجه شمالی و 85 درجه جنوبی محدود شده است.
توجه: یک برجستگی مرکاتور از نظر طولی دارای عرض محدود اما از نظر عرضی یک ارتفاع نامحدود است. ما تصاویر نقشه پایه را با استفاده از طرح ریزی Mercator در حدود +/- 85 درجه "قطع" می کنیم تا نقشه حاصل را مربع شکل کنیم، که امکان منطق آسان تر را برای انتخاب کاشی فراهم می کند.
Maps SDK برای Android به شما امکان می دهد با تغییر دوربین نقشه، دیدگاه کاربر را نسبت به نقشه تغییر دهید.
تغییرات در دوربین هیچ تغییری در نشانگرها، پوششها یا سایر گرافیکهایی که اضافه کردهاید ایجاد نمیکند، اگرچه ممکن است بخواهید موارد اضافه شده خود را تغییر دهید تا با نمای جدید مطابقت داشته باشد.
از آنجایی که میتوانید به حرکات کاربر روی نقشه گوش دهید، میتوانید نقشه را در پاسخ به درخواستهای کاربر تغییر دهید. به عنوان مثال، روش پاسخ به تماس OnMapClickListener.onMapClick()
به یک ضربه روی نقشه پاسخ می دهد. از آنجایی که روش، طول و عرض جغرافیایی محل ضربه را دریافت میکند، میتوانید با حرکت دادن یا بزرگنمایی به آن نقطه پاسخ دهید. روشهای مشابهی برای پاسخ دادن به ضربههای روی حباب نشانگر یا برای پاسخ دادن به حرکت کشیدن روی نشانگر موجود است.
همچنین میتوانید به حرکات دوربین گوش دهید، به طوری که برنامه شما زمانی که دوربین شروع به حرکت میکند، در حال حرکت است یا حرکت را متوقف میکند، اعلان دریافت میکند. برای جزئیات، به راهنمای رویدادهای تغییر دوربین مراجعه کنید.
موقعیت دوربین
نمای نقشه به صورت دوربینی که در یک صفحه صاف از پایین نگاه می کند، مدل سازی شده است. موقعیت دوربین (و در نتیجه رندر نقشه) با ویژگی های زیر مشخص می شود: هدف (موقعیت طول و عرض جغرافیایی) ، بلبرینگ ، شیب ، و بزرگنمایی .
هدف (مکان)
هدف دوربین محل مرکز نقشه است که به صورت مختصات طول و عرض جغرافیایی مشخص شده است.
عرض جغرافیایی می تواند بین 85- تا 85 درجه باشد. مقادیر بالاتر یا پایینتر از این محدوده به نزدیکترین مقدار در این محدوده گیره میشوند. برای مثال، با تعیین عرض جغرافیایی 100، مقدار 85 تنظیم می شود. مقادیر بالاتر یا پایین تر از این محدوده به گونه ای بسته بندی می شوند که در محدوده (-180، 180) قرار می گیرند. به عنوان مثال، 480، 840 و 1200 همه تا 120 درجه پیچیده می شوند.بلبرینگ (جهت گیری)
بلبرینگ دوربین جهت قطب نما را مشخص می کند که بر حسب درجه از شمال واقعی، مطابق با لبه بالای نقشه اندازه گیری می شود. اگر یک خط عمودی از مرکز نقشه تا لبه بالایی نقشه بکشید، بلبرینگ با عنوان دوربین (اندازهگیری شده بر حسب درجه) نسبت به شمال واقعی مطابقت دارد.
یاتاقان 0 به این معنی است که بالای نقشه به شمال واقعی اشاره می کند. مقدار باربری 90 به معنای بالای نقاط نقشه به سمت شرق است (90 درجه روی قطب نما). مقدار 180 به معنای بالای نقاط نقشه به سمت جنوب است.
Maps API به شما امکان می دهد بلبرینگ نقشه را تغییر دهید. به عنوان مثال، شخصی که رانندگی می کند اغلب نقشه راه را می چرخاند تا آن را با جهت سفر خود هماهنگ کند، در حالی که کوهنوردانی که از نقشه و قطب نما استفاده می کنند معمولاً نقشه را طوری جهت می دهند که یک خط عمودی به سمت شمال باشد.
شیب (زاویه دید)
شیب موقعیت دوربین را روی یک قوس مستقیماً بر روی موقعیت مرکزی نقشه مشخص میکند که بر حسب درجه از نادر اندازهگیری میشود (جهتی که مستقیماً به زیر دوربین اشاره میکند). مقدار 0 مربوط به دوربینی است که مستقیماً به سمت پایین است. مقادیر بیشتر از 0 مربوط به دوربینی است که با تعداد درجه مشخصی به سمت افق کشیده شده است. وقتی زاویه دید را تغییر میدهید، نقشه در پرسپکتیو ظاهر میشود و ویژگیهای دور کوچکتر و ویژگیهای نزدیک بزرگتر ظاهر میشوند. تصاویر زیر این را نشان می دهد.
در تصاویر زیر زاویه دید 0 درجه است. تصویر اول شماتیکی از این را نشان می دهد. موقعیت 1 موقعیت دوربین و موقعیت 2 موقعیت فعلی نقشه است. نقشه حاصل در زیر آن نشان داده شده است.
در تصاویر زیر زاویه دید 45 درجه است. توجه داشته باشید که دوربین در نیمه راه در امتداد قوس بین مستقیم بالای سر (0 درجه) و زمین (90 درجه) به موقعیت 3 حرکت می کند. دوربین همچنان به نقطه مرکزی نقشه اشاره می کند، اما منطقه ای که با خط در موقعیت 4 نشان داده شده است اکنون قابل مشاهده است.
نقشه در این اسکرین شات همچنان در همان نقطه در نقشه اصلی قرار دارد، اما ویژگی های بیشتری در بالای نقشه ظاهر شده است. با افزایش زاویه بیش از 45 درجه، ویژگیهای بین دوربین و موقعیت نقشه به نسبت بزرگتر به نظر میرسند، در حالی که ویژگیهای فراتر از موقعیت نقشه نسبتاً کوچکتر به نظر میرسند و جلوهای سهبعدی ایجاد میکنند.
بزرگنمایی ضربه بزنید؛
سطح زوم دوربین مقیاس نقشه را تعیین می کند. در سطوح بزرگنمایی بزرگتر، جزئیات بیشتری روی صفحه نمایش دیده می شود، در حالی که در سطوح بزرگنمایی کوچکتر، می توان بیشتر جهان را روی صفحه مشاهده کرد. در سطح زوم 0، مقیاس نقشه به گونه ای است که پهنای کل جهان تقریباً 256dp ( پیکسل های مستقل از چگالی ) است.
افزایش سطح زوم به میزان 1، عرض جهان روی صفحه را دو برابر می کند. بنابراین در سطح زوم N، عرض جهان تقریباً 256 * 2 N dp است. به عنوان مثال، در سطح زوم 2، کل جهان تقریباً 1024dp عرض دارد.
لازم نیست سطح بزرگنمایی یک عدد صحیح باشد. محدوده سطوح بزرگنمایی مجاز توسط نقشه به عوامل مختلفی از جمله هدف، نوع نقشه و اندازه صفحه بستگی دارد. هر عدد خارج از محدوده به نزدیکترین مقدار معتبر بعدی تبدیل می شود که می تواند حداقل سطح بزرگنمایی یا حداکثر سطح بزرگنمایی باشد. لیست زیر سطح تقریبی جزئیاتی را که میتوانید انتظار داشته باشید در هر سطح بزرگنمایی ببینید را نشان میدهد:
- 1: جهان
- 5: خشکی / قاره
- 10: شهر
- 15: خیابان ها
- 20: ساختمان ها
حرکت دوربین
Maps API به شما این امکان را می دهد که تغییر دهید کدام قسمت از جهان روی نقشه قابل مشاهده است. این با تغییر موقعیت دوربین (بر خلاف حرکت نقشه) به دست می آید.
وقتی دوربین را تغییر میدهید، میتوانید حرکت دوربین حاصل را متحرک کنید. انیمیشن بین ویژگیهای دوربین فعلی و ویژگیهای دوربین جدید درونیابی میشود. همچنین می توانید مدت زمان انیمیشن را کنترل کنید.
برای تغییر موقعیت دوربین، باید با استفاده از CameraUpdate
مشخص کنید که میخواهید دوربین را به کجا منتقل کنید. Maps API به شما امکان می دهد انواع مختلفی از CameraUpdate
را با استفاده از CameraUpdateFactory
ایجاد کنید. گزینه های زیر در دسترس هستند:
تغییر سطح زوم و تنظیم حداقل/حداکثر بزرگنمایی
CameraUpdateFactory.zoomIn()
و CameraUpdateFactory.zoomOut()
CameraUpdate
به شما ارائه می دهد که سطح بزرگنمایی را 1.0 تغییر می دهد، در حالی که تمام خصوصیات دیگر یکسان باقی می ماند.
CameraUpdateFactory.zoomTo(float)
CameraUpdate
در اختیار شما قرار می دهد که سطح بزرگنمایی را به مقدار داده شده تغییر می دهد، در حالی که همه ویژگی های دیگر را یکسان نگه می دارد.
CameraUpdateFactory.zoomBy(float)
و CameraUpdateFactory.zoomBy(float, Point)
به شما CameraUpdate
می دهند که سطح بزرگنمایی را با مقدار داده شده افزایش می دهد (یا کاهش می دهد، اگر مقدار آن منفی باشد). دومی نقطه داده شده روی صفحه را طوری ثابت می کند که در همان مکان (طول/طول جغرافیایی) باقی بماند و بنابراین ممکن است مکان دوربین را برای دستیابی به این هدف تغییر دهد.
ممکن است برای شما مفید باشد که حداقل و/یا حداکثر سطح زوم ترجیحی را تنظیم کنید. به عنوان مثال، اگر برنامه شما یک منطقه تعریف شده در اطراف یک نقطه مورد علاقه را نشان می دهد، یا اگر از یک پوشش کاشی سفارشی با مجموعه محدودی از سطوح بزرگنمایی استفاده می کنید، این برای کنترل تجربه کاربر مفید است.
کاتلین
private lateinit var map: GoogleMap map.setMinZoomPreference(6.0f) map.setMaxZoomPreference(14.0f)
جاوا
private GoogleMap map; map.setMinZoomPreference(6.0f); map.setMaxZoomPreference(14.0f);
توجه داشته باشید که ملاحظات فنی وجود دارد که ممکن است مانع از این می شود که API به کاربران اجازه بزرگنمایی خیلی کم یا زیاد را بدهد. برای مثال، ماهواره یا زمین ممکن است حداکثر زوم کمتری نسبت به کاشی های نقشه پایه داشته باشد.
تغییر موقعیت دوربین
دو روش راحت برای تغییر موقعیت مشترک وجود دارد. CameraUpdateFactory.newLatLng(LatLng)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند. CameraUpdateFactory.newLatLngZoom(LatLng, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی و بزرگنمایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند.
برای انعطاف کامل در تغییر موقعیت دوربین، از CameraUpdateFactory.newCameraPosition(CameraPosition)
استفاده کنید که به شما CameraUpdate
می دهد که دوربین را به موقعیت داده شده حرکت می دهد. یک CameraPosition
می توان مستقیماً با استفاده از new CameraPosition()
یا با CameraPosition.Builder
با استفاده از new CameraPosition.Builder()
بدست آورد.
پانینگ (پیمایش)
CameraUpdateFactory.scrollBy(float, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را طوری تغییر می دهد که نقشه برحسب تعداد پیکسل مشخص شده حرکت کند. یک مقدار x مثبت باعث می شود دوربین به سمت راست حرکت کند، به طوری که به نظر می رسد نقشه به سمت چپ حرکت کرده است. یک مقدار مثبت y باعث می شود دوربین به سمت پایین حرکت کند، به طوری که به نظر می رسد نقشه به سمت بالا حرکت کرده است. برعکس، مقادیر منفی x باعث حرکت دوربین به سمت چپ می شود، به طوری که به نظر می رسد نقشه به سمت راست حرکت کرده است و مقادیر منفی y باعث می شود دوربین به سمت بالا حرکت کند. پیمایش نسبت به جهت فعلی دوربین است. به عنوان مثال، اگر دوربین دارای یک یاتاقان 90 درجه باشد، شرق "بالا" است.
تعیین مرزها
تعیین محدوده نقشه
گاهی اوقات جابجایی دوربین به گونهای مفید است که کل ناحیه مورد نظر با بیشترین زوم ممکن قابل مشاهده باشد. برای مثال، اگر همه پمپ بنزینها را در فاصله پنج مایلی موقعیت فعلی کاربر نمایش میدهید، ممکن است بخواهید دوربین را طوری حرکت دهید که همه آنها روی صفحه قابل مشاهده باشند. برای این کار ابتدا LatLngBounds
را که می خواهید روی صفحه نمایش داده شود محاسبه کنید. سپس میتوانید از CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding)
برای بهدست آوردن CameraUpdate
استفاده کنید که موقعیت دوربین را طوری تغییر میدهد که LatLngBounds
دادهشده کاملاً با نقشه مطابقت داشته باشد، با در نظر گرفتن بالشتک (بر حسب پیکسل) مشخص شده. CameraUpdate
بازگشتی تضمین می کند که فاصله (بر حسب پیکسل) بین مرزهای داده شده و لبه نقشه حداقل به اندازه بالشتک مشخص شده باشد. توجه داشته باشید که شیب و یاتاقان نقشه هر دو 0 خواهد بود.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
وسط نقشه در یک منطقه
در برخی موارد، ممکن است بخواهید دوربین خود را به جای درج کردن مرزهای شدید، در یک محدوده قرار دهید. به عنوان مثال، برای متمرکز کردن دوربین روی یک کشور در حالی که زوم ثابتی را حفظ می کند. در این مورد، می توانید با ایجاد یک LatLngBounds
و استفاده از CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
با LatLngBounds
از روش مشابهی استفاده کنید. متد getCenter()
. متد getCenter() مرکز جغرافیایی LatLngBounds
را برمی گرداند.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
اضافه بار روش، newLatLngBounds(boundary, width, height, padding)
به شما امکان می دهد یک عرض و ارتفاع را بر حسب پیکسل برای یک مستطیل مشخص کنید، با این هدف که اینها با ابعاد نقشه مطابقت داشته باشند. مستطیل طوری قرار می گیرد که مرکز آن با نمای نقشه یکی باشد (به طوری که اگر ابعاد مشخص شده با نمای نقشه یکسان باشد، مستطیل با نمای نقشه منطبق است). CameraUpdate
برگردانده شده دوربین را به گونه ای حرکت می دهد که LatLngBounds
مشخص شده با در نظر گرفتن بالشتک مورد نیاز، در مستطیل داده شده در بیشترین سطح بزرگنمایی ممکن بر روی صفحه متمرکز شوند.
توجه: فقط در صورتی از روش سادهتر newLatLngBounds(boundary, padding)
برای تولید CameraUpdate
استفاده کنید که قرار است بعد از طرحبندی نقشه برای جابجایی دوربین استفاده شود. در حین چیدمان، API مرزهای نمایش نقشه را محاسبه می کند که برای نمایش صحیح جعبه مرزی مورد نیاز است. در مقایسه، میتوانید از CameraUpdate
بازگردانده شده با روش پیچیدهتر newLatLngBounds(boundary, width, height, padding)
در هر زمان، حتی قبل از اینکه نقشه تحت طرحبندی قرار گیرد، استفاده کنید، زیرا API مرزهای نمایش را از روی آرگومانهایی که پاس میکنید محاسبه میکند.
محدود کردن حرکت کاربر به یک منطقه مشخص
در سناریوهای بالا، شما محدوده های نقشه را تعیین می کنید اما کاربر می تواند خارج از این محدوده ها حرکت کند یا حرکت کند. در عوض، ممکن است بخواهید مرزهای مرکز lat/lng نقطه کانونی نقشه (هدف دوربین) را محدود کنید تا کاربران فقط بتوانند در این محدوده ها حرکت کنند و حرکت کنند. به عنوان مثال، یک برنامه خردهفروشی برای یک مرکز خرید یا فرودگاه ممکن است بخواهد نقشه را به یک محدوده خاص محدود کند، و به کاربران این امکان را میدهد که در آن محدودهها حرکت کنند و حرکت کنند.
کاتلین
// Create a LatLngBounds that includes the city of Adelaide in Australia. val adelaideBounds = LatLngBounds( LatLng(-35.0, 138.58), // SW bounds LatLng(-34.9, 138.61) // NE bounds ) // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds)
جاوا
// Create a LatLngBounds that includes the city of Adelaide in Australia. LatLngBounds adelaideBounds = new LatLngBounds( new LatLng(-35.0, 138.58), // SW bounds new LatLng(-34.9, 138.61) // NE bounds ); // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds);
نمودار زیر سناریویی را نشان می دهد که هدف دوربین محدود به ناحیه ای است که کمی بزرگتر از درگاه دید است. کاربر می تواند اسکرول و حرکت کند، مشروط بر اینکه هدف دوربین در ناحیه محدود باقی بماند. ضربدر نشان دهنده هدف دوربین است:
نقشه همیشه درگاه دید را پر میکند، حتی اگر منجر به نمایش قسمتهایی شود که خارج از محدودههای تعریف شده هستند. به عنوان مثال، اگر هدف دوربین را در گوشه ای از ناحیه محدود قرار دهید، ناحیه آن سوی گوشه در نمای دید قابل مشاهده است اما کاربران نمی توانند بیشتر در آن ناحیه حرکت کنند. نمودار زیر این سناریو را نشان می دهد. ضربدر نشان دهنده هدف دوربین است:
در نمودار زیر، هدف دوربین دارای محدودههای بسیار محدودی است که به کاربر فرصت بسیار کمی برای اسکرول یا حرکت نقشه را میدهد. ضربدر نشان دهنده هدف دوربین است:
به روز رسانی نمای دوربین
برای اعمال CameraUpdate
روی نقشه، میتوانید دوربین را فوراً حرکت دهید یا دوربین را به آرامی متحرک کنید. برای حرکت فوری دوربین با CameraUpdate
داده شده، می توانید با GoogleMap.moveCamera(CameraUpdate)
تماس بگیرید.
میتوانید با متحرک کردن تغییرات، تجربه کاربر را به خصوص برای حرکات کوتاه لذتبخشتر کنید. برای انجام این کار به جای تماس با GoogleMap.moveCamera
GoogleMap.animateCamera
تماس بگیرید. نقشه به آرامی به ویژگی های جدید منتقل می شود. دقیق ترین شکل این روش، GoogleMap.animateCamera(cameraUpdate, duration, callback)
، سه آرگومان ارائه می دهد:
-
cameraUpdate
-
CameraUpdate
که محل حرکت دوربین را توضیح می دهد. -
callback
- شی ای که
GoogleMap.CancellableCallback
را پیاده سازی می کند. این رابط تعمیم یافته برای رسیدگی به وظایف، دو روش «onCancel()» و «onFinished()» را تعریف می کند. برای انیمیشن، متدها در شرایط زیر فراخوانی می شوند:-
onFinish()
- اگر انیمیشن بدون وقفه کامل شود، فراخوانی می شود.
-
onCancel()
اگر انیمیشن با فراخوانی
stopAnimation()
یا شروع یک حرکت دوربین جدید قطع شود، فراخوانی می شود.از طرف دیگر، اگر
GoogleMap.stopAnimation()
فراخوانی کنید، ممکن است این اتفاق بیفتد.
-
-
duration
- مدت زمان مورد نظر انیمیشن، بر حسب میلی ثانیه، به عنوان
int
.
قطعه کد زیر برخی از روش های متداول حرکت دوربین را نشان می دهد.
کاتلین
val sydney = LatLng(-33.88, 151.21) val mountainView = LatLng(37.4, -122.1) // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f)) // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()) // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null) // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. val cameraPosition = CameraPosition.Builder() .target(mountainView) // Sets the center of the map to Mountain View .zoom(17f) // Sets the zoom .bearing(90f) // Sets the orientation of the camera to east .tilt(30f) // Sets the tilt of the camera to 30 degrees .build() // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
جاوا
LatLng sydney = new LatLng(-33.88,151.21); LatLng mountainView = new LatLng(37.4, -122.1); // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()); // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. CameraPosition cameraPosition = new CameraPosition.Builder() .target(mountainView ) // Sets the center of the map to Mountain View .zoom(17) // Sets the zoom .bearing(90) // Sets the orientation of the camera to east .tilt(30) // Sets the tilt of the camera to 30 degrees .build(); // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
نقشههای موجود در Maps SDK برای Android را میتوان با حرکات ساده کج کرد و چرخاند و به کاربران این امکان را میدهد که نقشه را با جهتی که برایشان منطقی است تنظیم کنند. در هر سطح بزرگنمایی، میتوانید نقشه را جابهجا کنید، یا پرسپکتیو آن را با تأخیر بسیار کم به لطف ردپای کوچکتر کاشیهای نقشه مبتنی بر برداری تغییر دهید.
نمونه کد
مخزن ApiDemos در GitHub شامل نمونه ای است که ویژگی های دوربین را نشان می دهد:
- CameraDemoActivity - Kotlin : تغییر موقعیت دوربین
- CameraDemoActivity - Java : تغییر موقعیت دوربین
مقدمه
مانند Google Maps در وب، Maps SDK برای Android، سطح جهان (یک کره) را در صفحه دستگاه شما (یک صفحه تخت) با استفاده از طرح ریزی Mercator نشان می دهد. در جهت شرق و غرب، نقشه بی نهایت تکرار می شود، زیرا جهان به طور یکپارچه روی خود می پیچد. در جهت شمال و جنوب نقشه تقریباً به 85 درجه شمالی و 85 درجه جنوبی محدود شده است.
توجه: یک برجستگی مرکاتور از نظر طولی دارای عرض محدود اما از نظر عرضی یک ارتفاع نامحدود است. ما تصاویر نقشه پایه را با استفاده از طرح ریزی Mercator در حدود +/- 85 درجه "قطع" می کنیم تا نقشه حاصل را مربع شکل کنیم، که امکان منطق آسان تر را برای انتخاب کاشی فراهم می کند.
Maps SDK برای Android به شما امکان می دهد با تغییر دوربین نقشه، دیدگاه کاربر را نسبت به نقشه تغییر دهید.
تغییرات در دوربین هیچ تغییری در نشانگرها، پوششها یا سایر گرافیکهایی که اضافه کردهاید ایجاد نمیکند، اگرچه ممکن است بخواهید موارد اضافه شده خود را تغییر دهید تا با نمای جدید مطابقت داشته باشد.
از آنجایی که میتوانید به حرکات کاربر روی نقشه گوش دهید، میتوانید نقشه را در پاسخ به درخواستهای کاربر تغییر دهید. به عنوان مثال، روش پاسخ به تماس OnMapClickListener.onMapClick()
به یک ضربه روی نقشه پاسخ می دهد. از آنجایی که روش، طول و عرض جغرافیایی محل ضربه را دریافت میکند، میتوانید با حرکت دادن یا بزرگنمایی به آن نقطه پاسخ دهید. روشهای مشابهی برای پاسخ دادن به ضربههای روی حباب نشانگر یا برای پاسخ دادن به حرکت کشیدن روی نشانگر موجود است.
همچنین میتوانید به حرکات دوربین گوش دهید، به طوری که برنامه شما زمانی که دوربین شروع به حرکت میکند، در حال حرکت است یا حرکت را متوقف میکند، اعلان دریافت میکند. برای جزئیات، به راهنمای رویدادهای تغییر دوربین مراجعه کنید.
موقعیت دوربین
نمای نقشه به صورت دوربینی که در یک صفحه صاف از پایین نگاه می کند، مدل سازی شده است. موقعیت دوربین (و در نتیجه رندر نقشه) با ویژگی های زیر مشخص می شود: هدف (موقعیت طول و عرض جغرافیایی) ، بلبرینگ ، شیب ، و بزرگنمایی .
هدف (مکان)
هدف دوربین محل مرکز نقشه است که به صورت مختصات طول و عرض جغرافیایی مشخص شده است.
عرض جغرافیایی می تواند بین 85- تا 85 درجه باشد. مقادیر بالاتر یا پایینتر از این محدوده به نزدیکترین مقدار در این محدوده گیره میشوند. برای مثال، با تعیین عرض جغرافیایی 100، مقدار 85 تنظیم می شود. مقادیر بالاتر یا پایین تر از این محدوده به گونه ای بسته بندی می شوند که در محدوده (-180، 180) قرار می گیرند. به عنوان مثال، 480، 840 و 1200 همه تا 120 درجه پیچیده می شوند.بلبرینگ (جهت گیری)
بلبرینگ دوربین جهت قطب نما را مشخص می کند که بر حسب درجه از شمال واقعی، مطابق با لبه بالای نقشه اندازه گیری می شود. اگر یک خط عمودی از مرکز نقشه تا لبه بالایی نقشه بکشید، بلبرینگ با عنوان دوربین (اندازهگیری شده بر حسب درجه) نسبت به شمال واقعی مطابقت دارد.
یاتاقان 0 به این معنی است که بالای نقشه به شمال واقعی اشاره می کند. مقدار باربری 90 به معنای بالای نقاط نقشه به سمت شرق است (90 درجه روی قطب نما). مقدار 180 به معنای بالای نقاط نقشه به سمت جنوب است.
Maps API به شما امکان می دهد بلبرینگ نقشه را تغییر دهید. به عنوان مثال، شخصی که رانندگی می کند اغلب نقشه راه را می چرخاند تا آن را با جهت سفر خود هماهنگ کند، در حالی که کوهنوردانی که از نقشه و قطب نما استفاده می کنند معمولاً نقشه را طوری جهت می دهند که یک خط عمودی به سمت شمال باشد.
شیب (زاویه دید)
شیب موقعیت دوربین را روی یک قوس مستقیماً بر روی موقعیت مرکزی نقشه مشخص میکند که بر حسب درجه از نادر اندازهگیری میشود (جهتی که مستقیماً به زیر دوربین اشاره میکند). مقدار 0 مربوط به دوربینی است که مستقیماً به سمت پایین است. مقادیر بیشتر از 0 مربوط به دوربینی است که با تعداد درجه مشخصی به سمت افق کشیده شده است. وقتی زاویه دید را تغییر میدهید، نقشه در پرسپکتیو ظاهر میشود و ویژگیهای دور کوچکتر و ویژگیهای نزدیک بزرگتر ظاهر میشوند. تصاویر زیر این را نشان می دهد.
در تصاویر زیر زاویه دید 0 درجه است. تصویر اول شماتیکی از این را نشان می دهد. موقعیت 1 موقعیت دوربین و موقعیت 2 موقعیت فعلی نقشه است. نقشه حاصل در زیر آن نشان داده شده است.
در تصاویر زیر زاویه دید 45 درجه است. توجه داشته باشید که دوربین در نیمه راه در امتداد قوس بین مستقیم بالای سر (0 درجه) و زمین (90 درجه) به موقعیت 3 حرکت می کند. دوربین همچنان به نقطه مرکزی نقشه اشاره می کند، اما منطقه ای که با خط در موقعیت 4 نشان داده شده است اکنون قابل مشاهده است.
نقشه در این اسکرین شات همچنان در همان نقطه در نقشه اصلی قرار دارد، اما ویژگی های بیشتری در بالای نقشه ظاهر شده است. با افزایش زاویه بیش از 45 درجه، ویژگیهای بین دوربین و موقعیت نقشه به نسبت بزرگتر به نظر میرسند، در حالی که ویژگیهای فراتر از موقعیت نقشه نسبتاً کوچکتر به نظر میرسند و جلوهای سهبعدی ایجاد میکنند.
بزرگنمایی ضربه بزنید؛
سطح زوم دوربین مقیاس نقشه را تعیین می کند. در سطوح بزرگنمایی بزرگتر، جزئیات بیشتری روی صفحه نمایش دیده می شود، در حالی که در سطوح بزرگنمایی کوچکتر، می توان بیشتر جهان را روی صفحه مشاهده کرد. در سطح زوم 0، مقیاس نقشه به گونه ای است که پهنای کل جهان تقریباً 256dp ( پیکسل های مستقل از چگالی ) است.
افزایش سطح زوم به میزان 1، عرض جهان روی صفحه را دو برابر می کند. بنابراین در سطح زوم N، عرض جهان تقریباً 256 * 2 N dp است. به عنوان مثال، در سطح زوم 2، کل جهان تقریباً 1024dp عرض دارد.
لازم نیست سطح بزرگنمایی یک عدد صحیح باشد. محدوده سطوح بزرگنمایی مجاز توسط نقشه به عوامل مختلفی از جمله هدف، نوع نقشه و اندازه صفحه بستگی دارد. هر عدد خارج از محدوده به نزدیکترین مقدار معتبر بعدی تبدیل می شود که می تواند حداقل سطح بزرگنمایی یا حداکثر سطح بزرگنمایی باشد. لیست زیر سطح تقریبی جزئیاتی را که میتوانید انتظار داشته باشید در هر سطح بزرگنمایی ببینید را نشان میدهد:
- 1: جهان
- 5: خشکی / قاره
- 10: شهر
- 15: خیابان ها
- 20: ساختمان ها
حرکت دوربین
Maps API به شما این امکان را می دهد که تغییر دهید کدام قسمت از جهان روی نقشه قابل مشاهده است. این با تغییر موقعیت دوربین (بر خلاف حرکت نقشه) به دست می آید.
وقتی دوربین را تغییر میدهید، میتوانید حرکت دوربین حاصل را متحرک کنید. انیمیشن بین ویژگیهای دوربین فعلی و ویژگیهای دوربین جدید درونیابی میشود. همچنین می توانید مدت زمان انیمیشن را کنترل کنید.
برای تغییر موقعیت دوربین، باید با استفاده از CameraUpdate
مشخص کنید که میخواهید دوربین را به کجا منتقل کنید. Maps API به شما امکان می دهد انواع مختلفی از CameraUpdate
را با استفاده از CameraUpdateFactory
ایجاد کنید. گزینه های زیر در دسترس هستند:
تغییر سطح زوم و تنظیم حداقل/حداکثر بزرگنمایی
CameraUpdateFactory.zoomIn()
و CameraUpdateFactory.zoomOut()
CameraUpdate
به شما ارائه می دهد که سطح بزرگنمایی را 1.0 تغییر می دهد، در حالی که تمام خصوصیات دیگر یکسان باقی می ماند.
CameraUpdateFactory.zoomTo(float)
CameraUpdate
در اختیار شما قرار می دهد که سطح بزرگنمایی را به مقدار داده شده تغییر می دهد، در حالی که همه ویژگی های دیگر را یکسان نگه می دارد.
CameraUpdateFactory.zoomBy(float)
و CameraUpdateFactory.zoomBy(float, Point)
به شما CameraUpdate
می دهند که سطح بزرگنمایی را با مقدار داده شده افزایش می دهد (یا کاهش می دهد، اگر مقدار آن منفی باشد). دومی نقطه داده شده روی صفحه را طوری ثابت می کند که در همان مکان (طول/طول جغرافیایی) باقی بماند و بنابراین ممکن است مکان دوربین را برای دستیابی به این هدف تغییر دهد.
ممکن است برای شما مفید باشد که حداقل و/یا حداکثر سطح زوم ترجیحی را تنظیم کنید. به عنوان مثال، اگر برنامه شما یک منطقه تعریف شده در اطراف یک نقطه مورد علاقه را نشان می دهد، یا اگر از یک پوشش کاشی سفارشی با مجموعه محدودی از سطوح بزرگنمایی استفاده می کنید، این برای کنترل تجربه کاربر مفید است.
کاتلین
private lateinit var map: GoogleMap map.setMinZoomPreference(6.0f) map.setMaxZoomPreference(14.0f)
جاوا
private GoogleMap map; map.setMinZoomPreference(6.0f); map.setMaxZoomPreference(14.0f);
توجه داشته باشید که ملاحظات فنی وجود دارد که ممکن است مانع از این می شود که API به کاربران اجازه بزرگنمایی خیلی کم یا زیاد را بدهد. برای مثال، ماهواره یا زمین ممکن است حداکثر زوم کمتری نسبت به کاشی های نقشه پایه داشته باشد.
تغییر موقعیت دوربین
دو روش راحت برای تغییر موقعیت مشترک وجود دارد. CameraUpdateFactory.newLatLng(LatLng)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند. CameraUpdateFactory.newLatLngZoom(LatLng, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی و بزرگنمایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند.
برای انعطاف کامل در تغییر موقعیت دوربین، از CameraUpdateFactory.newCameraPosition(CameraPosition)
استفاده کنید که به شما CameraUpdate
می دهد که دوربین را به موقعیت داده شده حرکت می دهد. یک CameraPosition
می توان مستقیماً با استفاده از new CameraPosition()
یا با CameraPosition.Builder
با استفاده از new CameraPosition.Builder()
بدست آورد.
پانینگ (پیمایش)
CameraUpdateFactory.scrollBy(float, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را طوری تغییر می دهد که نقشه برحسب تعداد پیکسل مشخص شده حرکت کند. یک مقدار x مثبت باعث می شود دوربین به سمت راست حرکت کند، به طوری که به نظر می رسد نقشه به سمت چپ حرکت کرده است. یک مقدار مثبت y باعث می شود دوربین به سمت پایین حرکت کند، به طوری که به نظر می رسد نقشه به سمت بالا حرکت کرده است. برعکس، مقادیر منفی x باعث حرکت دوربین به سمت چپ می شود، به طوری که به نظر می رسد نقشه به سمت راست حرکت کرده است و مقادیر منفی y باعث می شود دوربین به سمت بالا حرکت کند. پیمایش نسبت به جهت فعلی دوربین است. به عنوان مثال، اگر دوربین دارای یک یاتاقان 90 درجه باشد، شرق "بالا" است.
تعیین مرزها
تعیین محدوده نقشه
گاهی اوقات جابجایی دوربین به گونهای مفید است که کل ناحیه مورد نظر با بیشترین زوم ممکن قابل مشاهده باشد. برای مثال، اگر همه پمپ بنزینها را در فاصله پنج مایلی موقعیت فعلی کاربر نمایش میدهید، ممکن است بخواهید دوربین را طوری حرکت دهید که همه آنها روی صفحه قابل مشاهده باشند. برای این کار ابتدا LatLngBounds
را که می خواهید روی صفحه نمایش داده شود محاسبه کنید. سپس میتوانید از CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding)
برای بهدست آوردن CameraUpdate
استفاده کنید که موقعیت دوربین را طوری تغییر میدهد که LatLngBounds
دادهشده کاملاً با نقشه مطابقت داشته باشد، با در نظر گرفتن بالشتک (بر حسب پیکسل) مشخص شده. CameraUpdate
بازگشتی تضمین می کند که فاصله (بر حسب پیکسل) بین مرزهای داده شده و لبه نقشه حداقل به اندازه بالشتک مشخص شده باشد. توجه داشته باشید که شیب و یاتاقان نقشه هر دو 0 خواهد بود.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
وسط نقشه در یک منطقه
در برخی موارد، ممکن است بخواهید دوربین خود را به جای درج کردن مرزهای شدید، در یک محدوده قرار دهید. به عنوان مثال، برای متمرکز کردن دوربین روی یک کشور در حالی که زوم ثابتی را حفظ می کند. در این مورد، می توانید با ایجاد یک LatLngBounds
و استفاده از CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
با LatLngBounds
از روش مشابهی استفاده کنید. متد getCenter()
. متد getCenter() مرکز جغرافیایی LatLngBounds
را برمی گرداند.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
اضافه بار روش، newLatLngBounds(boundary, width, height, padding)
به شما امکان می دهد یک عرض و ارتفاع را بر حسب پیکسل برای یک مستطیل مشخص کنید، با این هدف که اینها با ابعاد نقشه مطابقت داشته باشند. مستطیل طوری قرار می گیرد که مرکز آن با نمای نقشه یکی باشد (به طوری که اگر ابعاد مشخص شده با نمای نقشه یکسان باشد، مستطیل با نمای نقشه منطبق است). CameraUpdate
برگردانده شده دوربین را به گونه ای حرکت می دهد که LatLngBounds
مشخص شده با در نظر گرفتن بالشتک مورد نیاز، در مستطیل داده شده در بیشترین سطح بزرگنمایی ممکن بر روی صفحه متمرکز شوند.
توجه: فقط در صورتی از روش سادهتر newLatLngBounds(boundary, padding)
برای تولید CameraUpdate
استفاده کنید که قرار است بعد از طرحبندی نقشه برای جابجایی دوربین استفاده شود. در حین چیدمان، API مرزهای نمایش نقشه را محاسبه می کند که برای نمایش صحیح جعبه مرزی مورد نیاز است. در مقایسه، میتوانید از CameraUpdate
بازگردانده شده با روش پیچیدهتر newLatLngBounds(boundary, width, height, padding)
در هر زمان، حتی قبل از اینکه نقشه تحت طرحبندی قرار گیرد، استفاده کنید، زیرا API مرزهای نمایش را از روی آرگومانهایی که پاس میکنید محاسبه میکند.
محدود کردن حرکت کاربر به یک منطقه مشخص
در سناریوهای بالا، شما محدوده های نقشه را تعیین می کنید اما کاربر می تواند خارج از این محدوده ها حرکت کند یا حرکت کند. در عوض، ممکن است بخواهید مرزهای مرکز lat/lng نقطه کانونی نقشه (هدف دوربین) را محدود کنید تا کاربران فقط بتوانند در این محدوده ها حرکت کنند و حرکت کنند. به عنوان مثال، یک برنامه خردهفروشی برای یک مرکز خرید یا فرودگاه ممکن است بخواهد نقشه را به یک محدوده خاص محدود کند، و به کاربران این امکان را میدهد که در آن محدودهها حرکت کنند و حرکت کنند.
کاتلین
// Create a LatLngBounds that includes the city of Adelaide in Australia. val adelaideBounds = LatLngBounds( LatLng(-35.0, 138.58), // SW bounds LatLng(-34.9, 138.61) // NE bounds ) // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds)
جاوا
// Create a LatLngBounds that includes the city of Adelaide in Australia. LatLngBounds adelaideBounds = new LatLngBounds( new LatLng(-35.0, 138.58), // SW bounds new LatLng(-34.9, 138.61) // NE bounds ); // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds);
نمودار زیر سناریویی را نشان می دهد که هدف دوربین محدود به ناحیه ای است که کمی بزرگتر از درگاه دید است. کاربر می تواند اسکرول و حرکت کند، مشروط بر اینکه هدف دوربین در ناحیه محدود باقی بماند. ضربدر نشان دهنده هدف دوربین است:
نقشه همیشه درگاه دید را پر میکند، حتی اگر منجر به نمایش قسمتهایی شود که خارج از محدودههای تعریف شده هستند. به عنوان مثال، اگر هدف دوربین را در گوشه ای از ناحیه محدود قرار دهید، ناحیه آن سوی گوشه در نمای دید قابل مشاهده است اما کاربران نمی توانند بیشتر در آن ناحیه حرکت کنند. نمودار زیر این سناریو را نشان می دهد. ضربدر نشان دهنده هدف دوربین است:
در نمودار زیر، هدف دوربین دارای محدودههای بسیار محدودی است که به کاربر فرصت بسیار کمی برای اسکرول یا حرکت نقشه را میدهد. ضربدر نشان دهنده هدف دوربین است:
به روز رسانی نمای دوربین
برای اعمال CameraUpdate
روی نقشه، میتوانید دوربین را فوراً حرکت دهید یا دوربین را به آرامی متحرک کنید. برای حرکت فوری دوربین با CameraUpdate
داده شده، می توانید با GoogleMap.moveCamera(CameraUpdate)
تماس بگیرید.
میتوانید با متحرک کردن تغییرات، تجربه کاربر را به خصوص برای حرکات کوتاه لذتبخشتر کنید. برای انجام این کار به جای تماس با GoogleMap.moveCamera
GoogleMap.animateCamera
تماس بگیرید. نقشه به آرامی به ویژگی های جدید منتقل می شود. دقیق ترین شکل این روش، GoogleMap.animateCamera(cameraUpdate, duration, callback)
، سه آرگومان ارائه می دهد:
-
cameraUpdate
-
CameraUpdate
که محل حرکت دوربین را توضیح می دهد. -
callback
- شی ای که
GoogleMap.CancellableCallback
را پیاده سازی می کند. این رابط تعمیم یافته برای رسیدگی به وظایف، دو روش «onCancel()» و «onFinished()» را تعریف می کند. برای انیمیشن، متدها در شرایط زیر فراخوانی می شوند:-
onFinish()
- اگر انیمیشن بدون وقفه کامل شود، فراخوانی می شود.
-
onCancel()
اگر انیمیشن با فراخوانی
stopAnimation()
یا شروع یک حرکت دوربین جدید قطع شود، فراخوانی می شود.از طرف دیگر، اگر
GoogleMap.stopAnimation()
فراخوانی کنید، ممکن است این اتفاق بیفتد.
-
-
duration
- مدت زمان مورد نظر انیمیشن، بر حسب میلی ثانیه، به عنوان
int
.
قطعه کد زیر برخی از روش های متداول حرکت دوربین را نشان می دهد.
کاتلین
val sydney = LatLng(-33.88, 151.21) val mountainView = LatLng(37.4, -122.1) // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f)) // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()) // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null) // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. val cameraPosition = CameraPosition.Builder() .target(mountainView) // Sets the center of the map to Mountain View .zoom(17f) // Sets the zoom .bearing(90f) // Sets the orientation of the camera to east .tilt(30f) // Sets the tilt of the camera to 30 degrees .build() // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
جاوا
LatLng sydney = new LatLng(-33.88,151.21); LatLng mountainView = new LatLng(37.4, -122.1); // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()); // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. CameraPosition cameraPosition = new CameraPosition.Builder() .target(mountainView ) // Sets the center of the map to Mountain View .zoom(17) // Sets the zoom .bearing(90) // Sets the orientation of the camera to east .tilt(30) // Sets the tilt of the camera to 30 degrees .build(); // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
نقشههای موجود در Maps SDK برای Android را میتوان با حرکات ساده کج کرد و چرخاند و به کاربران این امکان را میدهد که نقشه را با جهتی که برایشان منطقی است تنظیم کنند. در هر سطح بزرگنمایی، میتوانید نقشه را جابهجا کنید، یا پرسپکتیو آن را با تأخیر بسیار کم به لطف ردپای کوچکتر کاشیهای نقشه مبتنی بر برداری تغییر دهید.
نمونه کد
مخزن ApiDemos در GitHub شامل نمونه ای است که ویژگی های دوربین را نشان می دهد:
- CameraDemoActivity - Kotlin : تغییر موقعیت دوربین
- CameraDemoActivity - Java : تغییر موقعیت دوربین
مقدمه
مانند Google Maps در وب، Maps SDK برای Android، سطح جهان (یک کره) را در صفحه دستگاه شما (یک صفحه تخت) با استفاده از طرح ریزی Mercator نشان می دهد. در جهت شرق و غرب، نقشه بی نهایت تکرار می شود، زیرا جهان به طور یکپارچه روی خود می پیچد. در جهت شمال و جنوب نقشه تقریباً به 85 درجه شمالی و 85 درجه جنوبی محدود شده است.
توجه: یک برجستگی مرکاتور از نظر طولی دارای عرض محدود اما از نظر عرضی یک ارتفاع نامحدود است. ما تصاویر نقشه پایه را با استفاده از طرح ریزی Mercator در حدود +/- 85 درجه "قطع" می کنیم تا نقشه حاصل را مربع شکل کنیم، که امکان منطق آسان تر را برای انتخاب کاشی فراهم می کند.
Maps SDK برای Android به شما امکان می دهد با تغییر دوربین نقشه، دیدگاه کاربر را نسبت به نقشه تغییر دهید.
تغییرات در دوربین هیچ تغییری در نشانگرها، پوششها یا سایر گرافیکهایی که اضافه کردهاید ایجاد نمیکند، اگرچه ممکن است بخواهید موارد اضافه شده خود را تغییر دهید تا با نمای جدید مطابقت داشته باشد.
از آنجایی که میتوانید به حرکات کاربر روی نقشه گوش دهید، میتوانید نقشه را در پاسخ به درخواستهای کاربر تغییر دهید. به عنوان مثال، روش پاسخ به تماس OnMapClickListener.onMapClick()
به یک ضربه روی نقشه پاسخ می دهد. از آنجایی که روش، طول و عرض جغرافیایی محل ضربه را دریافت میکند، میتوانید با حرکت دادن یا بزرگنمایی به آن نقطه پاسخ دهید. روشهای مشابهی برای پاسخ دادن به ضربههای روی حباب نشانگر یا برای پاسخ دادن به حرکت کشیدن روی نشانگر موجود است.
همچنین میتوانید به حرکات دوربین گوش دهید، به طوری که برنامه شما زمانی که دوربین شروع به حرکت میکند، در حال حرکت است یا حرکت را متوقف میکند، اعلان دریافت میکند. برای جزئیات، به راهنمای رویدادهای تغییر دوربین مراجعه کنید.
موقعیت دوربین
نمای نقشه به صورت دوربینی که در یک صفحه صاف از پایین نگاه می کند، مدل سازی شده است. موقعیت دوربین (و در نتیجه رندر نقشه) با ویژگی های زیر مشخص می شود: هدف (موقعیت طول و عرض جغرافیایی) ، بلبرینگ ، شیب ، و بزرگنمایی .
هدف (مکان)
هدف دوربین محل مرکز نقشه است که به صورت مختصات طول و عرض جغرافیایی مشخص شده است.
عرض جغرافیایی می تواند بین 85- تا 85 درجه باشد. مقادیر بالاتر یا پایینتر از این محدوده به نزدیکترین مقدار در این محدوده گیره میشوند. برای مثال، با تعیین عرض جغرافیایی 100، مقدار 85 تنظیم می شود. مقادیر بالاتر یا پایین تر از این محدوده به گونه ای بسته بندی می شوند که در محدوده (-180، 180) قرار می گیرند. به عنوان مثال، 480، 840 و 1200 همه تا 120 درجه پیچیده می شوند.بلبرینگ (جهت گیری)
بلبرینگ دوربین جهت قطب نما را مشخص می کند که بر حسب درجه از شمال واقعی، مطابق با لبه بالای نقشه اندازه گیری می شود. اگر یک خط عمودی از مرکز نقشه تا لبه بالایی نقشه بکشید، بلبرینگ با عنوان دوربین (اندازهگیری شده بر حسب درجه) نسبت به شمال واقعی مطابقت دارد.
یاتاقان 0 به این معنی است که بالای نقشه به شمال واقعی اشاره می کند. مقدار باربری 90 به معنای بالای نقاط نقشه به سمت شرق است (90 درجه روی قطب نما). مقدار 180 به معنای بالای نقاط نقشه به سمت جنوب است.
Maps API به شما امکان می دهد بلبرینگ نقشه را تغییر دهید. به عنوان مثال، شخصی که رانندگی می کند اغلب نقشه راه را می چرخاند تا آن را با جهت سفر خود هماهنگ کند، در حالی که کوهنوردانی که از نقشه و قطب نما استفاده می کنند معمولاً نقشه را طوری جهت می دهند که یک خط عمودی به سمت شمال باشد.
شیب (زاویه دید)
شیب موقعیت دوربین را روی یک قوس مستقیماً بر روی موقعیت مرکزی نقشه مشخص میکند که بر حسب درجه از نادر اندازهگیری میشود (جهتی که مستقیماً به زیر دوربین اشاره میکند). مقدار 0 مربوط به دوربینی است که مستقیماً به سمت پایین است. مقادیر بیشتر از 0 مربوط به دوربینی است که با تعداد درجه مشخصی به سمت افق کشیده شده است. وقتی زاویه دید را تغییر میدهید، نقشه در پرسپکتیو ظاهر میشود و ویژگیهای دور کوچکتر و ویژگیهای نزدیک بزرگتر ظاهر میشوند. تصاویر زیر این را نشان می دهد.
در تصاویر زیر زاویه دید 0 درجه است. تصویر اول شماتیکی از این را نشان می دهد. موقعیت 1 موقعیت دوربین و موقعیت 2 موقعیت فعلی نقشه است. نقشه حاصل در زیر آن نشان داده شده است.
در تصاویر زیر زاویه دید 45 درجه است. توجه داشته باشید که دوربین در نیمه راه در امتداد قوس بین مستقیم بالای سر (0 درجه) و زمین (90 درجه) به موقعیت 3 حرکت می کند. دوربین همچنان به نقطه مرکزی نقشه اشاره می کند، اما منطقه ای که با خط در موقعیت 4 نشان داده شده است اکنون قابل مشاهده است.
نقشه در این اسکرین شات همچنان در همان نقطه در نقشه اصلی قرار دارد، اما ویژگی های بیشتری در بالای نقشه ظاهر شده است. با افزایش زاویه بیش از 45 درجه، ویژگیهای بین دوربین و موقعیت نقشه به نسبت بزرگتر به نظر میرسند، در حالی که ویژگیهای فراتر از موقعیت نقشه نسبتاً کوچکتر به نظر میرسند و جلوهای سهبعدی ایجاد میکنند.
بزرگنمایی ضربه بزنید؛
سطح زوم دوربین مقیاس نقشه را تعیین می کند. در سطوح بزرگنمایی بزرگتر، جزئیات بیشتری روی صفحه نمایش دیده می شود، در حالی که در سطوح بزرگنمایی کوچکتر، می توان بیشتر جهان را روی صفحه مشاهده کرد. در سطح زوم 0، مقیاس نقشه به گونه ای است که پهنای کل جهان تقریباً 256dp ( پیکسل های مستقل از چگالی ) است.
افزایش سطح زوم به میزان 1، عرض جهان روی صفحه را دو برابر می کند. بنابراین در سطح زوم N، عرض جهان تقریباً 256 * 2 N dp است. به عنوان مثال، در سطح زوم 2، کل جهان تقریباً 1024dp عرض دارد.
لازم نیست سطح بزرگنمایی یک عدد صحیح باشد. محدوده سطوح بزرگنمایی مجاز توسط نقشه به عوامل مختلفی از جمله هدف، نوع نقشه و اندازه صفحه بستگی دارد. هر عدد خارج از محدوده به نزدیکترین مقدار معتبر بعدی تبدیل می شود که می تواند حداقل سطح بزرگنمایی یا حداکثر سطح بزرگنمایی باشد. لیست زیر سطح تقریبی جزئیاتی را که میتوانید انتظار داشته باشید در هر سطح بزرگنمایی ببینید را نشان میدهد:
- 1: جهان
- 5: خشکی / قاره
- 10: شهر
- 15: خیابان ها
- 20: ساختمان ها
حرکت دوربین
Maps API به شما این امکان را می دهد که تغییر دهید کدام قسمت از جهان روی نقشه قابل مشاهده است. این با تغییر موقعیت دوربین (بر خلاف حرکت نقشه) به دست می آید.
وقتی دوربین را تغییر میدهید، میتوانید حرکت دوربین حاصل را متحرک کنید. انیمیشن بین ویژگیهای دوربین فعلی و ویژگیهای دوربین جدید درونیابی میشود. همچنین می توانید مدت زمان انیمیشن را کنترل کنید.
برای تغییر موقعیت دوربین، باید با استفاده از CameraUpdate
مشخص کنید که میخواهید دوربین را به کجا منتقل کنید. Maps API به شما امکان می دهد انواع مختلفی از CameraUpdate
را با استفاده از CameraUpdateFactory
ایجاد کنید. گزینه های زیر در دسترس هستند:
تغییر سطح زوم و تنظیم حداقل/حداکثر بزرگنمایی
CameraUpdateFactory.zoomIn()
و CameraUpdateFactory.zoomOut()
CameraUpdate
به شما ارائه می دهد که سطح بزرگنمایی را 1.0 تغییر می دهد، در حالی که تمام خصوصیات دیگر یکسان باقی می ماند.
CameraUpdateFactory.zoomTo(float)
CameraUpdate
در اختیار شما قرار می دهد که سطح بزرگنمایی را به مقدار داده شده تغییر می دهد، در حالی که همه ویژگی های دیگر را یکسان نگه می دارد.
CameraUpdateFactory.zoomBy(float)
و CameraUpdateFactory.zoomBy(float, Point)
به شما CameraUpdate
می دهند که سطح بزرگنمایی را با مقدار داده شده افزایش می دهد (یا کاهش می دهد، اگر مقدار آن منفی باشد). دومی نقطه داده شده روی صفحه را طوری ثابت می کند که در همان مکان (طول/طول جغرافیایی) باقی بماند و بنابراین ممکن است مکان دوربین را برای دستیابی به این هدف تغییر دهد.
ممکن است برای شما مفید باشد که حداقل و/یا حداکثر سطح زوم ترجیحی را تنظیم کنید. به عنوان مثال، اگر برنامه شما یک منطقه تعریف شده در اطراف یک نقطه مورد علاقه را نشان می دهد، یا اگر از یک پوشش کاشی سفارشی با مجموعه محدودی از سطوح بزرگنمایی استفاده می کنید، این برای کنترل تجربه کاربر مفید است.
کاتلین
private lateinit var map: GoogleMap map.setMinZoomPreference(6.0f) map.setMaxZoomPreference(14.0f)
جاوا
private GoogleMap map; map.setMinZoomPreference(6.0f); map.setMaxZoomPreference(14.0f);
توجه داشته باشید که ملاحظات فنی وجود دارد که ممکن است مانع از این می شود که API به کاربران اجازه بزرگنمایی خیلی کم یا زیاد را بدهد. برای مثال، ماهواره یا زمین ممکن است حداکثر زوم کمتری نسبت به کاشی های نقشه پایه داشته باشد.
تغییر موقعیت دوربین
دو روش راحت برای تغییر موقعیت مشترک وجود دارد. CameraUpdateFactory.newLatLng(LatLng)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند. CameraUpdateFactory.newLatLngZoom(LatLng, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی و بزرگنمایی دوربین را تغییر می دهد و در عین حال تمام خصوصیات دیگر را حفظ می کند.
برای انعطاف کامل در تغییر موقعیت دوربین، از CameraUpdateFactory.newCameraPosition(CameraPosition)
استفاده کنید که به شما CameraUpdate
می دهد که دوربین را به موقعیت داده شده حرکت می دهد. یک CameraPosition
می توان مستقیماً با استفاده از new CameraPosition()
یا با CameraPosition.Builder
با استفاده از new CameraPosition.Builder()
بدست آورد.
پانینگ (پیمایش)
CameraUpdateFactory.scrollBy(float, float)
به شما CameraUpdate
می دهد که طول و عرض جغرافیایی دوربین را طوری تغییر می دهد که نقشه برحسب تعداد پیکسل مشخص شده حرکت کند. یک مقدار x مثبت باعث می شود دوربین به سمت راست حرکت کند، به طوری که به نظر می رسد نقشه به سمت چپ حرکت کرده است. یک مقدار مثبت y باعث می شود دوربین به سمت پایین حرکت کند، به طوری که به نظر می رسد نقشه به سمت بالا حرکت کرده است. برعکس، مقادیر منفی x باعث حرکت دوربین به سمت چپ می شود، به طوری که به نظر می رسد نقشه به سمت راست حرکت کرده است و مقادیر منفی y باعث می شود دوربین به سمت بالا حرکت کند. پیمایش نسبت به جهت فعلی دوربین است. به عنوان مثال، اگر دوربین دارای یک یاتاقان 90 درجه باشد، شرق "بالا" است.
تعیین مرزها
تعیین محدوده نقشه
گاهی اوقات جابجایی دوربین به گونهای مفید است که کل ناحیه مورد نظر با بیشترین زوم ممکن قابل مشاهده باشد. برای مثال، اگر همه پمپ بنزینها را در فاصله پنج مایلی موقعیت فعلی کاربر نمایش میدهید، ممکن است بخواهید دوربین را طوری حرکت دهید که همه آنها روی صفحه قابل مشاهده باشند. برای این کار ابتدا LatLngBounds
را که می خواهید روی صفحه نمایش داده شود محاسبه کنید. سپس میتوانید از CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int padding)
برای بهدست آوردن CameraUpdate
استفاده کنید که موقعیت دوربین را طوری تغییر میدهد که LatLngBounds
دادهشده کاملاً با نقشه مطابقت داشته باشد، با در نظر گرفتن بالشتک (بر حسب پیکسل) مشخص شده. CameraUpdate
بازگشتی تضمین می کند که فاصله (بر حسب پیکسل) بین مرزهای داده شده و لبه نقشه حداقل به اندازه بالشتک مشخص شده باشد. توجه داشته باشید که شیب و یاتاقان نقشه هر دو 0 خواهد بود.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
وسط نقشه در یک منطقه
در برخی موارد، ممکن است بخواهید دوربین خود را به جای درج کردن مرزهای شدید، در یک محدوده قرار دهید. به عنوان مثال، برای متمرکز کردن دوربین روی یک کشور در حالی که زوم ثابتی را حفظ می کند. در این مورد، می توانید با ایجاد یک LatLngBounds
و استفاده از CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
با LatLngBounds
از روش مشابهی استفاده کنید. متد getCenter()
. متد getCenter() مرکز جغرافیایی LatLngBounds
را برمی گرداند.
کاتلین
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
جاوا
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
اضافه بار روش، newLatLngBounds(boundary, width, height, padding)
به شما امکان می دهد یک عرض و ارتفاع را بر حسب پیکسل برای یک مستطیل مشخص کنید، با این هدف که اینها با ابعاد نقشه مطابقت داشته باشند. مستطیل طوری قرار می گیرد که مرکز آن با نمای نقشه یکی باشد (به طوری که اگر ابعاد مشخص شده با نمای نقشه یکسان باشد، مستطیل با نمای نقشه منطبق است). CameraUpdate
برگردانده شده دوربین را به گونه ای حرکت می دهد که LatLngBounds
مشخص شده با در نظر گرفتن بالشتک مورد نیاز، در مستطیل داده شده در بیشترین سطح بزرگنمایی ممکن بر روی صفحه متمرکز شوند.
توجه: فقط در صورتی از روش سادهتر newLatLngBounds(boundary, padding)
برای تولید CameraUpdate
استفاده کنید که قرار است بعد از طرحبندی نقشه برای جابجایی دوربین استفاده شود. در حین چیدمان، API مرزهای نمایش نقشه را محاسبه می کند که برای نمایش صحیح جعبه مرزی مورد نیاز است. در مقایسه، میتوانید از CameraUpdate
بازگردانده شده با روش پیچیدهتر newLatLngBounds(boundary, width, height, padding)
در هر زمان، حتی قبل از اینکه نقشه تحت طرحبندی قرار گیرد، استفاده کنید، زیرا API مرزهای نمایش را از روی آرگومانهایی که پاس میکنید محاسبه میکند.
محدود کردن حرکت کاربر به یک منطقه مشخص
در سناریوهای بالا، شما محدوده های نقشه را تعیین می کنید اما کاربر می تواند خارج از این محدوده ها حرکت کند یا حرکت کند. در عوض، ممکن است بخواهید مرزهای مرکز lat/lng نقطه کانونی نقشه (هدف دوربین) را محدود کنید تا کاربران فقط بتوانند در این محدوده ها حرکت کنند و حرکت کنند. به عنوان مثال، یک برنامه خردهفروشی برای یک مرکز خرید یا فرودگاه ممکن است بخواهد نقشه را به یک محدوده خاص محدود کند، و به کاربران این امکان را میدهد که در آن محدودهها حرکت کنند و حرکت کنند.
کاتلین
// Create a LatLngBounds that includes the city of Adelaide in Australia. val adelaideBounds = LatLngBounds( LatLng(-35.0, 138.58), // SW bounds LatLng(-34.9, 138.61) // NE bounds ) // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds)
جاوا
// Create a LatLngBounds that includes the city of Adelaide in Australia. LatLngBounds adelaideBounds = new LatLngBounds( new LatLng(-35.0, 138.58), // SW bounds new LatLng(-34.9, 138.61) // NE bounds ); // Constrain the camera target to the Adelaide bounds. map.setLatLngBoundsForCameraTarget(adelaideBounds);
نمودار زیر سناریویی را نشان می دهد که هدف دوربین محدود به ناحیه ای است که کمی بزرگتر از درگاه دید است. کاربر می تواند اسکرول و حرکت کند، مشروط بر اینکه هدف دوربین در ناحیه محدود باقی بماند. ضربدر نشان دهنده هدف دوربین است:
نقشه همیشه درگاه دید را پر میکند، حتی اگر منجر به نمایش قسمتهایی شود که خارج از محدودههای تعریف شده هستند. به عنوان مثال، اگر هدف دوربین را در گوشه ای از ناحیه محدود قرار دهید، ناحیه آن سوی گوشه در نمای دید قابل مشاهده است اما کاربران نمی توانند بیشتر در آن ناحیه حرکت کنند. نمودار زیر این سناریو را نشان می دهد. ضربدر نشان دهنده هدف دوربین است:
در نمودار زیر، هدف دوربین دارای محدودههای بسیار محدودی است که به کاربر فرصت بسیار کمی برای اسکرول یا حرکت نقشه را میدهد. ضربدر نشان دهنده هدف دوربین است:
به روز رسانی نمای دوربین
برای اعمال CameraUpdate
روی نقشه، میتوانید دوربین را فوراً حرکت دهید یا دوربین را به آرامی متحرک کنید. برای حرکت فوری دوربین با CameraUpdate
داده شده، می توانید با GoogleMap.moveCamera(CameraUpdate)
تماس بگیرید.
میتوانید با متحرک کردن تغییرات، تجربه کاربر را به خصوص برای حرکات کوتاه لذتبخشتر کنید. برای انجام این کار به جای تماس با GoogleMap.moveCamera
با GoogleMap.animateCamera
تماس بگیرید. نقشه به آرامی به ویژگی های جدید منتقل می شود. دقیق ترین شکل این روش، GoogleMap.animateCamera(cameraUpdate, duration, callback)
، سه آرگومان ارائه می دهد:
-
cameraUpdate
-
CameraUpdate
که محل حرکت دوربین را توضیح می دهد. -
callback
- شی ای که
GoogleMap.CancellableCallback
را پیاده سازی می کند. این رابط تعمیم یافته برای رسیدگی به وظایف، دو روش «onCancel()» و «onFinished()» را تعریف می کند. برای انیمیشن، متدها در شرایط زیر فراخوانی می شوند:-
onFinish()
- اگر انیمیشن بدون وقفه کامل شود، فراخوانی می شود.
-
onCancel()
اگر انیمیشن با فراخوانی
stopAnimation()
یا شروع یک حرکت دوربین جدید قطع شود، فراخوانی می شود.از طرف دیگر، اگر
GoogleMap.stopAnimation()
فراخوانی کنید، ممکن است این اتفاق بیفتد.
-
-
duration
- مدت زمان مورد نظر انیمیشن، بر حسب میلی ثانیه، به عنوان
int
.
قطعه کد زیر برخی از روش های متداول حرکت دوربین را نشان می دهد.
کاتلین
val sydney = LatLng(-33.88, 151.21) val mountainView = LatLng(37.4, -122.1) // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f)) // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()) // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10f), 2000, null) // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. val cameraPosition = CameraPosition.Builder() .target(mountainView) // Sets the center of the map to Mountain View .zoom(17f) // Sets the zoom .bearing(90f) // Sets the orientation of the camera to east .tilt(30f) // Sets the tilt of the camera to 30 degrees .build() // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
جاوا
LatLng sydney = new LatLng(-33.88,151.21); LatLng mountainView = new LatLng(37.4, -122.1); // Move the camera instantly to Sydney with a zoom of 15. map.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15)); // Zoom in, animating the camera. map.animateCamera(CameraUpdateFactory.zoomIn()); // Zoom out to zoom level 10, animating with a duration of 2 seconds. map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null); // Construct a CameraPosition focusing on Mountain View and animate the camera to that position. CameraPosition cameraPosition = new CameraPosition.Builder() .target(mountainView ) // Sets the center of the map to Mountain View .zoom(17) // Sets the zoom .bearing(90) // Sets the orientation of the camera to east .tilt(30) // Sets the tilt of the camera to 30 degrees .build(); // Creates a CameraPosition from the builder map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));