Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Geoname Bundle Laravel Package

bordeux/geoname-bundle

Symfony bundle to import and access GeoNames.org geographic data in PostgreSQL via Doctrine ORM. Load countries, timezones, states/provinces, and cities/towns/suburbs from the GeoNames export using built-in console import commands.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation:

    composer require bordeux/geoname-bundle
    

    Note: If using Laravel, install Symfony console components first:

    composer require symfony/console symfony/dependency-injection
    
  2. Configure Database: Ensure your config/database.php uses PostgreSQL (required for v3.0+). Example:

    'connections' => [
        'pgsql' => [
            'driver' => 'pgsql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '5432'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'charset' => 'utf8',
            'prefix' => '',
            'schema' => 'public', // Critical for bundle's schema
            'sslmode' => 'prefer',
        ],
    ],
    
  3. Run Schema Update: For Laravel, create a custom Artisan command to mimic Symfony’s schema update:

    php artisan make:command GeoNameSchemaUpdate
    

    Then update the command:

    // app/Console/Commands/GeoNameSchemaUpdate.php
    public function handle()
    {
        $this->call('migrate', ['--path' => 'vendor/bordeux/geoname-bundle/src/Resources/migrations']);
    }
    

    Run it:

    php artisan geoname:schema-update
    
  4. Import GeoNames Data: Create a Laravel Artisan command to trigger the import:

    php artisan make:command GeoNameImport
    

    Update the command to call the bundle’s importer:

    // app/Console/Commands/GeoNameImport.php
    public function handle()
    {
        $importer = new \Bordeux\Bundle\GeoNameBundle\Command\GeoNameImportCommand();
        $importer->setContainer($this->app); // Laravel's service container
        $importer->run(new \Symfony\Component\Console\Input\ArrayInput([]), new \Symfony\Component\Console\Output\ConsoleOutput());
    }
    

    Execute:

    php artisan geoname:import
    

    Warning: This downloads ~350MB of data. Run in a non-production environment first.

  5. First Query: Use Eloquent to query the imported data. Example for cities:

    // app/Models/GeoNameCity.php
    namespace App\Models;
    use Illuminate\Database\Eloquent\Model;
    
    class GeoNameCity extends Model
    {
        protected $table = 'geoname_cities';
        protected $primaryKey = 'geonameid';
        public $incrementing = false;
        protected $keyType = 'integer';
    }
    

    Query:

    $cities = GeoNameCity::where('name', 'like', '%Paris%')->get();
    

Implementation Patterns

Daily Workflows

  1. Data Normalization:

    • Use Case: Standardize user-provided location data (e.g., "NY" → "New York, US").
    • Pattern:
      // Find a city by alternate name
      $geoname = \App\Models\GeoNameCity::where('alternatenames', 'like', '%NY%')->first();
      if ($geoname) {
          $standardizedName = $geoname->name . ', ' . $geoname->country->name;
      }
      
    • Laravel Tip: Cache frequent lookups with Illuminate\Support\Facades\Cache:
      $geoname = Cache::remember("geoname_{$alternateName}", now()->addHours(1), function () use ($alternateName) {
          return \App\Models\GeoNameCity::where('alternatenames', 'like', "%{$alternateName}%")->first();
      });
      
  2. Geospatial Enrichment:

    • Use Case: Add timezone or population data to user profiles.
    • Pattern:
      // Enrich a user with their city's timezone
      $user->city = \App\Models\GeoNameCity::where('geonameid', $user->city_id)->first();
      $user->timezone = $user->city->timezone->name;
      
    • Performance: Use Laravel’s with() to eager-load relationships:
      $user = User::with(['city.timezone'])->find($userId);
      
  3. Validation:

    • Use Case: Check if a location exists during user signup.
    • Pattern:
      public function validateLocation($locationName)
      {
          return \App\Models\GeoNameCity::where('name', $locationName)->exists();
      }
      
    • Extension: Add a custom validation rule:
      // app/Rules/ValidGeoName.php
      use Illuminate\Contracts\Validation\Rule;
      use App\Models\GeoNameCity;
      
      class ValidGeoName implements Rule
      {
          public function passes($attribute, $value)
          {
              return GeoNameCity::where('name', $value)->orWhere('alternatenames', 'like', "%{$value}%")->exists();
          }
      }
      
      Usage:
      $request->validate([
          'city' => ['required', new ValidGeoName],
      ]);
      
  4. Console Automation:

    • Use Case: Schedule periodic data updates (e.g., monthly).
    • Pattern: Add to Laravel’s app/Console/Kernel.php:
      protected function schedule(Schedule $schedule)
      {
          $schedule->command('geoname:import')->monthly()->onOneServer();
      }
      
    • Partial Updates: For large datasets, split imports by entity (e.g., countries first):
      php artisan geoname:import --entity=countries
      

Integration Tips

  1. Doctrine ORM in Laravel:

    • If you need Doctrine’s advanced features (e.g., DQL), install doctrine/dbal and use it alongside Eloquent:
      use Doctrine\DBAL\Connection;
      $conn = new Connection(['url' => 'postgres://user:pass@localhost/db']);
      $stmt = $conn->executeQuery('SELECT * FROM geoname_cities WHERE name = ?', ['Paris']);
      
    • For hybrid apps, use Laravel’s DB facade with raw SQL:
      $cities = DB::select('SELECT * FROM geoname_cities WHERE name = ?', ['Paris']);
      
  2. PostGIS Integration:

    • Enable PostGIS in PostgreSQL and use Laravel’s spatie/laravel-postgis for geospatial queries:
      composer require spatie/laravel-postgis
      
    • Example query:
      use Spatie\Postgis\PostgisFacade as Postgis;
      
      $nearbyCities = Postgis::select('geoname_cities')
          ->where('ST_DWithin', 'ST_GeomFromText(:point, 4326)', ['point' => 'POINT(-73.935242 40.730610)', 'radius' => 10000])
          ->get();
      
  3. Alternate Names:

    • The bundle stores alternate names in a serialized array. Normalize them for queries:
      // Split alternatenames for full-text search
      DB::statement("
          CREATE INDEX idx_geoname_cities_alternatenames ON geoname_cities
          USING gin (to_tsvector('english', alternatenames))
      ");
      
    • Query using Laravel’s DB:
      $results = DB::select("
          SELECT * FROM geoname_cities
          WHERE to_tsvector('english', alternatenames) @@ to_tsquery('english', ?)
      ", ['NY | New York']);
      
  4. Caching Strategies:

    • Cache entire tables for read-heavy apps:
      // app/Providers/AppServiceProvider.php
      public function boot()
      {
          Cache::rememberForever('geoname_cities', function () {
              return \App\Models\GeoNameCity::all()->keyBy('geonameid');
          });
      }
      
    • Use Laravel’s remember for query results:
      $cities = Cache::remember("cities_{$countryId}", now()->addHours(6), function () use ($countryId) {
          return \App\Models\GeoNameCity::where('country_code', $countryId)->get();
      });
      
  5. Event-Driven Updates:

    • Trigger updates when GeoNames data changes (e.g., via webhooks or cron):
      // app/Listeners/UpdateGeoNamesData.php
      public function handle()
      {
          Artisan::call('geoname:import', ['--entity' => 'cities
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui