我们本次实践的主要内容
- 地理围栏数据构建
- mysql 如何使用geo相关字段类型
- 围栏算法计算
地理围栏数据构建
使用DDL创建一个数据库模式:
CREATE TABLE `geo_1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`fence_point` point NOT NULL COMMENT '中心点',
`fence_polygon` polygon NOT NULL COMMENT '单个围栏',
`fence_multipolygon` multipolygon NOT NULL COMMENT '多围栏',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
使用原生sql语句插入几条数据
INSERT INTO `geo_1`(
`id`,
`fence_point`,
`fence_polygon`,
`fence_multipolygon`
)
VALUES(
NULL,
GEOMFROMTEXT('POINT(117.134516 36.672215)'),
GEOMFROMTEXT(
'POLYGON((117.147711 36.692958,117.152174 36.664804,117.120588 36.659434,117.116297 36.678848,117.147711 36.692958))'
),
GEOMFROMTEXT(
'MULTIPOLYGON(((117.143528 36.678686,117.144215 36.676758,117.142927 36.67669,117.142412 36.677997,117.143528 36.678686)),((117.144837 36.675829,117.144794 36.674487,117.143743 36.674659,117.14385 36.675881,117.144837 36.675829)),((117.127574 36.670235,117.124227 36.668858,117.124785 36.666448,117.13075 36.667412,117.127574 36.670235)))'
)
);
特别要注意的几点:
- POINT类型是单个点,构建只需要一个POINT类型数据即可
- POLYGON类型或者MULTIPOLYGON中的数据必须是首位相连,也就是第一组数据和最后一组数据是相同的,以构成一个闭合的多边形。
mysql 如何使用geo相关字段类型
这里推荐使用 grimzy/laravel-mysql-spatial 来处理地理数据,具体使用方式可参考官方文档。
composer.json "grimzy/laravel-mysql-spatial": "^2.2",
在模型中使用Trait方式引入
use GrimzyLaravelMysqlSpatialEloquentSpatialTrait;
模型类中使用示例
class MyMap extends Model { use SpatialTrait; protected $spatialFields = [ 'fence_point', 'fence_polygon', 'fence_multipolygon', ]; }
这样我们对数据字段的读写都会经过处理,转换成我们书西的colllection对象。极大方便数据的处理方式。举几个例子:
需要引入的类型
use GrimzyLaravelMysqlSpatialTypesMultiPolygon; use GrimzyLaravelMysqlSpatialTypesPoint; use GrimzyLaravelMysqlSpatialTypesPolygon; use GrimzyLaravelMysqlSpatialTypesLineString;
保存中心点数据
$mapInfo = Map::find(1); $mapInfo->fence_point = new Point(117.1234556, 36.123456); $mapInfo->save();
保存多边形数据
$coorArr = [[117.147711 36.692958],[117.152174 36.664804],[117.120588 36.659434],[117.116297 36.678848],[117.147711 36.692958]]; $mapInfo = Map::find(1); $linePath = []; foreach ($coorArr as $point){ array_push($linePath, new Point($point[1], $point[0])); } array_push($linePath, array_first($linePath)); $lineStringPath = new LineString($linePath); $mapInfo->fence_polygon= new Polygon([$lineStringPath]); $mapInfo->save();
配合百度地图api我们可以实现如下效果,在线划围栏、围栏展示等可视化操作
围栏算法计算
配合我之前文章里面提到的围栏算法,可以实现左边点围栏是否在指定区域应用。
Related Posts:
拜读猫神大作~~~