Mapbox — это SDK с открытым исходным кодом для идеальных по пикселям векторных карт, который обещает скорость рендеринга и плавность видеоигры. Если вы заинтересованы в интеграции функциональности карты в свои приложения, тогда стоит рассмотреть Mapbox.
Обзор и примеры Mapbox Android SDK являются хорошей отправной точкой. В этом уроке я создам что-то более сложное, приложение, которое рисует лучший маршрут от пункта отправления до пункта назначения на карте.
Давайте начнем!
Вы можете найти код для окончательного проекта на GitHub .
Для использования Mapbox в вашем приложении вам понадобится токен доступа API. Чтобы получить его, создайте учетную запись Mapbox и найдите свою здесь .
Добавьте токен в strings.xml в вашем проекте Android:
<string name="accessToken">Your access token</string>
В AndroidManifest.xml добавьте следующие разрешения для доступа в Интернет и определения местоположения.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
Примечание . В Android Marshmallow (API 23) и выше необходимо запрашивать разрешения во время выполнения .
Установка Mapbox
Откройте build.gradle (Module: app) и добавьте MapBox в качестве зависимости.
repositories { mavenCentral() } dependencies { . . . compile('com.mapbox.mapboxsdk:mapbox-android-sdk:3.2.0@aar') { transitive = true } compile ('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0@aar'){ transitive=true } }
Первая зависимость представляет собой Mapbox, а вторая — это библиотека маршрутов, позволяющая добавлять в приложение маршруты вождения, прогулок и езды на велосипеде и рисовать их на карте.
Макет карты
В файле макета content_main.xml замените содержимое следующим:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:mapbox="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.valdio.mapboxintegration.MainActivity" tools:showIn="@layout/activity_main"> <com.mapbox.mapboxsdk.views.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" mapbox:access_token="@string/accessToken" /> </RelativeLayout>
Инициализируйте переменные, которые вам понадобятся в классе MainActivity
:
public class MainActivity extends AppCompatActivity { private MapView mapView = null; private String MAPBOX_ACCESS_TOKEN = ""; private DirectionsRoute currentRoute = null; ...
В onCreate()
файла MainActivity.java удалите панель инструментов и код кнопки плавающего действия и инициализируйте карту, добавив:
String MAPBOX_ACCESS_TOKEN = getResources().getString(R.string.accessToken); // Set up a standard Mapbox map MapView mapView = (MapView) findViewById(R.id.mapview); mapView.setAccessToken(MAPBOX_ACCESS_TOKEN); mapView.setStyleUrl(Style.MAPBOX_STREETS); // specify the map style mapView.setZoom(14); // zoom level mapView.onCreate(savedInstanceState);
Карты Mapbox должны реализовывать методы жизненного цикла Activity
чтобы избежать ошибок времени выполнения, поэтому добавьте необходимые функции переопределения.
@Override protected void onStart() { super.onStart(); mapView.onStart(); } @Override protected void onStop() { super.onStop(); mapView.onStop(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); } @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); }
Теперь, когда Mapbox настроен, пришло время начать сборку приложения.
Добавление маркера на карту
Добавьте следующее в onCreate
в MainActivity
:
CameraPosition cameraPosition = new CameraPosition.Builder() .target(new LatLng(41.327752, 19.818666)) // Sets the center of the map to the specified location .zoom(13) // Sets the zoom level .build(); //set the user's viewpoint as specified in the cameraPosition object mapView.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); //Add a marker to the map in the specified location mapView.addMarker(new MarkerOptions() .position(new LatLng(41.327752, 19.818666)) .title("MapBox Marker!") .snippet("Welcome to my marker."));
CameraPosition
— это полезный класс Mapbox, используемый для установки положения, угла, масштабирования и наклона точки обзора пользователя.
Вот как выглядит маркер на карте:
Получить местоположение устройства.
Чтобы Mapbox мог получить доступ к местоположению устройства, службы определения местоположения должны быть включены, и приложение должно иметь разрешение на их использование. Как упоминалось ранее, в Android Marshmallow (API 23) и более поздних версиях необходимо запрашивать разрешения во время выполнения .
Добавьте код, чтобы получить текущее местоположение для новой функции:
private void myLocation() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } mapView.setMyLocationEnabled(true); mapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW); mapView.getMyLocation(); }
И вызвать эту функцию после кода инициализации карты:
... mapView.onCreate(savedInstanceState); myLocation();
В этом случае для отслеживания установлено значение TRACKING_FOLLOW
, что означает, что местоположение пользователя будет постоянно отслеживаться, и карта будет обновляться по мере изменения.
Почти готово!
Теперь у вас есть маркер и местоположение, затем рисует маршрут на карте.
При этом используется вторая библиотека, импортированная в зависимостях, «Библиотека направлений», также созданная командой Mapbox.
Вот как это работает:
- Создайте две
Waypoint
, источник и пункт назначения. - Создайте
MapboxDirections
построителяMapboxDirections
, который представляет собой сетевой запрос к API-интерфейсу Mapbox, содержащий исходную и конечнуюWaypoint
и профиль маршрута (вождение, ходьба или езда на велосипеде). - Выполнить запрос направления асинхронно. Класс
MapboxDirections
имеет встроенный асинхронный запрос с использованием Retrofit API, используяenqueue()
для выполнения запроса. - Метод
onResponse()
возвращает ответ Retrofit, который является стандартным ответом JSON API. - Тело ответа содержит пары координат местоположения, координаты, которые будут нарисованы на карте.
- С помощью Mapbox Polyline координаты нарисованы на карте. Полилиния — это геометрический объект с незамкнутым списком координат, нарисованным в виде линии.
Чтобы использовать библиотеку «Направление», получите местоположение устройства в качестве начальной точки и местоположение, указанное пользователем, для чего нажмите и удерживайте нажатой карту на карте в качестве конечной точки.
Создайте две точки маршрута и добавьте маркер в пункте назначения.
Добавьте следующее в onCreate
функции onCreate
:
mapView.setOnMapLongClickListener(new MapView.OnMapLongClickListener() { @Override public void onMapLongClick(LatLng point) { //Remove previously added markers //Marker is an annotation that shows an icon image at a geographical location //so all markers can be removed with the removeAllAnnotations() method. mapView.removeAllAnnotations(); // Set the origin waypoint to the devices location Waypoint origin = new Waypoint(mapView.getMyLocation().getLongitude(), mapView.getMyLocation().getLatitude()); // Set the destination waypoint to the location point long clicked by the user Waypoint destination = new Waypoint(point.getLongitude(), point.getLatitude()); // Add marker to the destination waypoint mapView.addMarker(new MarkerOptions() .position(new LatLng(point)) .title("Destination Marker") .snippet("My destination")); // Get route from API getRoute(origin, destination); } });
Создайте сетевой запрос MapboxDirections и выполните его асинхронно.
Добавьте следующий метод, чтобы получить лучший маршрут:
private void getRoute(Waypoint origin, Waypoint destination) { MapboxDirections directions = new MapboxDirections.Builder() .setAccessToken(MAPBOX_ACCESS_TOKEN) .setOrigin(origin) .setDestination(destination) .setProfile(DirectionsCriteria.PROFILE_WALKING) .build(); directions.enqueue(new Callback<DirectionsResponse>() { @Override public void onResponse(Response<DirectionsResponse> response, Retrofit retrofit) { // Display some info about the route currentRoute = response.body().getRoutes().get(0); showToastMessage(String.format("You are %d meters \nfrom your destination", currentRoute.getDistance())); // Draw the route on the map drawRoute(currentRoute); } @Override public void onFailure(Throwable t) { showToastMessage("Error: " + t.getMessage()); } }); }
Нарисуйте ломаную линию на основе координат на карте.
Добавьте этот метод, чтобы нарисовать маршрут:
private void drawRoute(DirectionsRoute route) { // Convert List<Waypoint> into LatLng[] List<Waypoint> waypoints = route.getGeometry().getWaypoints(); LatLng[] point = new LatLng[waypoints.size()]; for (int i = 0; i < waypoints.size(); i++) { point[i] = new LatLng( waypoints.get(i).getLatitude(), waypoints.get(i).getLongitude()); } // Draw Points on MapView mapView.addPolyline(new PolylineOptions() .add(point) .color(Color.parseColor("#38afea")) .width(5)); } private void showToastMessage(String message) { Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); }
Запустите проект, выберите две точки, и вы должны увидеть что-то вроде ниже.
Пройдя лишнюю милю
В этом уроке я рассмотрел основы, чтобы вы начали работать с MapBox SDK и библиотекой Direction. MapBox имеет более интересные функции для использования в вашем приложении, такие как различные стили карт или для чего-то другого, собственные векторные карты.
Другая библиотека, которую я рекомендую, — это библиотека геокодирования для преобразования координат в адреса или наоборот. Чтобы узнать больше о MapBox, проверьте его мобильные карты , где вы можете найти информацию о библиотеках, упомянутых в этом руководстве.