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

走远了吗. 提交于 2020-01-22 12:44:07

问题


I have a public facing app that is based on Postgres and PostGIS.

I have tried Googling for hours but have been unable to find any documentation that can show some basic geospatial stuff like getting distance between two points using Doctrine2. Not being able to use an ORM is a big deal for me in terms of determining my database of choice.

Can someone show me a basic example of lets say showing all points within a radius of lets say 10 miles using Doctrine?


回答1:


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());



回答2:


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


来源:https://stackoverflow.com/questions/11713508/how-do-i-use-doctrine2-to-work-with-geospatial-queries-using-postgis

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!