sparefoot / geocoder

几乎完美的 Geocoder PHP 5.4 库。

v3.3.0 2015-12-06 20:17 UTC

README

Build Status Total Downloads Latest Stable Version PHP7 ready

重要:您正在浏览 Geocoder 4.x(尚未发布)的文档。

3.x 版本的文档可在此处找到:[Geocoder 3.x 文档](https://github.com/geocoder-php/Geocoder/blob/3.x/README.md)。

2.x 版本的文档可在此处找到:[Geocoder 2.x 文档](https://github.com/geocoder-php/Geocoder/blob/2.x/README.md)。

Geocoder 是一个 PHP 库,通过提供强大的抽象层来帮助您构建地理感知应用程序。

安装

安装 Geocoder 的推荐方法是使用 Composer

$ composer require willdurand/geocoder

使用

Geocoder 和其配套的 Geocoder Extra 提供了许多 提供商

首先选择符合您需求的提供商。假设您正在寻找的是 GoogleMaps,那么让我们看看如何使用它。在下面的代码片段中,已经选择了 curl 作为 HTTP 层,但这取决于您,因为每个基于 HTTP 的提供商都实现了 PSR-7

$adapter  = new \Http\Adapter\Guzzle6\Client();
$provider = new \Geocoder\Provider\GoogleMaps($adapter);
$geocoder = new \Geocoder\StatefulGeocoder($provider, 'en');

$geocoder->geocode(...);
$geocoder->reverse(...);

Provider 接口有三个方法

  • geocodeQuery(GeocodeQuery $query):AddressCollection
  • reverseQuery(ReverseQuery $query):AddressCollection
  • getName():string

Geocoder 接口扩展了 Provider 接口并公开了两个额外的方法。这将使从 3.x 迁移更加平滑。

  • geocode($streetOrIpAddress)
  • reverse($latitude, $longitude)

地址 & 地址集合

两个 geocode()reverse() 方法都返回一个 Address 对象的集合 (AddressCollection),每个对象提供以下 API

  • getCoordinates() 将返回一个 Coordinates 对象(具有 latitudelongitude 属性);
  • getLatitude() 将返回 latitude 值;
  • getLongitude() 将返回 longitude 值;
  • getBounds() 将返回一个 Bounds 对象(具有 southwestnortheast 属性);
  • getStreetNumber() 将返回 street number/house number 值;
  • getStreetName() 将返回 street name 值;
  • getLocality() 将返回 localitycity
  • getPostalCode() 将返回 postalCodezipcode
  • getSubLocality() 将返回 city districtsublocality
  • getAdminLevels() 将返回一个有序集合 (AdminLevelCollection),其中包含具有 levelnamecode 属性的 AdminLevel 对象。
  • getCountry() 将返回一个具有 namecode 属性的 Country 对象;
  • getCountryCode() 将返回 ISO country 代码;
  • getTimezone() 将返回时区 timezone

AddressCollection 暴露以下方法:

  • count()(此类实现了 Countable 接口);
  • first() 获取第一个 Address 对象;
  • slice($offset, $length = null) 返回从 $offsetlengthAddress 对象;
  • get($index) 使用其 $index 获取 Address 对象;
  • all() 返回所有 Address 对象;
  • getIterator()(此类实现了 IteratorAggregate 接口)。

ProviderAggregator

ProviderAggregator 用于注册多个提供者,以便您可以在稍后决定使用哪个提供者。

<?php

$geocoder = new \Geocoder\ProviderAggregator();

$geocoder->registerProviders([
    new \Geocoder\Provider\GoogleMaps(
        $adapter, $locale, $region, $useSsl
    ),
    new \Geocoder\Provider\GoogleMapsBusiness(
        $adapter, '<CLIENT_ID>', '<PRIVATE_KEY>', $locale, $region, $useSsl
    ),
    new \Geocoder\Provider\Yandex(
        $adapter, $locale, $toponym
    ),
    new \Geocoder\Provider\MaxMind(
        $adapter, '<MAXMIND_API_KEY>', $service, $useSsl
    ),
    new \Geocoder\Provider\ArcGISOnline(
        $adapter, $sourceCountry, $useSsl
    ),
]);

$geocoder->registerProvider(
    new \Geocoder\Provider\Nominatim(
        $adapter, 'http://your.nominatim.server', $locale
    )
);

$geocoder
    ->using('google_maps')
    ->geocode('...');

$geocoder
    ->limit(10)
    ->reverse($lat, $lng);

ProviderAggregator 的 API 是流利的,这意味着您可以编写:

<?php

$addresses = $geocoder
    ->registerProvider(new \My\Provider\Custom($adapter))
    ->using('custom')
    ->limit(10)
    ->geocode('68.145.37.34')
    ;

using() 方法允许您通过名称选择要使用的 provider。当您处理多个提供者时,您可能想选择其中一个。默认行为是使用第一个,但这可能很烦人。

limit() 方法允许您配置返回的最大结果数。根据提供者,您可能不会得到期望的那么多结果,这是一个最大限制,而不是期望的结果数。

TimedGeocoder

TimedGeocoder 类对每个 geocodereverse 调用进行性能分析。因此,您可以轻松地找出每个 geocoder/reverse 调用花费了多少时间/内存。

// configure you geocoder object

$stopwatch = new \Symfony\Component\Stopwatch\Stopwatch();
$geocoder = new \Geocoder\TimedGeocoder($geocoder, $stopwatch);

$geocoder->geocode('Paris, France');

// Now you can debug your application

我们使用底层的 symfony/stopwatch 组件。这意味着,如果您使用 Symfony 框架,geocoder 调用将出现在 Web Profiler 的时间线部分。

HTTP 适配器

为了与地理编码 API 通信,您需要 HTTP 适配器。虽然它在 Geocoder 1.x 和 2.x 库中是部分,但 Geocoder 3.x 及更高版本现在依赖于 PSR-7 标准,该标准定义了如何实现 HTTP 消息。您可以使用任何实现 php-http/client-implementation 的库来发送 HTTP 消息。

要使用 Guzzle 6,您应该运行以下命令

$ composer require php-http/guzzle6-adapter php-http/message

提供商

提供者为您执行地理编码的“黑魔法”(与 API 通信、获取结果、处理错误等),并且非常可配置。

基于地址的提供商

下面将提供有关这些提供者的更多信息。

ArcGISOnline

您可以为 sourceCountry 指定一个值,以将结果限制到这个特定的国家,从而减少请求时间(请注意,这不适用于反向地理编码)。

GeoIP2

需要 数据库文件webservice(表示 GeoIP2),它被注入到 GeoIP2Adapter 中。必须安装 geoip2/geoip2 包。

此提供者只能与相应的 GeoIP2Adapter 一起使用。

<?php

// Maxmind GeoIP2 Provider: e.g. the database reader
$reader   = new \GeoIp2\Database\Reader('/path/to/database');

$adapter  = new \Geocoder\Adapter\GeoIP2Adapter($reader);
$geocoder = new \Geocoder\Provider\GeoIP2($adapter);

$address   = $geocoder->geocode('74.200.247.59')->first();
GoogleMaps

可以指定语言和/或区域。

$geocoder = new \Geocoder\Provider\GoogleMaps(
    $httpAdapter,
    $locale,
    $region,
    $useSsl, // true|false
    $apiKey
);
GoogleMapsBusiness

需要一个有效的 Client ID。私有密钥是可选的。此提供者还支持 SSL,并扩展了 GoogleMaps 提供者。

Mapzen

需要一个有效的 API key。此提供者还支持 SSL。

MaxMindBinary

此提供者需要数据文件,并且必须安装 geoip/geoip 包。

值得注意的是,此提供者存在严重的性能问题,不应在生产环境中使用。有关更多信息,请参阅 问题 #301

Nominatim

需要访问 Nominatim 服务器。有关更多信息,请参阅 Nominatim Wiki 页面

TomTom

默认语言区域设置为en,您可以选择以下语言:deesfritnlplptsv

Yandex

默认语言区域设置为ru-RU,您可以选择以下语言:uk-UAbe-BYen-USen-BRtr-TR。此提供者还可以根据坐标(纬度、经度)反转信息。可以通过精确地名来获得更准确的反向地理编码结果:housestreetmetrodistrictlocality

基于 IP 的提供商

重要:Geocoder Extra库包含更多官方提供者!

区域感知提供商

具有区域意识的提供者公开以下方法

$geocoder->setLocale('xyz');

$locale = $geocoder->getLocale();

链式提供商

Chain提供者是一个特殊的提供者,它接受提供者列表并遍历此列表以获取信息。请注意,它会在提供者返回结果时停止迭代。结果由GoogleMaps返回,因为FreeGeoIpHostIp无法对街道地址进行地理编码。BingMaps被忽略。

$geocoder = new \Geocoder\ProviderAggregator();
$adapter  = new \Http\Adapter\Guzzle6\Client();

$chain = new \Geocoder\Provider\Chain([
    new \Geocoder\Provider\FreeGeoIp($adapter),
    new \Geocoder\Provider\HostIp($adapter),
    new \Geocoder\Provider\GoogleMaps($adapter, 'fr_FR', 'France', true),
    new \Geocoder\Provider\BingMaps($adapter, '<API_KEY>'),
    // ...
]);

$geocoder->registerProvider($chain);

try {
    $geocode = $geocoder->geocode('10 rue Gambetta, Paris, France');
    var_export($geocode);
} catch (Exception $e) {
    echo $e->getMessage();
}

一切正常,祝您使用愉快!

导出器

Geocoder提供了一些导出器,旨在将Address对象转换为标准格式。

GPS eXchange Format (GPX)

GPS eXchange格式旨在共享地理定位数据,如兴趣点、轨迹、路径,以及坐标。Geocoder提供了一个导出器,可以将Address对象转换为符合GPX格式的格式。

假设我们得到了之前看到的$address对象

<?php

$dumper = new \Geocoder\Dumper\Gpx();
$strGpx = $dumper->dump($address);

echo $strGpx;

它将显示

<gpx
    version="1.0"
    creator="Geocoder" version="1.0.1-dev"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.topografix.com/GPX/1/0"
    xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
    <bounds minlat="2.388911" minlon="48.863151" maxlat="2.388911" maxlon="48.863151"/>
    <wpt lat="48.8631507" lon="2.3889114">
        <name><![CDATA[Paris]]></name>
        <type><![CDATA[Address]]></type>
    </wpt>
</gpx>

GeoJSON

GeoJSON是一种用于编码各种地理数据结构的格式。

GeoArray

这是一个简单的PHP数组格式,可用于与自己的编码器一起使用。

Keyhole Markup Language (KML)

Keyhole Markup Language是一种XML表示法,用于在基于互联网的二维地图和三维地球浏览器中表达地理注释和可视化。

Well-Known Binary (WKB)

几何值已知的二进制(WKB)表示法由OpenGIS规范定义。

Well-Known Text (WKT)

已知的文本(WKT)是一种文本标记语言,用于在地图上表示矢量几何对象、空间对象的参考系统和空间参考系统之间的转换。

格式化

一个常见的用途是打印地理编码数据。感谢StringFormatter类,格式化Address对象为字符串非常简单

<?php

// $address is an instance of Address
$formatter = new \Geocoder\Formatter\StringFormatter();

$formatter->format($address, '%S %n, %z %L');
// 'Badenerstrasse 120, 8001 Zuerich'

$formatter->format($address, '<p>%S %n, %z %L</p>');
// '<p>Badenerstrasse 120, 8001 Zuerich</p>'

以下是映射关系

  • 街道号码:%n

  • 街道名称:%S

  • 城市:%L

  • 城市区域:%D

  • 邮编:%z

  • 行政级别名称:%A1%A2%A3%A4%A5

  • 行政级别代码:%a1%a2%a3%a4%a5

  • 国家:%C

  • 国家代码:%c

  • 时区:%T

扩展功能

您可以通过实现Provider接口来编写自己的provider

您可以通过实现Dumper接口来提供自己的dumper

版本控制

Geocoder遵循语义版本化

生命终结

1.x

截至2014年12月,分支1.7不再官方支持,这意味着主要版本1已达到生命终结。最后一个版本是:1.7.1

2.x

截至2014年12月,版本2.x处于功能冻结状态。所有新功能应贡献给3.0及以上版本。最后一个版本是:2.8.1

主要版本 2 将于2015年12月达到生命周期的终点。

稳定版本

版本 3.x 是Geocoder当前的主要稳定版本。

食谱

我们有一个小的食谱,其中您可以找到常见用例的示例。

贡献

请参阅 CONTRIBUTING 文件。

单元测试

为了运行测试套件,请安装开发依赖项

$ composer install --dev

然后,运行以下命令

$ composer test

由于需要API密钥,您将获得一些 跳过的 单元测试。

phpunit.xml.dist 文件重命名为 phpunit.xml,然后取消注释以下行并添加您自己的API密钥

<php>
    <!-- <server name="IPINFODB_API_KEY" value="YOUR_API_KEY" /> -->
    <!-- <server name="BINGMAPS_API_KEY" value="YOUR_API_KEY" /> -->
    <!-- <server name="GEOIPS_API_KEY" value="YOUR_API_KEY" /> -->
    <!-- <server name="MAXMIND_API_KEY" value="YOUR_API_KEY" /> -->
    <!-- <server name="GEONAMES_USERNAME" value="YOUR_USERNAME" /> -->
    <!-- <server name="TOMTOM_MAP_KEY" value="YOUR_MAP_KEY" /> -->
    <!-- <server name="GOOGLE_GEOCODING_KEY" value="YOUR_GEOCODING_KEY" /> -->
    <!-- <server name="OPENCAGE_API_KEY" value="YOUR_API_KEY" /> -->
</php>

您就完成了。

致谢

贡献者行为准则

作为本项目的贡献者和维护者,我们承诺尊重所有通过报告问题、发布功能请求、更新文档、提交拉取请求或补丁以及其他活动做出贡献的人。

我们致力于为所有人提供一个无骚扰的参与体验,无论经验水平、性别、性别认同和表达、性取向、残疾、个人外观、体型、种族、年龄或宗教。

参与者不可接受的行为示例包括使用性语言或图像、侮辱性评论或人身攻击、恶作剧、公开或私下的骚扰、侮辱或其他不专业行为。

项目负责人有权利和义务删除、编辑或拒绝与该行为准则不一致的评论、提交、代码、维基编辑、问题和其他贡献。不遵守行为准则的项目负责人可能会被从项目团队中移除。

可以通过提交问题或联系一个或多个项目负责人来报告滥用、骚扰或其他不可接受的行为。

本行为准则改编自 贡献者契约,版本1.0.0,可在 http://contributor-covenant.org/version/1/0/0/ 查找。

许可证

Geocoder是在MIT许可证下发布的。有关详细信息,请参阅附带LICENSE文件。