nashgao / hyperf-mysql-spatial
Hyperf 的 MySQL 空间数据类型扩展。
Requires
- php: >=8.1
- ext-pdo: *
- geo-io/interface: dev-main
- geo-io/wkb-parser: dev-main
- hyperf/database: ~3.1
- hyperf/db-connection: ~3.1
- jmikola/geojson: ^1.0
Requires (Dev)
- doctrine/dbal: ^2.5
- friendsofphp/php-cs-fixer: ~3.0
- hyperf/testing: ~3.0
- mockery/mockery: ^1.3
- phpstan/phpstan: ~1.0
- swoole/ide-helper: ~4.6
Suggests
- ext-json: *
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();
注意:在保存集合几何形状(
LineString
、Polygon
、MultiPoint
、MultiLineString
和GeometryCollection
)时,仅最高层的几何形状应在构造函数中设置 SRID。在上面的示例中,当创建一个
new Polygon()
时,我们只在Polygon
上设置 SRID,并使用默认值用于LineString
和Point
对象。
检索模型
$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
集合几何形状(LineString
、Polygon
、MultiPoint
、MultiLineString
和 GeometryCollection
)实现了 IteratorAggregate
和 ArrayAccess
,这使得执行迭代器和数组操作变得简单。例如
$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)
几何类实现了 JsonSerializable
和 Illuminate\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包的启发。