确保您的 postgresql 服务器上安装了 postgis 扩展。
通过 Composer 安装包。
composer require jsor/doctrine-postgis
将类型添加到doctrine-bundle 的配置中。
Example:
# app/config/config.yml
doctrine:
orm:
# [..]
entity_managers:
default:
dql:
string_functions:
Geometry: Jsor\Doctrine\PostGIS\Functions\Geometry
Geography: Jsor\Doctrine\PostGIS\Functions\Geography
ST_Distance: Jsor\Doctrine\PostGIS\Functions\ST_Distance
ST_Distance_Sphere: Jsor\Doctrine\PostGIS\Functions\ST_Distance_Sphere
ST_DWithin: Jsor\Doctrine\PostGIS\Functions\ST_DWithin
ST_GeomFromText: Jsor\Doctrine\PostGIS\Functions\ST_GeomFromText
ST_GeographyFromText: Jsor\Doctrine\PostGIS\Functions\ST_GeographyFromText
ST_Transform: Jsor\Doctrine\PostGIS\Functions\ST_Transform
ST_Point: Jsor\Doctrine\PostGIS\Functions\ST_Point
ST_SetSRID: Jsor\Doctrine\PostGIS\Functions\ST_SetSRID
ST_AsEWKT: Jsor\Doctrine\PostGIS\Functions\ST_AsEWKT
创建一个实体:
namespace My\Entity;
class GeoLocation
{
protected $latitude;
protected $longitude;
protected $point;
public function __construct($latitude, $longitude)
{
$this->longitude = $longitude;
$this->latitude = $latitude;
$this->setPoint();
}
protected function setPoint()
{
$this->point = sprintf(
'POINT(%f %f)',
(string)$this->longitude,
(string)$this->latitude
);
}
public function getPoint()
{
return $this->point;
}
public function getLatitude()
{
return (float) $this->latitude;
}
public function getLongitude()
{
return (float) $this->longitude;
}
}
为您的实体添加映射:
My\Entity\GeoLocation:
type: 'entity'
indexes:
idx_point:
columns:
- 'point'
flags:
- 'spatial'
id:
id:
type: integer
generator:
strategy: AUTO
fields:
longitude:
nullable: true
type: 'decimal'
precision: 9
scale: 6
latitude:
nullable: true
type: 'decimal'
precision: 8
scale: 6
point:
nullable: true
type: 'geography'
options:
geometry_type: 'POINT'
srid: 4326
更新您的数据库架构:
app/console doctrine:schema:update [--force]
现在节省一些积分...
最后使用您的学说存储库中的 postgis 类型:
public function findByDistanceFrom($latitude, $longitude, $distanceInMeters)
{
$qb = $this->createQueryBuilder('geolocation');
$pointFrom = 'Geography(ST_SetSRID(ST_Point(geolocation.longitude, geolocation.latitude), 4326))';
$pointTo = 'Geography(ST_SetSRID(ST_Point(:longitude, :latitude), 4326))';
$qb
->where( $qb->expr()->eq("ST_DWithin($pointFrom, $pointTo, :distance_in_meters)", $qb->expr()->literal(true) ) )
->setParameter('latitude', $latitude)
->setParameter('longitude', $longitude)
->setParameter('distance_in_meters', $distanceInMeters)
;
return $qb
->getQuery()
->getResult()
;
}