@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 '@'
  • Вопрос задан
  • 2486 просмотров
Решения вопроса 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
Нравится делать что-то интересное и полезное.
Иван, и все-таки было бы интересно увидеть.
Сейчас работаю над небольшим проектом, сильно нужен красивый алгоритм
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы