当前位置: 首页 > article >正文

【mysql】基于城市多边形,配合mysql库,查询目标点是否在指定城市内

文章目录

    • 前言
    • 技术背景
      • 1、MySQL空间数据类型
      • 2、MySQL空间函数
      • 距离计算函数
      • 空间关系函数
      • 几何计算函数
      • 缓冲区分析函数
      • 空间数据类型转换函数
      • 其他空间函数
    • 目标
    • 实现
      • 建表
      • 造数
        • ST_GeomFromText
        • **目标坐标点数据表insert 数据**
        • **城市区域多边形数据表insert数据**
    • 测试
        • 查询目标点是否在指定的城市区域内
        • 查询两个目标点的距离
        • 查询目标点半径范围内的其他点
    • 小结
    • 问题记录:
          • 1、写入多边形区域数据报格式错误
          • 2、`ST_Within`查询点是否在多边形内,`不包含边界点`

前言

最近遇到一个需求,需要查询给定的经纬度坐标点,是否在指定的城市内。 分析需求,需要获取城市区域的边界,再判断目标坐标点是否在边界内。组内的大佬说mysql有这块空间函数的支持,可以了解一下。

所以有了这篇内容。

技术背景

1、MySQL空间数据类型

在MySQL中,空间数据类型是专门用于存储和管理空间数据(如地理位置、几何形状等)的数据类型。这些数据类型使得MySQL能够高效地处理和查询与空间相关的信息。以下是一些MySQL中常见的空间数据类型:

  1. GEOMETRY

    • 这是一个通用的空间数据类型,可以存储任何类型的空间数据,包括点、线、多边形等。
    • 它通常作为其他具体空间数据类型的基类或父类。
  2. POINT

    • 用于存储二维空间中的点,由一对坐标(X, Y)表示。
    • 适用于表示具体的地理位置,如城市的位置、用户的坐标等。
  3. LINESTRING

    • 用于存储一系列点组成的线段或折线。
    • 可以表示道路、河流、路径等线性空间要素。
  4. POLYGON

    • 用于存储由一系列点组成的多边形,这些点构成了一个闭合的环
    • 适用于表示区域、地块、湖泊等面状空间要素。

此外,MySQL还支持其他更复杂的空间数据类型,如MULTIPOINT(多个点的集合)、MULTILINESTRING(多条线段的集合)、MULTIPOLYGON(多个多边形的集合)以及GEOMETRYCOLLECTION(几何对象的集合)等。

2、MySQL空间函数

  1. MySQL空间函数是指用于处理和分析空间数据的函数集合。在MySQL中,空间数据通常指的是具有地理位置信息的数据,如地图数据、几何形状等。这些函数允许用户对空间数据进行各种操作,包括计算距离、判断空间关系、进行几何计算等。它们主要用于支持地理信息系统(GIS)应用、位置服务、物联网(IoT)等领域的数据处理和分析需求。

  2. 以下是一些常见的MySQL空间函数列表,这些函数主要用于处理和分析空间数据。这些函数通常用于地理信息系统(GIS)、位置服务、物联网(IoT)等领域。

    距离计算函数

    函数名称描述
    ST_Distance计算两个几何对象之间的最短距离。
    ST_Distance_Sphere计算球体上两点之间的最短球面距离,考虑了地球的曲率。

    空间关系函数

    函数名称描述
    ST_Within判断一个几何对象是否位于另一个几何对象内部。
    ST_Contains判断一个几何对象是否包含另一个几何对象。
    ST_Intersects判断两个几何对象是否相交。
    ST_Touches判断两个几何对象是否相切。
    ST_Crosses判断两个几何对象是否交叉。
    ST_Overlaps判断两个几何对象是否重叠。

    几何计算函数

    函数名称描述
    ST_Area计算多边形对象的面积。
    ST_Length计算线对象的长度。
    ST_Centroid计算多边形对象的质心。
    ST_Perimeter计算多边形对象的周长。
    ST_ConvexHull计算一组点的凸包。

    缓冲区分析函数

    函数名称描述
    ST_Buffer对几何对象进行缓冲区分析,生成一个以该对象为中心的缓冲区。

    空间数据类型转换函数

    函数名称描述
    ST_GeomFromText将WKT(Well-Known Text)格式的几何对象转换为MySQL中的几何对象。
    ST_AsText将MySQL中的几何对象转换为WKT格式的字符串。
    ST_GeomFromGeoJSON将GeoJSON格式的几何对象转换为MySQL中的几何对象。
    ST_AsGeoJSON将MySQL中的几何对象转换为GeoJSON格式的字符串。

    其他空间函数

    函数名称描述
    ST_StartPoint获取LineString的起始点。
    ST_EndPoint获取LineString的终点。
    ST_NumPoints获取LineString中的点数。
    ST_PointN获取LineString中的第N个点。
    ST_IsClosed判断LineString是否闭合。
    ST_IsValid判断几何对象是否有效。

    请注意,MySQL空间函数的完整列表和功能可能会因MySQL版本的不同而有所差异。为了获取最准确和最新的信息,建议参考MySQL的官方文档或相关权威资源。

目标

学习了解mysql空间函数,了解实现需求需要用到什么空间函数,并创建数据表、造数据实践调用一下对应的空间函数。

实现

建表

  1. 创建目标坐标点数据表

    CREATE TABLE `target_coordinate_table` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `coordinate` geometry NOT NULL COMMENT '坐标点',
      PRIMARY KEY (`id`),
      SPATIAL KEY `coordinate` (`coordinate`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 COMMENT='坐标点表';
    
  2. 创建城市区域多边形数据表

    CREATE TABLE `city_polygon_table` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
      `name` varchar(100) NOT NULL COMMENT '多边形名称-城市名',
      `polygon` geometry NOT NULL COMMENT '多边形数据',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_name` (`name`),
      SPATIAL KEY `polygon` (`polygon`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='城市区域多边形数据表';
    

造数

ST_GeomFromText

ST_GeomFromText 是 MySQL 中用于将 Well-Known Text (WKT) 格式的几何数据转换为 MySQL 内部几何数据类型的函数。对于 MULTIPOLYGON 类型的数据,WKT 格式遵循一定的规范来定义多边形集合。

MULTIPOLYGON 的 WKT 格式通常如下所示:

MULTIPOLYGON(((x1 y1, x2 y2, ..., xn yn, x1 y1)), ((x'1 y'1, x'2 y'2, ..., x'n y'n, x'1 y'1)), ...)

这里是一个具体的例子,包含两个多边形的 MULTIPOLYGON

MULTIPOLYGON(
    ((10 10, 40 40, 20 20, 10 10)),  -- 第一个多边形
    ((15 15, 35 35, 30 15, 15 15))   -- 第二个多边形
)

要使用 ST_GeomFromText 将这个 MULTIPOLYGON 写入 MySQL 数据库,你可以执行类似以下的 SQL 语句:

INSERT INTO your_table_name (your_geometry_column)
VALUES (ST_GeomFromText('MULTIPOLYGON(((10 10, 40 40, 20 20, 10 10)), ((15 15, 35 35, 30 15, 15 15)))'));

在这个例子中,your_table_name 是包含几何数据列的表的名称,your_geometry_column 是该表中用于存储几何数据的列的名称。这个列应该具有适当的空间数据类型,比如 GEOMETRYMULTIPOLYGON 或与之兼容的类型。

目标坐标点数据表insert 数据
INSERT INTO target_coordinate_table (coordinate) VALUES
(ST_GeomFromText('POINT (108.696992 30.933541)')),
(ST_GeomFromText('POINT (108.711323 30.939757)')),
(ST_GeomFromText('POINT (108.769703 31.005251)')),
(ST_GeomFromText('POINT (108.729993 31.007736)')),
(ST_GeomFromText('POINT (106.529617 29.454004)')),
(ST_GeomFromText('POINT (106.53302 29.459989)')),
(ST_GeomFromText('POINT (106.525336 29.453735)')),
(ST_GeomFromText('POINT (106.437501 29.501508)')),
(ST_GeomFromText('POINT (109.102051 30.574327)')),
(ST_GeomFromText('POINT (109.099044 30.573383)'));

城市区域多边形数据表insert数据
INSERT INTO
city_polygon_table (name, polygon)
VALUES  ("重庆郊县",
ST_GeomFromText(
'MULTIPOLYGON (((109.098646 30.579115, 109.098655 30.578657, 109.099332 30.577264, 109.100392 30.575931, 109.102051 30.574327, 109.10437 30.572002, 109.10536 30.571059, 109.106124 30.570777, 
109.103692 30.56583, 109.098819 30.57029, 109.09683 30.57217, 109.095353 30.574395, 109.093476 30.577624, 109.092868 30.578731, 
109.098646 30.579115)))'
));

测试

查询目标点是否在指定的城市区域内

执行SQL:

select  coordinate
from   target_coordinate_table tct
where st_within(tct.coordinate, (select polygon from city_polygon_table cpt where id = 1)) = 1;

查询结果:

image-20241113095301645

查询两个目标点的距离

执行SQL

select  coordinate, st_distance_sphere(corrdinate, point(106.529617,29.454004)) as distance
from   target_coordinate_table;

查询结果:

image-20241113100135828

查询目标点半径范围内的其他点
SELECT *
FROM (
    SELECT 
        coordinate, 
        st_distance_sphere(coordinate, point(106.529617,29.454004)) as distance
    FROM 
        target_coordinate_table
) AS subquery
WHERE subquery.distance < 20000;

image-20241113100440446

小结

本文记录了学习和实践MySQL中的空间数据类型和空间函数的过程,并成功实现了查询目标坐标点是否在指定城市区域内的需求。总结如下:

  1. MySQL空间数据类型:常见的类型包括GEOMETRYPOINTLINESTRINGPOLYGON等,以及它们各自的应用场景。这些数据类型为存储和管理空间数据提供了高效的方式,使得MySQL能够处理和查询与空间相关的信息。

  2. MySQL空间函数:包括距离计算函数(如ST_DistanceST_Distance_Sphere)、空间关系函数(如ST_WithinST_ContainsST_Intersects等)、几何计算函数(如ST_AreaST_Length等)以及其他相关函数,后续可按需使用。

  3. 实践应用

    • 我们创建了目标坐标点数据表和城市区域多边形数据表,并插入了相应的数据。
    • 通过使用ST_Within函数,我们成功查询了目标坐标点是否在指定的城市区域内。
    • 我们还实践了查询两个目标点的距离以及查询目标点半径范围内的其他点,验证了MySQL空间函数的有效性和实用性。
  4. 注意事项

    • 在使用MySQL空间函数时,需要注意函数的参数和返回值类型,确保它们与数据表中的空间数据类型相匹配。

    • 对于复杂的空间查询,可能需要考虑查询的性能和优化策略,如使用空间索引、合理的数据结构等。

问题记录:

1、写入多边形区域数据报格式错误

image-20241112175447265

报错信息 “Data truncation: Invalid GIS data provided to function st_geometryfromtext.” 指出你提供的 GIS 数据在解析时遇到了问题。这通常是因为数据格式错误、数据点不符合规范、或者多边形没有正确闭合等原因造成的。

需要留意提供的 MULTIPOLYGON 数据中,是否有以下问题:

  1. 多边形未闭合:每个多边形都应该是一个闭合的环,即第一个点和最后一个点应该是相同的。每个多边形都要达到这个要求。
  2. 数据点顺序问题:多边形的点应该按照顺时针或逆时针的顺序排列,这通常是为了定义多边形的“内部”和“外部”。如果点的顺序混乱,可能会导致解析错误。
  3. 坐标值超出范围或格式错误:确保所有的坐标值都在合理的范围内,并且格式正确(例如,经度应在 -180 到 180 之间,纬度应在 -90 到 90 之间)。
  4. 多余或缺失的括号MULTIPOLYGON 的定义中括号的使用非常重要,确保每个多边形和整个多边形集合的括号都正确匹配。
2、ST_Within查询点是否在多边形内,不包含边界点

在地理空间数据查询中,ST_Within 函数用于判断一个几何对象是否完全位于另一个几何对象内部。

ST_Within函数的一个核心定义特性:几何体的边界不被视为几何体内部的一部分。

为了处理边界点的情况,可以考虑使用其他空间查询函数或方法,例如:

  • ST_Touches:用于判断两个几何对象是否相接触,但不重叠。这可以捕捉到边界点接触的情况。
  • ST_Intersects:用于判断两个几何对象是否相交。这个函数会考虑几何对象的内部和边界,因此如果边界点相交,它也会返回真(TRUE)。

http://www.kler.cn/a/397802.html

相关文章:

  • 蓝桥杯每日真题 - 第15天
  • Flowable 构建后端服务(后端以及数据库搭建) Flowable Modeler 设计器搭建(前端)
  • 30-集群Backup Restore
  • ThinkPHP 模型如何更新数据
  • Python如何获取request response body
  • 【JAVA】使用IDEA创建maven聚合项目
  • VSCode设置
  • RabbitMQ教程:工作队列(Work Queues)(二)
  • 推荐15个2024最新精选wordpress模板
  • centos7 升级openssl 与升级openssh 安装卸载 telnet-server
  • Go中数组和切片
  • stm32——通用定时器时钟知识点
  • 【小白可懂】微信小程序---课表渲染
  • 使用Python爬虫获取商品订单详情:从API到数据存储
  • FastAPI 中间件详解:实现高性能 Web 应用的完整指南和实际案例
  • 安装paddle
  • 鸿蒙学习基本概念
  • React Hooks 深度解析与实战
  • MyBatis从入门到进阶
  • 【代码随想录】刷题记录(31)-有效的括号
  • 【星海随笔】ZooKeeper-Mesos
  • 【3D Slicer】的小白入门使用指南五
  • 【ict基础软件赛道】真题-50%openGauss
  • 【CSS】absolute定位的默认位置
  • 在Node.js中如何使用TypeScript
  • 无人装备在巷战中的作用