Безопасность

Аутентификация

Все запросы требуют API-ключ в заголовке Authorization.

Заголовок
Authorization: Bearer YOUR_API_KEY

Ключи создаются в портале в разделе «API Keys». Каждый ключ привязан к вашему аккаунту и имеет собственные лимиты.

POST Маршрут /v1/route

Построение маршрута между двумя точками с учетом типа транспорта. Поддерживает до 20 промежуточных точек (waypoints).

Параметры запроса
Параметр Тип Обязателен По умолчанию Описание
from object Да Начальная точка {lat, lon}
to object Да Конечная точка {lat, lon}
waypoints array Нет Промежуточные точки (до 20). Массив объектов {lat, lon}
mode string Нет "car" Тип транспорта: car, foot, bike
alternatives boolean Нет false Возвращать альтернативные маршруты
steps boolean Нет false Включить пошаговые инструкции
language string Нет "en" Язык инструкций: en, ru
Пример запроса
Пример ответа
GET Геокодинг /v1/geocode

Прямой геокодинг — поиск координат по текстовому адресу.

Параметры запроса
Параметр Тип Обязателен По умолчанию Описание
q string Да Поисковый запрос (адрес, название места)
limit integer Нет 5 Максимальное количество результатов (1-20)
language string Нет "en" Язык результатов: en, ru
countrycodes string Нет Ограничить поиск странами (ISO 3166-1 alpha-2)
Пример запроса
GET /v1/geocode?q=Москва&limit=5&language=ru
Пример ответа
GET Обратный геокодинг /v1/reverse

Обратный геокодинг — получение адреса по координатам.

Параметры запроса
Параметр Тип Обязателен По умолчанию Описание
lat number Да Широта (-90 до 90)
lon number Да Долгота (-180 до 180)
language string Нет "en" Язык результата: en, ru
zoom integer Нет 18 Уровень детализации (0-18)
Пример запроса
GET /v1/reverse?lat=55.7558&lon=37.6176&language=ru
Пример ответа
Flutter SDK

Установка

Flutter SDK для навигации, маршрутизации, геокодинга и интерактивных карт на базе MapLibre GL. Версия 0.2.0.

pubspec.yaml
dependencies: qorvia_maps_sdk: ^latest_versionz
Android — AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
iOS — Info.plist
<key>NSLocationWhenInUseUsageDescription</key> <string>App needs location access for navigation</string> <key>NSLocationAlwaysAndWhenInUseUsageDescription</key> <string>App needs background location for turn-by-turn navigation</string>
SDK Инициализация

Инициализируйте SDK перед использованием. URL тайлов загружается автоматически.

main.dart
import 'package:qorvia_maps_sdk/qorvia_maps_sdk.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); // Инициализация SDK (URL тайлов загружается автоматически) await QorviaMapsSDK.init( apiKey: 'YOUR_API_KEY', baseUrl: 'https://qorviamapkit.ru', // опционально enableLogging: true, // для отладки prefetchTileUrl: true, // предзагрузка тайлов ); runApp(MyApp()); }
Проверка и доступ
// Проверка инициализации if (QorviaMapsSDK.isInitialized) { final client = QorviaMapsSDK.instance.client; } // Получить URL тайлов final tileUrl = await QorviaMapsSDK.instance.getTileUrl(); // Освобождение ресурсов QorviaMapsSDK.dispose();
SDK Карта BaseMapView

Виджет интерактивной карты с поддержкой жестов, маркеров и маршрутов.

Базовый пример
final controller = QorviaMapController(); QorviaMapView( controller: controller, options: const MapOptions( initialCenter: Coordinates(lat: 55.7539, lon: 37.6208), initialZoom: 13, showUserLocation: true, showCompass: true, showZoomControls: false, ), onMapCreated: (ctrl) => print('Map ready'), onMapTap: (coordinates) => print('Tapped: $coordinates'), onMapLongPress: (coordinates) => print('Long press: $coordinates'), )
Параметры QorviaMapView
Параметр Тип Описание
controller QorviaMapController? Контроллер карты
options MapOptions Конфигурация карты (центр, зум, жесты)
markers List<Marker> Маркеры для отображения
clusterOptions MarkerClusterOptions? Настройки кластеризации маркеров
routeLines List<RouteLine> Линии маршрутов
onMapCreated Function(QorviaMapController) Callback готовности карты
onMapTap Function(Coordinates) Callback нажатия на карту
onMapLongPress Function(Coordinates) Callback долгого нажатия
onMarkerTap Function(Marker) Callback нажатия на маркер
onClusterTap Function(MarkerCluster) Callback нажатия на кластер
onCameraMove Function(CameraPosition) Callback движения камеры
Управление камерой
// Анимация к позиции await controller.animateCamera( CameraUpdate.newCameraPosition(CameraPosition( center: Coordinates(lat: 55.75, lon: 37.62), zoom: 15, tilt: 45, bearing: 90, )), duration: Duration(milliseconds: 800), ); // Перемещение к координатам с зумом await controller.animateCamera( CameraUpdate.newLatLngZoom( Coordinates(lat: 55.75, lon: 37.62), 16, ), ); // Вписать в границы await controller.animateCamera( CameraUpdate.newLatLngBounds(coordinates, padding: 50), ); // Управление зумом, наклоном и поворотом await controller.zoomIn(); await controller.zoomOut(); await controller.animateCamera(CameraUpdate.tiltTo(60)); await controller.animateCamera(CameraUpdate.bearingTo(180));
SDK Маркеры

Разнообразные типы маркеров: стандартные, нумерованные, анимированные, с кастомными иконками.

Добавление маркеров
QorviaMapView( controller: controller, markers: [ // Стандартный маркер Marker( id: 'start', position: Coordinates(lat: 55.7539, lon: 37.6208), icon: DefaultMarkerIcon.start, ), // Нумерованный маркер Marker( id: 'waypoint1', position: Coordinates(lat: 55.7545, lon: 37.6220), icon: NumberedMarkerIcon(number: 1), ), // Анимированный маркер Marker( id: 'active', position: Coordinates(lat: 55.7550, lon: 37.6230), icon: AnimatedMarkerIcon.pulsingPrimary, ), ], onMarkerTap: (marker) => print('Tapped: \${marker.id}'), )
Программное управление маркерами
// Добавить маркер await controller.addMarker(Marker( id: 'new', position: Coordinates(lat: 55.76, lon: 37.63), icon: DefaultMarkerIcon.primary, )); // Обновить позицию маркера await controller.updateMarkerPosition( 'new', Coordinates(lat: 55.77, lon: 37.64), ); // Удалить маркер / все маркеры await controller.removeMarker('new'); await controller.clearMarkers();
Типы иконок
// Стандартные пресеты DefaultMarkerIcon.primary // Синий DefaultMarkerIcon.red // Красный DefaultMarkerIcon.green // Зелёный DefaultMarkerIcon.start // Старт (зелёный с флагом) DefaultMarkerIcon.end // Финиш (красный с пином) // Кастомный стандартный DefaultMarkerIcon( color: MarkerColors.purple, size: 56, style: MarkerStyle.modern, innerIcon: Icons.star, ) // Нумерованные NumberedMarkerIcon(number: 1) NumberedMarkerIcon.letter('A') NumberedMarkerIcon.sequence(5) // [1, 2, 3, 4, 5] // Анимированные AnimatedMarkerIcon.pulsingPrimary AnimatedMarkerIcon.dropInStart AnimatedMarkerIcon.rippleLocation // Из файлов AssetMarkerIcon('assets/pin.png', width: 32, height: 32) SvgMarkerIcon('assets/icon.svg', size: 24, color: Colors.blue) NetworkMarkerIcon('https://example.com/icon.png')
Кластеризация
QorviaMapView( controller: controller, markers: myMarkers, clusterOptions: const MarkerClusterOptions( enabled: true, radiusPx: 60, minClusterSize: 3, ), onClusterTap: (cluster) => print('Cluster: \${cluster.count} markers'), )
SDK Маршруты

Расчёт и отображение маршрутов между точками.

Расчёт маршрута
// Получаем клиент из SDK final client = QorviaMapsSDK.instance.client; // Строим маршрут final route = await client.route( from: Coordinates(lat: 55.7539, lon: 37.6208), to: Coordinates(lat: 55.7614, lon: 37.6500), mode: TransportMode.car, language: 'ru', ); print('Дистанция: \${route.formattedDistance}'); print('Время: \${route.formattedDuration}');
Отображение на карте
// Отобразить маршрут controller.displayRoute(route, options: RouteLineOptions.primary()); // Вписать маршрут в экран await controller.fitRoute(route, padding: EdgeInsets.all(50)); // Очистить маршруты await controller.clearRoutes();
Типы транспорта
Режим Описание
TransportMode.car Автомобиль
TransportMode.bike Велосипед
TransportMode.foot Пешком
TransportMode.truck Грузовик (с ограничениями)
SDK Геокодинг

Прямой и обратный геокодинг через SDK.

Адрес → Координаты
final response = await client.geocode( query: 'Красная площадь, Москва', limit: 5, language: 'ru', ); for (final result in response.results) { print('\${result.displayName}: \${result.coordinates}'); }
Координаты → Адрес
final address = await client.reverse( coordinates: Coordinates(lat: 55.7539, lon: 37.6208), language: 'ru', ); print('Адрес: \${address.displayName}');
SDK Turn-by-Turn навигация

Полнофункциональная навигация с голосовыми подсказками и отслеживанием позиции.

NavigationView
NavigationView( route: route, options: NavigationOptions( enableVoiceInstructions: true, voiceGuidanceOptions: const VoiceGuidanceOptions( language: 'ru-RU', speechRate: 0.5, ), trackingMode: CameraTrackingMode.followWithBearing, autoReroute: true, ), onStateChanged: (state) { print('До финиша: \${state.distanceRemaining}м'); print('ETA: \${state.estimatedArrival}'); }, onStepChanged: (step) => print('Следующий: \${step.instruction}'), onOffRoute: () => print('Сошёл с маршрута'), onArrival: () => print('Прибыл!'), onReroute: (from, to) async { return await client.route(from: from, to: to); }, )
NavigationOptions
Опция По умолчанию Описание
trackingMode followWithBearing Режим слежения камеры
zoom 17 Зум при навигации
tilt 0 Наклон камеры (градусы)
enableVoiceInstructions false Голосовые подсказки TTS
offRouteThreshold 30 Метры для срабатывания off-route
arrivalThreshold 20 Метры для срабатывания arrival
autoReroute true Автоматический перерасчёт
showNextTurnPanel true Панель следующего манёвра
showEtaPanel true Панель ETA/дистанции
showSpeedIndicator true Индикатор скорости
showRecenterButton true Кнопка возврата к слежению
smooth60FpsCamera true Плавная камера 60 FPS
snapToRouteEnabled true Привязка позиции к маршруту
snapToRouteThreshold 15 Метры для привязки к маршруту
motionPredictionEnabled true Предсказание позиции между GPS-апдейтами
simulateLocation false Симуляция GPS для тестирования
Готовые пресеты
// Оптимизировано для вождения NavigationOptions.driving() // Оптимизировано для пешеходов NavigationOptions.walking() // Режим симуляции (для тестирования без GPS) NavigationOptions.simulation(speedMultiplier: 2.0)
Программное управление
final navController = NavigationController( options: NavigationOptions.driving(), onStateChanged: (state) => print(state), onArrival: () => print('Arrived!'), ); // Старт навигации await navController.startNavigation(route); // Обновить маршрут (reroute) await navController.updateRoute(newRoute); // Управление камерой navController.setTrackingMode(CameraTrackingMode.follow); navController.pauseTracking(); // Пользователь сдвинул карту navController.recenter(); // Вернуться к слежению // Остановка navController.stopNavigation(); navController.dispose();
SDK Геолокация LocationService

Сервис GPS-трекинга с фильтрацией Калмана и мониторингом состояния.

Получение текущей позиции
final locationService = LocationService(); // Запрос разрешений final status = await locationService.requestPermission(); if (status == LocationPermissionStatus.granted) { // Текущая позиция final location = await locationService.getCurrentLocation( accuracy: LocationAccuracy.high, ); print('\${location.coordinates}, speed: \${location.speedKmh} km/h'); }
Непрерывное отслеживание
// Начать отслеживание await locationService.startTracking( LocationSettings.navigation(), // настройки для навигации LocationFilterSettings(), // фильтрация шума GPS ); // Слушать поток позиций locationService.locationStream.listen((location) { print('Lat: \${location.coordinates.lat}'); print('Lon: \${location.coordinates.lon}'); print('Heading: \${location.heading}'); print('Accuracy: \${location.accuracy}m'); }); // Остановить отслеживание locationService.stopTracking();
Диагностика
// Проверка здоровья GPS-сервиса final health = locationService.checkHealth(); // Статистика print('Получено: \${locationService.locationsReceived}'); print('Отфильтровано: \${locationService.locationsFiltered}'); print('Перезапусков: \${locationService.streamRestarts}');
SDK Квоты и статистика

Мониторинг использования API прямо из приложения.

Квоты
final client = QorviaMapsSDK.instance.client; final quota = await client.quota(); print('Тариф: \${quota.plan}'); print('Дневной лимит: \${quota.dailyUsed}/\${quota.dailyLimit}'); print('Месячный лимит: \${quota.monthlyUsed}/\${quota.monthlyLimit}'); if (quota.isMonthlyLimitNear) { print('Внимание: использовано более 90% месячного лимита'); }
Статистика использования
final usage = await client.usage(period: UsagePeriod.month); print('Всего запросов: \${usage.totalRequests}'); print('Всего units: \${usage.totalUnits}'); // По эндпоинтам final routeUsage = usage.getEndpointUsage('route'); if (routeUsage != null) { print('Маршруты: \${routeUsage.requests} запросов'); } // По дням for (final day in usage.byDay) { print('\${day.date}: \${day.requests} запросов'); }
Ответы

Ошибки

При возникновении ошибки API возвращает JSON с информацией об ошибке:

Коды ошибок
HTTP код Описание
400 Неверные параметры запроса
401 Отсутствует или неверный API-ключ
403 Доступ запрещен (ключ деактивирован)
429 Превышен лимит запросов
500 Внутренняя ошибка сервера
Квоты

Лимиты

Каждый запрос потребляет определенное количество единиц (units):

Эндпоинт Units
/v1/route 5
/v1/geocode 1
/v1/reverse 1
/v1/smart-search 10

Лимиты зависят от вашего тарифного плана. Текущее использование можно отслеживать в разделе «Usage» личного кабинета.