PHPackages                             two-faces/laravel-cities - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. two-faces/laravel-cities

ActiveLibrary[Database &amp; ORM](/categories/database)

two-faces/laravel-cities
========================

Seed all countries/cities from geonames.org database. Searchable DB tree, ready to use API! Refactored for Laravel 10+ and PHP 8.2+

v1.0.2(4mo ago)023MITPHPPHP ^8.2CI passing

Since Dec 17Pushed 4mo agoCompare

[ Source](https://github.com/Two-Faces/laravel-cities)[ Packagist](https://packagist.org/packages/two-faces/laravel-cities)[ Docs](https://github.com/Two-Faces/laravel_cities.git)[ RSS](/packages/two-faces-laravel-cities/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (5)Versions (4)Used By (0)

[![License](https://camo.githubusercontent.com/589340e4d38c06303314e5b71c133ff2e3cadd15c677f1bfc9e8c11233b359a3/687474703a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d6f72616e67652e737667)](https://tldrlegal.com/license/mit-license)

Introduction
============

[](#introduction)

What you get:

- Deploy and use geonames.org (ex MaxCDN) database localy to query countries/cities
- Get information like lattitude/longtityde, population etc
- Optimized [DB tree structure](https://en.wikipedia.org/wiki/Nested_set_model) for searching and traversing the tree.
- Provides an Eloquent model (geo) with multiple query-scopes to help you build your queries.
- Exposes a simple API that you can use to create AJAX calls. (Eg search while typing etc).

What you dont get:

- geoIP &amp; Postalcodes (not included in free sets)
- Map elements smaller than "3rd Administration Division" (=Cities)

Instructions
============

[](#instructions)

- Install with copmoser. Run:

`composer require two-faces/laravel-cities`

The Service provider will be autodiscovered and registered by Laravel. If you are using Laravel version &lt;5.5 then you must manually add the Service Provider in app.php:

```
'providers' => [
    //...
    TwoFaces\LaravelCities\GeoServiceProvider::class,
];
```

- Create a folder `geo` into app's storage folder ('\\storage\\geo'). Download &amp; unzip "hieararcy.txt" &amp; "allCountries.txt" from geonames.org ()

\[Tip\] Quick script to download on your remote server with:

```
mkdir -p storage/geo && cd storage/geo
wget http://download.geonames.org/export/dump/allCountries.zip && unzip allCountries.zip && rm allCountries.zip
wget http://download.geonames.org/export/dump/hierarchy.zip && unzip hierarchy.zip && rm hierarchy.zip

```

or otherwise you can use

```
artisan geo:download

```

Download a \*.txt files from geonames.org By default it will download allcountries and hierarchy files otherwise you can pass flag --countries for specific countries

- Migrate and Seed. Run:

```
artisan migrate
artisan geo:seed

```

you can increase the memory limit for the cli invocation on demand to have process the command at once

```
php -d memory_limit=8000M artisan geo:seed --chunk=100000

```

So this will increase the memory limit for the command to 8GB with large chunk for each batches

You can also pass `--chunk` argument to specify how much chunk you want to process at once suppose you want `3000` records to be processed at once you can pass. This gives flexibility to make the import with low memory footprints

```
artisan geo:seed --chunk=3000

```

by default it is `1000`

Note: If you don't want all the countries, you can download only country specific files (eg US.txt) and import each one of them with:

```
artisan geo:seed US --append

```

Seed with custom data
=====================

[](#seed-with-custom-data)

Create a json file with custom data at `storage\geo` and run the following command to pick a file to seed:

```
php artisan geo:import-json
```

If an item exists in the DB (based on the 'id' value), then it will be updated else a new entry will be inserted. For example the following json file will rename `United States` to `USA` and it will add a child item (set by the parent\_id value)

```
[
  {
    "id": 6252001,
    "name": "USA"
  },
  {
    "name": "USA Child Item",
    "parent_id": 6252001,
    "alternames": ["51st State", "dummy name"],
    "population": 310232863,
    "lat": "39.760000",
    "long": "-98.500000"
  }
]
```

Please note that adding new items to the DB will reindex ALL items to rebuild the tree structure. Please be patient...

An example file is provided: [countryNames.json](https://github.com/Two-Faces/laravel-cities/blob/master/data/countryNames.json) which updates the official country names with a most popular simplified version.

Tip: You can get a json representation from the DB by quering the API (see below)

Geo Model:
==========

[](#geo-model)

You can use `TwoFaces\LaravelCities\Geo` Model to access the database. List of available properties:

```
$geo->name;       // name of geographical point in plain ascii
$geo->alternames; // Array of alternate names (Stored as Json)
$geo->country;    // 2-letter country code (ISO-3166)
$geo->id;         // Original id from geonames.org database (geonameid)
$geo->population; // Population (Where provided)
$geo->lat;        // latitude in decimal degrees (wgs84)
$geo->long;       // longitude in decimal degrees (wgs84)
$geo->level;      // Administrator level code (feature code)
// parent_id, left, right, depth: Used to build hierarcy tree
```

Visit  &gt; Info, for a more detailed description.

Usage
=====

[](#usage)

Searching:
----------

[](#searching)

```
use TwoFaces\LaravelCities\Models\Geo;

Geo::getCountries();               // Get a Collection of all countries
Geo::getCountry('US');             // Get item by Country code
Geo::findName('Nomos Kerkyras');   // Find item by (ascii) name
Geo::searchNames('york');          // Search item by all alternative names. Case insensitive
Geo::searchNames('vegas', Geo::getCountry('US'));  // ... and belongs to an item
Geo::getByIds([390903,3175395]);   // Get a Collection of items by Ids
```

Traverse tree
-------------

[](#traverse-tree)

```
$children    = $geo->getChildren();    // Get direct Children of $geo (Collection)
$parent      = $geo->getParent();      // Get single Parent of $geo (Geo)
$ancenstors  = $geo->getAncensors();   // Get Ancenstors tree of $geo from top->bottom (Collection)
$descendants = $geo->getDescendants(); // Get all Descentants of $geo alphabetic (Collection)
```

Check Hierarchy Relations:
--------------------------

[](#check-hierarchy-relations)

```
$geo1->isParentOf($geo2);       // (Bool) Check if $geo2 is direct Parent of $geo1
$geo2->isChildOf($geo1);        // (Bool) Check if $geo2 is direct Child of $geo1
$geo1->isAncenstorOf($geo2);    // (Bool) Check if $geo2 is Ancenstor of $geo1
$geo2->isDescendantOf($geo1);   // (Bool) Check if $geo2 is Descentant of $geo1
```

### Query Scopes

[](#query-scopes)

Build custom queries using these powerful scopes:

```
use TwoFaces\LaravelCities\Models\Geo;

// Filter by administration level
Geo::level(Geo::LEVEL_COUNTRY)->get();  // All countries
Geo::level(Geo::LEVEL_CAPITAL)->get();  // All capitals
Geo::level(Geo::LEVEL_1)->get();        // Admin level 1
Geo::level(Geo::LEVEL_2)->get();        // Admin level 2
Geo::level(Geo::LEVEL_3)->get();        // Admin level 3

// Filter by country code
Geo::country('US')->get();

// Filter capitals only
Geo::capital()->get();

// Search by name (case-insensitive, includes alternames)
Geo::search('new york')->get();

// Get descendants of a location
Geo::areDescentants($parentGeo)->get();

// Instance scopes
$geo->ancenstors();     // Query ancestors
$geo->descendants();    // Query descendants
$geo->children();       // Query direct children
```

**Advanced Query Examples:**

```
// Get all US states alphabetically
$usStates = Geo::getCountry('US')
    ->children()
    ->orderBy('name')
    ->get();

// Get all cities in California with population > 100,000
$californiaCity = Geo::findName('California');
$largeCities = Geo::areDescentants($californiaCity)
    ->where('population', '>', 100000)
    ->orderBy('population', 'desc')
    ->get();

// Get all European capitals
$europeanCountries = Geo::country('DE')
    ->orWhere('country', 'FR')
    ->orWhere('country', 'IT')
    ->get();

$capitals = Geo::capital()
    ->whereIn('country', $europeanCountries->pluck('country'))
    ->get();

// Search for cities starting with 'San' in USA
$sanCities = Geo::country('US')
    ->where('name', 'like', 'San%')
    ->orderBy('population', 'desc')
    ->get();
```

// Get the 3 biggest cities of Greece Geo::getCountry('GR') -&gt;level(Geo::LEVEL\_3) -&gt;orderBy('population','DESC') -&gt;limit(3) -&gt;get();

```

If you need more functionality you can extend `TwoFaces\LaravelCities\Geo` model and add your methods.

# HTTP API

This package defines some API routes that can be used to query the DB through simple HTTP requests. To use them insert in your routes file:

```php
\TwoFaces\LaravelCities\Models\Geo::ApiRoutes();

```

For example if you insert them in your `routes\api.php` (recomended) then the following URLs will be registered:

URL Endpoind (GET)DescriptionReturns (JSON)api/geo/search/{name}/{parent-id?}Search items containing 'name', (and belong to parent-id)Collectionapi/geo/item/{id}Get item by idGeoapi/geo/items/{ids}Get multiple items by ids (comma seperated list)Collectionapi/geo/children/{id}Get children of itemCollectionapi/geo/parent/{id}Get parent of itemGeoapi/geo/country/{code}get country by two-letter codeGeoapi/geo/countrieslist of countriesCollectionThe response is always a JSON representation of either a Geo class or a Collection.

To reduce bandwith, all Geo model attributes will be returned except from `alternames`, `left`, `right` and `depth`. You can change this behavior by passing an optional parameter on any request:

URL Params (aplly to all routes)DescriptionExamplefields=field1,field2Returns only the specified attributesapi/geo/countries?fields=id,namefields=allReturns all attributesapi/geo/countries?fields=allAlternative you may publish the component with

`artisan vendor:publish --provider="TwoFaces\LaravelCities\GeoServiceProvider"`

###  Health Score

38

—

LowBetter than 84% of packages

Maintenance79

Regular maintenance activity

Popularity6

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 74.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

142d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d82c785b4d58a08843201d12550893fa500d91cb521d1e0fc891cf49f54e169?d=identicon)[ariesel](/maintainers/ariesel)

---

Top Contributors

[![igaster](https://avatars.githubusercontent.com/u/4586319?v=4)](https://github.com/igaster "igaster (94 commits)")[![msonowal](https://avatars.githubusercontent.com/u/6334484?v=4)](https://github.com/msonowal "msonowal (15 commits)")[![Two-Faces](https://avatars.githubusercontent.com/u/32146703?v=4)](https://github.com/Two-Faces "Two-Faces (10 commits)")[![beingjungshahi](https://avatars.githubusercontent.com/u/3274491?v=4)](https://github.com/beingjungshahi "beingjungshahi (2 commits)")[![mohamedsabil83](https://avatars.githubusercontent.com/u/10126040?v=4)](https://github.com/mohamedsabil83 "mohamedsabil83 (1 commits)")[![joefazee](https://avatars.githubusercontent.com/u/1267708?v=4)](https://github.com/joefazee "joefazee (1 commits)")[![ricardosierra](https://avatars.githubusercontent.com/u/5499444?v=4)](https://github.com/ricardosierra "ricardosierra (1 commits)")[![shaibow](https://avatars.githubusercontent.com/u/12056542?v=4)](https://github.com/shaibow "shaibow (1 commits)")[![stephenlake](https://avatars.githubusercontent.com/u/1300442?v=4)](https://github.com/stephenlake "stephenlake (1 commits)")

---

Tags

laravelgeolocationcountriesgeographynested-setcitiesGeoNames.org

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/two-faces-laravel-cities/health.svg)

```
[![Health](https://phpackages.com/badges/two-faces-laravel-cities/health.svg)](https://phpackages.com/packages/two-faces-laravel-cities)
```

###  Alternatives

[lwwcas/laravel-countries

A comprehensive package for managing country data in Laravel applications, including multilingual support, geographic coordinates, and detailed metadata for seamless integration with Laravel.

12464.0k](/packages/lwwcas-laravel-countries)[igaster/laravel_cities

Seed all countries/cities from geonames.org database. Searchable DB tree, ready to use API &amp; a bonus vue.js component!

17988.7k1](/packages/igaster-laravel-cities)[nnjeim/world

Laravel countries, states, cities, currencies, languages and IP geolocation

970361.2k3](/packages/nnjeim-world)[anourvalar/eloquent-serialize

Laravel Query Builder (Eloquent) serialization

11320.2M21](/packages/anourvalar-eloquent-serialize)[altwaireb/laravel-world

Laravel World, Countries States Cities DB Migration &amp; Seeder

989.4k](/packages/altwaireb-laravel-world)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
