How do I use Doctrine2 to work with GeoSpatial Queries using PostGIS?

I wrote an article on my blog, explaining how to use Doctrine 2 (version 2.2+) and Postgis. The article is in French, but the code is PHP, which an international language :

http://web.archive.org/web/20161118060448/http://blog.fastre.info:80/2012/02/doctrine2-2-2-et-types-geographiques/

As you will see, importing data from database to an object need some conversion:

  1. The data are converted to geojson by postgis (json is readable by php, using json_decode function)
  2. The data are transformed into a Point object

And from the object's world to database:

  1. The object Point is converted into WKT. Why WKT and not json ? Because Postgis has a ST_GeogFromWKT function, but not (yet) a ST_GeogFromGeoJson function.
  2. The data are inserted into the database.

I also wrote a custom DQL function class which dealt with the "covered" operation in DQL queries. This is not exactly what you ask, but you may inspire from this and adapt the code.

namespace Progracqteur\WikipedaleBundle\Resources\Doctrine\Functions;

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

/**
*
* @author Julien Fastré <julien arobase fastre point info>
*/
class Covers extends FunctionNode {

    private $polygon = null;
    private $point = null;


    public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) {
        return 'ST_Covers('.$this->polygon->dispatch($sqlWalker).', '.$this->point->dispatch($sqlWalker).')';
    }

    public function parse(\Doctrine\ORM\Query\Parser $parser) {

        $parser->match(Lexer::T_IDENTIFIER);
        $parser->match(Lexer::T_OPEN_PARENTHESIS);

        $this->polygon = $parser->StringExpression();

        $parser->match(Lexer::T_COMMA);

        $this->point = $parser->StringPrimary();

        $parser->match(Lexer::T_CLOSE_PARENTHESIS);

    }
}

and this function is added to doctrine using app/config/config.yml :

        dql:
          string_functions:
            covers: Progracqteur\WikipedaleBundle\Resources\Doctrine\Functions\Covers

Be careful: to use this function, you will have to create other functions which will use the 'ST_FromWKT' function before, and convert your point to WKT in your getSql (using the __toString function ?). I did not need it in my application, so I do not have code for this to present to you.

This is an example of using my function : ($entity->getPolygon() return the postgis's string, without any conversion - i do not need to dealt with a polygon's object in my app.)

$em->createQuery('SELECT p from MyEntity p where covers(:polygon, p.geom) = true)
            ->setParameter('polygon', $entity->getPolygon());

I know this is a little bit old but may help others.

I've found this library:

https://github.com/djlambert/doctrine2-spatial

They support Postgis and MySQL.

The Postgis functions are:

  • ST_Area
  • ST_AsBinary
  • ST_AsText
  • ST_Centroid
  • ST_ClosestPoint
  • ST_Contains
  • ST_ContainsProperly
  • ST_CoveredBy
  • ST_Covers
  • ST_Crosses
  • ST_Disjoint
  • ST_Distance
  • ST_Envelope
  • ST_GeomFromText
  • ST_Length
  • ST_LineCrossingDirection
  • ST_StartPoint
  • ST_Summary