From 99c9a07a922f7fbbc3660017f661e771e81d7cbb Mon Sep 17 00:00:00 2001 From: Stefano Mtangoo Date: Thu, 10 Oct 2024 15:21:29 +0300 Subject: [PATCH] Initial commit after moving to Yii2 extensions --- .gitignore | 19 +++ Behaviors/GeometryBehavior.php | 278 +++++++++++++++++++++++++++++++++ Behaviors/StBufferBehavior.php | 78 +++++++++ Components/StBuffer.php | 149 ++++++++++++++++++ Db/PostgisQueryTrait.php | 227 +++++++++++++++++++++++++++ Helpers/GeoJsonHelper.php | 69 ++++++++ Helpers/PostgisHelper.php | 28 ++++ LICENSE | 32 ++++ README.md | 182 +++++++++++++++++++++ composer.json | 36 +++++ 10 files changed, 1098 insertions(+) create mode 100644 .gitignore create mode 100644 Behaviors/GeometryBehavior.php create mode 100644 Behaviors/StBufferBehavior.php create mode 100644 Components/StBuffer.php create mode 100644 Db/PostgisQueryTrait.php create mode 100644 Helpers/GeoJsonHelper.php create mode 100644 Helpers/PostgisHelper.php create mode 100644 LICENSE create mode 100644 README.md create mode 100644 composer.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e26fa30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +# composer vendor dir +/vendor + +# phpstorm project files +.idea + +# netbeans project files +nbproject + +# zend studio for eclipse project files +.buildpath +.project +.settings + +# windows thumbnail cache +Thumbs.db + +# Mac DS_Store Files +.DS_Store \ No newline at end of file diff --git a/Behaviors/GeometryBehavior.php b/Behaviors/GeometryBehavior.php new file mode 100644 index 0000000..de8095d --- /dev/null +++ b/Behaviors/GeometryBehavior.php @@ -0,0 +1,278 @@ + + */ +class GeometryBehavior extends Behavior +{ + + /** + * Geometry names + */ + const GEOMETRY_POINT = 'Point'; + const GEOMETRY_MULTIPOINT = 'MultiPoint'; + const GEOMETRY_LINESTRING = 'LineString'; + const GEOMETRY_MULTILINESTRING = 'MultiLineString'; + const GEOMETRY_POLYGON = 'Polygon'; + const GEOMETRY_MULTIPOLYGON = 'MultiPolygon'; + + /** + * @var string|array|callable|Connection Db connection for PostgreSQL database with installed Postgis extension + * to convert model attribute from Postgis binary to GeoJson. + * Will be used as fallback if [[owner]] does not provide db connection via [[getDb()]] method. + * You can configure this connection explicitly in [[behaviors()]] + * section or via container definitions in your app config. + */ + public $db; + + /** + * @var string attribute name that will be automatically handled + */ + public $attribute; + + /** + * @var string geometry name + */ + public $type; + + /** + * @var string srid number + */ + public $srid; + + /** + /** + * @var bool don't convert attribute afterFind if it in Postgis binary format (it requires a separate query) + */ + public $skipAfterFindPostgis = false; + + /** + * @var array stored coordinates for afterSave + */ + protected $_coordinates; + + /** + * @inheritdoc + */ + public function events() + { + + $events = [ + ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave', + ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave', + ActiveRecord::EVENT_AFTER_INSERT => 'afterSave', + ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave', + ActiveRecord::EVENT_AFTER_FIND => 'afterFind', + ]; + + return $events; + } + + /** + * @inheritdoc + * @throws InvalidConfigException + */ + public function init() + { + + if (empty($this->attribute)) { + throw new InvalidConfigException("Class property 'attribute' does`t set"); + } + + if (empty($this->type)) { + throw new InvalidConfigException("Class property 'geometry' does`t set"); + } + + if (!in_array($this->type, $this->geometryNames)) { + throw new InvalidConfigException('Unknow geometry type'); + } + + parent::init(); + } + + /** + * Convert array to GeoJson expression before save + * @return bool + */ + public function beforeSave() + { + + $attributeChanged = $this->owner->isAttributeChanged($this->attribute); + + // store coordinates for afterSave; + $this->_coordinates = $this->owner->{$this->attribute}; + + $this->coordinatesToGeoJson(); + + if (!$attributeChanged) { + $this->owner->setOldAttribute($this->attribute, $this->owner->{$this->attribute}); + } + + return true; + } + + /** + * Convert attribute to array after save + * @return bool + */ + public function afterSave() + { + + $this->owner->{$this->attribute} = $this->_coordinates; + + $this->owner->setOldAttribute($this->attribute, $this->owner->{$this->attribute}); + + return true; + } + + /** + * Convert attribute to array after find + * + * @return bool + * @throws InvalidConfigException + * @throws \yii\db\Exception + */ + public function afterFind() + { + + if (!is_object(json_decode($this->owner->{$this->attribute}))) { + + if ($this->skipAfterFindPostgis) { + return true; + } else { + $this->postgisToGeoJson(); + } + } + + $this->geoJsonToCoordinates(); + + $this->owner->setOldAttribute($this->attribute, $this->owner->{$this->attribute}); + + return true; + } + + /** + * Return available geometry names + * @return array + */ + public function getGeometryNames() + { + return [ + self::GEOMETRY_POINT, + self::GEOMETRY_MULTIPOINT, + self::GEOMETRY_LINESTRING, + self::GEOMETRY_MULTILINESTRING, + self::GEOMETRY_POLYGON, + self::GEOMETRY_MULTIPOLYGON, + ]; + } + + /** + * Convert model attribute from array to GeoJson insert expression + * @return Expression + */ + protected function coordinatesToGeoJson() + { + + $coordinates = $this->owner->{$this->attribute}; + + if (!empty($coordinates)) { + + $query = is_array($coordinates) ? GeoJsonHelper::toGeometry($this->type, $coordinates, $this->srid) : "'$coordinates'"; + + $this->owner->{$this->attribute} = new Expression($query); + } else { + $this->owner->{$this->attribute} = null; + } + } + + /** + * Convert model attribute from GeoJson to array + * @return array + */ + protected function geoJsonToCoordinates() + { + if (!empty($this->owner->{$this->attribute})) { + $this->owner->{$this->attribute} = GeoJsonHelper::toArray($this->owner->{$this->attribute}); + } + } + + /** + * Convert model attribute from Postgis binary to GeoJson + * + * @throws InvalidConfigException + * @throws \yii\db\Exception + */ + protected function postgisToGeoJson() + { + $attribute = $this->attribute; + + if (!empty($this->owner->$attribute)) { + $db = $this->_getDb(); + $query = new Query(); + $res = $query->select("ST_asGeoJson('" . $this->owner->$attribute . "') as $attribute")->createCommand($db)->queryOne(); + $geoJson = $res[$attribute]; + + $this->owner->$attribute = $geoJson; + } + } + + /** + * @var Connection + */ + private $_db; + + /** + * @var Connection + */ + private $_dbInitialized = false; + + /** + * @return Connection|null + * @throws InvalidConfigException + */ + private function _getDb() + { + if (empty($this->_db) && !$this->_dbInitialized) { + if ($this->db !== null) { + // if db connection is set explicitly, use it + $db = Instance::ensure($this->db, Connection::class); + } elseif (method_exists($this->owner, 'getDb') && ($db = $this->owner->getDb()) !== null) { + // Do not use $this->owner->canGetProperty('db') as $this->owner->db, + // since owner can have db attribute, which is not component name + // and owner may be not an ActiveRecord instance + + // ActiveRecord default getDb() returns already created Connection object, + // but there is may be a name, config or lambda which we also want to respect + if ((is_string($db) || is_array($db) || is_callable($db)) && !$db instanceof Connection) { + $db = Instance::ensure($db, Connection::class); + } + } else { + // do not execute the following code, since db component may change during app lifecycle and + // we want to respect such behavior + // $db = Yii::$app->getDb() + $db = null; + } + + $this->_db = $db; + $this->_dbInitialized = true; + } + + return $this->_db; + } +} diff --git a/Behaviors/StBufferBehavior.php b/Behaviors/StBufferBehavior.php new file mode 100644 index 0000000..ad0cc7f --- /dev/null +++ b/Behaviors/StBufferBehavior.php @@ -0,0 +1,78 @@ + + */ +class StBufferBehavior extends Behavior +{ + /** + * @var string attribute name for saving ST_Buffer + */ + public $attribute; + + /** + * @var string geometry attribute name + */ + public $attributeGeometry; + + /** + * @var string radius attribute name + */ + public $attributeRadius; + + /** + * @var bool use Geography instead Geometry + */ + public $geography = false; + + /** + * @var string radius units + */ + public $radiusUnit; + + /** + * @var array options for ST_Buffer + */ + public $options = []; + + /** + * @inheritdoc + */ + public function events() + { + + return [ + ActiveRecord::EVENT_BEFORE_INSERT => 'setGeometry', + ActiveRecord::EVENT_BEFORE_UPDATE => 'setGeometry', + ]; + } + + /** + * Generate expression for saving ST_Buffer + */ + public function setGeometry() + { + $model = $this->owner; + + if ($model->isAttributeChanged($this->attributeRadius, false) or $model->isAttributeChanged($this->attributeGeometry, false)) { + + $stBuffer = \Yii::createObject([ + 'class' => StBuffer::className(), + 'geography' => $this->geography, + 'radiusUnit' => $this->radiusUnit, + 'options' => $this->options, + ]); + + $model->{$this->attribute} = $stBuffer->getBuffer($model->{$this->attributeGeometry}, $model->{$this->attributeRadius}); + } + } +} diff --git a/Components/StBuffer.php b/Components/StBuffer.php new file mode 100644 index 0000000..df993bf --- /dev/null +++ b/Components/StBuffer.php @@ -0,0 +1,149 @@ + + */ +class StBuffer extends Component +{ + + /** + * Radius units + */ + const RADIUS_UNIT_DEG = 'deg'; + const RADIUS_UNIT_KM = 'km'; + const RADIUS_UNIT_M = 'm'; + + /** + * @var bool use Geography instead Geometry + */ + public $geography = false; + + /** + * @var string radius units + */ + public $radiusUnit; + + /** + * @var array additional parameters for ST_Buffer + */ + public $options = []; + + /** + * @inheritdoc + */ + public function init() + { + if (is_null($this->radiusUnit)) { + $this->radiusUnit = $this->geography ? self::RADIUS_UNIT_M : self::RADIUS_UNIT_DEG; + } + + if (!in_array($this->radiusUnit, $this->radiusUnits)) { + throw new InvalidConfigException("Invalid radius unit"); + } + + parent::init(); + } + + /** + * Returns expression for ST_Buffer + * @param $geometry + * @param $radius + * @return Expression + */ + public function getBuffer($geometry, $radius, $options = []) + { + + if ($geometry instanceof Expression) { + $geometry = $geometry->expression; + } + + if ($radius and !empty($geometry) and is_string($geometry)) { + + if ($this->geography) { + + $geometry = rtrim($geometry, '::geography') . '::geography'; + $radius = $this->getGeographyBufferRadius($radius); + $params = ''; + } else { + + $radius = $this->getGeometryBufferRadius($radius); + + $params = []; + $options = ArrayHelper::merge($this->options, $options); + + foreach ($options as $key => $value) { + $params[] = "$key=$value"; + } + + $params = !empty($params) ? ", '" . implode(' ', $params) . "'" : ''; + } + + $sql = "ST_Buffer($geometry, $radius $params)"; + + return new Expression($sql); + } + } + + /** + * Returns buffer radius in metters + * @param $radius + * @return float + */ + public function getGeographyBufferRadius($radius) + { + + if ($this->radiusUnit == self::RADIUS_UNIT_DEG) { + // TODO correct conversion from degrees + $radius = $radius * 111; + } + + if ($this->radiusUnit != self::RADIUS_UNIT_M) { + $radius = $radius * 1000; + } + + return $radius; + } + + /** + * Returns buffer radius in degrees + * @param $radius + * @return float + */ + public function getGeometryBufferRadius($radius) + { + + if ($this->radiusUnit == self::RADIUS_UNIT_M) { + $radius = $radius * 1000; + } + + if ($this->radiusUnit != self::RADIUS_UNIT_DEG) { + // TODO correct conversion to degrees + $radius = $radius / 111; + } + + return $radius; + } + + /** + * Returns available radius units + * @return array + */ + public function getRadiusUnits() + { + return [ + self::RADIUS_UNIT_DEG, + self::RADIUS_UNIT_KM, + self::RADIUS_UNIT_M, + ]; + } +} diff --git a/Db/PostgisQueryTrait.php b/Db/PostgisQueryTrait.php new file mode 100644 index 0000000..fdac74f --- /dev/null +++ b/Db/PostgisQueryTrait.php @@ -0,0 +1,227 @@ + + */ +trait PostgisQueryTrait +{ + /** + * @var bool select geoFields as GeoJson automatically + */ + public $autoGeoJson = true; + + /** + * @var bool exclude all geoFields from select + */ + public $exceptGeoFields = false; + + /** + * @var array fields, which must be excluded from select + */ + public $exceptFields = []; + + /** + * @var array table columns + */ + protected $_tableColumns; + + /** + * @var array table columns names + */ + protected $_tableColumnsNames; + + /** + * @var array indexes of teable columns + */ + protected $_tableColumnsIndexes; + + /** + * @var array model attributes which must selected as GeoJson + */ + protected $_geoFields; + + /** + * @inheritdoc + */ + public function init() + { + $this->select = $this->tableColumnsNames; + + parent::init(); + + if ($this->exceptGeoFields) { + $this->excludeFields($this->geoFields); + } elseif ($this->autoGeoJson) { + $this->withGeoFields(); + } + + $this->excludeFields(); + } + + /** + * Select fields as GeoJson + * @param null|string|array $fields + * @return $this + */ + public function withGeoFields($fields = null) + { + + if (is_null($fields)) { + $fields = $this->geoFields; + } elseif (is_string($fields)) { + $fields = [$fields]; + } + + if (!empty($fields) and is_array($fields)) { + + foreach ($fields as $field) { + + if (isset($this->tableColumnsIndexes[$field])) { + $key = $this->tableColumnsIndexes[$field]; + $this->select[$key] = "ST_AsGeoJson($this->tableName.[[$field]]) as [[$field]]"; + } + } + } + + return $this; + } + + /** + * Exclude fields from select + * It may be usefull with large fields (for example ST_Buffer), when reading rows take much time + * @param null $fields + * @return $this + */ + public function excludeFields($fields = null) + { + if (is_null($fields)) { + $fields = $this->exceptFields; + } elseif (is_string($fields)) { + $fields = [$fields]; + } + + if (!empty($fields) and is_array($fields)) { + $columns = $this->tableColumnsNames; + $columnNames = array_flip($columns); + + foreach ($fields as $field) { + + if (isset($this->tableColumnsIndexes[$field])) { + + $key = $this->tableColumnsIndexes[$field]; + + if (isset($this->select[$key])) { + unset($this->select[$key]); + } + } + } + } + + return $this; + } + + /** + * Returns model attributes which must selected as GeoJson + * If it was not set - returns all columns whith type geometry or geograpy + * @return array + * @throws \yii\base\InvalidConfigException + */ + public function getGeoFields() + { + if (is_null($this->_geoFields)) { + + $this->_geoFields = []; + + foreach ($this->tableColumns as $column) { + if (in_array($column->dbType, ['geography', 'geometry'])) { + $this->_geoFields[] = $column->name; + } + } + } + + return $this->_geoFields; + } + + /** + * Set model attributes, which must selected as GeoJson + * @param $value + */ + public function setGeoFields($value) + { + + if (is_array($value)) { + $this->_geoFields = $value; + } + } + + /** + * Returns table name of AR model + * @return string + */ + public function getTableName() + { + $class = $this->modelClass; + return $class::tableName(); + } + + /** + * Returns table columns of AR model + * @return yii\db\ColumnSchema[] + */ + public function getTableColumns() + { + if (is_null($this->_tableColumns)) { + $class = $this->modelClass; + $this->_tableColumns = $class::getTableSchema()->columns; + } + + return $this->_tableColumns; + } + + /** + * Returns table columns names of AR model + * @return array + */ + public function getTableColumnsNames() + { + if (is_null($this->_tableColumnsNames)) { + $this->_tableColumnsNames = array_keys($this->tableColumns); + + foreach ($this->_tableColumnsNames as $key => $name) { + $this->_tableColumnsNames[$key] = "$this->tableName.$name"; + } + } + + return $this->_tableColumnsNames; + } + + /** + * Returns indexeses of table columns + * @return array + */ + protected function getTableColumnsIndexes() + { + + if (is_null($this->_tableColumnsIndexes)) { + $this->_tableColumnsNames = array_keys($this->tableColumns); + + foreach ($this->_tableColumnsNames as $key => $name) { + $this->_tableColumnsIndexes[$name] = $key; + } + } + + return $this->_tableColumnsIndexes; + } +} diff --git a/Helpers/GeoJsonHelper.php b/Helpers/GeoJsonHelper.php new file mode 100644 index 0000000..d280f81 --- /dev/null +++ b/Helpers/GeoJsonHelper.php @@ -0,0 +1,69 @@ + + */ +class GeoJsonHelper +{ + + /** + * Convert coordinates to GeoJson + * @param string $type geometry type + * @param array $coordinates array of coordinates + * @param int $srid SRID + * @return string json + */ + public static function toGeoJson($type, $coordinates, $srid = 4326) + { + + $geoJson = [ + 'type' => $type, + 'coordinates' => $coordinates, + ]; + + if (!is_null($srid)) { + + $geoJson['crs'] = [ + 'type' => 'name', + 'properties' => ['name' => "EPSG:$srid"], + ]; + } + + return Json::encode($geoJson); + } + + /** + * Convert coordinates to Geometry Expression + * @param string $type geometry type + * @param array $coordinates array of coordinates + * @param int $srid SRID + * @return string + */ + public static function toGeometry($type, $coordinates, $srid = 4326) + { + + $geoJson = self::toGeoJson($type, $coordinates, $srid); + + return "ST_GeomFromGeoJSON('$geoJson')"; + } + + /** + * Convert GeoJson to coordinates + * @param string $geoJson GeoJson + * @return mixed + */ + public static function toArray($geoJson) + { + + $geoJson = Json::decode($geoJson); + + return $geoJson['coordinates']; + } +} diff --git a/Helpers/PostgisHelper.php b/Helpers/PostgisHelper.php new file mode 100644 index 0000000..bc803ff --- /dev/null +++ b/Helpers/PostgisHelper.php @@ -0,0 +1,28 @@ + + */ +class PostgisHelper +{ + + /** + * Create sql expression for ST_Within function + * + * boolean ST_Within(geometry A, geometry B); + * @param string $geometry1 + * @param string $geometry2 + * @return Expression sql expression + */ + public static function stWithin($geometry1, $geometry2) + { + return new Expression("ST_Within($geometry1, $geometry2)"); + } +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9d2aa63 --- /dev/null +++ b/LICENSE @@ -0,0 +1,32 @@ +The Yii2-postgis extension is free software. It is released under the terms of +the following BSD License. + +Copyright © 2015 by Denis Chernyavsky +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name of Yii Software LLC nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c99750 --- /dev/null +++ b/README.md @@ -0,0 +1,182 @@ +# Yii2 Postgis + +Extension for working with [Postgis](http://postgis.net/). As intermediate format used Geo Json. + +## Installing + +The preferred way to install this extension is through Composer. + +```json +{ + "require": { + "yii2-extensions/postgis": "*" + } +} +``` + +## GeometryBehavior + +Converts coordinates array to SQL expression for saving in postgis binary format before insert/update and from postgis binary to array after find. + +```php + GeometryBehavior::class, + 'type' => GeometryBehavior::GEOMETRY_POINT, + 'attribute' => 'point', + // explicitly set custom db connection if you do not want to use + // static::getDb() or Yii::$app->getDb() connections + 'db' => 'db_custom' + ], + [ + 'class' => GeometryBehavior::class, + 'type' => GeometryBehavior::GEOMETRY_LINESTRING, + 'attribute' => 'line', + // skip attribute if it was not selected as Geo Json (by PostgisQueryTrait), because it requires a separate query. + 'skipAfterFindPostgis' => true, + ], + ]; + } + + // ... + +} + +// ... + +$model = new MyModel; + +$model->point = [39.234, 54.456]; +$model->line = [[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]]; + +$model->save(); + +?> +``` +| Option | Type | Default | Description | +|-----------------------|-----------|-----------|---------------| +| attribute | string | | attribute that will be automatically handled| +| type | string | | geometry type: `Point`, `LineString`, `Polygon`, `MultiPoint`, `MultiLineString`, `MultiPolygon`| +| skipAfterFindPostgis | boolean | false | skip convertion after find, if data in postgis binary (it requires a separate query, look `PostgisQueryTrait`)| + +## StBufferBehavior +Generate SQL expression before insert/update based on geometry and radius + +```php + GeometryBehavior::className(), + 'attribute' => 'point', + 'type' => GeometryBehavior::GEOMETRY_POINT, + ], + [ + 'class' => StBufferBehavior::className(), + 'attribute' => 'buffer', + 'attributeGeometry' => 'point', + 'attributeRadius' => 'radius', + ], + ]; + } + + // ... + +} + +// ... + +$model = new MyModel; + +$model->point = [39.234, 54.456]; +$model->radius = 5; + +// It will be save St_Buffer for `$model->point` with `$model->radius` in `$model->buffer` +$model->save(); + +?> +``` + +| Option | Type | Default | Description | +|-------------------|-----------|-----------|---------------| +| attribute | string | | attribute for saving buffer | +| attributeGeometry | string | | attribute with geometry | +| attributeRadius | string | | attribute with radius | +| geography | boolean | false | build buffer as geography | +| radiusUnit | string | `deg` for geomtery or `m` for geography | units of buffer radius: `deg`, `m`, `km` | +| options | array |[] | additional options for St_Buffer function | + +## PostgisQueryTrait + +Extends ActiveQuery for working with Postgis data. + +```php + MyQuery::className(), + ], [get_called_class()]); + } +} +?> +``` + +| Option | Type | Default | Description | +|-------------------|-----------|-----------|---------------| +| autoGeoJson | boolean | true | select all geo columns as GeoJson automatically | +| geoFields | array | all table columns with data type `geometry` or `geography` | table columns, that must be selected as Geo Json | +| exceptGeoFields | boolean | false | exclude all geo columns from select statement | +| exceptFields | array | [] | columns, which must be excluded from select statement | + +| Method | Description | +|-------------------------------|---------------| +| withGeoFields($fields=null) | Add columns, that must be selected as Geo Json. Accepts `null`, `string`, `array`. If `fields` is null - all `geoFileds` will be added. | +| excludeFields($fields=null) | Exclude columns from select statement. Accepts `null`, `string`, `array`. If `fields` is null - all `exceptFields` will be excluded from select statement. | + +## GeoJsonHelper +Helper for working with Geo Json + +| Method | Returns | Description | +|-----------------------------------------------|---------------------------|-------------| +| toArray($geoJson) | array | returns coordinates array by Geo Json +| toGeoJson($type, $coordinates, $srid=4326) | string (geo json) | returns Geo Json by geometry type, coordinates array and SRID +| toGeometry($type, $coordinates, $srid=4326) | string (sql expression) | the same, that `toGeoJson`, but wraps result by `"ST_GeomFromGeoJSON('$geoJson')"` + + +## CREDITS +This extension was forked and lives here to keep going great work in keeping with Yii2 community open source spirit. Find Original code at https://github.com/nanson/yii2-postgis \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..3007a3f --- /dev/null +++ b/composer.json @@ -0,0 +1,36 @@ +{ + "name": "yii2-extensions/postgis", + "description": "Yii2-extension to work with postgis data", + "keywords": [ + "postgis", + "yii2", + "yii", + "extension", + "behavior", + "postgre", + "postgres", + "postgresql", + "spatial" + ], + "homepage": "https://github.com/yii2-extensions/postgis", + "type": "yii2-extension", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Denis Chernyavsky", + "email": "panopticum87@gmail.com" + }, + { + "name": "Stefano Mtangoo", + "email": "mwinjilisti@gmail.com" + } + ], + "require": { + "yiisoft/yii2": "*" + }, + "autoload": { + "psr-4": { + "Yii2\\Extension\\Postgis\\": "" + } + } +} \ No newline at end of file