如何用Sequelize(SQL Server)通过经纬度查询半径/多边形内的数据?
基于Sequelize实现地理范围查询
一、查询指定半径内的数据(点+半径)
前提:你的表需存储经纬度字段(如latitude、longitude),且数据库支持空间查询(MySQL 5.7+/PostgreSQL+PostGIS)。以下分两种常见数据库场景给出实现:
1. MySQL 环境
利用ST_Distance_Sphere计算球面距离(单位:米),筛选出距离目标点在指定半径内的数据:
const targetLat = 39.9042; // 目标纬度 const targetLng = 116.4074; // 目标经度 const radius = 5000; // 搜索半径,单位米 await models.AddressAddress.findAll({ raw: true, where: Sequelize.where( Sequelize.fn( 'ST_Distance_Sphere', Sequelize.fn('POINT', Sequelize.col('longitude'), Sequelize.col('latitude')), Sequelize.fn('POINT', targetLng, targetLat) ), '<=', radius ) });
2. PostgreSQL + PostGIS 环境
使用ST_DWithin函数,需先将坐标转换为WGS84地理坐标系(SRID=4326):
const targetLat = 39.9042; const targetLng = 116.4074; const radius = 5000; // 搜索半径,单位米 await models.AddressAddress.findAll({ raw: true, where: Sequelize.where( Sequelize.fn( 'ST_DWithin', Sequelize.fn('ST_SetSRID', Sequelize.fn('ST_MakePoint', Sequelize.col('longitude'), Sequelize.col('latitude')), 4326), Sequelize.fn('ST_SetSRID', Sequelize.fn('ST_MakePoint', targetLng, targetLat), 4326), radius ), '=', true ) });
二、查询多边形范围内的数据
需准备闭合的多边形坐标串(格式:POLYGON((lng1 lat1, lng2 lat2, ..., lng1 lat1))),以下是两种数据库的实现:
1. MySQL 环境
通过ST_Contains判断坐标是否在多边形内:
// 示例多边形坐标串(需闭合) const polygonCoords = "POLYGON((116.3 39.8, 116.4 39.8, 116.4 39.9, 116.3 39.9, 116.3 39.8))"; await models.AddressAddress.findAll({ raw: true, where: Sequelize.where( Sequelize.fn( 'ST_Contains', Sequelize.fn('ST_GeomFromText', polygonCoords, 4326), Sequelize.fn('POINT', Sequelize.col('longitude'), Sequelize.col('latitude')) ), '=', 1 ) });
2. PostgreSQL + PostGIS 环境
同样使用ST_Contains,配合坐标系转换:
const polygonCoords = "POLYGON((116.3 39.8, 116.4 39.8, 116.4 39.9, 116.3 39.9, 116.3 39.8))"; await models.AddressAddress.findAll({ raw: true, where: Sequelize.where( Sequelize.fn( 'ST_Contains', Sequelize.fn('ST_SetSRID', Sequelize.fn('ST_PolygonFromText', polygonCoords), 4326), Sequelize.fn('ST_SetSRID', Sequelize.fn('ST_MakePoint', Sequelize.col('longitude'), Sequelize.col('latitude')), 4326) ), '=', true ) });
关键注意事项
- 数据库需开启空间支持:MySQL需启用
gis扩展,PostgreSQL需安装postgis插件。 - 坐标顺序:多数空间函数要求经度在前,纬度在后,不要与日常习惯的
lat,lng顺序混淆。 - 若表中存储的是预定义地理字段(如MySQL的
POINT类型、PostgreSQL的GEOGRAPHY类型),可直接使用字段名替代ST_MakePoint的构造逻辑。
内容的提问来源于stack exchange,提问作者Vyacheslav Tarshevskiy
相关产品推荐
相关产品推荐

