项目需求是跟用户当前位置判断是否在给定的地理位置范围内,符合位置限制才可以打卡,其中的位置范围是一个或多个不规则的多边形。如下图,判断用户是在清华还是北大。

图形获取区域坐标

因为项目前端使用微信小程序的wx.getLocation获取地理位置,为了坐标的一致性,后台选取区域范围采用了腾讯地图的地理位置服务,在应用工具->绘制几何图形里,提供了点、线、多边形和圆形可以方便的选取看这里

在官方提供的示例上稍加改动即可获取选定的位置坐标。

存储位置

取到坐标位置后,接着就是怎么存储?

开放地理空间联盟(OGC)是一个由 250多家公司,机构和大学组成的国际联盟,参与开发公开可用的空间解决方案,这些解决方案可用于管理空间数据的各种应用程序。OGC发布了地理信息的 OpenGISImplementation 标准,该规范可从 OGC 网站http://www.opengeospatial.org/standards/sfs获得。为了遵循 OGC 规范,MySQL 将空间 extensions 实现为具有 Geometry Types 环境的 SQL 的子集,提供生成、存储、分析空间的功能。总之,MySQL可以满足我们的需求。

MySQL提供单个的存储类型 POINT、LINESTRING、POLYGON 对应几何图形点、线、多边形,GEOMETRY 可以存储三种中的任何一种。同时拥有存储多种类型的能力, MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION依次对应单个图形的复数。

回到项目中,我们用到的是 POLYGON ,

建表语句 如下:

CREATE TABLE `polygon` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`polygon` polygon NOT NULL,
PRIMARY KEY (`id`),
SPATIAL KEY `d` (`polygon`)
) DEFAULT CHARSET=utf8;

插入数据

MySQL 支持将Well-Known 文本(WKT)格式和Well-Known 二进制(WKB)格式两种格式转换为object类型存储起来,我们使用更易于理解的WKT格式。对WKB感兴趣的可以看这里

插入语句如下:

INSERT INTO `polygon` VALUES ('1', '清华大学', GeomFromText('POLYGON((
40.01169924229143 116.31565081888039,39.99304082299905 116.31616541796757,39.99343506780591 116.33297565023167,40.00237067000859 116.33743550702275,40.01340715321479 116.33057418815224,40.01169924229143 116.31565081888039))')); INSERT INTO `polygon` VALUES ('2', '北京大学', GeomFromText('POLYGON((39.99711457525893 116.30450117461078,39.98673259872773 116.30535884106575,39.98673259872773 116.31702308311287,39.99963848242885 116.31598375134854,39.99711457525893 116.30450117461078))'));

需要注意的是腾讯地图返回的多边形的点不是闭合的,而polygon函数需要为了确定多边形是否闭合要求第一个点和最后一个点是一样的。如果不是闭合的polygon返回的结果将是NULL,插入语句就会执行失败。

如果几何满足诸如此(非穷举)列表中的条件,则它在语法上是 well-formed:

  • 线串至少有两个点
  • 多边形至少有一个环
  • 多边形环关闭(第一个和最后一个点相同)
  • 多边形环至少有 4 个点(最小多边形是一个三角形,第一个和最后一个点相同)
  • 集合不为空(除了GeometryCollection)

查询判断

SELECT * FROM polygon WHERE
MBRWithin (ST_GeomFromText('POINT(39.991333490218544 116.30964748487895)'), polygon);
# 在北京大学 SELECT * FROM polygon WHERE
MBRWithin (ST_GeomFromText('POINT(39.988967560246685 116.3286905102832)'), polygon);
# 不在北大

细心的同学可能发现了这里的查询语句里用的是函数,在以往的SQL里如果存在查询字段上使用函数必然导致索引失效、全表扫描,但是在空间数据上不会,先看 EXPLAIN 语句和结果:

可见MySQL空间类型的数据同样可以建立索引,使用的关键词是 SPATIAL

用法如下:

CREATE TABLE geom (g GEOMETRY NOT NULL);
CREATE SPATIAL INDEX g ON geom (g);

常用的空间计算函数

1、判断两点之间的距离

ST_Distance(g1,g2),返回g1和g2之间的距离。如果任一参数是NULL或空几何,则 return value 为NULL。

2、图形1是否完全包含图形2

ST_Contains(g1,g2),返回 1 或 0 以指示g1是否完全包含g2。还可以用ST_Within(g2,g1)达到相同的效果。

3、不相交

ST_Disjoint(g1,g2),返回 1 或 0 以指示g1是否在空间上与(不相交)g2不相交。

4、关于图形相交的情况比较复杂,包含重叠、外相交等情况,具体可以看这里

总结

本文通过一个地理位置打卡的需求,使用 MySQL 自带的 Polygon 数据类型实现了空间数据的存储,用ST_Contains(g1,g2) 函数代入了后台预置的地理区域和前端获取到的用户地理位置可以得出用户是否在打卡范围内。其中还涉及到了 MySQL 在使用函数作为查询字段的情况下依然可以使用索引,最后延伸了一些其他的空间处理函数。

MySQL空间函数实现位置打卡的更多相关文章

  1. mysql常用函数参考

    mysql常用函数参考   对于针对字符串位置的操作,第一个位置被标记为1. ASCII(str) 返回字符串str的最左面字符的ASCII代码值.如果str是空字符串,返回0.如果str是NULL, ...

  2. MySQL 时间函数加减计算

    一.MySQL 获得当前日期时间 函数 1.1 获得当前日期 + 时间(date + time) 函数:now() mysql> select now();+———————+| now() |+ ...

  3. mysql 日期函数总结

    1.0 格式化:DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据. 语法 DATE_FORMAT(date,format) date 参数是合法的日期.format 规定日期/时间的 ...

  4. 【数据库】MySql常用函数梳理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/5866388.html MySql常用函数梳理: 1:数学函数 使用格式:一般用于插入.修改语句中,直接 函数( ...

  5. Mysql日期函数,时间函数使用的总结

    一.MySQL 获得当前日期时间 函数 1.1 获得当前日期+时间(date + time)函数:now() mysql> select now();+--------------------- ...

  6. Oracle/Mysql/SqlServer函数区别

    mysql日期和时间格式转换 Linux scp 使用详解 Oracle/Mysql/SqlServer函数区别 2011-07-01 12:34:36|  分类: Mysql技术 |  标签:mys ...

  7. MySQL字符串函数、日期时间函数

    MySQL字符串函数.日期时间函数 一.常见字符串函数: 1.CHAR_LENGTH  获取长度(字符为单位) 2.FORMAT  格式化 3.INSERT  替换的方式插入 4.INSTR  获取位 ...

  8. 学生选课数据库SQL语句45道练习题整理及mysql常用函数(20161019)

    学生选课数据库SQL语句45道练习题: 一.            设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher).四 ...

  9. [转载]MySQL UUID() 函数

    目录 目录 一 引子 二 MySQL UUID() 函数 三 复制中的 UUID()四 UUID_SHORT() 函数 3.1 实验环境介绍 3.2 搭建复制环境 3.3 基于 STATEMENT 模 ...

随机推荐

  1. 015.Nginx重定向

    一 重定向概述 1.1 重定向介绍 重定向(Redirect)指通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向.域名的重定向.路由选择的变化也是对数据报文经由路径的一种重定向). ...

  2. 支持向量机SMO算法实现(注释详细)

    一:SVM算法 (一)见西瓜书及笔记 (二)统计学习方法及笔记 (三)推文https://zhuanlan.zhihu.com/p/34924821 (四)推文 支持向量机原理(一) 线性支持向量机 ...

  3. tomcat 认证爆破之custom iterator使用

    众所周知,BurpSuite是渗透测试最基本的工具,也可是神器,该神器有非常之多的模块:反正,每次翻看大佬们使用其的骚操作感到惊叹,这次我用其爆破模块的迭代器模式来练练手[不喜勿喷] 借助vulhub ...

  4. 前端学习(一):Html

    进击のpython ***** 前端学习--HTML HTML全称HyperText Mackeup Language,超文本标记语言 网页的超链接,图片,音频,视频都可以超文本 标记就相当于你在本子 ...

  5. SYN 攻击原理及解决方法

    原理SYN foold攻击主要针对tcp通信三次握手期间做的手脚,所以要弄懂这个攻击的原理我们首先必须知道tcp三次握手的详细过程 由上图可知tcp三次握手顾名思义要经过三个步骤,这三个步骤分别是 客 ...

  6. Centos 7下编译安装Apache

    (1)下载apr.apr-util.httpd源码包 百度云下载地址:https://pan.baidu.com/s/1HyW_9XTLhhhf5j_IuNCQsQ 提取码:pg4d (2)安装编译工 ...

  7. turtle库常用函数

  8. map 函数基本写法

    map(需要对对象使用的函数,要操作的对象) 函数可以是自定义的,也可以是内置函数的,或者 lambda 匿名函数 操作的对象多为 可迭代对象可以是函数名的列表集合     2020-05-04

  9. 一图看懂华为云DevCloud如何应对敏捷开发的测试挑战

    作为敏捷开发中测试团队的一员,在微服务测试过程中,你是不是也遇到同样困惑:服务不具备独立验证能力.自动化用例开发效率很低等? 华为云DevCloud API全场景测试技术来支招~围绕API的全场景,打 ...

  10. 初学用记事本运行java报错:找不到或无法加载主类解决方法,部分出错解决办法

    刚开始学习java的人第一个程序可能通过记事本运行,当中间可能会会出现各种错误,我在下面间可能解决出现的问题 1. java环境变量没有安装好 以我的win10系统为例,在装好相应的jdk后,环境变量 ...