6

Postgres と PostGIS に基づく公開アプリがあります。

私は何時間もグーグルを試しましたが、Doctrine2 を使用して 2 点間の距離を取得するなど、いくつかの基本的な地理空間情報を示すことができるドキュメントを見つけることができませんでした。ORM を使用できないことは、選択したデータベースを決定するという点で私にとって大きな問題です。

Doctrineを使用して半径10マイル以内のすべてのポイントを表示する基本的な例を誰かに見せてもらえますか?

4

2 に答える 2

9

Doctrine 2 (バージョン 2.2+) と Postgis の使用方法を説明する記事をブログに書きました。記事はフランス語ですが、コードは国際言語である PHP です。

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

ご覧のとおり、データベースからオブジェクトにデータをインポートするには、何らかの変換が必要です。

  1. データは postgis によって geojson に変換されます (json は json_decode 関数を使用して、php で読み取り可能です)
  2. データは Point オブジェクトに変換されます

オブジェクトの世界からデータベースへ:

  1. オブジェクト Point は WKT に変換されます。なぜ json ではなく WKT なのですか? Postgis には ST_GeogFromWKT 関数がありますが、(まだ) ST_GeogFromGeoJson 関数はありません。
  2. データがデータベースに挿入されます。

また、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->getPolygon() 変換なしで postgis の文字列を返します - アプリでポリゴンのオブジェクトを処理する必要はありません。)

$em->createQuery('SELECT p from MyEntity p where covers(:polygon, p.geom) = true)
            ->setParameter('polygon', $entity->getPolygon());
于 2012-08-30T10:24:40.663 に答える