nashgao/hyperf-mysql-spatial

Hyperf 的 MySQL 空间数据类型扩展。

0.2.1 2023-12-08 02:11 UTC

This package is auto-updated.

Last update: 2024-09-08 03:51:31 UTC


README

hyperf/database 提供空间数据类型支持

移植自 grimzy/laravel-mysql-spatial

安装

使用 composer 添加包

$ composer require nashgao/hyperf-mysql-spatial:~0.1

然后编辑您刚刚创建的模型。它必须使用 SpatialTrait 并定义一个名为 $spatialFields 的数组,其中包含在迁移中创建的 MySQL 空间数据字段名称

namespace App;

use Nashgao\HyperfMySQLSpatial\Eloquent\SpatialTrait;
use Hyperf\Database\Model\Model;
/**
 * @property \Nashgao\HyperfMySQLSpatial\Types\Point   $location
 * @property \Nashgao\HyperfMySQLSpatial\Types\Polygon $area
 */
class Place extends Model
{
    use SpatialTrait;

    protected $fillable = [
        'name'
    ];

    protected $spatialFields = [
        'location',
        'area'
    ];
}

保存模型

use Nashgao\HyperfMySQLSpatial\Types\Point;
use Nashgao\HyperfMySQLSpatial\Types\Polygon;
use Nashgao\HyperfMySQLSpatial\Types\LineString;

$place1 = new Place();
$place1->name = 'Empire State Building';

// saving a point
$place1->location = new Point(40.7484404, -73.9878441);	// (lat, lng)
$place1->save();

// saving a polygon
$place1->area = new Polygon([new LineString([
    new Point(40.74894149554006, -73.98615270853043),
    new Point(40.74848633046773, -73.98648262023926),
    new Point(40.747925497790725, -73.9851602911949),
    new Point(40.74837050671544, -73.98482501506805),
    new Point(40.74894149554006, -73.98615270853043)
])]);
$place1->save();

或者如果您的数据库字段使用特定的 SRID 创建

use Nashgao\HyperfMySQLSpatial\Types\Point;
use Nashgao\HyperfMySQLSpatial\Types\Polygon;
use Nashgao\HyperfMySQLSpatial\Types\LineString;

$place1 = new Place();
$place1->name = 'Empire State Building';

// saving a point with SRID 4326 (WGS84 spheroid)
$place1->location = new Point(40.7484404, -73.9878441, 4326);	// (lat, lng, srid)
$place1->save();

// saving a polygon with SRID 4326 (WGS84 spheroid)
$place1->area = new Polygon([new LineString([
    new Point(40.74894149554006, -73.98615270853043),
    new Point(40.74848633046773, -73.98648262023926),
    new Point(40.747925497790725, -73.9851602911949),
    new Point(40.74837050671544, -73.98482501506805),
    new Point(40.74894149554006, -73.98615270853043)
])], 4326);
$place1->save();

注意:在保存集合几何形状(LineStringPolygonMultiPointMultiLineStringGeometryCollection)时,仅最高层的几何形状应在构造函数中设置 SRID。

在上面的示例中,当创建一个 new Polygon() 时,我们只在 Polygon 上设置 SRID,并使用默认值用于 LineStringPoint 对象。

检索模型

$place2 = Place::first();
$lat = $place2->location->getLat();	// 40.7484404
$lng = $place2->location->getLng();	// -73.9878441

几何类

可用的几何类

查看类图

使用几何类

为了使您的 Eloquent 模型处理几何类,它必须使用 Nashgao\HyperfMySQLSpatial\Eloquent\SpatialTrait 特性,并定义一个 protected 属性 $spatialFields,它是一个包含 MySQL 空间数据类型列名的数组(例如在 快速入门 中)。

IteratorAggregate 和 ArrayAccess

集合几何形状(LineStringPolygonMultiPointMultiLineStringGeometryCollection)实现了 IteratorAggregateArrayAccess,这使得执行迭代器和数组操作变得简单。例如

$polygon = $multipolygon[10];	// ArrayAccess

// IteratorAggregate
for($polygon as $i => $linestring) {
  echo (string) $linestring;
}

辅助工具

从/到 Well Known Text(WKT)
// fromWKT($wkt, $srid = 0)
$point = Point::fromWKT('POINT(2 1)');
$point->toWKT();	// POINT(2 1)

$polygon = Polygon::fromWKT('POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))');
$polygon->toWKT();	// POLYGON((0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1))
从/到 字符串
// fromString($wkt, $srid = 0)
$point = new Point(1, 2);	// lat, lng
(string)$point			// lng, lat: 2 1

$polygon = Polygon::fromString('(0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)');
(string)$polygon;	// (0 0,4 0,4 4,0 4,0 0),(1 1, 2 1, 2 2, 1 2,1 1)
从/到 JSON(GeoJSON)

几何类实现了 JsonSerializableIlluminate\Contracts\Support\Jsonable 以帮助将数据序列化为 GeoJSON

$point = new Point(40.7484404, -73.9878441);

json_encode($point); // or $point->toJson();

// {
//   "type": "Feature",
//   "properties": {},
//   "geometry": {
//     "type": "Point",
//     "coordinates": [
//       -73.9878441,
//       40.7484404
//     ]
//   }
// }

要将 GeoJSON 字符串反序列化为几何类,您可以使用 Geometry::fromJson($json_string)

$location = Geometry::fromJson('{"type":"Point","coordinates":[3.4,1.2]}');
$location instanceof Point::class;  // true
$location->getLat();  // 1.2
$location->getLng(); // 3.4

范围:空间分析函数

空间分析函数是使用 Eloquent Local Scopes 实现的。

可用的范围

  • distance($geometryColumn, $geometry, $distance)
  • distanceExcludingSelf($geometryColumn, $geometry, $distance)
  • distanceSphere($geometryColumn, $geometry, $distance)
  • distanceSphereExcludingSelf($geometryColumn, $geometry, $distance)
  • comparison($geometryColumn, $geometry, $relationship)
  • within($geometryColumn, $polygon)
  • crosses($geometryColumn, $geometry)
  • contains($geometryColumn, $geometry)
  • disjoint($geometryColumn, $geometry)
  • equals($geometryColumn, $geometry)
  • intersects($geometryColumn, $geometry)
  • overlaps($geometryColumn, $geometry)
  • doesTouch($geometryColumn, $geometry)
  • orderBySpatial($geometryColumn, $geometry, $orderFunction, $direction = 'asc')
  • orderByDistance($geometryColumn, $geometry, $direction = 'asc')
  • orderByDistanceSphere($geometryColumn, $geometry, $direction = 'asc')

请注意,MySQL 空间分析函数的行为和可用性在每个 MySQL 版本中都不相同(参见表格 文档)。

贡献

欢迎提出建议和拉取请求!带有测试的拉取请求是最好的!还有很多MySQL空间函数待实现,或者有创造性的使用空间函数的方法。

致谢

最初受到njbarrett的Laravel postgis包的启发。

移植自 grimzy/laravel-mysql-spatial