如何使用Doctrine2使用PostGIS处理GeoSpatial Queries?

时间:2012-07-29 22:23:55

标签: symfony doctrine-orm geospatial postgis

我有一个面向公众的应用程序,它基于Postgres和PostGIS。

我已经尝试了谷歌搜索几个小时,但一直找不到任何可以显示一些基本地理空间的文档,比如使用Doctrine2获得两点之间的距离。在确定我选择的数据库方面,无法使用ORM对我来说是一件大事。

有人能告诉我一个基本的例子,让我们说使用Doctrine可以说10英里范围内的所有点吗?

2 个答案:

答案 0 :(得分:5)

我在博客上写了一篇文章,解释了如何使用Doctrine 2(版本2.2+)和Postgis。这篇文章是法语,但代码是PHP,它是一种国际语言:http://blog.fastre.info/2012/02/doctrine2-2-2-et-types-geographiques/

正如您将看到的,将数据从数据库导入对象需要进行一些转换:

  1. 数据通过postgis转换为geojson(json可以通过php读取,使用json_decode函数)
  2. 将数据转换为Point对象
  3. 从对象的世界到数据库:

    1. 对象Point转换为WKT。为什么WKT而不是json?因为Postgis有一个ST_GeogFromWKT函数,但还没有(还有)ST_GeogFromGeoJson函数。
    2. 将数据插入数据库。
    3. 我还编写了一个自定义DQL函数类,它处理DQL查询中的“覆盖”操作。这不完全是你所要求的,但你可以从中激发灵感并调整代码。

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

      并使用app / config / config.yml将此函数添加到doctrine中:

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

      注意:要使用此功能,您必须创建其他将使用'ST_FromWKT'函数的函数,并将您的点转换为getSql中的WKT(使用__toString函数?)。我在我的应用程序中不需要它,所以我没有代码可以呈现给你。

      这是使用我的函数的一个例子:($ entity-&gt; getPolygon()返回postgis的字符串,没有任何转换 - 我不需要在我的应用程序中处理多边形的对象。)

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

答案 1 :(得分:3)

我知道这有点旧,但也可以帮助别人。

我找到了这个图书馆:

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

他们支持Postgis和MySQL。

Postgis的功能是:

  • 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