尊重出处和别人的劳动成果
mysql中geometry类型的简单使用 - 青春阳光 - 博客园www.cnblogs.com建立表语句
CREATE
这里我创建了一张位置信息表,每个人对应的经纬度都会以geometry类型存在表中,geohash字段是把坐标系分成很多小方格,然后将经纬度转化成字符串,其原理可自行百度,在这里就不多说了。
哦,对了,geometry类型好像不能为null,所以建表时必须为not null。
插入表数据
insert
名字是我随便起的,不要喷我哦,经纬度是我在地图上随便取的点,geomfromtext()函数是将字符串格式的点坐标,转化成geometry类型,还有个字段geohash是根据gis字段的值自动生成的,可以仔细看看建表脚本。
如果数据库的版本是8.0以上的,用下面的语句
insert
参考地址
MySQL空间数据操作:GeomFromText()函数报错解决_sinat_34326100的博客-CSDN博客blog.csdn.net接下来是几个简单的查询例子
1. 查询张三的经纬度信息
mysql 8以上用第二条
select
astext()函数是将geometry类型转化为字符串
sql执行结果
2. 修改张三的位置信息
update
我用的Mysql Workbench工具,修改时报错如下:
You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.
好像是除了用id修改,其他修改都会报这个错,下面这样设置一下就OK了 。
set sql_safe_updates = 0;
3. 查询张三和李四之间的距离
SELECT
本来想格式化sql语句的,但是发现格式化之后的sql 基本全变成大写的了,我觉得辨识度更低了,所有大家就这样将就看吧,st_distance_sphere()函数是计算两点之间距离的,所以传两个参数,都是geometry类型的,floor()函数是把计算出的距离取整。
sql执行结果
4. 查询距离张三500米内的所有人
SELECT
sql执行结果
如果表中数据非常多时,这样查效率会非常低,这时就会用到geohash字段查询
sql语句如下:
SELECT
前面说过geohash是把经纬度转成字符串,建表的时候我定义让它转成8位字符,当两个点离得越近时,它生成的geohash字符串前面相同的位数越多,所以我在这里先用left()截取前6位字符,前6位相同的误差在±600米左右,然后模糊查询,查出大概符合条件的数据,最后再精确比较,下面是geohash官方文档对geohash长度和距离误差的说明:
注意:用geohash 查询会有边界问题,所以查询出来的结果又可能不准确,可以用程序(例如java代码)先查出当前点周围8个范围的geohash值,然后再匹配这9个范围的所有数据,这样就解决了geohash 的边界问题。
geohash官方文档地址:https://en.wikipedia.org/wiki/Geohash
实际应用
首先是对经纬做限制
@NotNull @Min(-180) @Max(180) @RequestHeader(BaseConstants.RequestHeaderKey.YC_LNG) BigDecimal lng,
@NotNull @Min(-90) @Max(90) @RequestHeader(BaseConstants.RequestHeaderKey.YC_LAT) BigDecimal lat
其次 校验格式需要这样玩
@RequestBody @Valid Param param,
@NotNull @Min(-180) @Max(180) @RequestHeader(BaseConstants.RequestHeaderKey.YC_LNG) BigDecimal lng,
@NotNull @Min(-90) @Max(90) @RequestHeader(BaseConstants.RequestHeaderKey.YC_LAT) BigDecimal lat) {
if (lng != null && lat != null && lng.doubleValue() != 0 && lat.doubleValue() != 0) {
param.setUserGeopoint(new GeoPoint(lng, lat));
} else {
// 没有定位时 显示福州市政府附近商家 119.296411, 26.074286 福州市政府
param.setUserGeopoint(new GeoPoint(new BigDecimal(119.296411), new BigDecimal(26.074286)));
}
最后
经纬对应java的属性