Java+MySQL处理地理数据 开发简易的网点/门店地理位置查询系统
·

技术选型与基础准备
- 后端框架:Spring Boot(集成JDBC或MyBatis-Plus操作MySQL)
- 数据库:MySQL 5.7+(支持空间函数)或 PostgreSQL(PostGIS扩展更强大)
- 地理数据处理:
- MySQL内置函数:
ST_Distance_Sphere、POINT类型 - Java库:JTS Topology Suite或GeoTools(复杂地理计算)
- MySQL内置函数:
- 前端交互(可选):高德地图API/百度地图API(展示网点位置)
数据库设计
CREATE TABLE `store` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '网点名称',
`address` varchar(255) DEFAULT NULL COMMENT '详细地址',
`location` point NOT NULL COMMENT '经纬度坐标',
PRIMARY KEY (`id`),
SPATIAL INDEX `idx_location` (`location`)
) ENGINE=InnoDB;
-- 插入示例数据(经度,纬度)
INSERT INTO `store` (`name`, `location`)
VALUES ('门店A', ST_GeomFromText('POINT(116.404 39.915)'));
核心功能实现
按半径查询附近网点
// Spring Boot + MyBatis 示例
@Mapper
public interface StoreMapper {
@Select("SELECT id, name, address, " +
"ST_X(location) AS lng, ST_Y(location) AS lat, " +
"ST_Distance_Sphere(location, POINT(#{lng}, #{lat})) AS distance " +
"FROM store " +
"WHERE ST_Distance_Sphere(location, POINT(#{lng}, #{lat})) <= #{radius} " +
"ORDER BY distance")
List<Store> findNearbyStores(@Param("lng") double lng,
@Param("lat") double lat,
@Param("radius") int radius);
}
// 实体类
@Data
public class Store {
private Long id;
private String name;
private String address;
private Double lng; // 经度
private Double lat; // 纬度
private Double distance; // 单位:米
}
地理坐标范围查询
-- 查询矩形范围内的网点(左下角、右上角坐标)
SELECT * FROM store
WHERE ST_Within(location, ST_MakeEnvelope(116.30, 39.80, 116.50, 40.00));
性能优化建议
- 使用
SPATIAL INDEX加速查询,MySQL需使用InnoDB引擎 - 对高频查询结果缓存(如Redis)
- 数据量超过百万时考虑分库分表或迁移至PostgreSQL+PostGIS
前端集成示例(高德地图API)
<div id="map-container" style="width:800px;height:500px"></div>
<script>
AMapLoader.load({
key: "您的Key",
version: "2.0"
}).then((AMap) => {
const map = new AMap.Map("map-container");
// 添加标记点
stores.forEach(store => {
new AMap.Marker({
position: [store.lng, store.lat],
title: store.name
}).setMap(map);
});
});
</script>
注意事项
- 坐标系统一:国内常用GCJ-02(高德/腾讯),WGS-84(GPS原始数据)需转换
- 距离计算精度:MySQL的
ST_Distance_Sphere基于球体模型,误差约0.5%
更多推荐
所有评论(0)