Skip to content

Commit

Permalink
Merge pull request #16 from farzai/v2
Browse files Browse the repository at this point in the history
Refactor and modernize Geonames library
  • Loading branch information
parsilver authored Feb 13, 2025
2 parents c342c79 + b8a340a commit 92221b2
Show file tree
Hide file tree
Showing 52 changed files with 1,185 additions and 1,619 deletions.
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@ phpunit.xml
psalm.xml
/vendor
.php-cs-fixer.cache
test.zip
test.zip
/data
/tests/data
.DS_Store
**/.DS_Store
/.phpunit.cache
260 changes: 114 additions & 146 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,179 +4,147 @@
[![Tests](https://img.shields.io/github/actions/workflow/status/farzai/geonames-php/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/farzai/geonames-php/actions/workflows/run-tests.yml)
[![codecov](https://codecov.io/gh/farzai/geonames-php/branch/main/graph/badge.svg)](https://codecov.io/gh/farzai/geonames-php)
[![Total Downloads](https://img.shields.io/packagist/dt/farzai/geonames.svg?style=flat-square)](https://packagist.org/packages/farzai/geonames)
A PHP library for downloading and converting Geonames data. This library provides easy access to both Postal Codes and Gazetteer data from Geonames.

This package provides a simple way to download Geonames data and format it for friendly use.
(https://www.geonames.org/)
## Features

## Requirements
```
PHP ^8.1
ext-curl
ext-json
ext-zip
```
- Download postal codes data for specific countries or all countries
- Download detailed geographical data (Gazetteer) including administrative divisions
- Convert data to JSON format with proper structure
- Memory-efficient processing for large datasets
- Progress bars for all operations
- Support for filtering by feature types (for Gazetteer data)

## Installation

## Setup
You can install the package via Composer:
```bash
composer require farzai/geonames
```

## Example
```php
use Farzai\Geonames\Client;
## Usage

// Create a new client
$client = new Client();
### Postal Codes

// Get all countries and return $resource
$resource = $client->getCountryInfo(); // \Farzai\Geonames\Resource\CollectionResource
Download postal codes for a specific country:

// Now, you can access the data using the following methods:
$countries = $resource->asArray(); // Array
$json = $resource->asJson(); // String

// Or acccess data as entity
foreach ($resource->all() as $country) {
/** @var \Farzai\Geonames\Entities\CountryEntity $country */
echo $country->name;
}
```bash
./bin/geonames geonames:download TH
```

Download postal codes for all countries:

---
```bash
./bin/geonames geonames:download all
```

## Available methods
Options:
- `--output (-o)`: Output directory (default: ./data)
- `--format (-f)`: Output format (default: json)

The postal codes data includes:
- Country code
- Postal code
- Place name
- Administrative divisions (state/province, county/district, community)
- Latitude and longitude
- Accuracy level

### Get all countries
```php
// GET: https://download.geonames.org/export/dump/countryInfo.txt
$resource = $client->getCountryInfo();
### Gazetteer Data

// $entity instanceof \Farzai\Geonames\Entities\CountryEntity
foreach ($resource->all() as $entity) {
echo $entity->iso;
// ...
}
```
Download geographical data for a specific country:

| Property | Type | Description | Example | Required |
| --- | --- | --- | --- | --- |
| iso | string | ISO 3166-1 alpha-2 | TH | Yes |
| iso3 | string | ISO 3166-1 alpha-3 | THA | Yes |
| iso_numeric | string | ISO 3166-1 numeric | 764 | Yes |
| fips | string | FIPS 10-4 | TH | No |
| name | string | Country name | Thailand | Yes |
| capital | string | Capital | Bangkok | No |
| area | float | Area in km² | 514000.0 | No |
| population | int | Population | 67089500 | No |
| continent | string | Continent code | AS | No |
| tld | string | Top level domain | .th | No |
| currency_code | string | Currency code | THB | No |
| currency_name | string | Currency name | Baht | No |
| phone | string | Phone calling code | 66 | No |
| postal_code_format | string | Postal code format | 5 digits | No |
| postal_code_regex | string | Postal code regex | \^[1-9]\d{4}$ | No |
| languages | string | Languages (comma separated) | th,en,ar-AE,km,la | No |
| geoname_id | string | Geoname ID | 1605651 | No |
| neighbours | string | Neighbours (comma separated) | LA,MM,KH,MY | No |
| equivalent_fips_code | string | Equivalent FIPS code | TH | No |


### Get languages
```php
// GET: https://download.geonames.org/export/dump/iso-languagecodes.txt
$resource = $client->getLanguages();

// $entity instanceof \Farzai\Geonames\Entities\LanguageEntity
foreach ($resource->all() as $entity) {
// ...
}
```bash
./bin/geonames geonames:gazetteer:download TH
```
| Property | Type | Description | Example | Required |
| --- | --- | --- | --- | --- |
| iso_639_3 | string | ISO 639-3 code | tha | Yes |
| iso_639_2 | string | ISO 639-2 code | tha | Yes |
| iso_639_1 | string | ISO 639-1 code | th | Yes |
| language_name | string | Language name | Thai | Yes |



### Geonames available resources
```php
// GET: https://download.geonames.org/export/dump
$resource = $client->getGeonamesAvailable();
Download geographical data for all countries:

/** @var string[] $countryCodes */
$countryCodes = $resource->all();
```bash
./bin/geonames geonames:gazetteer:download all
```

### Geonames by country code
```php
// GET: https://download.geonames.org/export/dump/{countryCode}.zip
$resource = $client->getGeonamesByCountryCode('TH');

// $entity instanceof \Farzai\Geonames\Entities\GeonameEntity
foreach ($resource->all() as $entity) {
// ...
Options:
- `--output (-o)`: Output directory (default: ./data)
- `--format (-f)`: Output format (default: json)
- `--feature-class (-c)`: Filter by feature class (default: P)

Available feature classes:
- `A`: Country, state, region
- `H`: Stream, lake
- `L`: Parks, area
- `P`: City, village
- `R`: Road, railroad
- `S`: Spot, building, farm
- `T`: Mountain, hill, rock
- `U`: Undersea
- `V`: Forest, heath

The Gazetteer data includes:
- Geoname ID
- Name (with ASCII and alternate names)
- Geographical coordinates
- Feature class and code
- Administrative divisions with names
- Population
- Elevation
- Digital elevation model (DEM)
- Timezone
- Modification date

## Data Structure

### Postal Codes JSON Structure

```json
{
"country_code": "TH",
"postal_code": "10200",
"place_name": "Bang Rak",
"admin_name1": "Bangkok",
"admin_code1": "10",
"admin_name2": "",
"admin_code2": "",
"admin_name3": "",
"admin_code3": "",
"latitude": 13.7235,
"longitude": 100.5147,
"accuracy": 1
}
```
| Property | Type | Description | Example | Required |
| --- | --- | --- | --- | --- |
| id | string | Geoname ID | 1605651 | Yes |
| name | string | Name of geographical point (utf8) | Ban Khlong Nung | Yes |
| asciiname | string | Name of geographical point in plain ascii characters | Ban Khlong Nung | Yes |
| alternatenames | string | Alternatenames, comma separated | Ban Khlong Nung,Ban Khlong Nung,Ban Khlong Nung | Yes |
| latitude | float | Latitude in decimal degrees (wgs84) | 13.75 | Yes |
| longitude | float | Longitude in decimal degrees (wgs84) | 100.46667 | Yes |
| feature_class | string | See http://www.geonames.org/export/codes.html | P | Yes |
| feature_code | string | See http://www.geonames.org/export/codes.html | PPL | Yes |
| country_code | string | ISO-3166 2-letter country code, 2 characters | TH | Yes |
| cc2 | string | Alternate country codes, comma separated, ISO-3166 2-letter country code, 60 characters | TH | No |
| admin1_code | string | Fipscode (subject to change to iso code), see exceptions below, see file admin1Codes.txt for display names of this code; varchar(20) | 40 | No |
| admin2_code | string | Code for the second administrative division, a county in the US, see file admin2Codes.txt; varchar(80) | 40 | No |
| admin3_code | string | Code for third level administrative division, varchar(20) | 40 | No |
| admin4_code | string | Code for fourth level administrative division, varchar(20) | 40 | No |
| population | int | Bigint (8 byte int) | 0 | No |
| elevation | int | In meters | 0 | No |
| dem | int | Digital elevation model, srtm3 or gtopo30, average elevation of 3''x3'' (ca 90mx90m) or 30''x30'' (ca 900mx900m) area in meters, integer. srtm processed by cgiar/ciat. | 0 | No |
| timezone | string | The iana timezone id (see file timeZone.txt) varchar(40) | Asia/Bangkok | No |
| modification_date | string | Date of last modification in yyyy-MM-dd format | 2011-03-03 | No |


### Alternate names available resources
```php
// GET: https://download.geonames.org/export/dump/alternatenames
$resource = $client->getAlternateNamesAvailable();

/** @var string[] $countryCodes */
$countryCodes = $resource->all();
```

### Alternate names by country code
```php
// GET: https://download.geonames.org/export/dump/alternatenames/{countryCode}.zip
$resource = $client->getAlternateNamesByCountryCode('TH');

// $entity instanceof \Farzai\Geonames\Entities\AlternateNameEntity
foreach ($resource->all() as $entity) {
//
### Gazetteer JSON Structure

```json
{
"geoname_id": 1609350,
"name": "Bangkok",
"ascii_name": "Bangkok",
"alternate_names": ["Krung Thep", "กรุงเทพมหานคร"],
"latitude": 13.75,
"longitude": 100.51667,
"feature_class": "P",
"feature_code": "PPLC",
"country_code": "TH",
"cc2": [],
"admin1_code": "40",
"admin1_name": "Bangkok",
"admin2_code": "",
"admin2_name": "",
"admin3_code": "",
"admin4_code": "",
"population": 5104476,
"elevation": 2,
"dem": 4,
"timezone": "Asia/Bangkok",
"modification_date": "2023-01-12"
}
```
| Property | Type | Description | Example | Required |
| --- | --- | --- | --- | --- |
| id | string | the id of this alternate name | 1 | Yes |
| geoname_id | string | geonameId referring to id in table 'geoname' | 3041563 | Yes |
| iso_language | string | iso 639 language code 2- or 3-characters; 4-characters 'post' for postal codes and 'iata','icao' and faac for airport codes, fr_1793 for French Revolution names, abbr for abbreviation, link to a website (mostly to wikipedia), wkdt for the wikidataid | en | Yes |
| name | string | alternate name or name variant | Ban Khlong Nung | Yes |
| is_preferred_name | bool | true, if this alternate name is an official/preferred name | true | Yes |
| is_short_name | bool | true, if this is a short name like 'California' for 'State of California' | true | Yes |
| is_colloquial | bool | true, if this alternate name is a colloquial or slang term. Example: 'Big Apple' for 'New York'. | true | Yes |
| is_historic | bool | true, if this alternate name is historic and was used in the past. | true | Yes |
| from | string | from period when the name was used | 2011-03-03 | No |
| to | string | to period when the name was used | 2011-03-03 | No |


## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

This package is open-sourced software licensed under the MIT license.

## Credits

- Data provided by [GeoNames](https://www.geonames.org/) under a [Creative Commons Attribution 4.0 License](https://creativecommons.org/licenses/by/4.0/)
- Developed by [Parsilver](https://github.com/parsilver)
15 changes: 15 additions & 0 deletions bin/geonames
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env php
<?php

declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Symfony\Component\Console\Application;
use Farzai\Geonames\Console\Commands\DownloadPostalCodesCommand;
use Farzai\Geonames\Console\Commands\DownloadGazetteerCommand;

$application = new Application('Geonames CLI', '1.0.0');
$application->add(new DownloadPostalCodesCommand());
$application->add(new DownloadGazetteerCommand());
$application->run();
8 changes: 5 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{
"name": "farzai/geonames",
"type": "library",
"description": "This package provides a simple way to download Geonames data and format it for friendly use.",
"description": "A PHP library for downloading and converting Geonames data.",
"keywords": ["geonames", "countries", "data"],
"homepage": "https://github.com/farzai/geonames-php",
"require": {
"php": "^8.1",
"farzai/transport": "^1.0.0"
"symfony/console": "^6.0",
"guzzlehttp/guzzle": "^7.0"
},
"require-dev": {
"pestphp/pest": "^2.8",
Expand All @@ -28,7 +30,7 @@
"authors": [
{
"name": "parsilver",
"role": "DevOps"
"role": "Developer"
}
],
"config": {
Expand Down
Loading

0 comments on commit 92221b2

Please sign in to comment.