@antonowano
Профессиональный самоучка

Как найти в БД объекты лежащие в заданном на карте многоугольнике?

Имеются координаты всех точек многоугольника.
Поиск осуществляется с помощью MBRContains в MySQL (или есть другие решения?).
Как реализовать это на базе SYNFONY2 и DOCTRINE2?
Пока, вот что:
$rsm = new ResultSetMapping();
$coords = '('. implode('),(', $value) .')';
$result = $this->getEntityManager()->createNativeQuery('SET @polygon = GeomFromText("Polygon('. $coords .')");', $rsm);
$this->query->andWhere('MBRContains(@polygon, GeomFromText("Point(offer.latitude, offer.longitude)")) = TRUE');

$value - массив координат
В результате ошибка:
Error: Expected StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression, got '@'
  • Вопрос задан
  • 2483 просмотра
Решения вопроса 1
@antonowano Автор вопроса
Профессиональный самоучка
Долгими мучениями всё-таки сделал:
<?php

namespace AppBundle\DQL;

use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\Lexer;

/**
 * MBRContainsFunction ::= "MBRContains" "(" StringPrimary ", " StringExpression ", " StringExpression ")"
 */
class MBRContainsFunction extends FunctionNode
{
    public $polygonExpression = null;
    public $pointCordOne = null;
    public $pointCordTwo = null;

    public function getSql(SqlWalker $sqlWalker)
    {
        $returnString = 'MBRContains(GeomFromText(' . $this->polygonExpression->dispatch($sqlWalker) . '), '.
            'Point(' . $this->pointCordOne->dispatch($sqlWalker) .', '. $this->pointCordTwo->dispatch($sqlWalker) .'))';

        return $returnString;
    }

    public function parse(Parser $parser)
    {
        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);
        $this->polygonExpression = $parser->StringPrimary();
        $parser->match(Lexer::T_COMMA);
        $this->pointCordOne = $parser->StringExpression();
        $parser->match(Lexer::T_COMMA);
        $this->pointCordTwo = $parser->StringExpression();
        $parser->match(Lexer::T_CLOSE_PARENTHESIS);
    }
}

Использование:
$coords = '123,123 200,200 123,200 123,123';
$this->createQueryBuilder('offer')
       ->andWhere('MBRContains(:coords, offer.latitude, offer.longitude) = TRUE')
       ->setParameter('coords', 'Polygon(('. $coords .'))');
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
VladimirZhid
@VladimirZhid
Нравится делать что-то интересное и полезное.
Иван, и все-таки было бы интересно увидеть.
Сейчас работаю над небольшим проектом, сильно нужен красивый алгоритм
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы