This library allows you to use Doctrine with PostGIS, the spatial database extension for PostgreSQL. Both PostGIS 1.5 and 2.x are supported.
Install the latest version with Composer.
composer require jsor/doctrine-postgis
Check the Packagist page for all available versions.
All you have to do is, to register an event subscriber.
use Jsor\Doctrine\PostGIS\Event\ORMSchemaEventSubscriber;
$entityManager->getEventManager()->addEventSubscriber(new ORMSchemaEventSubscriber());
You can also use this library with the DBAL only.
use Jsor\Doctrine\PostGIS\Event\DBALSchemaEventSubscriber;
$connection->getEventManager()->addEventSubscriber(new DBALSchemaEventSubscriber());
If you use Symfony, see the documentation on how to register event subscribers.
A setup could look like this in the services.yml
.
services:
Jsor\Doctrine\PostGIS\Event\ORMSchemaEventSubscriber:
tags:
- { name: doctrine.event_subscriber, connection: default }
It is also recommended to register the DBAL types in the
doctrine section
of the config/packages/doctrine.yaml
config file.
doctrine:
dbal:
types:
geography:
class: 'Jsor\Doctrine\PostGIS\Types\GeographyType'
commented: false
geometry:
class: 'Jsor\Doctrine\PostGIS\Types\GeometryType'
commented: false
raster:
class: 'Jsor\Doctrine\PostGIS\Types\RasterType'
commented: false
By default, Symfony's console commands make:migrations
and doctrine:migrations:diff
would try to drop everything in the tiger, tiger_data and topology schemas. This can be avoided by using the schema_filter
option to the aforementioned config/packages/doctrine.yaml
file, e.g. like this:
doctrine:
dbal:
schema_filter: ~^(?!tiger)(?!topology)~
The above value (~^(?!tiger)(?!topology)~
) uses lookahead regular expressions to filter out all the namespaced tables beginning with "tiger" and "topology".
See also: Manual tables in Symfony Docs.
In the aforementioned config/packages/doctrine.yaml
file, please add the following lines:
doctrine:
dbal:
mapping_types:
_text: string
Once the event subscriber is registered, you can use the column types
geometry
and geography
in your property mappings (please read the
PostGIS docs
to understand the difference between these two types).
/** @Entity */
class MyEntity
{
/**
* @Column(type="geometry")
*/
private $geometry;
/**
* @Column(type="geography")
*/
private $geography;
}
There are 2 options you can set to define the geometry.
geometry_type
This defines the type of the geometry, likePOINT
,LINESTRING
etc. If you omit this option, the generic typeGEOMETRY
is used.srid
This defines the Spatial Reference System Identifier (SRID) of the geometry.
/** @Entity */
class MyEntity
{
/**
* @Column(type="geometry", options={"geometry_type"="POINT"})
*/
private $point;
/**
* @Column(type="geometry", options={"geometry_type"="POINTZM"})
*/
private $point4D;
/**
* @Column(type="geometry", options={"geometry_type"="POINT", "srid"=3785})
*/
private $pointWithSRID;
}
Values provided for the properties must be in the WKT format. Please note, that the values returned from database may differ from the values you have set. The library uses ST_AsEWKT to retain as much information as possible (like SRID's). Read more in the PostGIS docs.
$entity = new MyEntity();
$entity->setPoint('POINT(37.4220761 -122.0845187)');
$entity->setPoint4D('POINT(1 2 3 4)');
$entity->setPointWithSRID('SRID=3785;POINT(37.4220761 -122.0845187)');
You can define spatial indexes for your geometry columns.
Simply set the spatial
flag for indexes.
/**
* @Entity
* @Table(
* indexes={
* @Index(name="idx_point", columns={"point"}, flags={"spatial"}),
* @Index(name="idx_polygon", columns={"polygon"}, flags={"spatial"})
* }
* )
*/
class MyEntity
{
}
This uses index flags introduced in Doctrine ORM 2.5.
If you need to support Doctrine versions < 2.5, you have to define which indexes should be spatial indexes through the table options.
/**
* @Entity
* @Table(
* options={"spatial_indexes"={"idx_point", "idx_polygon"}},
* indexes={
* @Index(name="idx_point", columns={"point"}),
* @Index(name="idx_polygon", columns={"polygon"})
* }
* )
*/
class MyEntity
{
}
Full support for the ORM Schema Tool and the DBAL Schema Manager is provided.
Most PostGIS functions are also
available for the DQL under the Jsor\Doctrine\PostGIS\Functions
namespace.
For a full list of all supported functions, see the Function Index.
You can register the functions with a Doctrine\ORM\Configuration
instance.
$configuration = new Doctrine\ORM\Configuration();
$configuration->addCustomStringFunction(
'ST_Distance',
'Jsor\Doctrine\PostGIS\Functions\ST_Distance'
);
$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);
There's a convenience Configurator class which can be used to register all at once.
$configuration = new Doctrine\ORM\Configuration();
Jsor\Doctrine\PostGIS\Functions\Configurator::configure($configuration);
$dbParams = [/***/];
$entityManager = Doctrine\ORM\EntityManager::create($dbParams, $configuration);
If you use Symfony, you need to setup the functions in the
doctrine section
of the config.yml
.
doctrine:
orm:
dql:
string_functions:
ST_Distance: Jsor\Doctrine\PostGIS\Functions\ST_Distance
Copyright (c) 2014-2019 Jan Sorgalla. Released under the MIT License.