You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:10:23