jsor/doctrine-postgis

使用PostGIS和Doctrine实现空间和地理数据。

v2.3.0 2024-02-20 22:32 UTC

This package is auto-updated.

Last update: 2024-09-09 07:04:34 UTC


README

Build Status Coverage Status

此库允许您使用Doctrine (ORM或DBAL) 与PostGIS一起,它是PostgreSQL的空间数据库扩展。

支持版本

以下表格显示了此库官方支持的版本。

安装

使用Composer安装最新版本。

composer require jsor/doctrine-postgis

请查看Packagist页面以获取所有可用的版本。

设置

要使用Doctrine ORM与该库一起使用,请注册ORMSchemaEventSubscriber事件订阅者。

use Jsor\Doctrine\PostGIS\Event\ORMSchemaEventSubscriber;

$entityManager->getEventManager()->addEventSubscriber(new ORMSchemaEventSubscriber());

要仅使用DBAL,请注册DBALSchemaEventSubscriber事件订阅者。

use Jsor\Doctrine\PostGIS\Event\DBALSchemaEventSubscriber;

$connection->getEventManager()->addEventSubscriber(new DBALSchemaEventSubscriber());

Symfony

有关将此库集成到Symfony项目中的信息,请参阅专门的Symfony文档

属性映射

注册事件订阅者后,可以在属性映射中使用列类型geometrygeography(请阅读PostGIS文档了解这两种类型之间的区别)。

use Doctrine\ORM\Mapping as ORM;
use Jsor\Doctrine\PostGIS\Types\PostGISType;

#[ORM\Entity]
class MyEntity
{
    #[ORM\Column(type: PostGISType::GEOMETRY)]
    private string $geometry;

    #[ORM\Column(type: PostGISType::GEOGRAPHY)]
    private string $geography;
}

配置几何形状有两种选项。

  • geometry_type 这定义了几何形状的类型,如POINTLINESTRING等。如果您省略此选项,则使用通用类型GEOMETRY
  • srid 这定义了几何形状的空间参考系统标识符(SRID)。

示例

use Doctrine\ORM\Mapping as ORM;
use Jsor\Doctrine\PostGIS\Types\PostGISType;

#[ORM\Entity]
class MyEntity
{
    #[ORM\Column(
        type: PostGISType::GEOMETRY, 
        options: ['geometry_type' => 'POINT'],
    )]
    public string $point;

    #[ORM\Column(
        type: PostGISType::GEOMETRY, 
        options: ['geometry_type' => 'POINTZM'],
   )]
    public string $point4D;

    #[ORM\Column(
        type: PostGISType::GEOMETRY, 
        options: ['geometry_type' => 'POINT', 'srid' => 3785],
    )]
    public string $pointWithSRID;

    public function __construct(
        string $point,
        string $point4D,
        string $pointWithSRID,
    ) {
        $this->point = $point;
        $this->point4D = $point4D;
        $this->pointWithSRID = $pointWithSRID;
    }
}

为属性提供的值必须以WKT格式提供。请注意,数据库返回的值可能与您设置的值不同。此库使用ST_AsEWKT尽可能保留尽可能多的信息(如SRID)。有关更多信息,请参阅PostGIS文档

示例

$entity = new MyEntity(
    point: 'POINT(-122.0845187 37.4220761)',
    point4D: 'POINT(1 2 3 4)',
    pointWithSRID: 'SRID=3785;POINT(-122.0845187 37.4220761)',
);

空间索引

可以通过设置spatial标志为几何字段定义空间索引

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
#[ORM\Index(
    fields: ['pointWithSRID'],
    flags: ['spatial'],
)]
class MyEntity
{
}

模式工具

提供了对ORM模式工具DBAL模式管理器的完整支持。

DQL函数

大多数PostGIS函数也作为Jsor\Doctrine\PostGIS\Functions命名空间下的Doctrine查询语言(DQL)可用。

有关所有支持函数的完整列表,请参阅函数索引

请参阅专门的Symfony文档了解如何使用Symfony配置这些函数。

函数必须使用Doctrine\ORM\Configuration实例进行注册。

$configuration = new Doctrine\ORM\Configuration();

$configuration->addCustomStringFunction(
    'ST_Within',
    Jsor\Doctrine\PostGIS\Functions\ST_Within::class
);

$configuration->addCustomNumericFunction(
    'ST_Distance',
    Jsor\Doctrine\PostGIS\Functions\ST_Distance::class
);

$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);

有一个便捷的Configurator类,可以一次性注册所有函数。

$configuration = new Doctrine\ORM\Configuration();

Jsor\Doctrine\PostGIS\Functions\Configurator::configure($configuration);

$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);

已知问题

请阅读专门的Symfony文档,了解如何使用Symfony处理这些问题。

PostGIS模式排除

由于PostGIS可以添加一些新模式,如topologytigertiger_data,您可能希望排除它们,使Doctrine不处理它们。

这可以通过配置模式资产过滤器来实现。

$configuration = new Doctrine\ORM\Configuration();

$configuration->setSchemaAssetsFilter(static function ($assetName): bool {
     if ($assetName instanceof AbstractAsset) {
         $assetName = $assetName->getName();
     }

     return (bool) preg_match('/^(?!tiger)(?!topology)/', $assetName);
});

$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);

未知数据库类型

有时,模式工具会遇到它无法处理的数据库类型。一个常见的例子是

Doctrine\DBAL\Exception: Unknown database type _text requested, Doctrine\DBAL\Platforms\PostgreSQL100Platform may not support it.

要解决这个问题,可以将未知数据库类型映射到已知类型。

$configuration = new Doctrine\ORM\Configuration();

$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);

$entityManager->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('_text', 'string');

注意:此类型不适合用于实体映射。它只是防止模式工具在数据库检查期间抛出“未知数据库类型...”异常。

如果您想在实体中使用此类型,您必须配置真实数据库类型,例如使用PostgreSQL for Doctrine包。

运行测试

包含了一个简单的Docker设置,用于运行测试套件以针对不同的PostgreSQL / PostGIS组合进行测试。

这里的所有命令都应该从项目根目录运行。

首先,构建PHP容器。这必须只做一次。

./docker/build-php.sh

使用Composer安装依赖项。

./docker/run-php.sh composer install

接下来,启动数据库容器。

docker compose -f ./docker/docker-compose.yml up -d

有一些快捷脚本可用于在连接到特定数据库容器的PHP容器内执行命令。

脚本名称遵循run-<POSTGRESQL_VERSION>-<POSTGIS_VERSION>.sh模式。

要针对PostgreSQL 13和PostGIS 3.1运行测试套件,请使用脚本./docker/run-13-31.sh

./docker/run-13-31.sh vendor/bin/phpunit --exclude-group=postgis-3.0

注意,我们在此排除针对PostGIS 3.0的测试。当针对PostGIS 3.0运行测试时,排除3.1的测试。

./docker/run-13-30.sh vendor/bin/phpunit --exclude-group=postgis-3.1

许可证

版权所有(c)2014-2024 Jan Sorgalla。在MIT许可证下发布。