2017 © Pedro Peláez
 

yii2-extension yii2-geopoint

Yii2 ActiveRecord supporting MySQL spatial pint data

image

reza-id/yii2-geopoint

Yii2 ActiveRecord supporting MySQL spatial pint data

  • Monday, October 30, 2017
  • by Reza
  • Repository
  • 1 Watchers
  • 5 Stars
  • 350 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 2 Forks
  • 0 Open issues
  • 3 Versions
  • 60 % Grown

The README.md

Yii2-geopoint

ActiveRecord inspired by yii2-spatial but made simpler only to use specific spatial datatype: POINT.
Transform the internal MySQL format to simple coordinate text after finding, and vice versa before storing., (*1)

Yii2-geopoint can also be used to find the model or models which are nearest to a given location., (*2)

Notice that this extension can be used with MySQL >= 5.6.1, MariaDB >= 5.3.3, and PostgreSQL >= 9.1., (*3)

Installation

Install Yii2-geopoint with Composer. Either add the following to the require section of your composer.json file:, (*4)

"reza-id/yii2-geopoint": "*", (*5)

Or run:, (*6)

$ php composer.phar require reza-id/yii2-geopoint "*", (*7)

You can manually install Yii2-geopoint by downloading the source in ZIP-format., (*8)

Usage

Create spatial indexed table using migration:, (*9)

$this->createTable('{{%place}}', [
    'id' => $this->primaryKey(),
    'name' => $this->string(125)->notNull(),
    'location' => 'POINT NOT NULL',
], $tableOptions);

if ($this->db->driverName === 'mysql') {
    $this->execute('CREATE SPATIAL INDEX `idx-place-location` ON '.'{{%place}}(location);');
} elseif ($this->db->driverName === 'pgsql') {
    $this->execute('CREATE INDEX "idx-place-location" ON '.'{{%place}} USING GIST(location);');
}

Use a rezaid\geopoint\ActiveRecord as base class for your models, like so:, (*10)

<?php
namespace app\models;

use rezaid\geopoint\ActiveRecord;

class MyModel extends ActiveRecord
{
    // ...
}

Notice: if you override find() in a rezaid\geopoint\ActiveRecord-derived class, be sure to return a rezaid\geopoint\ActiveQuery and not an 'ordinary' yii\db\ActiveQuery., (*11)

ActiveQuery method

nearest()

public function nearest($from, $attribute, $radius, $unit)

Change the query so that it finds the model(s) nearest to the point given by $from., (*12)

  • $from - string: location in the form <lng>,<lat> (two floats).
  • $attribute - string attribute name of Point in the model.
  • $radius - number search radius in kilometers or miles. Default 100.
  • $unit - string unit value km for kilometers or mil for miles. Default km.

Example usages:, (*13)

$here = '4.9,52.3';     // longitude and latitude of my place


$nearestModel = <model>::find()->nearest($here, <attributeName>, 200, 'mil')->one();    // search radius is 200 miles

$fiveNearestModels =  <model>::find()->nearest($here, <attributeName>)->limit(5)->all();    // search radius is 100 km (default)

$dataProvider = new ActiveDataProvider([ 'query' => <model>::find()->nearest($here, <attributeName>) ]);

ActiveRecord method

getDistance()

Get the distance from given location in the ActiveQuery method nearest(), if you want to display the distance in RESTful API, add this as new field in your model:, (*14)

<?php
namespace app\models;

use rezaid\geopoint\ActiveRecord;

class MyModel extends ActiveRecord
{

    // ...

    public function fields()
    {
        $fields = parent::fields();

        $fields['distance'] = function ($model) {
            return $model->getDistance();
        };

        return $fields;
    }

    // ...

}

Example rest controller:, (*15)

<?php
namespace app\controllers;

use Yii;
use yii\rest\ActiveController;

class PlaceController extends ActiveController
{
    public $modelClass = 'app\models\MyModel';

    public function actionSearch()
    {
        $from = Yii::$app->request->get('from');
        $model = new $this->modelClass;
        $query = $model->find();

        if (!empty($from)) {
            $query->nearest($from, 'location', 200);
        }

        try {
            $provider = new \yii\data\ActiveDataProvider([
                'query' => $query,
            ]);
        } catch (Exception $ex) {
            throw new \yii\web\HttpException(500, 'Internal server error');
        }

        if ($provider->getCount() <= 0) {
            throw new \yii\web\HttpException(404, 'No entries found');
        } else {
            return $provider;
        }
    }
}

The Versions

30/10 2017

dev-master

9999999-dev

Yii2 ActiveRecord supporting MySQL spatial pint data

  Sources   Download

MIT

The Requires

 

extension yii2 geo yii mysql data db map spatial

30/10 2017

v1.1.0

1.1.0.0

Yii2 ActiveRecord supporting MySQL spatial pint data

  Sources   Download

MIT

The Requires

 

extension yii2 geo yii mysql data db map spatial

19/09 2016

v1.0.0

1.0.0.0

Yii2 ActiveRecord supporting MySQL spatial pint data

  Sources   Download

MIT

The Requires

 

extension yii2 geo yii mysql data db map spatial