Руководство

Коды аэропортов: различия IATA и ICAO

Разберитесь в различиях между системами кодирования аэропортов IATA и ICAO. Научитесь использовать коды аэропортов для поиска рейсов, бронирования отелей и навигации с практическими примерами и интеграцией API.

Pavel Volkov
30 августа 2025 г.
7 мин чтения

Введение в коды аэропортов: IATA vs ICAO

Коды аэропортов являются важными идентификаторами, используемыми в авиации, системах бронирования путешествий и логистике. Понимание различий между системами кодирования аэропортов IATA и ICAO имеет решающее значение для разработчиков, работающих с API путешествий, поисковиками рейсов и приложениями навигации по аэропортам.

Понимание двух систем

Коды IATA (3-буквенные коды)

Коды Международной ассоциации воздушного транспорта (IATA) являются наиболее часто используемыми идентификаторами аэропортов:

  • Формат: 3 буквы (например, JFK, LHR, CDG)
  • Использование: Бронирование рейсов, обработка багажа, пассажирские табло
  • Область применения: Коммерческая авиация, туристическая индустрия
  • Примеры: SVO (Шереметьево), DME (Домодедово), VKO (Внуково)

Коды ICAO (4-буквенные коды)

Коды Международной организации гражданской авиации (ICAO) используются для управления воздушным движением:

  • Формат: 4 буквы (например, UUDD, UUWW, UUEE)
  • Использование: Управление воздушным движением, планирование полётов, авиационная навигация
  • Область применения: Глобальные авиационные операции, все аэропорты и аэродромы
  • Примеры: UUDD (Домодедово), UUWW (Внуково), UUEE (Шереметьево)

Сравнение ключевых различий

Аспект IATA ICAO
Длина кода 3 буквы 4 буквы
Основное применение Коммерческая авиация Управление воздушным движением
Покрытие Только крупные аэропорты Все аэропорты и аэродромы
Системы бронирования Да Нет
Планирование полётов Ограниченно Да

Реализация в приложениях для путешествий

Интеграция с API поиска рейсов

Большинство API путешествий используют коды IATA для пользовательских функций:

// JavaScript: Поиск рейсов с несколькими API
class FlightSearchService {
    constructor() {
        this.apis = {
            amadeus: {
                baseUrl: 'https://api.amadeus.com',
                codeType: 'IATA'
            },
            skyscanner: {
                baseUrl: 'https://partners.api.skyscanner.net',
                codeType: 'IATA'
            }
        };
    }

    async searchFlights(origin, destination, departDate, returnDate = null) {
        // Валидация кодов IATA
        if (!this.isValidIATACode(origin) || !this.isValidIATACode(destination)) {
            throw new Error('Недействительные коды аэропортов. Используйте 3-буквенные коды IATA.');
        }

        const searchParams = {
            originLocationCode: origin,
            destinationLocationCode: destination,
            departureDate: departDate,
            returnDate: returnDate,
            adults: 1,
            max: 250
        };

        try {
            const response = await this.callAmadeusAPI('/shopping/flight-offers', searchParams);
            return this.formatFlightResults(response.data);
        } catch (error) {
            console.error('Поиск рейсов не удался:', error);
            throw error;
        }
    }

    isValidIATACode(code) {
        return /^[A-Z]{3}$/.test(code);
    }

    formatFlightResults(flights) {
        return flights.map(flight => ({
            id: flight.id,
            origin: flight.itineraries[0].segments[0].departure.iataCode,
            destination: flight.itineraries[0].segments.slice(-1)[0].arrival.iataCode,
            departureTime: flight.itineraries[0].segments[0].departure.at,
            arrivalTime: flight.itineraries[0].segments.slice(-1)[0].arrival.at,
            price: flight.price.total,
            currency: flight.price.currency,
            carrier: flight.validatingAirlineCodes[0]
        }));
    }
}

Реализация автодополнения аэропортов

Создание удобного поиска аэропортов с обоими типами кодов:

// PHP: Сервис поиска аэропортов
class AirportSearchService
{
    public function searchAirports(string $query, int $limit = 10): array
    {
        $query = strtoupper(trim($query));
        
        // Поиск по коду IATA, ICAO или названию
        $results = Airport::where(function ($q) use ($query) {
            $q->where('iata_code', 'LIKE', $query . '%')
              ->orWhere('icao_code', 'LIKE', $query . '%')
              ->orWhere('name_ru', 'LIKE', '%' . $query . '%')
              ->orWhere('city_ru', 'LIKE', '%' . $query . '%');
        })
        ->where('type', 'large_airport') // Приоритет крупным аэропортам
        ->orderByRaw('CASE 
            WHEN iata_code LIKE ? THEN 1
            WHEN icao_code LIKE ? THEN 2
            WHEN name_ru LIKE ? THEN 3
            ELSE 4
        END', [$query . '%', $query . '%', $query . '%'])
        ->limit($limit)
        ->get();

        return $results->map(function ($airport) {
            return [
                'iata_code' => $airport->iata_code,
                'icao_code' => $airport->icao_code,
                'name' => $airport->name_ru,
                'city' => $airport->city_ru,
                'country' => $airport->country_ru,
                'display_name' => $this->formatAirportDisplay($airport),
                'coordinates' => [
                    'lat' => $airport->latitude,
                    'lng' => $airport->longitude
                ]
            ];
        })->toArray();
    }

    private function formatAirportDisplay($airport): string
    {
        $parts = array_filter([
            $airport->iata_code,
            $airport->name_ru,
            $airport->city_ru,
            $airport->country_ru
        ]);
        
        return implode(' - ', $parts);
    }

    public function getAirportDetails(string $code): ?array
    {
        $airport = null;
        
        if (strlen($code) === 3) {
            $airport = Airport::where('iata_code', strtoupper($code))->first();
        } elseif (strlen($code) === 4) {
            $airport = Airport::where('icao_code', strtoupper($code))->first();
        }
        
        if (!$airport) {
            return null;
        }
        
        return [
            'iata_code' => $airport->iata_code,
            'icao_code' => $airport->icao_code,
            'name' => $airport->name_ru,
            'city' => $airport->city_ru,
            'country' => $airport->country_ru,
            'timezone' => $airport->timezone,
            'elevation' => $airport->elevation_ft,
            'runways' => $this->getRunwayInfo($airport),
            'services' => $this->getAirportServices($airport)
        ];
    }
}

React компонент селектора аэропортов

Создание современного интерфейса выбора аэропорта:

import React, { useState, useEffect, useRef } from 'react';

const AirportSelector = ({ onSelect, placeholder = "Поиск аэропортов...", value = "" }) => {
    const [query, setQuery] = useState(value);
    const [suggestions, setSuggestions] = useState([]);
    const [isLoading, setIsLoading] = useState(false);
    const [showSuggestions, setShowSuggestions] = useState(false);
    const debounceRef = useRef(null);

    useEffect(() => {
        if (query.length < 2) {
            setSuggestions([]);
            setShowSuggestions(false);
            return;
        }

        // Дебаунс запросов поиска
        if (debounceRef.current) {
            clearTimeout(debounceRef.current);
        }

        debounceRef.current = setTimeout(async () => {
            setIsLoading(true);
            try {
                const response = await fetch(`/api/airports/search?q=${encodeURIComponent(query)}`);
                const data = await response.json();
                setSuggestions(data.airports || []);
                setShowSuggestions(true);
            } catch (error) {
                console.error('Поиск аэропортов не удался:', error);
                setSuggestions([]);
            } finally {
                setIsLoading(false);
            }
        }, 300);
    }, [query]);

    const handleSelect = (airport) => {
        setQuery(airport.display_name);
        setShowSuggestions(false);
        onSelect(airport);
    };

    const highlightMatch = (text, query) => {
        if (!query) return text;
        const regex = new RegExp(`(${query})`, 'gi');
        return text.replace(regex, '$1');
    };

    return (
        
setQuery(e.target.value)} onFocus={() => query.length >= 2 && setShowSuggestions(true)} placeholder={placeholder} className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" /> {isLoading && (
)} {showSuggestions && suggestions.length > 0 && (
{suggestions.map((airport) => (
handleSelect(airport)} >
{airport.iata_code}
{airport.city}, {airport.country} {airport.icao_code && ( ICAO: {airport.icao_code} )}
{airport.coordinates && (
{airport.coordinates.lat.toFixed(2)}, {airport.coordinates.lng.toFixed(2)}
)}
))}
)} {showSuggestions && query.length >= 2 && suggestions.length === 0 && !isLoading && (
Аэропорты не найдены по запросу "{query}"
)}
); }; export default AirportSelector;

Интеграция с бронированием отелей

Коды аэропортов необходимы для поиска отелей по местоположению:

// Python: Поиск отелей рядом с аэропортом
import requests
from geopy.distance import geodesic
from typing import List, Dict, Optional

class HotelSearchService:
    def __init__(self, api_key: str):
        self.api_key = api_key
        self.base_url = "https://api.booking.com/v1"
        
    def search_hotels_near_airport(
        self, 
        airport_code: str, 
        check_in: str, 
        check_out: str,
        radius_km: int = 20,
        adults: int = 2
    ) -> List[Dict]:
        """Поиск отелей рядом с аэропортом по коду IATA или ICAO."""
        
        # Получение координат аэропорта
        airport_info = self.get_airport_info(airport_code)
        if not airport_info:
            raise ValueError(f"Аэропорт {airport_code} не найден")
            
        # Поиск отелей в радиусе
        search_params = {
            'latitude': airport_info['latitude'],
            'longitude': airport_info['longitude'],
            'radius': radius_km,
            'checkin': check_in,
            'checkout': check_out,
            'adults': adults,
            'currency': 'RUB'
        }
        
        hotels = self.call_booking_api('/hotels/search', search_params)
        
        # Обогащение результатов расстоянием от аэропорта
        for hotel in hotels:
            hotel_location = (hotel['latitude'], hotel['longitude'])
            airport_location = (airport_info['latitude'], airport_info['longitude'])
            
            distance = geodesic(airport_location, hotel_location).kilometers
            hotel['distance_from_airport_km'] = round(distance, 1)
            hotel['airport_code'] = airport_code
            hotel['airport_name'] = airport_info['name']
            
        # Сортировка по расстоянию от аэропорта
        return sorted(hotels, key=lambda x: x['distance_from_airport_km'])
    
    def get_airport_shuttle_hotels(self, airport_code: str) -> List[Dict]:
        """Поиск отелей с трансфером из аэропорта."""
        hotels = self.search_hotels_near_airport(airport_code, radius_km=30)
        
        return [
            hotel for hotel in hotels 
            if 'airport_shuttle' in hotel.get('amenities', []) or
               'free_airport_shuttle' in hotel.get('amenities', [])
        ]

Навигация по аэропорту и поиск пути

Использование кодов аэропортов для информации о терминалах и выходах:

// JavaScript: Сервис навигации по аэропорту
class AirportNavigationService {
    constructor() {
        this.terminalMaps = new Map();
        this.realTimeData = new Map();
    }

    async loadTerminalMap(airportCode) {
        if (this.terminalMaps.has(airportCode)) {
            return this.terminalMaps.get(airportCode);
        }

        try {
            const response = await fetch(`/api/airports/${airportCode}/terminals`);
            const terminalData = await response.json();
            
            this.terminalMaps.set(airportCode, terminalData);
            return terminalData;
        } catch (error) {
            console.error(`Не удалось загрузить карту терминала для ${airportCode}:`, error);
            return null;
        }
    }

    async getFlightGateInfo(airportCode, flightNumber, date = new Date()) {
        const dateStr = date.toISOString().split('T')[0];
        
        try {
            const response = await fetch(
                `/api/airports/${airportCode}/flights/${flightNumber}?date=${dateStr}`
            );
            const flightData = await response.json();
            
            return {
                flight_number: flightData.flight_number,
                gate: flightData.gate,
                terminal: flightData.terminal,
                status: flightData.status,
                scheduled_departure: flightData.scheduled_departure,
                estimated_departure: flightData.estimated_departure,
                aircraft_type: flightData.aircraft_type,
                destination: flightData.destination,
                navigation: await this.getNavigationToGate(
                    airportCode, 
                    flightData.terminal, 
                    flightData.gate
                )
            };
        } catch (error) {
            console.error(`Информация о рейсе не найдена:`, error);
            return null;
        }
    }

    async getNavigationToGate(airportCode, terminal, gate) {
        const terminalMap = await this.loadTerminalMap(airportCode);
        if (!terminalMap) return null;

        const gateLocation = this.findGateLocation(terminalMap, terminal, gate);
        if (!gateLocation) return null;

        return {
            terminal: terminal,
            gate: gate,
            walking_time_minutes: gateLocation.walking_time,
            directions: gateLocation.directions,
            amenities_nearby: gateLocation.nearby_amenities,
            security_checkpoint: gateLocation.security_checkpoint,
            distance_from_entrance: gateLocation.distance_meters
        };
    }
}

Схема базы данных для данных аэропортов

-- Комплексная схема базы данных аэропортов
CREATE TABLE airports (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    iata_code CHAR(3) UNIQUE,
    icao_code CHAR(4) UNIQUE,
    name_ru VARCHAR(255) NOT NULL,
    name_en VARCHAR(255) NOT NULL,
    city_ru VARCHAR(100) NOT NULL,
    city_en VARCHAR(100) NOT NULL,
    country_code CHAR(2) NOT NULL,
    region VARCHAR(100),
    continent VARCHAR(50),
    type ENUM('large_airport', 'medium_airport', 'small_airport', 'heliport', 'seaplane_base', 'closed') DEFAULT 'small_airport',
    elevation_ft INT,
    latitude DECIMAL(10, 8),
    longitude DECIMAL(11, 8),
    timezone VARCHAR(50),
    scheduled_service BOOLEAN DEFAULT false,
    home_link VARCHAR(255),
    wikipedia_link VARCHAR(255),
    keywords TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    
    INDEX idx_iata (iata_code),
    INDEX idx_icao (icao_code),
    INDEX idx_country (country_code),
    INDEX idx_type (type),
    INDEX idx_coordinates (latitude, longitude),
    INDEX idx_scheduled (scheduled_service),
    FULLTEXT idx_search_ru (name_ru, city_ru, iata_code, icao_code, keywords),
    FULLTEXT idx_search_en (name_en, city_en, iata_code, icao_code, keywords)
);

Оптимизация производительности

Кеширование данных аэропортов

// Redis кеширование для поиска аэропортов
class AirportCacheService
{
    private $redis;
    private int $defaultTTL = 3600; // 1 час
    
    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1', 6379);
    }
    
    public function getCachedAirportSearch(string $query): ?array
    {
        $cacheKey = "airport_search:" . md5(strtolower($query));
        $cached = $this->redis->get($cacheKey);
        
        return $cached ? json_decode($cached, true) : null;
    }
    
    public function cacheAirportSearch(string $query, array $results): void
    {
        $cacheKey = "airport_search:" . md5(strtolower($query));
        $this->redis->setex($cacheKey, $this->defaultTTL, json_encode($results));
    }
    
    public function preloadPopularAirports(): void
    {
        $popularAirports = [
            'SVO', 'DME', 'VKO', 'LED', 'KZN', 'ROV', 'UFA', 'KRR',
            'JFK', 'LAX', 'LHR', 'CDG', 'NRT', 'SIN', 'DXB', 'FRA'
        ];
        
        foreach ($popularAirports as $code) {
            $this->preloadAirportData($code);
        }
    }
}

Распространённые случаи использования и лучшие практики

Лучшие практики

  • Всегда валидируйте коды аэропортов - Проверяйте как формат, так и существование
  • Используйте IATA для пользовательских функций - Более узнаваемы для путешественников
  • Используйте ICAO для технических интеграций - Более полное покрытие
  • Реализуйте правильную обработку ошибок - Недействительные коды должны обрабатываться корректно
  • Кешируйте часто используемые данные - Информация об аэропортах редко изменяется
  • Учитывайте обработку часовых поясов - Необходимо для расписаний рейсов

Распространённые ошибки

  • Не все аэропорты имеют коды IATA - Малые аэродромы могут иметь только ICAO
  • Могут существовать конфликты кодов - Один и тот же код в разных регионах
  • Сезонные аэропорты - Некоторые коды активны только сезонно
  • Исторические коды - Старые аэропорты могут сохранять коды после закрытия

Понимание систем кодирования аэропортов IATA и ICAO необходимо для создания надёжных приложений для путешествий. Реализуя правильную валидацию, кеширование и обработку ошибок, вы можете создать бесшовный опыт для пользователей при интеграции с различными авиационными API и сервисами.

Последнее обновление: 18 сентября 2025 г.