nolazybits / propel2-geocodable-behavior
GeocodableBehavior 帮助您构建地理感知应用程序。当模型保存时,它会自动对您的模型进行地理编码,使您能够按位置搜索并计算记录之间的距离。
Requires
- php: >=5.2.4
- propel/propel: ~2.0@dev
- willdurand/geocoder: ~2.3
README
GeocodableBehavior 帮助您构建地理感知应用程序。当模型保存时,它会自动对您的模型进行地理编码,使您能够按位置搜索并计算记录之间的距离。
此行为使用 Geocoder,Geocoder PHP 5.3 库,并需要 Propel 2.0-dev 及以上版本。
安装
您需要将其添加到 composer。
Propel 会自动将其添加到可用的行为列表中
{
requires:
{
zeflasher/propel2-geocodable-behavior": "dev-master"
}
}
用法
只需在您的 schema.xml
文件中添加以下 XML 标签
<behavior name="geocodable" />
基本上,该行为将在您的模型中添加
- 两列新列(
latitude
和longitude
); - 四个新的 ActiveRecord API 方法(
getDistanceTo()
、isGeocoded()
、getCoordinates()
和setCoordinates()
); - 三个新的 ActiveQuery API 方法(
withDistance()
、filterByDistanceFrom()
、filterNear()
)。
ActiveRecord API
getDistanceTo()
返回当前对象和给定对象之间的距离。该方法接受两个参数
- 一个地理编码对象;
- 一个测量单位(在地理编码模型的
Peer
类中定义的KILOMETERS_UNIT
、MILES_UNIT
或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
接受三个参数
- 一个模型对象;
- 距离值;
- 一个测量单位(在地理编码模型的
Peer
类中定义的KILOMETERS_UNIT
、MILES_UNIT
或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
的类,它必须返回密钥。
默认情况下,默认的地理编码器 provider
是 YahooProvider
,因此您需要填写一个API密钥。
如果您想使用其他提供商,您需要设置一个新参数
<parameter name="geocoder_provider" value="\Geocoder\Provider\HostIpProvider" />
阅读 Geocoder 文档,以了解更多关于提供商的信息。
此配置将在您的模型中添加一个新列: ip_address
。您可以使用以下参数更改此列的名称
<parameter name="ip_column" value="ip" />
现在,行为将使用 ip_address
的值来填充 latitude
和 longitude
列,多亏了 Geocoder。
基于地址的地理编码###
要启用基于地址的地理编码,请添加以下配置
<behavior name="geocodable"> <parameter name="geocode_address" value="true" /> <parameter name="geocoder_api_key" value="<API_KEY>" /> </behavior>
默认情况下,默认的地理编码器 provider
是 YahooProvider
,因此您需要填写一个API密钥,但请注意,根据您选择的提供商,这可能是一个可选参数。
如果您想使用其他提供商,您需要设置一个新参数
<parameter name="geocoder_provider" value="\Geocoder\Provider\GoogleMapsProvider" />
阅读 Geocoder 文档,以了解更多关于提供商的信息。
基本上,行为会寻找名为街道、地区、邮编和国家等属性。它试图用它们制作一个完整的地址。像往常一样,您可以调整此参数,添加代表完整街道地址的属性列表。
<parameter name="address_columns" value="street,locality,region,postal_code,country" />
这些参数将连接并使用逗号分隔,以形成一个街道地址。此地址将用于获取 latitude
和 longitude
值。
现在,每次您保存对象时,由于 Geocoder,两个列 latitude
和 longitude
都会被填充。
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="11" /> <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
Xavier Martin zeflasher+geocodable@gmail.com