# Как да търсим транспортни спирки наблизо с API?

> Открийте търсенето на близки спирки с ROOTE API: координати, радиус, JavaScript пример, четене на резултати и управление на грешки.

Source: https://www.roote.ai/bg/guides/kak-da-tarsim-blizkite-prestani-s-api-roote/
Language: bg
Author: ROOTE

За да търсите спирки около точка, предайте нейната ширина, дължина и радиус към локализирано API. След това проверете статуса на отговора, върнатите обекти и информацията за покритието преди да покажете списъка или картата.

В ROOTE договор roote-1.0.0 пътят GET /v1/transit/nearby открива близките транспортни места. Той не извлича реалновременни тръгвания или предупреждения. Търсенето на място и търсенето на следващото му преминаване са две различни операции.

## Дефиниране на параметрите

Заявката използва lat за ширина и lng за дължина. Псевдонимът lon също е описан в договора. Параметърът radius задава радиус в метри; limit ограничава броя върнати резултати. Филтърът modes може да уточни търсените видове транспорт.

| Параметър | Пример | Значение |
| --- | --- | --- |
| lat | 44.8378 | Ширина на точката за търсене |
| lng | -0.5792 | Дължина на точката за търсене |
| radius | 600 | Искан радиус в метри |
| limit | 10 | Искан лимит на резултатите |
| modes | bus,tram | Търсени видове транспорт |

Тези координати служат за пример за търсене в Бордо; те не означават гарантирана спирка. Консултирайте се с [OpenAPI договора на ROOTE](https://api.roote.ai/openapi.json) за актуалните ограничения, полета и условия.

## Изпращане на първа заявка от сървъра

Ето един JavaScript пример за Node.js среда с fetch. Токенът, ако е необходим, се съхранява като променлива на средата на сървъра. Примерът не изисква поставяне на секрет в браузъра.

```
async function rechercherArrets(token = process.env.ROOTE_API_TOKEN) {
  const url = new URL('https://api.roote.ai/v1/transit/nearby');
  url.search = new URLSearchParams({
    lat: '44.8378',
    lng: '-0.5792',
    radius: '600',
    limit: '10',
    modes: 'bus,tram'
  }).toString();

  const headers = { Accept: 'application/json' };
  if (token) headers.Authorization = `Bearer ${token}`;

  const response = await fetch(url, {
    headers,
    signal: AbortSignal.timeout(10000)
  });
  if (!response.ok) {
    throw new Error(`Erreur HTTP ${response.status}`);
  }

  const data = await response.json();
  if (data.contract_version !== 'roote-1.0.0') {
    throw new Error('Version du contrat non reconnue');
  }
  if (!['success', 'empty', 'partial'].includes(data.status)) {
    throw new Error('Recherche indisponible');
  }
  if (!Array.isArray(data.stations)) {
    throw new Error('Réponse sans collection stations valide');
  }

  return {
    status: data.status,
    stations: data.stations,
    lines: data.lines,
    operators: data.operators,
    coverage: data.coverage,
    warnings: data.warnings,
    attributions: data.attributions,
    meta: data.meta
  };
}
```

Договорът позволява както анонимен достъп, така и достъп с токен, според приложимите политики. Проверете правата си и ограниченията за достъп. Коректен HTTP отговор не освобождава от валидиране на съдържанието; в продукция използвайте също проверка на обектите спрямо схемата.

## Четене на обекти и техните връзки

Колекцията stations съдържа върнатите локации. За всяка вижте най-вече id, name, entity_kind, location и distance_meters. Препратките line_ids и operator_ids позволяват свързване с колекциите lines и operators, когато са налични.

Показвайте географско разстояние като такова. Не го преобразувайте в време за ходене без изчисляване на маршрут. Гидът [намиране на близка спирка](https://www.roote.ai/bg/guides/kak-da-namerya-nay-blijkata-spirka-na-avtobus-ili-tramvay/) обяснява защо достъпите могат да променят реалното придвижване.

Обработете и явно неизвестната информация. В договора accessibility.wheelchair може да има стойност unknown: тази стойност не означава нито yes, нито no. Обявен капацитет на тръгвания не е списък на действителни тръгвания.

## Показване на списък или карта

Използвайте идентификатора за стабилизиране на елементите във интерфейса, името за етикет и location за позицията. Свържете линиите чрез препратките, а не по близост на имената им.

Ако показвате цветове или етикети на линии от данните, третирайте ги като външни входове, които трябва да се валидират. За имена използвайте текст, а не инжектиране на HTML.

Запазвайте източниците на данни и показвайте тези, които договорът изисква.

## Управление на празен резултат, частичен отговор и грешка

Резултат empty описва търсене без намерени обекти в известния периметър. Това не доказва физическо отсъствие на транспорт. Partial отговор може да съдържа полезни места, докато алармира за ограничения: представете резултатите и подходящото предупреждение.

Прочетете coverage, warnings и ограниченията в meta. Ограничен списък не описва изчерпателно покритието. При мрежова или HTTP грешка, показвайте, че е недостъпно, без да заменяте резултата с „няма спирка“.

При код 429 проверете инструкциите за повторен опит и възможните заглавки на услугата. Избягвайте непрекъснати повторения.

## Различаване на спирки, зони и перони

Полето entity_kind различава няколко нива на локации. Два близки резултата могат да са отделни перони; две подобни имена може да идват от различни източници.

Не сливайте автоматично локациите само по близост. Използвайте документалните връзки и идентичности, предоставени от услугата. Нашият гид [GTFS, GTFS-RT и GBFS](https://www.roote.ai/bg/guides/gtfs-gtfs-rt-i-gbfs-kakvi-sa-razlikite/) обяснява контекста на данните.

## Подготовка за продукционна интеграция

Активирайте търсения при значителна промяна на позиция или филтрите. Групирайте идентични повиквания, задайте таймаут и адаптирайте кеша към вида данни и условията на услугата.

Списък с места и реалновременна наличност не изискват еднаква свежест. Проверете маршрута с пълни, празни, частични и грешни отговори преди да представите търсенето на потребителите.

## Разширяване на търсенето до градски услуги

Спирките и градските услуги използват различни маршрути. За да търсите тоалетни около същата точка, GET маршрутът /v1/services/nearby изисква lat и lon с параметър types=toilets. Не изпращайте modes=toilets към този маршрут: тази терминология принадлежи на URL адреса за карта, не на филтъра за услуги.

Следният JavaScript пример изгражда URL за услуги с радиус от 600 метра. Той не инициира заявката; използвайте HTTP и договорните контроли описани по-горе. Очакваната колекция става services вместо stations. Запазете service_type, location, distance_meters и действително наличните атрибути.

REST договорът документира, между другото, toilets, drinking_water, fountain, wifi, parking, charging, aed и locker. Типовете, изложени от MCP, могат да се различават. За поддържаните параметри, техните граници и ограниченията на вашия достъп, вижте схемата на използвания интерфейс.

Атрибутите на услуга не гарантират, че тя е отворена по време на търсенето. Неизвестната достъпност не означава, че услугата е недостъпна; празният списък вследствие на грешка не доказва липсата на тоалетни. Запазете данните специфични за всяко семейство, вместо да ги свивате до име и точка.

За комбинирана карта свържете резултатите с тяхното семейство и идентификатори. Показвайте грешка за услуги без да изтривате спирките върнати от Transit. Търсенето остава съсредоточено върху същата точка, но статусите и покритието могат да са различни.

```
const url = new URL('https://api.roote.ai/v1/services/nearby');
url.search = new URLSearchParams({
  lat: '44.8416106', lon: '-0.5810938',
  radius: '600', limit: '10', types: 'toilets'
}).toString();
console.log(url.toString());
```

[Диагностициране на празно търсене или грешка](https://www.roote.ai/bg/guides/prazni-rezultati-ili-greshka-api-kak-da-otlichim/)

[Вграждане директно на филтрирана карта в сайт](https://www.roote.ai/bg/guides/kak-da-integrirate-karta-za-mobilnost-vashiya-sait/)

[Създаване на асистент около тези търсения](https://www.roote.ai/bg/guides/kak-da-sazdaem-asistent-za-mobilnost-okolo-adres/)

## Често задавани въпроси

### Дава ли Nearby следващите тръгвания?

Не в представения тук договор. Този път открива транспортни места; тръгванията изискват отделна възможност.

### Може ли да се покаже празен списък след грешка?

Покажете недостъпност. Грешката не доказва липса на спирки.

### Може ли API токенът да е в браузъра?

Тайна трябва да остане на сървърната страна. Използвайте модела на достъп, предвиден за вашето приложение и акаунт.
