首页 > 数据库 >mysql存储地理信息的方法

mysql存储地理信息的方法

时间:2024-05-27 23:55:48浏览次数:17  
标签:10 地理信息 20 name 多边形 存储 ST mysql position

MySQL 存储地理信息通常使用 GEOMETRY 数据类型或其子类型(如 POINT, LINESTRING, POLYGON 等)。为了支持这些数据类型,MySQL 提供了 SPATIAL 索引,这允许我们执行高效的地理空间查询。

1. 创建支持地理信息的表

首先,我们需要一个包含 GEOMETRY 或其子类型列的表。以下是一个示例,展示如何创建一个包含 POINT 类型的表:

CREATE TABLE locations (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    position POINT NOT NULL,  
    SPATIAL INDEX(position)  -- 为位置列创建空间索引  
) ENGINE=InnoDB;

2. 插入地理信息数据

我们可以使用 GeomFromText()PointFromText() 函数插入地理数据。以下是如何插入一个点的示例:

INSERT INTO locations (name, position)  
VALUES ('Location A', GeomFromText('POINT(10 20)'));  
-- 或者使用 PointFromText  
INSERT INTO locations (name, position)  
VALUES ('Location B', PointFromText('POINT(30 40)'));

3. 查询地理信息数据

我们可以使用 MBRContains(), Distance_Sphere(), ST_Distance_Sphere() 等函数来查询地理数据。以下是一些示例:

3.1查找指定矩形区域内的位置

-- 查找位置在 (0, 0) 到 (20, 20) 矩形区域内的所有位置  
SELECT * FROM locations  
WHERE MBRContains(  
    GeomFromText('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'),  
    position  
);

3.2查找距离特定点一定距离内的位置

注意:这里使用了 Distance_Sphere() 函数,它基于地球是完美球体的假设。对于更精确的计算,我们可以使用 ST_Distance_Sphere() 并指定地球半径。

-- 查找距离 (15, 15) 点 10 公里内的所有位置  
-- 假设地球半径为 6371 公里(平均半径)  
SELECT *, (6371 * acos(cos(radians(15))   
  * cos(radians(X(position)))   
  * cos(radians(Y(position)) - radians(15))   
  + sin(radians(15))   
  * sin(radians(X(position))))) AS distance_km   
FROM locations   
HAVING distance_km < 10;

3.3使用 ST_Distance_Sphere() 查找距离

这是一个更精确的距离计算示例,它使用 ST_Distance_Sphere() 函数并指定地球的平均半径。

-- 查找距离 (15, 15) 点 10 公里内的所有位置  
SELECT *, ST_Distance_Sphere(point(15, 15), position, 6371) AS distance_km   
FROM locations   
HAVING distance_km < 10;

注意:上述查询中的距离计算是基于 Haversine 公式的简化版本,它假设地球是一个完美的球体。在实际应用中,我们可能需要使用更复杂的算法来考虑地球的不规则形状。

此外,我们还可以使用 MySQL 的其他地理空间函数和操作符来执行更复杂的地理空间查询和操作。

4.查询地理信息进阶示例

我们可以探讨一个更复杂的示例,该示例涉及POLYGON地理数据类型,并使用ST_Contains函数来检查一个点是否位于多边形内部。同时,我们也会使用ST_Distance_Sphere函数来计算点与多边形中心点的距离。

4.1创建表并插入数据

首先,我们创建一个包含POLYGON列的表,并插入一些多边形数据。

CREATE TABLE polygons (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    shape POLYGON NOT NULL,  
    SPATIAL INDEX(shape)  
) ENGINE=InnoDB;  
  
INSERT INTO polygons (name, shape)  
VALUES ('Polygon A', GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'));  
INSERT INTO polygons (name, shape)  
VALUES ('Polygon B', GeomFromText('POLYGON((20 20, 30 20, 30 30, 20 30, 20 20))'));  
  
-- 创建一个包含点的表  
CREATE TABLE points (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(255) NOT NULL,  
    position POINT NOT NULL,  
    SPATIAL INDEX(position)  
) ENGINE=InnoDB;  
  
INSERT INTO points (name, position)  
VALUES ('Point 1', GeomFromText('POINT(5 5)'));  
INSERT INTO points (name, position)  
VALUES ('Point 2', GeomFromText('POINT(25 25)'));

4.2查询点是否在多边形内部,并计算距离

现在,我们可以编写一个查询来检查点是否位于多边形内部,并计算这些点与多边形中心点的距离。

-- 假设我们想要检查'Point 1'和'Point 2'是否分别位于'Polygon A'和'Polygon B'内部  
-- 并计算它们与各自多边形中心点的距离  
  
-- 首先,我们需要计算每个多边形的中心点  
SET @polygonA_center = ST_Centroid(GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'));  
SET @polygonB_center = ST_Centroid(GeomFromText('POLYGON((20 20, 30 20, 30 30, 20 30, 20 20))'));  
  
-- 然后,我们可以使用这些中心点与点表中的点进行比较和距离计算  
SELECT   
    p.name AS point_name,  
    p.position,  
    CASE   
        WHEN ST_Contains(pg.shape, p.position) THEN 'Inside'  
        ELSE 'Outside'  
    END AS location_status,  
    ST_Distance_Sphere(p.position, CASE pg.name WHEN 'Polygon A' THEN @polygonA_center ELSE @polygonB_center END, 6371) AS distance_km  
FROM   
    points p  
JOIN   
    polygons pg ON (  
        (p.name = 'Point 1' AND pg.name = 'Polygon A') OR  
        (p.name = 'Point 2' AND pg.name = 'Polygon B')  
    );

这个查询首先计算了两个多边形的中心点,并使用JOIN语句将点表与多边形表连接起来。它使用ST_Contains函数来检查点是否位于多边形内部,并使用ST_Distance_Sphere函数来计算点与对应多边形中心点的距离(以公里为单位)。注意,我们使用了CASE语句来根据点的名称选择正确的多边形中心点进行计算。

这个查询将返回每个点的名称、位置、是否在多边形内部的状态以及与对应多边形中心点的距离。

标签:10,地理信息,20,name,多边形,存储,ST,mysql,position
From: https://www.cnblogs.com/TS86/p/18216882

相关文章

  • 数据库初始,SQL语句介绍,MySQL数据库安装,SQL语句基础,操作MySQL数据库
    Ⅰ数据库初识【一】存储数据的演变过程【1】文件基于内存保存在早期,随意地存放到一个文件中、数据格式也是千差万别的,完全取决于个人员工管理系统是基于列表或字典(内存)存储数据【2】文件操作用本地的文本文件存储数据有的人喜欢存储到本地的一个文件中有的人喜欢存......
  • 成为MySQL DBA后,再看ORACLE数据库(二、监听与连接)
    一、监听器的启动ORACLE启动完成后,可以通过sqlplus/assysdba连接数据库,但是这个只是本地连接,无法通过tcp/ip远程访问数据库,这时候就要启动ORAClE的监听器。启动监听器的命令是lsnrctlstart,启动成功后,可以观察到1521端口也随之监听,这时候就能通过ip加端口远程访问数据库了。在......
  • mysql 8.0.18的docker安装
    1.拉取镜像sudodockerpullmysql:8.0.182.运行dockersudodockerrun-p3306:3306--namemysql--restart=always--privileged=true\-v/home/cy/soft/mysql/conf/mysql/log:/var/log/mysql\-v/home/cy/soft/mysql/data:/var/lib/mysql\-v/home/cy/soft/mysql/conf/......
  • MySQL 数据库-JDBC
    1.事务事务(Transaction):要么都成功,要么都失败事务原则:ACID原则(原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability))原子性:要么都成功,要么都失败一致性:事务前后的数据完整性要保证一致(如,转账操作后,两个人的总额不变)持久性:事务一旦提交不可逆,被持久化到了......
  • 无法连接阿里云服务器本地mysql问题
    1.登录服务器,进入本地mysql数据库,修改root账号访问权限为:%,表示所有IP都可以连接usemysql;updateusersethost="%"whereuser="root";//刷新权限FLUSHPRIVILEGES; 2. 查看是否修改成功:selectuser,host,pluginfrommysql.user; 3.修改 bind-address......
  • ubuntu安装mysql
    ubuntu安装mysql更新软件包列表sudoaptupdate安装mysql服务器sudoaptinstallmsyql-server启动并检查mysql服务sudosystemctlstartmysqlsudosystemctlstatusmysql无密码登录mysqlsudomysql-uroot给root创建密码如果是mysql5.0版本,使用alteruser'root'......
  • 升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0 uniapp、vue、android、web 框
    升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0uniapp、vue、android、web框架:Vue3+SpringBoot3),界面功能(一)  升鲜宝供应链管理系统重构版发布(技术点:Java8、mysql8.0uniapp、vue、android、web框架:Vue3+SpringBoot3),界面功能(一) 1.登录与申请试用界......
  • MySQL函数查询目录树问题记录
    DELIMITER//CREATEFUNCTION`getChildXzqhList`(rootIdBIGINT)RETURNSVARCHAR(4000)BEGINSETSESSIONgroup_concat_max_len=1000000;--设置为1MB设置GROUP_CONCAT函数输出的最大长度大小,太小的话整体会被截掉RETURN(WITH......
  • 时空AI软件:地理信息与遥感领域的智慧引擎
    在地理信息与遥感技术的广阔疆域,时空AI软件如同一颗璀璨新星,将时空信息与智能深度融合,驱动着地理信息分析、决策支持、环境监测、城市规划等领域的深刻变革。本文将深入剖析其技术核心、应用实例、未来趋势,探索时空AI软件如何在地理信息与遥感领域中引领智慧进程。时空AI软件:智能......
  • MySQL--备份恢复
    目录一、备份恢复的工作职责1.备份的时间周期2.备份的方式3.恢复方案4.检查备份5.定期恢复演练6.故障恢复策略7.迁移升级二、逻辑备份工具--mysqldump1.介绍2.使用场景3.mysqldump命令的参数介绍1)全备:2)单库或多库备份:--常用3)备份某个库下的单表或多表:--不常用4......