Yii与PostGis,选择经度和纬度

时间:2013-02-15 16:46:18

标签: postgresql yii postgis

我在我的应用程序中使用Yii和PostgreSQL以及PostGIS。我有一个带有“位置”字段的模型“用户”。 Location-field的内容对于人类来说毫无意义,但是Postgres可以使用ST_asText方法转换Location-field的值并将其转换为Longitude和Latitude。我已经在我的模型中为经度和纬度创建了虚拟字段。当我保存模型时,我使用beforeSave和afterSave方法将位置设置为正确的值。

我现在的问题是我希望在创建模型时填充纬度和经度虚拟字段(使用数据库中的现有对象)。我当时认为可能有类似beforeSelect和afterSelect的东西,我可以使用额外的计算列附加查询,因此能够在查询运行后处理从该额外列返回的值。

这有可能吗?

2 个答案:

答案 0 :(得分:1)

我能够很容易地解决这个问题。当我应该在寻找beforeFind和afterFind时,我在CActiveRecord类中寻找一个beforeSelect和afterSelect方法。

我是怎么做到的。欢迎任何改进建议:)

public function beforeFind(){
    $criteria = new CDbCriteria;
    $criteria->select = "*,ST_asText(location) as location";
    $this->dbCriteria->mergeWith($criteria);
    return parent::beforeFind();
}

public function afterFind(){
    $location = str_replace('POINT(','',$this->location);
    $location = str_replace(')','',$location);
    $location = explode(" ", $location);

    $this->lon = $location[0];
    $this->lat = $location[1];
    return parent::afterFind();
}

答案 1 :(得分:0)

我在Yii2上遇到了这个问题,这就是我解决的方法。

  1. 覆盖AR的find()方法并定义自己的ActiveQuery类:

    public static function find()
    {
        $query =  new MyActiveQueryClass(get_called_class());
        return $query->select('*, ST_AsGeoJSON(location) AS location');
    }
    
  2. afterFind()中,您将拥有geo-json,并可以获取lat / lng:

    public function afterFind()
    {
        parent::afterFind();
    
        $geoJson = json_decode($this->location, true);
        $this->lat = $geoJson['coordinates'][0];
        $this->lng = $geoJson['coordinates'][1];
    }
    

Yii2就是这样。保存之前,请记住将经/纬度转换为正确的对象。我的是地理专栏。这是奖励:

public function beforeSave($insert)
{
    //create field as expression
    if(!empty($this->lat) && !empty($this->lng))
        $this->location = new \yii\db\Expression("'POINT({$this->lat} {$this->lng})'");

    return parent::beforeSave($insert);
}