Главная/Гиды/Разработчики
Разработчики

Доступность велосипедов в реальном времени: как отобразить в приложении?

Отображайте доступность велосипедов с помощью API ROOTE: отметки времени, актуальность, неизвестные значения, обновления и устаревшие данные в вашем приложении.

By ROOTE·7 минут чтения
Доступность велосипедов в реальном времени: как отобразить в приложении?
Наблюдаемая доступность с её контекстом.

Главное за несколько секунд

Показывайте доступное количество с индикацией актуальности, отметками времени и условиями взятия велосипеда. Неизвестное значение остаётся неизвестным; старая наблюдаемая информация не становится актуальной только потому, что ваше приложение её получило.

Чтобы отобразить доступность велосипедов в реальном времени в приложении, связывайте возвращаемое количество с показателем актуальности и условиями взятия транспортного средства. Наблюдение описывает, что источник знал в момент времени; оно не гарантирует, что велосипед будет доступен к прибытию.

Контракт мобильности ROOTE различает станции, отдельные транспортные средства и их состояния. Интерфейс должен выражать эти различия, не перепутывая неизвестное значение, пустую станцию и временно недоступный источник.

Разделение станции и отдельного транспортного средства

Станция может показывать счётчики велосипедов и свободных мест для возврата. Отдельное транспортное средство имеет состояние доступности и дополнительную информацию. Избегайте счёта станции как велосипеда или суммирования счётчиков, относящихся к одному запасу.

В DTO мобильности ROOTE поля availability.bikes и availability.docks могут быть неизвестны. Поля, связанные с приводом или аккумулятором, должны отображаться только при их наличии и интерпретироваться согласно контракту.

Контракт OpenAPI ROOTE

Чтение актуальности и отметок времени

ПолеИнтерпретация
freshness.stateОбъявленное состояние: fresh, stale, unknown или static
freshness.source_updated_atДата обновления источника, если известна
freshness.received_atДата получения по контракту
freshness.expires_atУказанный срок годности, если известен
availability.bikesИзвестное количество или неизвестное значение
pickup.enabled и pickup.stateИнформация о возможности взять велосипед на станции

Время вашего запроса не обязательно совпадает со временем наблюдения. Результат, полученный в 10 часов, может содержать источник, обновлённый в 9:45. Не отображайте «обновлено сейчас» только на основании времени получения интерфейсом.

Планируйте различные состояния отображения

Полученные данныеПредполагаемое отображение
Известное количество и свежие данныеНаблюдаемое количество и временная индикация
Количество равно нулюВелосипеды не обнаружены, с указанием временного контекста
Количество nullНеизвестная доступность
Состояние stale или истёкший срок годностиСтарые данные; рекомендуется обновление
pickup.enabled=falseВзятие недоступно, даже если счётчик положителен
Ошибка поискаВременно отсутствует доступность, не преобразуйте в ноль

Не классифицируйте состояние unknown или static как свежее. Информация о станции может быть стабильной, тогда как счётчик быстро меняется. Также сохраняйте предупреждения и необходимые атрибуции ответа.

Пример нормализации перед отображением

Следующая функция создаёт состояние для отображения из станции, уже проверенной по схеме ROOTE. Это не полный валидатор ответа. Видимые подписи должны поступать из ключей локализации вашего интерфейса.

function availabilityView(station, now = Date.now()) {
  const freshness = station.freshness;
  const expiresAt = freshness.expires_at
    ? Date.parse(freshness.expires_at) : null;
  const expired = expiresAt !== null &&
    Number.isFinite(expiresAt) && expiresAt <= now;
  if (station.pickup.enabled === false ||
      station.pickup.state === 'unavailable_now') {
    return { state: 'pickup_unavailable', count: null };
  }
  if (expired || freshness.state === 'stale') {
    return { state: 'stale', count: null };
  }
  const count = station.availability.bikes;
  if (freshness.state !== 'fresh' || count === null ||
      !Number.isFinite(count) || count < 0) {
    return { state: 'unknown', count: null };
  }
  return {
    state: count === 0 ? 'empty' : 'observed', count,
    sourceUpdatedAt: freshness.source_updated_at,
    receivedAt: freshness.received_at,
    pickupState: station.pickup.state
  };
}

Даже при состоянии observed не преобразовывайте pickupState=unknown в подтверждённое взятие. Счётчик остаётся наблюдением. Отображайте контекст взятия, если ваш продукт помогает пользователю выбрать станцию.

Обновление без излишних вызовов

Настраивайте обновление под опубликованный срок, условия сервиса и поведение пользователя. Группируйте одинаковые запросы, избегайте фоновых вызовов на неактивной странице и отменяйте устаревшие запросы.

Локальный кеш не гарантирует свежесть источника. После ошибки можно сохранять последний датированный результат, если интерфейс явно показывает его как устаревший. Не снимайте это разграничение при первом успешном повторе, если источник остаётся stale.

Понимание связи с GBFS

GBFS описывает сервисы совместного использования и их публикуемые состояния. Прямая интеграция должна интерпретировать файлы, версии и отметки времени потока. Используя стандартизированный API, применяйте контракт API; не добавляйте поле GBFS, отсутствующее в ответе.

Выбор между GTFS, GTFS Realtime и GBFS

Тестирование ситуаций, вводящих пользователя в заблуждение

Проверьте реальные нули, неизвестные значения, превышение срока годности, отключённое взятие и ошибку после валидного результата. Также проверьте часовые пояса отображения. Положительный счётчик не должен показывать «велосипед зарезервирован», а недоступность не должна заменяться вымышленным нулём.

Обработка пустых ответов и ошибок

Применение этих правил в ИИ-помощнике

Руководство пользователя по поиску велосипеда

Для разработчиковROOTE Mobility API

Мобильность вокруг точки.
Прямо в вашем приложении.

  • Поиск
    вокруг позиции
  • Доступ к
    данным о мобильности
  • Интегрировать в
    ваше приложение

Перейдите от карты к данным: ищите мобильность и сервисы рядом с помощью API ROOTE.

Часто задаваемые вопросы

Обеспечивает ли положительное количество велосипед при моём прибытии?

Нет. Это наблюдаемое значение, которое может измениться между поиском и вашим прибытием.

Можно ли заменить null на ноль?

Нельзя. null означает неизвестное значение; ноль — известное количество с другим смыслом.

Нужно ли обновлять каждую секунду?

Используйте указания по актуальности, ограничения сервиса и требования интерфейса. Произвольная частота не гарантирует более свежие данные.

А не посмотреть ли вокруг себя?

Исследуйте свой район с ROOTE и найдите доступную информацию для подготовки поездки.

Исследовать карту ROOTE ↗