MySQL 5.7 地理空间匹配适配

文章目录

  • [一. 背景](#一. 背景)
  • [二 . 实操](#二 . 实操)
    • [1.MySQL 5.7 环境部署(Docker 方式)](#1.MySQL 5.7 环境部署(Docker 方式))
      • [1.1 部署脚本优化](#1.1 部署脚本优化)
      • [1.2 部署注意事项](#1.2 部署注意事项)
    • [2. 地理空间知识说明](#2. 地理空间知识说明)
      • [2.1 地理空间字段类型](#2.1 地理空间字段类型)
      • [2.2 地理函数](#2.2 地理函数)
    • [3.地理匹配实战:数据库表设计与 SQL 操作](#3.地理匹配实战:数据库表设计与 SQL 操作)
      • [3.1 表结构设计](#3.1 表结构设计)
      • [3.2 数据插入(场景示例)](#3.2 数据插入(场景示例))
      • [3.3 地理匹配查询(核心逻辑)](#3.3 地理匹配查询(核心逻辑))

一. 背景

为实现警情案例的区域化管理与精准溯源,需完成 "经纬度警情案例与围栏区域的空间匹配" 核心任务:基于含精准经纬度坐标的警情数据,通过空间几何计算判定每个警情所属的预设围栏区域,最终输出 "警情信息 - 经纬度 - 围栏标识" 的关联整合结果,为后续区域警情分析、资源调度提供数据支撑。

输入数据说明

警情案例数据:

含具体警情相关信息及对应的经纬度坐标(示例数据如下)

id longitude latitude incident_content
1 113.886000 22.558000 壹方城购物中心前发生两车追尾事故,造成交通拥堵,需交警前往处理
2 113.868000 22.578000 西乡地铁站B出口发生盗窃案件,嫌疑人已逃跑,需要民警介入调查
3 113.810000 22.639000 T3航站楼2号门有旅客突发晕倒,需要医疗救助
4 113.915000 22.578000 新安公园旁餐饮店发生小火情,已初步控制,需要消防检查
5 113.880000 22.561000 宝安中心区夜间施工噪声扰民,居民多次投诉无果
6 113.880500 22.583200 宝安大仟里夜间施工噪声扰民,居民多次投诉无果

围栏数据:

包含围栏唯一名称及区域范围定义,支持 圆形围栏多边形围栏 两种类型(字段互斥,同一围栏仅对应一种类型),示例如下:

name geofence_point radius geofence_polygon
宝安大仟里商圈 POINT(113.8781 22.5806) 500
西丽国际创新谷商圈 POINT(113.9472 22.5925) 600
高新园万象城商圈 POINT(113.9398 22.5412) 800
宝安中心区 POLYGON((113.875 22.556,113.885 22.556,113.885 22.566,113.875 22.566,113.875 22.556))
西乡街道 POLYGON((113.86 22.575,113.87 22.575,113.87 22.585,113.865 22.588,113.86 22.585,113.86 22.575))
宝安机场 POLYGON((113.805 22.635,113.815 22.635,113.815 22.645,113.81 22.648,113.805 22.645,113.805 22.635))
新安街道 POLYGON((113.91 22.572,113.92 22.572,113.92 22.582,113.915 22.584,113.91 22.582,113.91 22.572))

预期输出结果

核心匹配规则

  1. 优先保障匹配唯一性:若单个警情同时满足多个围栏的判定条件(极端重叠场景),按 "多边形围栏优先于圆形围栏""小范围围栏优先于大范围围栏" 的优先级输出唯一结果;
  2. 无匹配处理:若警情坐标未落在任何预设围栏内,围栏名称字段留空。

预期输出结果

输出整合后的结构化数据,包含警情全量信息、经纬度及对应围栏名称,示例如下:

id longitude latitude incident_content name
6 113.880500 22.583200 宝安大仟里夜间施工噪声扰民,居民多次投诉无果 宝安大仟里商圈
5 113.880000 22.561000 宝安中心区夜间施工噪声扰民,居民多次投诉无果 宝安中心区
2 113.868000 22.578000 西乡地铁站B出口发生盗窃案件,嫌疑人已逃跑,需要民警介入调查 西乡街道
3 113.810000 22.639000 T3航站楼2号门有旅客突发晕倒,需要医疗救助 宝安机场
4 113.915000 22.578000 新安公园旁餐饮店发生小火情,已初步控制,需要消防检查 新安街道
1 113.886000 22.558000 壹方城购物中心前发生两车追尾事故,造成交通拥堵,需交警前往处理

二 . 实操

1.MySQL 5.7 环境部署(Docker 方式)

1.1 部署脚本优化

优化说明:修复日志查看容器名不一致问题,增加目录提前创建逻辑,避免挂载失败,同时优化脚本可读性和可维护性。

sh 复制代码
# 1. 创建相关目录(避免挂载时权限或目录不存在问题)
mkdir -p /home/mysql/{conf,data,logs}
cd /home/mysql

# 2. 编写 docker-compose 配置文件
cat > /home/mysql/docker-compose.yml << EOF
version: '3'
services:
  scs-mysql: 
    image: mysql:5.7.30
    hostname: scs-mysql
    container_name: scs-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - TZ=Asia/Shanghai
    restart: always
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-uroot", "-p123456"]
      interval: 5s
      timeout: 1s
      retries: 10
    privileged: true
    ports:
      - 3306:3306
    volumes:
      - $PWD/data:/var/lib/mysql
      - $PWD/logs:/var/log/mysql
      - $PWD/conf/my.cnf:/etc/mysql/my.cnf
    command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci','--default-time-zone=+08:00']
    entrypoint: bash -c "chown -R mysql:mysql /var/log/mysql && exec /entrypoint.sh mysqld"

EOF

# 3. 编写 MySQL 配置文件
cat > /home/mysql/conf/my.cnf << EOF
!includedir /etc/mysql/conf.d/ 
!includedir /etc/mysql/mysql.conf.d/
[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

[mysql.server]
default-character-set=utf8

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
default-time-zone=+08:00
max_connections=1024
slow_query_log=1
long_query_time=2
slow_query_log_file=/var/log/mysql/slow.log
log_error=/var/log/mysql/error.log
EOF


# 4. 启动容器并查看日志
docker-compose up -d
docker logs -f scs-mysql  

1.2 部署注意事项

  1. 确保服务器已安装 Docker 和 Docker Compose;
  2. 若 3306 端口已被占用,可修改 ports 中的宿主端口(如 3307:3306);
  3. 部署完成后,可通过 mysql -h 127.0.0.1 -uroot -p123456 验证连接。

2. 地理空间知识说明

2.1 地理空间字段类型

分类 类型 描述 示例(WKT格式)
多边形类型 POLYGON 一个由封闭边界定义的多边形区域。 POLYGON((0 0,10 0,10 10,0 10,0 0))
单值类型 POINT 一个坐标点。 POINT(121.213342 31.234532)
集合类型 MULTIPOLYGON(暂时不用) 多个多边形的集合。 MULTIPOLYGON(((0 0, 100 0, 100 100, 0 100, 0 0), (20 20, 80 20, 80 80, 20 80, 20 20)), ((200 0, 250 0, 250 50, 200 50, 200 0)))

2.2 地理函数

函数类别 函数示例 用途说明
数据转换 ST_GeomFromText('POINT(1 2)') 将文本(WKT格式)转换为空间数据。
ST_AsText(geom_column) 将空间数据转换回可读的文本格式。
空间关系判断 ST_Within(point, polygon) 判断一个点是否在一个多边形内。
ST_Contains(polygon, point) 判断一个多边形是否包含一个点。
空间计算 ST_Distance_Sphere(point1, point2) 计算两点在地球球面上的近似距离(单位:米)。

3.地理匹配实战:数据库表设计与 SQL 操作

3.1 表结构设计

sql 复制代码
-- 区域围栏表
drop table if exists mcp_geofence_xxxx;
CREATE TABLE `mcp_geofence_xxxx` (
  `name` VARCHAR(100) comment '围栏名称',
  `geofence_point` POINT  NULL comment '圆心坐标',
  `radius` DOUBLE NULL comment '半径(单位:米)',
  `geofence_polygon` POLYGON NULL comment '边界'
);
-- SPATIAL KEY `idx_geofence` (`geofence_point`),
-- SPATIAL KEY `idx_geofence` (`geofence_polygon`)
-- 由于空间索引不允许为空,所以删除

-- 警情表
drop table if exists mcp_police_test;
create TABLE mcp_police_test (
    id INT PRIMARY KEY AUTO_INCREMENT,
    longitude DECIMAL(10,6) NOT NULL COMMENT '经度',
    latitude DECIMAL(10,6) NOT NULL COMMENT '纬度',
    incident_content TEXT NOT NULL COMMENT '警情内容',
    INDEX idx_location(longitude, latitude)
) COMMENT='警情信息表';

3.2 数据插入(场景示例)

sql 复制代码
-- 圆形
-- 宝安大仟里商圈(大约位置:22.5806° N, 113.8781° E)
INSERT INTO `mcp_geofence_xxxx` (`name`, `geofence_point`, `radius`) 
VALUES ('宝安大仟里商圈', ST_GeomFromText('POINT(113.8781 22.5806)'), 500);

-- 西丽国际创新谷商圈(大约位置:22.5925° N, 113.9472° E)
INSERT INTO `mcp_geofence_xxxx` (`name`, `geofence_point`, `radius`) 
VALUES ('西丽国际创新谷商圈', ST_GeomFromText('POINT(113.9472 22.5925)'), 600);

-- 高新园万象城商圈(大约位置:22.5412° N, 113.9398° E)
INSERT INTO `mcp_geofence_xxxx` (`name`, `geofence_point`, `radius`) 
VALUES ('高新园万象城商圈', ST_GeomFromText('POINT(113.9398 22.5412)'), 800);

-- 多边形
INSERT INTO mcp_geofence_xxxx (name, geofence_polygon) VALUES ('宝安中心区',ST_GeomFromText('POLYGON((113.875 22.556, 113.885 22.556, 113.885 22.566, 113.875 22.566, 113.875 22.556))')),('西乡街道',ST_GeomFromText('POLYGON((113.860 22.575, 113.870 22.575, 113.870 22.585, 113.865 22.588, 113.860 22.585, 113.860 22.575))')),('宝安机场',ST_GeomFromText('POLYGON((113.805 22.635, 113.815 22.635, 113.815 22.645, 113.810 22.648, 113.805 22.645, 113.805 22.635))')),('新安街道',ST_GeomFromText('POLYGON((113.910 22.572, 113.920 22.572, 113.920 22.582, 113.915 22.584, 113.910 22.582, 113.910 22.572))'));

SELECT name, ST_AsText(geofence_point), radius,ST_AsText(geofence_polygon) AS point_text FROM mcp_geofence_xxxx ;



-- 插入6条分布在宝安区不同地点的警情数据
INSERT INTO mcp_police_test 
(longitude, latitude, incident_content) VALUES

(113.886, 22.558, 
 '壹方城购物中心前发生两车追尾事故,造成交通拥堵,需交警前往处理'),

-- 2. 西乡街道 - 治安事件
(113.868, 22.578,
 '西乡地铁站B出口发生盗窃案件,嫌疑人已逃跑,需要民警介入调查'),

-- 3. 宝安机场 - 紧急求助
(113.810, 22.639,
 'T3航站楼2号门有旅客突发晕倒,需要医疗救助'),

-- 4. 新安街道 - 消防警情
(113.915, 22.578,
 '新安公园旁餐饮店发生小火情,已初步控制,需要消防检查'),

-- 5. 宝安中心区 - 噪声投诉
(113.880, 22.561,
 '宝安中心区夜间施工噪声扰民,居民多次投诉无果'),
-- 6. 宝安大仟里 - 噪声投诉
(113.8805,22.5832, '宝安大仟里夜间施工噪声扰民,居民多次投诉无果');

3.3 地理匹配查询(核心逻辑)

sql 复制代码
drop table if exists mcp_police_result; 
  create table mcp_police_result SELECT 
      pi.id,
      pi.incident_content,
      pi.longitude,
      pi.latitude,
      gf.name
  FROM 
      mcp_police_test pi
  LEFT JOIN 
      mcp_geofence_xxxx gf ON (
        (gf.geofence_polygon IS NOT NULL 
         and ST_Within(ST_GeomFromText(CONCAT('POINT(', pi.longitude, ' ', pi.latitude, ')')),gf.geofence_polygon))
        OR
        (gf.geofence_point IS NOT NULL AND gf.radius IS NOT NULL
              AND ST_Distance_Sphere(
                  ST_GeomFromText(CONCAT('POINT(', pi.longitude, ' ', pi.latitude, ')')),
                  gf.geofence_point
              ) <= gf.radius)
      );

SELECT * from mcp_police_result;
相关推荐
CV工程师的自我修养12 小时前
数据库出现死锁了。还不知道什么原因引起的?快来看看吧!
数据库
码界奇点12 小时前
灵活性与高性能兼得KingbaseES 对 JSON 数据的全面支持深度解析
数据库·json·es
2501_9418714512 小时前
面向微服务链路追踪与全局上下文管理的互联网系统可观测性设计与多语言工程实践分享
大数据·数据库·python
luoluoal12 小时前
基于python的语音和背景音乐分离算法及系统(源码+文档)
python·mysql·django·毕业设计·源码
·云扬·12 小时前
MySQL单机多实例部署两种实用方法详解
数据库·mysql·adb
odoo中国12 小时前
Pgpool-II 在 PostgreSQL 中的用例场景与优势
数据库·postgresql·中间件·pgpool
男孩李12 小时前
postgres数据库常用命令介绍
数据库·postgresql
IvorySQL13 小时前
让源码安装不再困难:IvorySQL 一键安装脚本的实现细节解析
数据库·人工智能·postgresql·开源
云和数据.ChenGuang13 小时前
openGauss赋能新能源汽车智能制造——比亚迪MES系统数据库国产化升级案例
数据库·汽车·opengauss·gaussdb·数据库权限管理
洛小豆13 小时前
她问我:数据库还在存 Timestamp?我说:大人,时代变了
数据库·后端·mysql