我们得到了以下实体:GeoShape(抽象、id、纬度和经度)、GeoCircle(只是一个半径)和GeoPolygon(只是一列多边形)。
现在我想用这样的东西查询所有形状:
if polygon is not null then
return ST_CONTAINS(polygon, ...)
else lat,lng in circle then
return in cirlce
但我得到的是:
if polygon is not null and ST_CONTAINS(polygon, ...) then
return true
else lat,lng in circle then
return in cirlce
我试图创建以下querybuilder,但无法存档我想要的内容:
$queryBuilder
->join(sprintf('%s.geoShape', $alias), 'geoShape')
->where($queryBuilder->expr()->andX(
$queryBuilder->expr()->isNotNull('polygon'),
$queryBuilder->expr()->eq('ST_CONTAINS(polygon, Point(:longitude, :latitude))', true)
))
// thats my problem. i don't know how to do the else case
->orWhere('
6371000 * acos(
cos(
radians( :latitude )
) * cos(
radians( geoShape.center.latitude )
) * cos(
radians( geoShape.center.longitude ) - radians( :longitude )
) + sin(
radians( :latitude )
) * sin(
radians( geoShape.center.latitude )
)
) <= :radius
')
->setParameters(
array(
'latitude' => $location->getLatitude(),
'longitude' => $location->getLongitude(),
'radius' => $radius
)
);
return $queryBuilder;
多边形必须比圆更重要。如果位置不在多边形中,则查询应停止,不检查圆。仅当未设置多边形时。
我找到了一个解决方案。现在我只问两种情况下的类型。
$qb
->join(sprintf('%s.geoShape', $alias), 'shape')
->leftJoin(GeoPolygon::class, 'p', Join::WITH, 'shape.id = p.id')
->leftJoin(GeoCircle::class, 'c', Join::WITH, 'shape.id = c.id')
->where($qb->expr()->andX(
$qb->expr()->isInstanceOf('shape', GeoPolygon::class),
$qb->expr()->eq('ST_CONTAINS(p.polygon, Point(:longitude, :latitude))', true)
))
->orWhere($qb->expr()->andX(
$qb->expr()->isInstanceOf('shape', GeoCircle::class),
$qb->expr()->lte('
6371000 * acos(
cos(
radians( :latitude )
) * cos(
radians( shape.center.latitude )
) * cos(
radians( shape.center.longitude ) - radians( :longitude )
) + sin(
radians( :latitude )
) * sin(
radians( shape.center.latitude )
)
)
', $radius)
))
->setParameters(
array(
'latitude' => $location->getLatitude(),
'longitude' => $location->getLongitude()
)
);
return $qb;