sql纯数学计算应该很快的--假设你推荐10个最近的人
select top 10 * from 表 order by [经纬度 与 我的经纬度 计算出的距离]或者你在增加一个字段,把所有人都跟三亚某个点计算距离,然后通过这个字段来跟自己比较大致算出谁离自己最近
呵呵,这个不是很准确

解决方案 »

  1.   

    这个用RTree和KDTree都可以做。Lz可以搜索一下第k近的邻居。实际上就是一个分支限界的搜索。如果数据量不大的话哪怕二分这个经度纬度范围,然后直接在数据库中Select也是可以的。
      

  2.   

    要看你的需求精度,如果只是查找经纬度的差异,误差很大,因为东经189度和西经189的的值相差很大,但是距离却可能很近。如果一定要精确的距离,就只能计算当前点到每个用户的距离,然后返回TOPK。这个算法也可以调优。不要使用经纬度,先转换成三维坐标存储,然后在计算距离时会简单得多。
      

  3.   

    想起来了,Sql里面自带这个二维空间的类型,是用4叉树实现的,虽然比RTree差一些,但普通应用足够了。只要加上索引就能用了,不用操心细节。
      

  4.   

    如果并发高的话,可以考虑做RTree缓存。
    否则用SqlServer2008自带的空间类型。
      

  5.   


    SQL SERVER 根据地图经纬度计算距离的公式
    go
    --创建经纬度距离计算函数
     CREATEFUNCTION [dbo].[fnGetDistance] 
     --LatBegin 开始经度
     --LngBegin 开始维度
    (@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) 
           RETURNSFLOAT
           AS
    BEGIN
           --距离(千米)
           DECLARE @Distance      REAL
           DECLARE @EARTH_RADIUS  REAL
           SET @EARTH_RADIUS = 6378.137 
           
           DECLARE @RadLatBegin  REAL,
                   @RadLatEnd    REAL,
                   @RadLatDiff   REAL,
                   @RadLngDiff   REAL
           
           SET @RadLatBegin = @LatBegin *PI()/ 180.0 
           SET @RadLatEnd = @LatEnd *PI()/ 180.0 
           SET @RadLatDiff = @RadLatBegin - @RadLatEnd 
           SET @RadLngDiff = @LngBegin *PI()/ 180.0 - @LngEnd *PI()/ 180.0 
           
           SET @Distance = 2 *ASIN(
                   SQRT(
                       POWER(SIN(@RadLatDiff / 2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd) 
                       *POWER(SIN(@RadLngDiff / 2), 2)
                   )
               )
           
           SET @Distance = @Distance * @EARTH_RADIUS 
           --SET @Distance = Round(@Distance * 10000) / 10000 
           
           RETURN @Distance
    END
     
    @Distance的单位为:千米
    经测试,误差在30米左右,完全可以接受.
      

  6.   


    呃,学艺不精啊,我还不知道sql里面有这个数据类型,多谢大哥了
      

  7.   

    private const double EARTH_RADIUS = 6378.137;//地球半径
    private static double rad(double d)
    {
       return d * Math.PI / 180.0;
    }public static double GetDistance(double lat1, double lng1, double lat2, double lng2)
    {
       double radLat1 = rad(lat1);
       double radLat2 = rad(lat2);
       double a = radLat1 - radLat2;
       double b = rad(lng1) - rad(lng2);   double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) +
        Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2)));
       s = s * EARTH_RADIUS;
       s = Math.Round(s * 10000) / 10000;
       return s;
    }