willdurand / propel-geocodable-behavior
GeocodableBehavior 帮助您构建地理感知应用程序。在保存模型时自动对其进行地理编码,使您能够通过位置进行搜索并计算记录之间的距离。
Requires
- php: >=5.2.4
- propel/propel1: ~1.6,>=1.6.4
- willdurand/geocoder: ~2.3
README
GeocodableBehavior 帮助您构建地理感知应用程序。在保存模型时自动对其进行地理编码,使您能够通过位置进行搜索并计算记录之间的距离。
此行为使用 Geocoder,Geocoder PHP 5.3 库,并需要 Propel 1.6.4-dev 及以上版本。
安装
选择 GeocodableBehavior.php
文件,并将其放在 src/
目录中,然后向您的 propel.ini
或 build.properties
配置文件中添加以下行
propel.behavior.geocodable.class = path.to.GeocodableBehavior
用法
只需在您的 schema.xml
文件中添加以下 XML 标签
<behavior name="geocodable" />
基本上,行为将为您的模型添加以下内容
- 两个新列(
latitude
和longitude
); - 四个新方法到 ActiveRecord API(
getDistanceTo()
、isGeocoded()
、getCoordinates()
和setCoordinates()
); - 三个新方法到 ActiveQuery API(
withDistance()
、filterByDistanceFrom()
和filterNear()
)。
ActiveRecord API
getDistanceTo()
返回当前对象与给定对象之间的距离。该方法接受两个参数
- 一个地理编码对象;
- 一个测量单位(
KILOMETERS_UNIT
、MILES_UNIT
或在地理编码模型类的Peer
类中定义的NAUTICAL_MILES_UNIT
)。
isGeocoded()
返回一个布尔值,表示对象是否已被地理编码。
getCoordinates()
、setCoordinates()
允许快速设置/获取纬度和经度值。
ActiveQuery API
withDistance()
接受三个参数
- 一个纬度值;
- 一个经度值;
- 一个测量单位(在地理编码模型类的
Peer
类中定义的KILOMETERS_UNIT
、MILES_UNIT
或NAUTICAL_MILES_UNIT
);
它将在当前查询中添加一个 Distance
列,并返回自身以实现流畅的接口。示例用法:结合 orderByDistance()
和 limit()
返回最接近的匹配项。
filterByDistanceFrom()
接受五个参数
- 一个纬度值;
- 一个经度值;
- 一个距离值;
- 一个测量单位(在地理编码模型类的
Peer
类中定义的KILOMETERS_UNIT
、MILES_UNIT
或NAUTICAL_MILES_UNIT
); - 一个比较符号(默认值为
Criteria::LESS_THAN
)。
它将在当前查询中添加一个基于距离的过滤器,并返回自身以实现流畅的接口。
filterNear
接受三个参数
- 一个模型对象;
- 一个距离值;
- 一个测量单位(
KILOMETERS_UNIT
、MILES_UNIT
或在地理编码模型类的Peer
类中定义的NAUTICAL_MILES_UNIT
)。
自动地理编码
在这个步骤中,您必须自行填写两个列(latitude
和 longitude
)。这难道不是很实用吗?
自动地理编码来拯救!有两种自动方式来获取地理编码信息
- 使用 IP 地址;
- 使用街道地址。
它提供了一个 geocode()
方法,可以自动更新位置值。为防止修改时自动填充,只需将 auto_update
属性设置为 false。
此方法返回一个 ResultInterface
对象,因此您可以重写此方法,根据您的模型填充更多字段
<?php class MyObject extends BaseMyObject { // ... /** * {@inheritdoc} */ public function geocode() { if (null !== $result = parent::geocode()) { if ($city = $result->getCity()) { $this->setCity($city); } } return $result; } }
注意:您可以使用这两个方法同时使用。
基于 IP 的地理编码
要启用基于 IP 的地理编码,请将以下配置添加到您的 schema.xml
文件中
<behavior name="geocodable"> <parameter name="geocode_ip" value="true" /> <parameter name="geocoder_api_key" value="<API_KEY>" /> <parameter name="geocoder_api_key_provider" value="<API_KEY_PROVIDER>" /> </behavior>
geocoder_api_key_provider
可以是返回 API 密钥的静态方法。格式为 class()->method()
或 class()->method()->subMethod()
的类方法,或者实现 getGoogleMapsKey
的类,该类必须返回密钥。
默认情况下,默认的 Geocoder provider
是 YahooProvider
,因此您需要填写一个 API 密钥。
如果您想使用其他提供商,您需要设置新的参数
<parameter name="geocoder_provider" value="\Geocoder\Provider\HostIpProvider" />
阅读 Geocoder 文档以了解更多有关提供商的信息。
此配置将在您的模型中添加一个新列:ip_address
。您可以使用以下参数更改此列的名称
<parameter name="ip_column" value="ip" />
现在,行为将使用 ip_address
值通过 Geocoder 来填充 latitude
和 longitude
列
基于地址的地理编码
要启用基于地址的地理编码,请添加以下配置
<behavior name="geocodable"> <parameter name="geocode_address" value="true" /> <parameter name="geocoder_api_key" value="<API_KEY>" /> </behavior>
默认情况下,默认的 Geocoder provider
是 YahooProvider
,因此您需要填写一个 API 密钥,但请注意,这取决于您选择的提供商,是一个可选参数。
如果您想使用其他提供商,您需要设置新的参数
<parameter name="geocoder_provider" value="\Geocoder\Provider\GoogleMapsProvider" />
阅读 Geocoder 文档以了解更多有关提供商的信息。
基本上,行为会查找名为 street、locality、region、fpostal_code 和 country 的属性。它试图使用这些属性创建一个完整的地址。像往常一样,您可以调整此参数以添加代表完整街道地址的自己的属性列表
<parameter name="address_columns" value="street,locality,region,postal_code,country" />
这些参数将连接起来,并用逗号分隔,以形成一个街道地址。此地址将用于获取 latitude
和 longitude
值。
现在,每次您保存对象时,latitude
和 longitude
这两列都会通过 Geocoder 填充。
HTTP 适配器
Geocoder 提供了可以通过行为配置的 HTTP 适配器。默认情况下,此行为使用 CurlHttpAdapter
。
如果您想使用其他 adapter
,您需要使用以下参数
<parameter name="geocoder_adapter" value="\Geocoder\HttpAdapter\BuzzHttpAdapter" />
阅读 Geocoder 文档以了解更多有关适配器的信息。
参数
<behavior name="geocodable"> <parameter name="auto_update" value="true" /> <parameter name="latitude_column" value="latitude" /> <parameter name="longitude_column" value="longitude" /> <parameter name="type" value="DOUBLE" /> <parameter name="size" value="10" /> <parameter name="scale" value="8" /> <!-- IP-Based Geocoding --> <parameter name="geocode_ip" value="false" /> <parameter name="ip_column" value="ip_address" /> <!-- Address-Based Geocoding --> <parameter name="geocode_address" value="false" /> <parameter name="address_columns" value="street,locality,region,postal_code,country" /> <!-- Geocoder --> <parameter name="geocoder_provider" value="\Geocoder\Provider\YahooProvider" /> <parameter name="geocoder_adapter" value="\Geocoder\HttpAdapter\CurlHttpAdapter" /> <parameter name="geocoder_api_key" value="false" /> <parameter name="geocoder_api_key_provider" value="false" /> </behavior>
这是默认配置。
致谢
William Durand william.durand1@gmail.com