plin-code/laravel-istat-geography
Composer 安装命令:
composer require plin-code/laravel-istat-geography
包简介
Laravel package for importing and managing Italian geography data from ISTAT
README 文档
README
A Laravel package for importing and managing Italian geographical data from ISTAT.
Features
- 🇮🇹 Import Italian regions, provinces, and municipalities from ISTAT
- 📮 Import Italian postal codes (CAP) with support for multi-CAP municipalities
- 🔄 Incremental updates: add new records, update changes, soft-delete removed ones
- 📊 Daily CSV caching to avoid unnecessary requests
- 🔗 Eloquent models with hierarchical relationships
- ⚡ Artisan commands for easy data import and synchronization
- 🔧 Fully configurable via configuration file
- 🆔 UUID primary keys and soft deletes support
- 🧪 Comprehensive test suite with mocked HTTP requests
Requirements
- PHP 8.3+
- Laravel 11.0+ or 12.0+
- league/csv 9.0+
- guzzlehttp/guzzle 7.0+
Installation
composer require plin-code/laravel-istat-geography
Quick Start
- Install the package:
composer require plin-code/laravel-istat-geography
- Publish the configuration:
php artisan vendor:publish --provider="PlinCode\IstatGeography\IstatGeographyServiceProvider"
- Run migrations:
php artisan migrate
- Import the data:
php artisan geography:import
That's it! You now have all Italian geographical data in your database.
Commands
geography:import
Performs a full import of all geographical data from ISTAT. Use this for the initial data load.
php artisan geography:import
Options
| Option | Description |
|---|---|
--cap |
Also import postal codes (CAP) after ISTAT data |
--cap-only |
Import only postal codes, skip ISTAT data (requires existing municipalities) |
--cap-file=<path> |
Use a local JSON file for CAP data instead of downloading |
Examples
# Import ISTAT data only php artisan geography:import # Import ISTAT data + CAP (using local file - recommended) php artisan geography:import --cap --cap-file=cap-dataset.json # Update only CAP on existing municipalities php artisan geography:import --cap-only --cap-file=cap-dataset.json
Note: The remote GeoJSON with geometries is ~464MB. Using
--cap-filewith a preprocessed JSON file (~3MB) is recommended for better performance.
geography:download-cap
Downloads CAP GeoJSON data and saves it locally for offline import. Useful when you want to download once and import multiple times.
# Download from default URL (config/env) php artisan geography:download-cap # Download from custom URL php artisan geography:download-cap --url=https://example.com/cap.json # Specify output path php artisan geography:download-cap --output=storage/app/my-cap.json
After downloading, import with:
php artisan geography:import --cap --cap-file=storage/app/cap-dataset.json
geography:update
Incrementally synchronizes your database with the latest ISTAT data. It compares the current ISTAT CSV against your existing records and applies only the differences: new records are added, changed records are updated, and records no longer present in ISTAT are soft-deleted.
php artisan geography:update
Options
| Option | Description |
|---|---|
--dry-run |
Simulate the update without making any database changes. Shows what would be added, modified, or deleted. |
--force |
Continue execution even if non-critical errors occur (errors are logged as warnings). |
Verbosity Levels
| Flag | Output |
|---|---|
| (none) | Final summary only (e.g. 3 added, 1 modified, 0 deleted) |
-v |
Download progress, list of new/modified/suppressed records, progress bar |
-vv |
Field-level change details (e.g. name: Old Name → New Name) |
-vvv |
Debug output with timing information for each operation |
Examples
# Preview changes without applying them php artisan geography:update --dry-run # Run with verbose output php artisan geography:update -v # Run with full debug output php artisan geography:update -vvv # Force continue on non-critical errors php artisan geography:update --force
All database operations are wrapped in a transaction. If any error occurs (and --force is not set), all changes are automatically rolled back.
Configuration
Publish the configuration file:
php artisan vendor:publish --provider="PlinCode\IstatGeography\IstatGeographyServiceProvider"
The config/istat-geography.php file allows you to customize:
- Database connection: Choose which database connection the package tables should use (defaults to the main connection)
- Table names: Customize the database table names
- Model classes: Use your own model classes by extending the base ones
- CSV URL: Change the ISTAT data source URL (also via
ISTAT_CSV_URLenv) - CAP GeoJSON URL: Change the CAP data source URL (also via
CAP_GEOJSON_URLenv) - Temporary file name: Customize the cache file name
Database Connection
By default the package uses your application's default database connection. To store the geographical tables on a separate connection, set the connection key in config/istat-geography.php or the ISTAT_DB_CONNECTION environment variable:
ISTAT_DB_CONNECTION=geography
Note
The connection config key is additive and fully backward compatible. If you published the config file before this option existed, the package falls back to your default database connection (config('database.default')), so no action is required on upgrade. To opt into a custom connection, either republish the config file or set the ISTAT_DB_CONNECTION environment variable.
Example Configuration
return [ 'connection' => env('ISTAT_DB_CONNECTION', env('DB_CONNECTION')), 'tables' => [ 'regions' => 'my_regions', 'provinces' => 'my_provinces', 'municipalities' => 'my_municipalities', ], 'models' => [ 'region' => \App\Models\Region::class, 'province' => \App\Models\Province::class, 'municipality' => \App\Models\Municipality::class, ], 'import' => [ 'csv_url' => 'https://custom-url.com/data.csv', 'temp_filename' => 'my_istat_data.csv', ], ];
Models
The package provides three Eloquent models:
Region
use PlinCode\IstatGeography\Models\Geography\Region; $region = Region::where('name', 'Piemonte')->first(); $provinces = $region->provinces;
Province
use PlinCode\IstatGeography\Models\Geography\Province; $province = Province::where('code', 'TO')->first(); $municipalities = $province->municipalities; $region = $province->region;
Municipality
use PlinCode\IstatGeography\Models\Geography\Municipality; $municipality = Municipality::where('name', 'Torino')->first(); $province = $municipality->province;
ISTAT Fields
Each model exposes a static istatFields() method that returns the list of fields managed by ISTAT data. These are the fields that the geography:update command is allowed to overwrite. Any additional fields you add to your extended models will not be touched during updates.
Region::istatFields(); // ['name', 'istat_code'] Province::istatFields(); // ['name', 'code', 'istat_code', 'region_id'] Municipality::istatFields(); // ['name', 'istat_code', 'province_id', 'bel_code'] Municipality::capFields(); // ['postal_code', 'postal_codes']
Extending Models
If you want to use the package models in your main project, you can extend them:
// app/Models/Region.php namespace App\Models; use PlinCode\IstatGeography\Models\Geography\Region as BaseRegion; class Region extends BaseRegion { // Add your project-specific logic here public function customMethod() { return $this->provinces()->count(); } }
// app/Models/Province.php namespace App\Models; use PlinCode\IstatGeography\Models\Geography\Province as BaseProvince; class Province extends BaseProvince { // Add your project-specific logic here }
// app/Models/Municipality.php namespace App\Models; use PlinCode\IstatGeography\Models\Geography\Municipality as BaseMunicipality; class Municipality extends BaseMunicipality { // Add your project-specific logic here }
Remember to update the models section in the configuration file to point to your custom classes.
Database Structure
Regions
id(UUID, primary key)name(string)istat_code(string, unique)created_at,updated_at,deleted_at
Provinces
id(UUID, primary key)region_id(UUID, foreign key)name(string)code(string, unique)istat_code(string, unique)created_at,updated_at,deleted_at
Municipalities
id(UUID, primary key)province_id(UUID, foreign key)name(string)istat_code(string, unique)bel_code(string, nullable) - Cadastral/Belfiore code for CAP matchingpostal_code(string, nullable) - Primary postal code (CAP)postal_codes(string, nullable) - Range of postal codes for large municipalities (e.g., "00118-00199")created_at,updated_at,deleted_at
Relationships
Region→hasMany→ProvinceProvince→belongsTo→RegionProvince→hasMany→MunicipalityMunicipality→belongsTo→Province
Replacing Existing Command
If you already have a geography:import command in your project, you can replace it with the package's command:
// In app/Console/Kernel.php or in your existing command Artisan::command('geography:import', function () { $this->info('Starting geographical data import...'); try { $count = \PlinCode\IstatGeography\Facades\IstatGeography::import(); $this->info("Import completed successfully! Imported {$count} municipalities."); } catch (\Exception $e) { $this->error('Error during import: ' . $e->getMessage()); } })->purpose('Import regions, provinces and municipalities from ISTAT');
Testing
Run the test suite:
composer test
The package includes:
- ✅ Unit tests for models and relationships
- ✅ Feature tests for the import service
- ✅ Feature tests for the update command and services
- ✅ Mocked HTTP requests (no external dependencies)
- ✅ PHPStan static analysis
- ✅ Pest PHP testing framework
Test Coverage
- Models and their relationships
- Import service with CSV processing
- Compare service for detecting changes
- Update service for applying changes
- Artisan command functionality (import and update)
- Configuration handling
Data Sources
ISTAT Data
Geographic data (regions, provinces, municipalities) is sourced from ISTAT (Italian National Institute of Statistics), the official Italian government statistics agency.
Postal Codes (CAP)
Postal code data is sourced from Zornade Data Downloads.
A huge thanks to Zornade for their incredible work in making Italian public data freely available. Their dedication to open data helps developers build better applications for Italian users.
Contributing
- Fork the project
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
The MIT License (MIT). Please see License File for more information.
plin-code/laravel-istat-geography 适用场景与选型建议
plin-code/laravel-istat-geography 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 6.78k 次下载、GitHub Stars 达 10, 最近一次更新时间为 2025 年 08 月 07 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「geography」 「laravel」 「countries」 「regions」 「provinces」 「italy」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 plin-code/laravel-istat-geography 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 plin-code/laravel-istat-geography 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 plin-code/laravel-istat-geography 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
List of all countries with names and ISO 3166-1 codes in all languages and data formats for Laravel
Laravel 5.2 package that provides basic geographical data like Countries, Regions and Cities.
PHP FFI bindings for Uber's H3 hexagonal hierarchical geospatial indexing system
Geo-Toolkit for PHP
A package to delivery a wide seed array of Countries & their respective cities.
Doctrine2 simple support for spatial types and functions
统计信息
- 总下载量: 6.78k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 10
- 点击次数: 37
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-08-07
