Source: https://maps.vietmap.vn/docs/vi/sdk-mobile/sdk-android/map/
# Bản đồ
### Cấu hình Gradle và AndroidManifest
### Thêm các dependency sau vào build.gradle của module app
```js
implementation 'com.github.vietmap-company:maps-sdk-android:2.0.4'
implementation 'com.github.vietmap-company:maps-sdk-plugin-localization-android:2.0.0'
implementation 'com.github.vietmap-company:vietmap-services-geojson-android:1.0.0'
implementation 'com.github.vietmap-company:vietmap-services-turf-android:1.0.2'
implementation 'com.squareup.okhttp3:okhttp:4.9.3'
implementation 'com.google.code.gson:gson:2.10.1'
```
Khai báo repository jitpack trong file `settings.gradle`
```js
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
// Add two lines below to the repositories block (In setting.gradle file)
maven { url 'https://plugins.gradle.org/m2' }
maven { url 'https://jitpack.io' }
}
}
```
Với dự án cũ, đặt khai báo này vào file **build.gradle** cấp project
```js
allprojects {
repositories {
google()
maven { url "https://jitpack.io" }
}
}
```
Nâng **compileSdk** và **targetSdk** lên **34**
```js
compileSdk 34
```
```js
targetSdk 34
```
Khai báo các quyền cần thiết trong file `AndroidManifest.xml`
```js
```
### Tạo activity chứa bản đồ
Tạo activity mới **VietMapMapViewActivity**
Thêm đoạn sau vào file layout **xml** của activity vừa tạo
```js
```
#### Khai báo các biến cần dùng trong activity
```js
private lateinit var mapView: MapView
private lateinit var vietMapGL: VietMapGL
private var polylines: MutableList? = null
private var polylineOptions: ArrayList? = ArrayList()
private var polygon: Polygon? = null
companion object {
private const val STATE_POLYLINE_OPTIONS = "polylineOptions"
private val HOCHIMINH = LatLng(10.791257, 106.669189)
private val NINHTHUAN = LatLng(11.550254, 108.960579)
private val DANANG = LatLng(16.045746, 108.202241)
private val HUE = LatLng(16.469602, 107.577462)
private val NGHEAN = LatLng(18.932151, 105.577207)
private val HANOI = LatLng(21.024696, 105.833099)
}
```
#### Thêm đoạn code sau vào hàm **onCreate**
SDK VIETMAP phải được khởi tạo trong hàm **onCreate** của activity thì mới chạy đúng
```js
override fun onCreate(savedInstanceState: Bundle?) {
/// Initialize vietmap SDK, you must add this line to ensure that the SDK works properly, without crashing
Vietmap.getInstance(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_viet_map_map_view_example_v2)
mapView = findViewById(R.id.vmMapView)
mapView.onCreate(savedInstanceState)
mapView.getMapAsync { vietMapGL: VietMapGL ->
this.vietMapGL = vietMapGL
/// Add vietmap vector style to vietmapSDK
vietMapGL.setStyle(
Style.Builder()
.fromUri("https://maps.vietmap.vn/api/maps/light/styles.json?apikey=YOUR_API_KEY_HERE")
)
vietMapGL.setOnPolylineClickListener { polyline: Polyline ->
Toast.makeText(
this ,
"You clicked on polyline with id = " + polyline.id,
Toast.LENGTH_SHORT
).show()
}
}
}
```
Muốn dùng màu và icon riêng, tạo bản đồ trong [Map Editor](https://tools.vietmap.vn/map-editor/) rồi thay URL style ở trên bằng link style của bản đồ đó.
#### Thêm marker kèm info window mặc định
```js
private fun addMarker(position:LatLng ): Marker {
return vietMapGL!!.addMarker(
MarkerOptions()
.position(position)
.title("Vietmap")
.snippet("Vietmap Android SDK")
.icon(
IconUtils().drawableToIcon(
this,
R.drawable.ic_launcher_foreground,
ResourcesCompat.getColor(resources,R.color.black , theme)
)
)
)
}
```
- Class `IconUtils` xem [tại đây](https://github.com/vietmap-company/vietmap-android-navigation-example/blob/v2.0.0/app/src/main/java/com/example/vietmapandroidnavigationexamplev2/util/IconUtils.kt)
#### Thêm polyline
```js
/// Define list of polyline options
private var polylineOptions: ArrayList? = ArrayList()
/// Define all polylines to add to the map
private val allPolylines: List
private get() {
val options: MutableList = ArrayList()
options.add(generatePolyline(HOCHIMINH, NINHTHUAN, "#F44336"))
options.add(generatePolyline(NINHTHUAN, DANANG, "#FF5722"))
options.add(generatePolyline(DANANG, HUE, "#673AB7"))
options.add(generatePolyline(HUE, NGHEAN, "#009688"))
options.add(generatePolyline(NGHEAN, HANOI, "#795548"))
return options
}
private fun generatePolyline(start: LatLng, end: LatLng, color: String): PolylineOptions {
val line = PolylineOptions()
line.add(start)
line.add(end)
line.color(Color.parseColor(color))
return line
}
/// Add all polylines to the map
private fun addPolyline(){
/// Add all polylines to the map
polylineOptions!!.addAll(allPolylines)
polylines = vietMapGL.addPolylines(polylineOptions!!)
}
```
- Bắt sự kiện bấm vào polyline
```js
private fun addPolyline(){
/// Add all polylines to the map
polylineOptions!!.addAll(allPolylines)
polylines = vietMapGL.addPolylines(polylineOptions!!)
...
///Add below line to implement on polyline click listener
vietMapGL.setOnPolylineClickListener { polyline: Polyline ->
Toast.makeText(
this ,
"You clicked on polyline with id = " + polyline.id,
Toast.LENGTH_SHORT
).show()
}
}
```
#### Thêm polygon
```js
/// Define list of lat lng points to draw a polygon
val STAR_SHAPE_POINTS: ArrayList = object : ArrayList() {
init {
add(LatLng(10.791257, 106.669189))
add(LatLng(11.550254, 108.960579))
add(LatLng(16.045746, 108.202241))
add(LatLng(16.469602, 107.577462))
}
}
/// Add a polygon to the map
private fun addPolygon(){
/// Add a polygon to the map
polygon = vietMapGL.addPolygon(
PolygonOptions()
.addAll(STAR_SHAPE_POINTS)
.fillColor(Color.parseColor("#3bb2d0"))
)
}
```
- Bắt sự kiện bấm vào polygon
```js
private fun addPolygon(){
/// Add a polygon to the map
polygon = vietMapGL.addPolygon(
PolygonOptions()
.addAll(STAR_SHAPE_POINTS)
.fillColor(Color.parseColor("#3bb2d0"))
)
...
/// Add below line to implement on polygon click listener
vietMapGL.setOnPolygonClickListener { polygon: Polygon ->
Toast.makeText(
this ,
"You clicked on polygon with id = " + polygon.id,
Toast.LENGTH_SHORT
).show()
}
}
```
#### Bắt sự kiện bấm vào bản đồ
Thêm callback vào activity để xử lý khi người dùng bấm lên bản đồ; callback trả về `latLng` của điểm được bấm
```js
/// Make the activity implement OnMapClickListener from VietMapGL
class VietMapMapViewExampleV2 : AppCompatActivity(),VietMapGL.OnMapClickListener{
...
}
/// Add map click listener to vietMapGL in onCreated function
override fun onCreate(savedInstanceState: Bundle?) {
...
vietMapGL?.addOnMapClickListener(this)
...
}
/// Handle onMapClick logic with clicked latLng response
override fun onMapClick(latLng: LatLng): Boolean {
addMarker(latLng)
return false
}
```
#### Hiển thị vị trí người dùng trên bản đồ
Khai báo các biến để bắt đầu theo dõi vị trí người dùng
```js
private var locationComponent: LocationComponent? = null
private var locationEngine: LocationEngine? = null
```
Thêm hàm sau vào activity
```js
private fun enableLocationComponent(style: Style?) {
locationComponent = vietMapGL!!.locationComponent
if (locationComponent != null) {
locationComponent!!.activateLocationComponent(
LocationComponentActivationOptions.builder(
this, style!!
).build()
)
if (!checkPermission()) {
return
}
locationComponent!!.setCameraMode(
CameraMode.TRACKING_GPS_NORTH, 750L, 18.0, 0.0, 0.0, null
)
locationComponent!!.isLocationComponentEnabled = true
locationComponent!!.zoomWhileTracking(19.0)
locationComponent!!.renderMode = RenderMode.GPS
locationComponent!!.locationEngine = locationEngine
}
updateMyLocationTrackingMode()
updateMyLocationRenderMode()
}
private fun updateMyLocationTrackingMode() {
val vietmapTrackingMode = intArrayOf(
CameraMode.NONE,
CameraMode.TRACKING,
CameraMode.TRACKING_COMPASS,
CameraMode.TRACKING_GPS
)
locationComponent!!.cameraMode = vietmapTrackingMode[0]
}
private fun updateMyLocationRenderMode() {
val vietmapRenderModes = intArrayOf(RenderMode.NORMAL, RenderMode.COMPASS, RenderMode.GPS)
locationComponent!!.renderMode = vietmapRenderModes[0]
}
/// check the permission is granted or not before using location
private fun checkPermission(): Boolean {
return ActivityCompat.checkSelfPermission(
this, ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
this, ACCESS_COARSE_LOCATION
) == PackageManager.PERMISSION_GRANTED
}
private fun initLocationEngine() {
val locationEngineDefault = LocationEngineDefault
locationEngine = locationEngineDefault.getDefaultLocationEngine(this)
}
```
Gọi `initLocationEngine` và `enableLocationComponent` trong callback của `setStyle`, bên trong hàm `onCreate`
```js
vietMapGL.setStyle(
Style.Builder()
.fromUri("https://maps.vietmap.vn/api/maps/light/styles.json?apikey=YOUR_API_KEY_HERE")
){
initLocationEngine()
enableLocationComponent(it)
}
```
#### Thêm các hàm vòng đời cần thiết
Activity cần có các hàm sau để ứng dụng không bị crash khi chạy
```js
override fun onStart() {
super.onStart()
mapView.onStart()
}
override fun onResume() {
super.onResume()
mapView.onResume()
}
override fun onPause() {
super.onPause()
mapView.onPause()
}
override fun onStop() {
super.onStop()
mapView.onStop()
}
override fun onLowMemory() {
super.onLowMemory()
mapView.onLowMemory()
}
override fun onDestroy() {
super.onDestroy()
mapView.onDestroy()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView.onSaveInstanceState(outState)
}
```
### Thêm API key
Thay mọi chỗ `YOUR_API_KEY_HERE` bằng API key VIETMAP cấp cho bạn, nếu không ứng dụng sẽ crash khi chạy. Lấy API key: [đăng ký miễn phí trên VIETMAP Console](https://maps.vietmap.vn/console-v2/register).