MDX расчет географического расстояния - PullRequest
1 голос
/ 14 октября 2009

Я использую SQL Server 2005 Analysis Services и пытаюсь вычислить расстояние внутри запроса многомерных выражений, чтобы я мог получить количество элементов, которые находятся рядом с моим текущим местоположением. Я создал измерение с широтой и долготой, а также создал сборку .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 не имеет квадратного корня, но я много раз тестировал этот код, и он выглядит правильно.

У кого-нибудь есть предложения относительно того, куда мне обратиться, чтобы решить мою проблему?

EDIT: Я начал задаваться вопросом, не были ли широта и долгота неправильно переданы в мою функцию GetDistance - поэтому я добавил туда строку кода, чтобы сгенерировать исключение, чтобы показать мне, что они были. Я добавил следующее:

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

И теперь, когда я запускаю свой запрос, я получаю следующую ошибку:

Выполнение управляемого хранимого Сбой процедуры GetDistance с следующая ошибка: исключение было брошенный целью invocation.endLat Имя параметра: endLat: 1033, endLong: 1033.

Так что теперь возникает вопрос: как мне заставить мои фактические значения широт проходить через эту функцию в фильтре? Похоже, сейчас передается только код языка.

Ответы [ 3 ]

2 голосов
/ 28 октября 2009

[Zip]. [Широта] является выражением члена. Чтобы передать это функции в виде числового значения, SSAS вернет эквивалент ([Zip]. [Latitude], Measures.CurrentMember). И вы не можете напрямую фильтровать одно измерение на основе другого в MDX. По определению, различные измерения полностью независимы, и в терминах OLAP каждый продукт может потенциально существовать в любом месте Zip.

Я подозреваю, что логика должна выглядеть следующим образом:

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;

Получает все члены Zip, которые имеют широту / долготу в пределах 100 миль, перекрестно соединяет их с продуктами, а затем возвращает тех, у которых непустой RowCount.

1 голос
/ 03 ноября 2009

Я решил проблему с помощью субкуба. Создав вложенный куб, я смог отфильтровать расстояние, а затем просто выбрал размер, который искал. Вот что у меня получилось ...

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;
1 голос
/ 14 октября 2009

Как вы уверены, что рассчитываете это в милях?

Я не уверен, что SQL Server 2008 доступен, если он есть, вы должны использовать его тип географических данных для расчета расстояний.

Если нет, проверьте библиотеки, такие как SharpMap и Proj.Net - они позволят вам построить истинную географическую точку и рассчитать точные расстояния между этими объектами.

...