MySQL空间查询(Geometry类)

本文介绍了如何在MySQL中进行空间查询,包括创建带有空间数据的表,导入经纬度数据,将数据转换为点,执行空间查询并测试性能。通过示例展示了如何查找特定区域内点的过程,并生成大量数据进行测试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


性能测试:

一、创建支持查询的表

创建一个包含空间数据的名为points的表。

CREATE TABLE points(

longitude  DOUBLE,

latitude  DOUBLE,

point  POINT

);

这条命令创建一个名为points的表,包含一个longitude字段,一个latitude字段,一个point字段。

二、向数据库中导入数据

因笔者已有一个包含经纬度的文件log.csv。把log.csv导入表log。

LOAD DATA INFILE 'C:\\log.csv' 
INTO TABLE log 
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '"' 
LINES TERMINATED BY  '\n'; 


把表log中的数据导入新表points中

INSERT INTO points(longitude, latitude)SELECT longitude, latitude FROM log;


三、根据表points中的longitude,latitude字段得到point字段

UPDATE points SET point = GeomFromText(CONCAT('POINT(',points.longitude,' ',points.latitude,')'));

报错:Error Code: 1175. 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 Queries and reconnect.

先执行SET SQL_SAFE_UPDATES = 0;语句,然后执行上面语句。


四、从表中读取数据

1、读取表中的point字段

SELECT  AsText(point)  FROM points;

以上语句的返回结果中的point会被转换成GIS标准字符串。实际上AsText函数仅仅是把数据库内部存储的几何对象转化为一个字符串而已。

2、返回一系列point的X()(经度)小于10,并且Y()(纬度)小于10的点的集合

SELECT AsText(point)  FROM points WHERE  X(point) < 10 AND Y(point) < 10;

3、

四、测试性能

SELECT  AsText(point) FROM points WHERE X(point) <13000000 and Y(point) > 60000000;

duration/fetch     :  11.606sec/0.047sec

SELECT *  FROM points WHERE longitude < 13000000 and  latitude > 60000000;

duration/fetch     :  11.2941sec/0.281sec

五、如果没有数据也不必担心,下面帮你制造数据

1、创建新表

CREATE TABLE `points` (

  `name` varchar(20) NOT NULL DEFAULT '',

  `location` point NOT NULL,

  `description` varchar(200) DEFAULT NULL,

  PRIMARY KEY (`name`),

  SPATIAL KEY `sp_index` (`location`)

) ENGINE=MyISAM DEFAULT CHARSET=gbk;


2、写函数

delimiter // -- 将SQL标识符设为 '//' 


CREATE PROCEDURE fill_points(
IN size INT(10)
)


BEGIN
DECLARE i DOUBLE(10,1) DEFAULT size;
DECLARE lon FLOAT(7,4);
DECLARE lat FLOAT(6,4);
DECLARE position VARCHAR(100);
 


DELETE FROM Points;
 
WHILE i > 0 DO
SET lon = RAND() * 360 - 180;
SET lat = RAND() * 180 - 90;
 
SET position = CONCAT( 'POINT(', lon, ' ', lat, ')' );
 
INSERT INTO Points(name, location) VALUES ( CONCAT('name_', i), GeomFromText(position) );
 
SET i = i - 1;
END WHILE;


END

3、生成数据

CALL fill_points(1000000);

4、查找区域内的点

SET @center = GeomFromText('POINT(10 10)');

SET @radius = 30;

SET @bbox = CONCAT('POLYGON((',

X(@center) - @radius, ' ', Y(@center) - @radius, ',',

X(@center) + @radius, ' ', Y(@center) - @radius, ',',

X(@center) + @radius, ' ', Y(@center) + @radius, ',',

X(@center) - @radius, ' ', Y(@center) + @radius, ',',

X(@center) - @radius, ' ', Y(@center) - @radius, '))'

);

 

[1]

SELECT name, AsText(location)

FROM Points

WHERE Intersects( location, GeomFromText(@bbox) )

AND SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) < @radius; To Obtain a result ordered by distance from the center of the selection area:

 

[2]

SELECT name, AsText(location), SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) AS distance

FROM Points

WHERE Intersects( location, GeomFromText(@bbox) )

AND SQRT(POW( ABS( X(location) - X(@center)), 2) + POW( ABS(Y(location) - Y(@center)), 2 )) < @radius

ORDER BY distance;


### MySQL Geometry 型的使用说明 #### 1. 数据型概述 MySQL 的 `Geometry` 型是一种用于存储空间数据的数据型,它遵循 OpenGIS 标准[^2]。该型支持多种子型,包括但不限于 `POINT`, `LINESTRING`, 和 `POLYGON` 等。 #### 2. 插入 Geometry 型数据的方法 在 MySQL 中插入 `Geometry` 型的数据通常可以通过以下几种方式实现: - **使用 WKT(Well-Known Text)字符串** 可以通过函数 `ST_GeomFromText()` 或者其旧版替代品 `GeomFromText()` 将 WKT 字符串转换为几何对象并插入到表中。例如: ```sql INSERT INTO temp (id, coordinate_center_geometry) VALUES (1, ST_GeomFromText('POINT(116.555555 39.555555)')); ``` 上述语句将一个表示地理位置的点插入到了名为 `temp` 的表中的列 `coordinate_center_geometry` 中[^4]。 - **使用 WKB(Well-Known Binary)二进制形式** 如果需要从其他系统导入几何数据,则可以利用 WKB 形式的字节流来创建几何对象。Java 应用程序可能通过 JDBC 驱动完成此操作,如下所示[^3]: ```java com.microsoft.sqlserver.jdbc.Geometry geometry1 = com.microsoft.sqlserver.jdbc.Geometry.STGeomFromWKB(resultSet.getBytes(s)); ``` #### 3. 查询与检索 Geometry 数据 查询 `Geometry` 列的内容时,可以直接读取原始的几何对象或者将其转化为更易理解的形式,比如 WKT 文本: ```sql SELECT AsText(coordinate_center_geometry) FROM temp WHERE id=1; ``` 这段 SQL 返回的是之前插入的那个 POINT 对象对应的 WKT 表达式 `"POINT(116.555555 39.555555)"`. #### 4. Java 应用集成示例 对于希望在 Java 应用中处理 MySQL 几何数据的情况,可参考特定库或自定义编码解码逻辑。下面是一个基于 JTS 工具包的例子链接[^5]: [Gitee Repository](https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/main/java/gu/sql2java/geometry/MysqlGeometryDataCodec.java) 这个项目展示了如何在 Java 层面解析来自 MySQL 的几何数据,并且能够执行必要的序列化和反序列化过程。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值