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

如何统计经纬度距离登录用户15英里范围内的其他用户数量

.NET 实现统计指定坐标15英里范围内用户数量的解决方案

核心原理

地球为球面,两点之间的距离不能直接用平面欧氏距离计算,需使用哈弗辛公式(Haversine Formula)计算球面距离,或直接使用数据库/框架内置的空间计算能力实现,最终筛选出距离当前登录用户小于等于15英里的其他用户即可。

实现方案

方案1:应用层C#直接实现

适合用户量较小的场景,无需修改数据库结构,直接在代码中计算距离:

// 计算两个经纬度坐标之间的距离,返回值单位为英里
public double CalculateDistanceInMiles(double lat1, double lon1, double lat2, double lon2)
{
    // 地球平均半径,单位为英里
    const double EarthRadiusInMiles = 3958.8;
    
    // 经纬度转弧度
    var radLat1 = lat1 * Math.PI / 180;
    var radLon1 = lon1 * Math.PI / 180;
    var radLat2 = lat2 * Math.PI / 180;
    var radLon2 = lon2 * Math.PI / 180;

    var deltaLat = radLat2 - radLat1;
    var deltaLon = radLon2 - radLon1;

    // 哈弗辛公式计算
    var haversine = Math.Pow(Math.Sin(deltaLat / 2), 2) +
                    Math.Cos(radLat1) * Math.Cos(radLat2) *
                    Math.Pow(Math.Sin(deltaLon / 2), 2);

    var centralAngle = 2 * Math.Atan2(Math.Sqrt(haversine), Math.Sqrt(1 - haversine));

    return EarthRadiusInMiles * centralAngle;
}

调用示例:拿到当前登录用户的经纬度后,遍历所有其他用户的经纬度,调用上述方法判断返回值是否小于等于15,累加符合条件的数量即可。

方案2:数据库层实现(推荐,性能更高)

适合用户量较大的场景,直接在数据库层面完成计算过滤,避免全量拉取用户数据。

SQL Server 原生SQL实现

使用SQL Server内置的GEOGRAPHY空间类型计算:

-- 定义当前登录用户的坐标,4326为WGS84 GPS坐标系统的SRID
DECLARE @currentLocation GEOGRAPHY = GEOGRAPHY::STPointFromText('POINT(' + CAST(@currentLongitude AS VARCHAR(20)) + ' ' + CAST(@currentLatitude AS VARCHAR(20)) + ')', 4326);

-- 统计15英里范围内的其他用户数量,STDistance返回单位为米,15英里=15*1609.34米
SELECT COUNT(*) AS NearbyUserCount
FROM Users
WHERE Id != @currentLoginUserId
  AND @currentLocation.STDistance(GEOGRAPHY::STPointFromText('POINT(' + CAST(Longitude AS VARCHAR(20)) + ' ' + CAST(Latitude AS VARCHAR(20)) + ')', 4326)) <= 15 * 1609.34

EF Core 集成实现

如果使用EF Core操作数据库,可引入空间数据支持包直接用LINQ实现:

  1. 先安装对应数据库的空间支持包,SQL Server环境下安装Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite
  2. 实体类新增Point类型的位置字段,配置SRID为4326
  3. LINQ查询写法:
// 构造当前用户坐标,注意Point构造参数先传经度再传纬度
var currentLocation = new Point(currentUserLongitude, currentUserLatitude) { SRID = 4326 };

var nearbyUserCount = await _dbContext.Users
    .Where(u => u.Id != currentLoginUserId 
             && u.Location.Distance(currentLocation) <= 15 * 1609.34)
    .CountAsync();

如果使用MySQL等其他数据库,对应也有ST_Distance_Sphere等内置空间函数,逻辑与上述实现一致。

常见踩坑提醒

  • 绝大多数空间计算库的坐标参数都要求先传经度、后传纬度,和日常表述的纬度在前的习惯不同,传反会导致距离计算完全错误
  • 注意单位转换,1英里=1609.34米,不要混淆单位导致阈值偏差
  • 用户量超过10万时建议给空间字段添加空间索引,可大幅提升查询性能

内容的提问来源于stack exchange,提问作者Sami In

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:24:08