Skip to content

Commit

Permalink
data: added more airports from a new source
Browse files Browse the repository at this point in the history
  • Loading branch information
amvid committed May 12, 2024
1 parent bbfa1fe commit 53027fd
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 7 deletions.
1 change: 1 addition & 0 deletions data/airports.json

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions migrations/Version20240512102913.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240512102913 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('DROP INDEX UNIQ_7E91F7C28C1034C3 ON airport');
$this->addSql('ALTER TABLE airport CHANGE icao icao VARCHAR(4) DEFAULT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE airport CHANGE icao icao VARCHAR(4) NOT NULL');
$this->addSql('CREATE UNIQUE INDEX UNIQ_7E91F7C28C1034C3 ON airport (icao)');
}
}
182 changes: 182 additions & 0 deletions src/Airport/Command/Import/ImportAirports2FromJsonCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
<?php

declare(strict_types=1);

namespace App\Airport\Command\Import;

use App\Airport\Entity\Airport;
use App\Airport\Factory\AirportFactoryInterface;
use App\Airport\Repository\AirportRepositoryInterface;
use App\Application\Command\Import\Config;
use App\City\Entity\City;
use App\City\Factory\CityFactoryInterface;
use App\City\Repository\CityRepositoryInterface;
use App\State\Repository\StateRepositoryInterface;
use App\Country\Repository\CountryRepositoryInterface;
use App\State\Factory\StateFactoryInterface;
use App\Timezone\Repository\TimezoneRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use JsonMachine\Items;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Throwable;

#[AsCommand(
name: 'app:import-airports2',
description: 'Import airports 2 from json file.',
hidden: false,
)]
class ImportAirports2FromJsonCommand extends Command
{
public function __construct(
private readonly AirportFactoryInterface $airportFactory,
private readonly AirportRepositoryInterface $airportRepository,
private readonly TimezoneRepositoryInterface $timezoneRepository,
private readonly CityRepositoryInterface $cityRepository,
private readonly CityFactoryInterface $cityFactory,
private readonly StateRepositoryInterface $stateRepository,
private readonly StateFactoryInterface $stateFactory,
private readonly CountryRepositoryInterface $countryRepository,
private readonly EntityManagerInterface $em,
) {
parent::__construct();
}

protected function configure(): void
{
$this->setHelp('This command will import airports 2 from json file.');
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
try {
$timezones = [];
$cities = [];
$imported = 0;
$skipped = 0;

$output->writeln('Importing...');

foreach (Items::fromStream(fopen(Config::getAirports2DataFilepath(), 'rb')) as $a) {
if (!is_array($a)) {
continue;
}

foreach ($a as $airport) {
if (empty($airport->Iata) || empty($airport->CityAscii) || true === $airport->IsClosed) {
continue;
}

$exists = $this->airportRepository->findByIata($airport->Iata);

if ($exists) {
continue;
}

$country = $this->countryRepository->findByIso2($airport->CountryIso2);

if (!$country) {
$output->writeln("Country '$airport->CountryIso2' not found. Skipping '$airport->Iata' airport");
continue;
}

if (!isset($cities[$airport->CityAscii . $airport->CountryIso2])) {
$city = $this->cityRepository->findByTitleAndCountry($airport->CityAscii, $country);

if (!$city) {
$output->writeln("City '$airport->CityAscii' not found. Creating...");

$state = null;

if (isset($airport->StateCode)) {
$state = $this->stateRepository->findByCode($airport->StateCode);

if (!$state) {
$output->writeln("State '$airport->StateCode' not found. Skipping '$airport->Iata' airport");
$skipped++;
continue;
}
}

$city = $this->cityFactory
->setCity(new City())
->setTitle($airport->CityAscii)
->setIata($airport->CityCode)
->setLongitude((float)$airport->Longitude)
->setLatitude((float)$airport->Latitude)
->setAltitude((int)$airport->Elevation)
->setState($state)
->setCountry($country)
->create();
}

if (!empty($airport->CityCode)) {
$existsCityIata = $this->cityRepository->findByIata($airport->CityCode);

if ($existsCityIata) {
$existsCityIata->setIata(null);
$this->cityRepository->save($existsCityIata, true);
}

$city->setIata($airport->CityCode);
$this->cityRepository->save($city, true);
}

$cities[$airport->CityAscii . $airport->CountryIso2] = $city;
} else {
$city = $cities[$airport->CityAscii . $airport->CountryIso2];
}

if (!isset($timezones[$airport->TimezoneId])) {
$timezone = $this->timezoneRepository->findByCode($airport->TimezoneId);

if (!$timezone) {
$output->writeln("Timezone '{$airport->TimezoneId}' not found. Skipping '$airport->Iata' airport");
continue;
}

$timezones[$airport->TimezoneId] = $timezone;
} else {
$timezone = $timezones[$airport->TimezoneId];
}

$newAirport = $this->airportFactory
->setAirport(new Airport())
->setCity($city)
->setTimezone($timezone)
->setTitle($airport->Name)
->setIcao($airport->Icao ?? null)
->setIata($airport->Iata)
->setLongitude((float)$airport->Longitude)
->setLatitude((float)$airport->Latitude)
->setAltitude((int)$airport->Elevation)
->create();

try {
$this->airportRepository->save($newAirport, true);
$imported++;
} catch (Throwable $e) {
dd($e->getMessage(), $airport);
}

if ($imported % 2000 === 0) {
$this->em->clear();
$timezones = [];
$cities = [];
gc_collect_cycles();
$output->writeln("Imported $imported airports... Still working...");
}
}
}
} catch (Throwable $e) {
$output->writeln('An error occurred: ' . $e->getMessage());
return Command::FAILURE;
}

$output->writeln("Imported $imported airports, skipped $skipped");

return Command::SUCCESS;
}
}
9 changes: 4 additions & 5 deletions src/Airport/Entity/Airport.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

#[ORM\Entity(repositoryClass: AirportRepository::class)]
#[ORM\HasLifecycleCallbacks]
#[UniqueEntity('icao')]
#[UniqueEntity('iata')]
class Airport
{
Expand All @@ -41,8 +40,8 @@ class Airport
#[ORM\Column(length: 3, unique: true, nullable: false)]
private string $iata;

#[ORM\Column(length: 4, unique: true, nullable: false)]
private string $icao;
#[ORM\Column(length: 4, nullable: true)]
private ?string $icao;

#[ORM\Column(length: 150, unique: false, nullable: false)]
private string $title;
Expand Down Expand Up @@ -112,12 +111,12 @@ public function setIata(string $iata): self
return $this;
}

public function getIcao(): string
public function getIcao(): ?string
{
return $this->icao;
}

public function setIcao(string $icao): self
public function setIcao(?string $icao = null): self
{
$this->icao = $icao;
return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/Airport/Factory/AirportFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function setTitle(string $title): AirportFactoryInterface
return $this;
}

public function setIcao(string $icao): AirportFactoryInterface
public function setIcao(?string $icao = null): AirportFactoryInterface
{
$this->airport->setIcao($icao);
return $this;
Expand Down
2 changes: 1 addition & 1 deletion src/Airport/Factory/AirportFactoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function setAirport(Airport $airport): self;

public function setTitle(string $title): self;

public function setIcao(string $icao): self;
public function setIcao(?string $icao = null): self;

public function setIata(string $iata): self;

Expand Down
5 changes: 5 additions & 0 deletions src/Application/Command/Import/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public static function getAirportsDataFilepath(): string
return getcwd() . '/data/cities_airports.json';
}

public static function getAirports2DataFilepath(): string
{
return getcwd() . '/data/airports.json';
}

public static function getNationalitiesDataFilepath(): string
{
return getcwd() . '/data/nationalities.json';
Expand Down

0 comments on commit 53027fd

Please sign in to comment.