jsor / doctrine-postgis
使用PostGIS和Doctrine实现空间和地理数据。
Requires
- php: ^8.0
- doctrine/dbal: ^2.13 || ^3.1
Requires (Dev)
- doctrine/orm: ^2.9
- friendsofphp/php-cs-fixer: ^3.13
- phpunit/phpunit: ^9.5
- symfony/doctrine-bridge: ^5.4 || ^6.0
- symfony/doctrine-messenger: ^5.4 || ^6.0
- vimeo/psalm: ^5.9
Suggests
- doctrine/orm: For using with the Doctrine ORM
README
此库允许您使用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文档。
属性映射
注册事件订阅者后,可以在属性映射中使用列类型geometry
和geography
(请阅读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
这定义了几何形状的类型,如POINT
、LINESTRING
等。如果您省略此选项,则使用通用类型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 { }
模式工具
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可以添加一些新模式,如topology
、tiger
和tiger_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许可证下发布。