Разработка мобильного приложения для велосипедистов
Велосипедные приложения — конкурентный рынок с Strava, Komoot, Wahoo. Выживают либо нишевые продукты (треккинг для конкретного региона, клубные функции, интеграция с конкретным железом), либо приложения с уникальной моделью данных. Разработка начинается с понимания, зачем пользователю ещё одно приложение и что конкретно оно делает лучше.
GPS-трекинг: качество данных важнее частоты
CLLocationManager на iOS с desiredAccuracy = kCLLocationAccuracyBestForNavigation и distanceFilter = 5 (обновление каждые 5 метров) — стандартная конфигурация для трекинга активности. На Android — Fused Location Provider с PRIORITY_HIGH_ACCURACY и интервалом 1-2 секунды.
Проблема GPS на велосипеде — не точность в чистом поле, а тоннели, путепроводы, плотная городская застройка. Точки «прыгают» на 50-100 метров. Сырой трек без фильтрации — это дерганая линия на карте и завышенный пробег.
Фильтрация Калмана — стандартный подход. Простой алгоритм сглаживания для GPS:
class GPSKalmanFilter {
private var latitude: Double = 0
private var longitude: Double = 0
private var variance: Double = -1
private let minAccuracy: Double = 1.0
mutating func process(lat: Double, lon: Double, accuracy: Double, timestamp: TimeInterval) -> CLLocationCoordinate2D {
let accuracy = max(accuracy, minAccuracy)
if variance < 0 {
latitude = lat; longitude = lon
variance = accuracy * accuracy
} else {
let timeStep = timestamp - lastTimestamp
if timeStep > 0 {
variance += timeStep * 3.0 // Q: process noise
}
let K = variance / (variance + accuracy * accuracy)
latitude += K * (lat - latitude)
longitude += K * (lon - longitude)
variance = (1 - K) * variance
}
lastTimestamp = timestamp
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
Дополнительно: точки с horizontalAccuracy > 50 метров отбрасываем полностью. Скачок более 10 м/с (36 км/ч) при ожидаемой скорости 25 км/ч — тоже выброс.
Bluetooth-датчики по протоколу ANT+/BLE
Велосипедисты используют внешние датчики: датчик каденса (обороты педалей), датчик мощности (ваттметр), пульсометр, датчик скорости. Протоколы — Bluetooth LE с профилями из GATT Cycling Profile (CP, CSC, HR) и проприетарный ANT+.
ANT+ на iOS недоступен из App Store (только через MFi-аксессуары). На Android — библиотека ant-android-sdk-stub через Ant+ Plugin Service. Реалистичная альтернатива — BLE-датчики с двойной трансляцией ANT+/BLE (Garmin, Wahoo, большинство современных датчиков).
// Android: подписка на Cycling Speed and Cadence (CSC) GATT
val CSC_SERVICE = UUID.fromString("00001816-0000-1000-8000-00805f9b34fb")
val CSC_MEASUREMENT = UUID.fromString("00002a5b-0000-1000-8000-00805f9b34fb")
fun parseCscMeasurement(value: ByteArray): CscData {
val flags = value[0].toInt()
var offset = 1
var wheelRevolutions = 0L
var wheelEventTime = 0
if (flags and 0x01 != 0) { // Wheel Revolution Data present
wheelRevolutions = value.getLong32(offset)
wheelEventTime = value.getUInt16(offset + 4)
offset += 6
}
var crankRevolutions = 0
var crankEventTime = 0
if (flags and 0x02 != 0) { // Crank Revolution Data present
crankRevolutions = value.getUInt16(offset)
crankEventTime = value.getUInt16(offset + 2)
}
return CscData(wheelRevolutions, wheelEventTime, crankRevolutions, crankEventTime)
}
Скорость из CSC считается по дельте оборотов колеса и дельте времени события. Длина окружности колеса — настройка пользователя или автовычисление по размеру шины.
Навигация по маршруту
Построение маршрута по велодорожкам — OpenStreetMap через OSRM или GraphHopper с велосипедным профилем. Отображение — MapLibre GL (открытый) или Mapbox SDK. Пошаговая навигация голосом: AVSpeechSynthesizer на iOS, TextToSpeech на Android — триггер за 150-200 метров до поворота.
Офлайн-карты критичны для велотуризма в горах. Mbtiles или PMTiles формат, загрузка региона заранее. MapLibre поддерживает офлайн из коробки.
Статистика и интеграция
После поездки: пробег, время, набор высоты (из CLLocationManager.altitude с барометрической коррекцией на iOS, аналогично через SensorManager на Android), средняя/максимальная скорость, мощность, каденс. Экспорт в .fit (формат Garmin/Strava) или GPX.
Интеграция со Strava через OAuth2 + Strava API v3: загрузка активности через POST /uploads с файлом .fit или .gpx. Koнечная точка поддерживает multipart/form-data с полями data_type, name, activity_type.
Разработка велосипедного приложения с GPS-трекингом, BLE-датчиками, картой и Strava-экспортом: 8-12 недель на одну платформу. Стоимость рассчитывается индивидуально.







