Bản đồ trong SDK bản đồ dành cho Android có thể được nghiêng và xoay một cách dễ dàng cử chỉ, giúp người dùng có thể điều chỉnh bản đồ theo hướng phù hợp với họ. Ở bất kỳ mức thu phóng nào, bạn có thể xoay bản đồ hoặc thay đổi với độ trễ rất thấp nhờ quy mô nhỏ hơn ô bản đồ dựa trên vectơ.
Mã mẫu
Kho lưu trữ Apidemos trên GitHub bao gồm một mẫu minh hoạ các tính năng của máy ảnh:
- Camera DemoActivity – Kotlin: Thay đổi vị trí của máy ảnh
- Camera DemoActivity – Java: Thay đổi vị trí của camera
Giới thiệu
Giống như Google Maps trên web, SDK bản đồ dành cho Android đại diện cho bề mặt của thế giới (hình cầu) trên màn hình của thiết bị (mặt phẳng) bằng cách sử dụng Phép chiếu bộ đo. Theo hướng đông và tây, bản đồ lặp đi lặp lại vô hạn khi thế giới tự bao quanh một cách liền mạch. Trong hướng bắc và nam bản đồ bị giới hạn ở khoảng 85 độ bắc và là 85 độ Nam.
Lưu ý: Phép chiếu Mercator có chiều rộng hữu hạn theo chiều dọc nhưng chiều cao vô hạn theo vĩ độ. Chúng tôi "đã cắt giảm" bản đồ cơ sở hình ảnh sử dụng phép chiếu Mercator ở khoảng +/- 85 độ đến làm cho hình dạng bản đồ thu được là hình vuông, cho phép áp dụng logic dễ dàng hơn cho ô lựa chọn.
SDK bản đồ dành cho Android cho phép bạn thay đổi quan điểm của người dùng về ánh xạ bằng cách sửa đổi máy ảnh của bản đồ.
Các thay đổi đối với máy ảnh sẽ không làm thay đổi điểm đánh dấu, lớp phủ hoặc nội dung khác đồ hoạ bạn đã thêm, mặc dù bạn có thể muốn thay đổi đồ hoạ bổ sung cho phù hợp hiệu quả hơn với chế độ xem mới.
Vì bạn có thể lắng nghe cử chỉ của người dùng trên bản đồ, nên bạn có thể thay đổi bản đồ trong
phản hồi yêu cầu của người dùng. Ví dụ: phương thức gọi lại
OnMapClickListener.onMapClick()
phản hồi một
một lần nhấn trên bản đồ. Vì phương thức này nhận được vĩ độ và kinh độ
của vị trí nhấn, bạn có thể phản hồi bằng cách xoay hoặc thu phóng tới điểm đó.
Bạn có thể dùng các phương thức tương tự để phản hồi khi người dùng nhấn vào bong bóng của điểm đánh dấu hoặc
để phản hồi cử chỉ kéo trên điểm đánh dấu.
Bạn cũng có thể theo dõi chuyển động của camera để ứng dụng nhận được thông báo khi camera bắt đầu di chuyển, hiện đang di chuyển hoặc dừng lại đang di chuyển. Để biết thông tin chi tiết, hãy xem hướng dẫn về sự kiện thay đổi camera.
Vị trí camera
Chế độ xem bản đồ được mô hình hoá như một máy ảnh nhìn xuống mặt phẳng. Vị trí của máy ảnh (và do đó kết xuất bản đồ) được chỉ định bởi các thuộc tính sau: target (vĩ độ/kinh độ vị trí), góc, nghiêng, và thu phóng.
![Sơ đồ thuộc tính của camera](https://developers-dot-devsite-v2-prod.appspot.com/static/maps/documentation/android-sdk/images/camera.png?authuser=3&hl=vi)
Mục tiêu (vị trí)
Mục tiêu máy ảnh là vị trí của tâm bản đồ, được chỉ định là vĩ độ và kinh độ.
Vĩ độ có thể nằm trong khoảng từ -85 đến 85 độ. Giá trị ở trên hoặc thấp hơn phạm vi này sẽ được giới hạn ở giá trị gần nhất trong phạm vi này. Ví dụ: chỉ định vĩ độ là 100 sẽ đặt giá trị thành 85. Kinh độ nằm trong khoảng từ -180 đến 180 độ. Giá trị cao hơn hoặc thấp hơn phạm vi sẽ được gói sao cho chúng nằm trong phạm vi (-180, 180). Để ví dụ: 480, 840 và 1200 đều sẽ được bọc ở 120 độ.Góc phương vị (hướng)
Góc phương vị của camera chỉ định hướng la bàn, được đo bằng độ từ hướng bắc thực, tương ứng vào cạnh trên của bản đồ. Nếu bạn vẽ một đường dọc từ tâm bản đồ đến cạnh trên của bản đồ, góc phương vị tương ứng với hướng của máy ảnh (được đo bằng độ) thành chính bắc.
Góc bằng 0 có nghĩa là đỉnh bản đồ trỏ đến hướng bắc thực sự. Giá trị mang 90 có nghĩa là điểm đầu của các điểm trên bản đồ về hướng đông (90 độ trên la bàn). Một giá trị 180 có nghĩa là điểm trên cùng của các điểm trên bản đồ đến ở hướng nam.
API Maps cho phép bạn thay đổi góc phương vị của bản đồ. Ví dụ: một người lái xe ô tô thường xoay bản đồ đường đi để căn chỉnh nó với hướng đi của họ, trong khi người đi bộ đường dài sử dụng bản đồ và la bàn thường định hướng bản đồ sao cho một đường thẳng đứng chỉ về hướng bắc.
Nghiêng (góc xem)
Độ nghiêng xác định vị trí của máy ảnh trên một vòng cung ngay phía trên bản đồ vị trí trung tâm, được đo bằng độ từ phần thấp nhất (hướng chỉ ngay bên dưới camera). Giá trị 0 tương ứng với một camera đã chỉ xuống. Giá trị lớn hơn 0 tương ứng với một máy ảnh được hướng về phía đường chân trời số độ được chỉ định. Khi bạn thay đổi góc nhìn, bản đồ sẽ xuất hiện trong phối cảnh với các đối tượng ở xa xuất hiện nhỏ hơn và các đối tượng lân cận xuất hiện lớn hơn. Nội dung sau đây hình minh hoạ minh hoạ điều này.
Trong các hình dưới đây, góc nhìn là 0 độ. Hình ảnh đầu tiên cho thấy sơ đồ của điều này; vị trí 1 là vị trí camera và vị trí 2 là vị trí hiện tại trên bản đồ. Bản đồ kết quả sẽ hiển thị bên dưới nó.
![]() |
![]() |
Trong các hình dưới đây, góc nhìn là 45 độ. Lưu ý rằng camera di chuyển theo nửa vòng cung giữa đường thẳng từ trên cao (0 độ) đến mặt đất (90 độ), vào vị trí 3. Máy ảnh vẫn đang hướng vào điểm giữa của bản đồ, nhưng khu vực được biểu thị bằng dòng ở vị trí 4 giờ đây sẽ hiển thị.
![]() |
![]() |
Bản đồ trong ảnh chụp màn hình này vẫn được căn giữa cùng một điểm như trong bản đồ gốc, nhưng nhiều đối tượng địa lý khác đã xuất hiện ở phía trên cùng của bản đồ. Khi bạn tăng góc trên 45 độ, đối tượng giữa máy ảnh và bản đồ vị trí xuất hiện lớn hơn tương ứng, trong khi các đối tượng nằm ngoài vị trí trên bản đồ xuất hiện nhỏ hơn tương ứng, mang lại hiệu ứng ba chiều.
Zoom (thu phóng)
Mức thu phóng của máy ảnh xác định tỷ lệ của bản đồ. Ở mức thu phóng lớn hơn có thể thấy nhiều chi tiết hơn trên màn hình ở mức thu phóng nhỏ hơn có thể nhìn thấy nhiều khu vực hơn thế giới trên màn hình. Ở mức thu phóng 0, tỷ lệ của bản đồ sao cho toàn bộ thế giới có chiều rộng xấp xỉ 256 dp (pixel không phụ thuộc vào mật độ).
Việc tăng mức thu phóng lên 1 sẽ tăng gấp đôi chiều rộng của thế giới trên màn hình. Do đó, ở mức thu phóng N, chiều rộng của thế giới xấp xỉ 256 * 2N dp. Ví dụ: ở mức thu phóng 2, toàn bộ thế giới xấp xỉ Rộng 1024 dp.
Mức thu phóng không cần phải là một số nguyên. Phạm vi thu phóng cấp độ mà bản đồ cho phép phụ thuộc vào một số yếu tố bao gồm cả mục tiêu, loại bản đồ và kích thước màn hình. Bất kỳ số nào nằm ngoài dải ô sẽ được chuyển đổi thành giá trị hợp lệ gần nhất tiếp theo, có thể là mức thu phóng tối thiểu hoặc mức thu phóng tối đa. Danh sách sau đây cho thấy mức độ chi tiết gần đúng bạn có thể thấy ở mỗi mức thu phóng:
- 1: Thế giới
- 5: Vùng đất/lục địa
- 10: Thành phố
- 15: Đường phố
- 20: Toà nhà
![]() |
![]() |
![]() |
Di chuyển camera
API Maps cho phép bạn thay đổi khu vực nào của thế giới hiển thị trên bản đồ. Bạn có thể thực hiện điều này bằng cách thay đổi vị trí của máy ảnh (thay vì di chuyển bản đồ).
Khi thay đổi camera, bạn có thể tạo ảnh động cho kết quả chuyển động camera. Ảnh động nội suy giữa máy ảnh hiện tại và các thuộc tính mới của camera. Bạn cũng có thể kiểm soát thời lượng của ảnh động.
Để thay đổi vị trí của camera, bạn phải chỉ định nơi bạn muốn
di chuyển camera bằng CameraUpdate
. API Maps
cho phép bạn tạo nhiều loại CameraUpdate
khác nhau bằng cách sử dụng
CameraUpdateFactory
. Bạn có các tuỳ chọn sau đây:
Thay đổi mức thu phóng và đặt mức thu phóng tối thiểu/tối đa
CameraUpdateFactory.zoomIn()
và
CameraUpdateFactory.zoomOut()
cung cấp cho bạn CameraUpdate
thay đổi mức thu phóng 1.0 mà vẫn giữ nguyên
tất cả các thuộc tính khác đều như nhau.
CameraUpdateFactory.zoomTo(float)
cung cấp cho bạn một CameraUpdate
thay đổi mức thu phóng thành giá trị đã cho,
trong khi vẫn giữ nguyên tất cả các thuộc tính khác.
CameraUpdateFactory.zoomBy(float)
và
CameraUpdateFactory.zoomBy(float, Point)
cung cấp cho bạn một CameraUpdate
tăng lên (hoặc giảm xuống nếu giá trị là
âm) mức thu phóng theo giá trị đã cho. Chính sách sau cố định điểm đã cho
trên màn hình để nó vẫn ở cùng một vị trí (vĩ độ/kinh độ)
Do đó, nó có thể thay đổi vị trí của camera nhằm đạt được mục tiêu này.
Bạn có thể thấy hữu ích khi đặt mức thu phóng tối thiểu và/hoặc tối đa ưa thích. Ví dụ: điều này rất hữu ích trong việc kiểm soát trải nghiệm của người dùng nếu ứng dụng của bạn hiển thị khu vực xác định xung quanh địa điểm yêu thích hoặc nếu bạn đang sử dụng ô tuỳ chỉnh với một tập hợp mức độ thu phóng giới hạn.
Kotlin
private lateinit var map: GoogleMap map.setMinZoomPreference(6.0f) map.setMaxZoomPreference(14.0f)
Java
private GoogleMap map; map.setMinZoomPreference(6.0f); map.setMaxZoomPreference(14.0f);
Xin lưu ý rằng có một số cân nhắc kỹ thuật có thể ngăn API cho phép người dùng thu phóng quá thấp hoặc quá cao. Ví dụ: vệ tinh hoặc địa hình có thể có mức thu phóng tối đa thấp hơn các ô bản đồ cơ sở.
Thay đổi vị trí của camera
Có hai phương pháp thuận tiện cho các thay đổi phổ biến về vị trí.
CameraUpdateFactory.newLatLng(LatLng)
cung cấp cho bạn CameraUpdate
có thể thay đổi vĩ độ và kinh độ của máy ảnh.
trong khi vẫn bảo toàn tất cả các thuộc tính khác.
CameraUpdateFactory.newLatLngZoom(LatLng, float)
cung cấp cho bạn CameraUpdate
để thay đổi
vĩ độ, kinh độ và mức thu phóng trong khi vẫn giữ nguyên tất cả các thuộc tính khác.
Để có thể linh hoạt thay đổi vị trí của camera, hãy sử dụng
CameraUpdateFactory.newCameraPosition(CameraPosition)
cung cấp cho bạn CameraUpdate
để di chuyển camera đến
vị trí đã cho. Bạn có thể lấy CameraPosition
trực tiếp bằng cách sử dụng
new CameraPosition()
hoặc với CameraPosition.Builder
sử dụng
new CameraPosition.Builder()
.
Lia máy (cuộn)
CameraUpdateFactory.scrollBy(float, float)
cung cấp cho bạn CameraUpdate
thay đổi vĩ độ và kinh độ của máy ảnh để bản đồ di chuyển theo
số lượng pixel đã chỉ định. Giá trị x dương khiến máy ảnh di chuyển đến
sang phải, để bản đồ dường như đã di chuyển sang trái. Y dương
giá trị này làm cho camera di chuyển xuống, do đó bản đồ dường như đã di chuyển
lên. Ngược lại, giá trị x âm làm cho máy ảnh di chuyển sang trái, do đó
rằng bản đồ dường như đã di chuyển sang phải và các giá trị y âm khiến
di chuyển lên. Thao tác cuộn tương ứng với dòng điện của camera
hướng. Ví dụ: nếu máy ảnh có góc 90 độ, thì hướng đông
là "lên".
Đặt ranh giới
Đặt ranh giới của bản đồ
Đôi khi, bạn nên di chuyển
sao cho toàn bộ khu vực quan tâm có thể nhìn thấy được ở phạm vi lớn nhất có thể
mức thu phóng. Ví dụ: nếu bạn đang hiển thị tất cả các trạm xăng trong
5 dặm từ vị trí hiện tại của người dùng, bạn có thể di chuyển camera sao cho
đều hiển thị trên màn hình. Để thực hiện việc này, trước tiên hãy tính toán
LatLngBounds
mà bạn muốn xuất hiện trên màn hình. Bạn
sau đó có thể dùng CameraUpdateFactory.newLatLngBounds(LatLngBounds bounds, int
padding)
để lấy CameraUpdate
có thể thay đổi máy ảnh
vị trí sao cho LatLngBounds
đã cho hoàn toàn nằm vừa vặn trên bản đồ, lấy
tính đến khoảng đệm (tính bằng pixel) được chỉ định. CameraUpdate
được trả về
đảm bảo khoảng cách (tính bằng pixel) giữa các giới hạn đã cho và cạnh của
ánh xạ tối thiểu phải bằng khoảng đệm được chỉ định. Lưu ý rằng độ nghiêng và
góc của bản đồ sẽ đều là 0.
Kotlin
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0))
Java
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngBounds(australiaBounds, 0));
Căn giữa bản đồ trong một khu vực
Trong một số trường hợp, bạn nên căn giữa camera trong một giới hạn thay vì
bao gồm cả biên giới cực đoan. Ví dụ: để căn giữa máy ảnh ở một quốc gia
mà vẫn duy trì được mức thu phóng không đổi. Trong trường hợp này, bạn có thể sử dụng phương pháp tương tự,
bằng cách tạo LatLngBounds
rồi sử dụng
CameraUpdateFactory.newLatLngZoom(LatLng latLng, float zoom)
bằng
LatLngBounds
.getCenter()
. Phương thức getCenter() sẽ trả về
trung tâm địa lý của LatLngBounds
.
Kotlin
val australiaBounds = LatLngBounds( LatLng((-44.0), 113.0), // SW bounds LatLng((-10.0), 154.0) // NE bounds ) map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.center, 10f))
Java
LatLngBounds australiaBounds = new LatLngBounds( new LatLng(-44, 113), // SW bounds new LatLng(-10, 154) // NE bounds ); map.moveCamera(CameraUpdateFactory.newLatLngZoom(australiaBounds.getCenter(), 10));
Phương thức quá tải, newLatLngBounds(boundary, width, height,
padding)
cho phép bạn chỉ định chiều rộng và chiều cao tính bằng pixel cho
hình chữ nhật với ý định tương ứng với kích thước của
bản đồ. Hình chữ nhật này được đặt sao cho tâm của nó giống với tâm
chế độ xem của bản đồ (để nếu kích thước được chỉ định giống với kích thước của
chế độ xem của bản đồ, thì hình chữ nhật đó trùng với chế độ xem của bản đồ). Chiến lược phát hành đĩa đơn
trả về CameraUpdate
sẽ di chuyển camera sao cho
LatLngBounds
được căn giữa trên màn hình trong hình chữ nhật đã cho ở
mức thu phóng lớn nhất có thể, có tính đến khoảng đệm bắt buộc.
Lưu ý: Chỉ sử dụng phương thức đơn giản hơn
newLatLngBounds(boundary, padding)
để tạo CameraUpdate
nếu dữ liệu này được dùng để di chuyển
camera sau khi bản đồ đã được bố trí. Trong khi bố cục, API
tính toán ranh giới hiển thị của bản đồ cần thiết để
chiếu hộp giới hạn. Để so sánh, bạn có thể sử dụng
CameraUpdate
được phương thức phức tạp hơn trả về
newLatLngBounds(boundary, width, height, padding)
bất kỳ lúc nào, ngay cả trước khi bản đồ trải qua bố cục, vì API
tính toán ranh giới hiển thị từ các đối số mà bạn truyền.
Hạn chế lia máy của người dùng trong một khu vực nhất định
Trong các trường hợp trên, bạn đặt giới hạn của bản đồ nhưng người dùng sau đó có thể cuộn hoặc xoay ra ngoài các giới hạn này. Thay vào đó, bạn nên đặt giới hạn vĩ độ/kinh độ trung tâm của tiêu điểm bản đồ (máy ảnh target) để người dùng chỉ có thể cuộn và di chuyển trong những giới hạn này. Ví dụ: ứng dụng bán lẻ cho trung tâm mua sắm hoặc sân bay có thể muốn ràng buộc bản đồ ở một các giới hạn cụ thể, cho phép người dùng cuộn và xoay trong các giới hạn đó.
Kotlin
// 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)
Java
// 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);
Sơ đồ dưới đây minh hoạ một tình huống trong đó mục tiêu của máy ảnh bị ràng buộc vào khu vực lớn hơn khung nhìn một chút. Người dùng có thể cuộn và xoay, miễn là mục tiêu máy ảnh vẫn nằm trong vùng giới hạn. Chiến lược phát hành đĩa đơn chữ thập biểu thị mục tiêu máy ảnh:
Bản đồ luôn lấp đầy khung nhìn, ngay cả khi việc đó khiến khung nhìn hiển thị các khu vực nằm ngoài giới hạn đã xác định. Ví dụ: nếu bạn định vị mục tiêu máy ảnh tại góc của khu vực bị giới hạn, phần nằm ngoài góc hiển thị trong khung nhìn nhưng người dùng không thể cuộn thêm vào khu vực đó. Chiến lược phát hành đĩa đơn biểu đồ dưới đây minh hoạ tình huống này. Chữ thập tượng trưng cho máy ảnh mục tiêu:
Trong sơ đồ dưới đây, mục tiêu của máy ảnh có giới hạn rất hạn chế, cung cấp cho người dùng rất ít cơ hội để cuộn hoặc xoay bản đồ. Hình chữ thập biểu thị mục tiêu máy ảnh:
Đang cập nhật chế độ xem camera
Để áp dụng CameraUpdate
cho bản đồ, bạn có thể di chuyển
máy ảnh ngay lập tức hoặc tạo ảnh động mượt mà cho máy ảnh. Để di chuyển camera
ngay lập tức bằng CameraUpdate
được cung cấp, bạn có thể gọi
GoogleMap.moveCamera(CameraUpdate)
.
Bạn có thể mang đến trải nghiệm dễ chịu hơn cho người dùng, đặc biệt là đối với các lượt di chuyển ngắn.
bằng cách tạo ảnh động cho thay đổi. Để làm việc này thay vì gọi
GoogleMap.moveCamera
cuộc gọi
GoogleMap.animateCamera
.
Bản đồ sẽ di chuyển trơn tru sang các thuộc tính mới. Hình thức chi tiết nhất của phương pháp này,
GoogleMap.animateCamera(cameraUpdate, duration, callback)
,
đưa ra ba đối số:
cameraUpdate
CameraUpdate
mô tả vị trí di chuyển camera.callback
- Đối tượng giúp triển khai
GoogleMap.CancellableCallback
. Giao diện tổng quát hoá để xử lý các tác vụ này xác định hai phương thức "onCancel()" và "onFinish()". Đối với ảnh động, các phương thức được gọi trong các trường hợp sau:onFinish()
- Được gọi nếu ảnh động hoàn tất mà không bị gián đoạn.
onCancel()
-
Được gọi nếu ảnh động bị gián đoạn do gọi
stopAnimation()
hoặc bắt đầu một chuyển động mới của camera.Ngoài ra, điều này cũng có thể xảy ra nếu bạn gọi
GoogleMap.stopAnimation()
.
duration
- Thời lượng mong muốn của ảnh động, tính bằng mili giây, dưới dạng
int
.
Các đoạn mã sau đây minh hoạ một số cách phổ biến để di chuyển máy ảnh.
Kotlin
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))
Java
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));