vitaliy_dior / laravel_cities
从 geonames.org 数据库中导入所有国家/城市。可搜索的数据库树,即用 API 及 Vue.js 组件奖励!
Requires
- laravel/framework: 5.*|^6.0|7.*|8.*
Requires (Dev)
- orchestra/testbench: ^4.0|^5.0
- phpunit/phpunit: ^8.0
README
简介
您将获得什么
- 本地部署并使用 geonames.org(如 MaxCDN)数据库查询国家/城市
- 获取如经纬度、人口等的信息
- 优化了嵌套集合模型的数据库树结构,以便于搜索和遍历树。
- 提供了一个 Eloquent 模型(geo),具有多个查询作用域,帮助您构建查询。
- 提供了一个简单的 API,您可以使用它来创建 AJAX 调用。(例如,在键入时搜索等)。
- 一个示例 Vue.js 组件,可以插入到您的表单中,并提供一个选择位置的界面。
您不会得到什么
- geoIP 和邮政编码(免费版不包括在内)
- 小于“第三级行政区划”(=城市)的地图元素
说明
- 使用 Composer 安装。运行
composer require igaster/laravel_cities
服务提供程序将被 Laravel 自动发现和注册。如果您使用的是 Laravel 版本 <5.5,则必须手动在 app.php 中添加服务提供程序。
'providers' => [ //... Igaster\LaravelCities\GeoServiceProvider::class, ];
- 在应用程序的存储文件夹中创建一个
geo
文件夹('\storage\geo')。从 geonames.org 下载并解压缩 "hieararcy.txt" 和 "allCountries.txt"(《http://download.geonames.org/export/dump》)
[提示] 使用以下快速脚本在远程服务器上下载
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
或者,您可以使用
artisan geo:download
从 geonames.org 下载 *.txt 文件。默认情况下,将下载所有国家和地区的文件以及层次结构文件,否则您可以传递 --countries 标志以指定特定国家
- 迁移和播种。运行
artisan migrate
artisan geo:seed
您可以根据需要增加 cli 调用的内存限制,以便一次性处理命令
php -d memory_limit=8000M artisan geo:seed --chunk=100000
因此,这将把命令的内存限制增加到 8GB,并为每个批次分配大块内存
您还可以传递 --chunk
参数以指定一次性要处理的数据块大小。例如,如果您想一次性处理 3000 条记录,您可以传递。这提供了在低内存占用下进行导入的灵活性
artisan geo:seed --chunk=3000
默认为 1000
注意:如果您不想下载所有国家,可以只下载特定国家的文件(例如,US.txt)并使用以下命令导入每个文件
artisan geo:seed US --append
使用自定义数据播种
在 storage\geo
中创建一个包含自定义数据的 json 文件,并运行以下命令以选择要播种的文件
artisan geo:json
如果数据库中存在条目(根据 'id' 值),则将其更新,否则将插入新条目。例如,以下 json 文件将把 United States
重命名为 USA
,并添加一个子项(由 parent_id 值设置)
[ { "id": 6252001, "name": "USA" }, { "name": "USA Child Item", "parent_id": 6252001, "alternames": ["51st State", "dummy name"], "population": 310232863, "lat": "39.760000", "long": "-98.500000" } ]
请注意,向数据库添加新项目将重新索引所有项目以重建树结构。请耐心等待...
提供了一个示例文件:[countryNames.json](https://github.com/igaster/laravel_cities/blob/master/data/countryNames.json),它使用最受欢迎的简写版本更新了官方国家名称。
提示:您可以通过查询 API 从数据库获取 json 表示(见下文)
Geo 模型
您可以使用 Igaster\LaravelCities\Geo
模型来访问数据库。以下是可以使用的属性列表
$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
访问 http://www.geonames.org > Info,获取更详细的描述。
使用方法
搜索
use Igaster\LaravelCities\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
遍历树
$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)
检查层次关系
$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
查询范围(用于构建自定义查询)
Geo::level($level); // Filter by Administration level: // Geo::LEVEL_COUNTRY, Geo::LEVEL_CAPITAL, Geo::LEVEL_1, Geo::LEVEL_2, Geo::LEVEL_3 Geo::country('US'); // (Shortcut) Items that belongs to country US Geo::capital(); // (Shortcut) Items that are capitals Geo::search($name); // Items that conain $name in name OR alternames (Case InSensitive) Geo::areDescentants($geo); // Items that belong to $geo $geo->ancenstors(); // Items that contain $geo $geo->descendants(); // Items that belong to $geo $geo->children(); // Items that are direct children of $geo //--Scope usage Examples: // Get the States of USA in aplhabetic order Geo::getCountry('US') ->children() ->orderBy('name') ->get(); // Get the 3 biggest cities of Greece Geo::getCountry('GR') ->level(Geo::LEVEL_3) ->orderBy('population','DESC') ->limit(3) ->get();
如果您需要更多功能,可以扩展 Igaster\LaravelCities\Geo
模型并添加您的方法。
HTTP API
此包定义了一些可以通过简单的HTTP请求查询数据库的API路由。要在路由文件中使用它们,请插入以下内容:
\Igaster\LaravelCities\Geo::ApiRoutes();
例如,如果您将它们插入到您的 routes\api.php
中(推荐),则以下URL将被注册
响应始终是Geo类或Collection的JSON表示形式。
为了减少带宽,将返回所有Geo模型属性,除了alternames
、left
、right
和depth
。您可以通过在任何请求中传递一个可选参数来更改此行为。
Vue组件
此包附带一个Vue组件,它可以连接到提供的API,并通过一系列步骤以交互式方式选择位置。抱歉,目前没有实时演示,只有一些截图
步骤1:选择您的位置。下拉列表异步加载
步骤2:到达目的地。显示路径和编辑选择的按钮
步骤3:在表单提交时,将提交几个字段
使用指南
假设您正在使用Webpack编译您的资源,并且已包含vue-app.js
添加到您的应用程序
在您的main vue-app.js文件中添加组件声明
Vue.component('geo-select', require('RELATIVE_PATH_TO/vendor/igaster/laravel_cities/src/vue/geo-select.vue'));
或者,您可以使用以下命令发布组件:
artisan vendor:publish --provider="Igaster\LaravelCities\GeoServiceProvider"
组件将被导出到/resources/LaravelCities/geo-select.vue
,以便您可以进行修改...
编译组件
npm run dev
(或npm run production
)
在blade文件中使用
示例
<form action="post-url" method="POST"> <geo-select></geo-select> <!-- Add more form fields here... --> <input type="submit"> </form>
以下输入将被提交
- geo-id
- geo-name
- geo-long
- geo-lat
- geo-country
- geo-country-code
完整语法
<geo-select prefix = "geo" <!-- change the fields name prefix --> api-root-url = "\api" <!-- Root url for API --> :countries = "[390903,3175395]" <!-- Limit to specific countries (defined by ids) --> :enable-breadcrumb = "true" <!-- Enable/Disable Breadcrumb --> ></geo-select>