tec4/geocode-bundle

此包的最新版本(dev-master)没有可用的许可信息。

Symfony2 地理编码包

安装: 160

依赖者: 0

建议者: 0

安全性: 0

星标: 0

关注者: 2

分支: 0

开放问题: 0

类型:symfony-bundle

dev-master 2019-06-01 16:50 UTC

This package is auto-updated.

Last update: 2024-09-29 04:19:44 UTC


README

此包提供围绕 BazingaGeocoderBundle 的包装。它提供了一种简单的方法将纬度/经度坐标实现到您的 doctrine 模型中。

安装

步骤 1: 下载包

打开命令行控制台,进入您的项目目录,并执行以下命令以下载此包的最新稳定版本

$ composer require tec4/geocode-bundle

此命令需要您全局安装了 Composer,具体请参考 Composer 文档的安装章节

步骤 2: 启用包

然后,在您的项目 app/AppKernel.php 文件中添加以下行以启用此包

<?php
// app/AppKernel.php

// ...
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
            // ...

            new Tec4\GeocodeBundle\Tec4GeocodeBundle(),
        );

        // ...
    }

    // ...
}

按照其文档安装 BazingaGeocoderBundle

步骤 3: 在模型上实现接口

将接口添加到您的模型(实体/文档)中。

如果您希望获得接口所需的大部分属性和属性,请使用预先创建的 traits。

必须在代码中实现名为 getGeocodeableName 的新方法

<?php

namespace Acme\SomeBundle\Model;

use Tec4\GeocodeBundle\Model\GeocodeableInterface;
use Tec4\GeocodeBundle\Model\GeocodeableTraits;

class NewClass implements GeocodeableInterface
{
    /**
     * Include properties and accessors for geocoding
     */
    use GeocodeableTraits;
    
    // ...
    private $address;
        
    // ...
    
    /**
     * {@inheridoc}
     */
    public function getGeocodeableName()
    {
        // Return some geocodeable, perhaps something like: $this->getAddress();
        // Example location would be: 1234 Some Street #1, Some City, Some State
        // Can be any geocodeable location
        return $this->address;
    }
}

用法

当某些字段更改或实体尚未进行地理编码时,自动更新实体

有关更多信息,请阅读 symfony 关于 注册事件监听器和订阅者 的文档

<?php

namespace Acme\SomeBundle\EventListener;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Bazinga\Bundle\GeocoderBundle\Geocoder\LoggableGeocoder;
use Tec4\GeocodeBundle\Model\GeocodeableInterface;
use Tec4\GeocodeBundle\Service\ModelGeocoder;

/**
 * Hook into Doctrine prePersist & preUpdate events
 * to update geocode specific fields if information
 * about an entity's location has changed.
 */
class GeocodeEntitySubscriber implements EventSubscriber
{ 
    /** @var LoggableGeocoder $geocoder */
    private $geocoder;

    /** @var ModelGeocoder $modelGeocoder */
    private $modelGeocoder;

    /**
     * @param LoggableGeocoder $geocoder
     * @param ModelGeocoder    $modelGeocoder
     */
    public function __construct(LoggableGeocoder $geocoder, ModelGeocoder $modelGeocoder)
    {
        $this->geocoder = $geocoder;
        $this->modelGeocoder = $modelGeocoder;
    }

    public function getSubscribedEvents()
    {
        return array(
            'prePersist',
            'preUpdate',
        );
    }

    /**
     * Geocode entity if it has not already been done
     *
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof GeocodeableInterface) {
            if (!$entity->isGeocoded()) {
                $this->geocode($entity);
            }
        }
    }

    /**
     * Geocode entity if has yet to be done or if location has changed
     *
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        if (($entity = $args->getEntity()) instanceof GeocodeableInterface) {
            if (!$entity->isGeocoded() || $args->hasChangedField('address')) {
                $this->geocode($entity);

                // Need to recompute changeset to update correctly
                $em = $args->getEntityManager();
                $uow = $em->getUnitOfWork();
                $meta = $em->getClassMetadata(get_class($entity));
                $uow->recomputeSingleEntityChangeSet($meta, $entity);
            }
        }
    }

    /**
     * Handle geocoding of entity
     *
     * @param GeocodeableInterface $entity
     */
    public function geocode(GeocodeableInterface $entity)
    {
        try {
            $this->modelGeocoder->updateModel($entity, $this->geocoder, true);
        } catch (\Exception $e) {
            // Perhaps do something here
            // Add message to flash bag?
        }
    }
}

配置服务

# src/Acme/SomeBundle/Resources/config/services.yml
services:
    acme.listener.geocode_entities:
        class: Acme\SomeBundle\EventListener\GeocodeEntitySubscriber
        arguments:
            - @bazinga_geocoder.geocoder
            - @tec4_geocode.model_geocoder
        tags:
            - { name: doctrine.event_subscriber, connection: default }

通过命令批量更新

除参数外,所有选项都是可选的。但是,类名是必需的。

php app/console tec4:geocode "Acme\\SomeBundle\\Model\\ClasName" --limit=100 --geocode_provider="google_maps"

待办事项

  1. 添加更好的日志记录(扩展日志记录器,实现自己的解决方案/通道以进行日志记录等)