代码之家  ›  专栏  ›  技术社区  ›  Scott Ivey

MDX地理距离计算

  •  1
  • Scott Ivey  · 技术社区  · 17 年前

    SQL Server 2005 Analysis Services 我试图计算MDX查询中的距离,这样我就可以得到当前位置附近的项目计数。我已经创建了一个带有纬度的维度&并且还创建了一个.NET程序集来进行计算,但是我很难在查询中解决所有问题。

    我在100英里半径范围内查找项目的查询如下所示:

    select   FILTER([DimProducts].[Product].[Product],
             ZipCalculatorLib.GetDistance(43.474208, [Zip].[Latitude], 96.687689, [Zip].[Longitude]) < 100)  on rows,
            [Measures].[RowCount] on columns
    from     MyCube;
    

    我在.NET中的距离代码如下所示:

    public static double GetDistance(double startLat, double endLat,
        double startLong, double endLong)
    {
        return Math.Sqrt(Math.Pow(69.1 * (startLat - endLat), 2) + Math.Pow(Math.Cos(endLat / 57.3) * 69.1 * (startLong - endLong), 2));
    }
    

    然而,当我运行该查询时,我得到的记录为零。如果我将距离从100改为10000,我得到的计数与100英里半径的计数相似。看起来.NET类没有做平方根运算,但我已经多次测试了该代码,而且看起来是正确的。

    有人对我应该在哪里解决问题有什么建议吗?

    编辑: 我开始怀疑纬度和经度是否没有正确地传递到GetDistance函数中——因此我在那里添加了一行代码来抛出一个异常,以显示它们是什么。我补充说:

    throw new ArgumentException("endLat", string.Format("endLat: {0}, endLong: {1}", endLat, endLong));
    

    现在,当我运行查询时,我得到以下错误:

    执行托管存储 过程GetDistance失败,原因是 被敌人的目标抛出 invocation.endLat参数名称: endLat:1033,endLong:1033。

    现在的问题是:如何让我的实际纬度值通过过滤器中的函数?看起来现在只传递了一个语言代码。

    3 回复  |  直到 16 年前
        1
  •  2
  •   Peter Mortensen Pieter Jan Bonestroo    16 年前

    [Zip].[Latitude]是一个成员表达式。为了将其作为数值传递给函数,SSAS将返回([Zip].[Latitude],Measures.CurrentMember)的等效值。在MDX中,您不能直接基于另一个维度过滤一个维度。根据定义,不同的维度是完全独立的,相互独立 OLAP 术语每个产品都可能存在于每个邮政编码位置。

    我认为逻辑应该是这样的:

    select   
    NONEMPTY([DimProducts].[Product].[Product] *
    FILTER([Zip].[Zip].[Zip] , ZipCalculatorLib.GetDistance(43.474208, [Zip].[Latitude].CurrentMember.MemberValue, 96.687689, [Zip].[Longitude].CurrentMember.MemberValue) < 100),[Measures].[RowCount])  on rows,        [Measures].[RowCount] on columns
    from     MyCube;
    

        2
  •  1
  •   George Silva    17 年前

    我不确定SQL Server 2008是否可用,如果可用,您应该使用其地理数据类型来计算距离。

    如果没有,请检查像SharpMap和Proj.Net这样的库-它们可以让您构建真实的地理点并计算这些对象之间的精确距离。

        3
  •  1
  •   Scott Ivey    16 年前

    我最终用一个子立方体解决了我的问题。通过创建子立方体,我能够过滤距离,然后对我要查找的维度进行选择。这就是我的结局。。。

    create subcube MyCube as
    select  Filter
            (
                (
                    [DimLocation].[Latitude].[Latitude], 
                    [DimLocation].[Longitude].[Longitude] 
                ), 
                (
                    ZipCalculatorLib.GetDistance(
                        43.474208, 
                        [DimLocation].[Latitude].CurrentMember.MemberValue, 
                        96.687689, 
                        DimLocation.Longitude.CurrentMember.MemberValue) < 100
                )
            ) on 0 from MyCube;
    
    select  DimProducts.Product.Product on rows,
            Measures.RowCount on columns
    from       MyCube;
    
    推荐文章