Клуб API Карт

Расстояние между двумя точками, Овалы, SQL выборка и один большой вопрос

Пост в архиве.

Здравствуйте. Уже видел в клубе много вопросов подобного характера, но почему то ни одно решение не подошло, видимо я тупой или руки кривые... А может и то и другое.

Задача простая, нужна функция дистанции между двумя точками, которая впоследствии превратится в SQL запрос на выборку точек из карты.

 Проблема заключается в том, что формула типа:

SELECT
sqrt(POWER((($x1 - x)*cos(RADIANS($x1))*40000/360), 2) + POWER((($y1 -
y)*111), 2)) as distance FROM `table` HAVING `distance` < 2

работает правильно и выбирает мне радиус точек меньше 2км от $x1 и $y1

НО

Круг, который начерчен средствами yandex map, а именно кодом:

            var myCircle = new Circle2(new YMaps.GeoPoint({location}), 1.8,{
                style : {
                    polygonStyle : {
                        outline : true,
                        strokeWidth : 2,
                        strokeColor : "0000ff22",
                        fillColor : "00000000"
                    }
                },
                interactive : YMaps.Interactivity.NONE
            });
            map.addOverlay(myCircle)

не совпадает с результатами выборки и имеется погрешность равная изгибу по паралели.

Помогите
найти решение, либо сделать из круга овал, который будет точно включать
в себя результаты запроса, либо изменить запрос, чтобы результаты
вписывались в этот круг.

Заранее благодарю за помощь

4 комментария
Дмитрий Сухоносов
28 января 2016, 06:21

Вам необходимо либо считать радиус по формулам для сферической системы координат в системе WGS-84,

либо хранить все в абсолютных(пиксильных) координатах и работать с ними с помощью обычной геометрии

 http://api.yandex.ru/maps/theory/concepts/coordinates.xml#geo_coordinates

http://api.yandex.ru/maps/jsapi/doc/ref/reference/converter.xml

Спасибо, боюсь второй вариант мне не подойдет, все завязано на GPS координаты, а конвертировать их туда и обратно слишком ресурсоемко.

Михаил Королев
28 января 2016, 06:21

Задача простая, нужна функция дистанции между двумя точками, которая впоследствии превратится в SQL запрос на выборку точек из карты.

 

 вот sql-функция, используется мною в проекте "GPS-Помощник" http://www.oneway.ru/ymaps/

-- =============================================
-- Description:    взято и модифицировано отсюда
-- http://sql.ru/forum/actualthread.aspx?bid=58&tid=325732&hl=%f0%e0%f1%f1%f2%ee%ff%ed%e8%ff+%e3%ee%f0%ee%e4%e0%ec%e8#3126137
-- =============================================
ALTER FUNCTION [dbo].[distance]
    (
          @StartLatitude numeric(18,15) -- Start Latitude
        , @StartLongitude numeric(18,15) -- Start Longitude
        , @FinalLatitude numeric(18,15) -- Final Latitude
        , @FinalLongitude numeric(18,15) -- Final Longitude
    )
RETURNS float-- @tbl TABLE (Distance float, Bearing float)
AS
    BEGIN
DECLARE
      @fPhimean numeric(18,15) -- Mean Latitude
    , @fdLambda numeric(18,15) -- Difference between longtitudes
    , @fdPhi numeric(18,15) -- Difference between lantitudes
    , @fAlpha numeric(18,15) -- Drift
    , @fRho float -- Meridian radius of curvature.
    , @fNu float -- Cross-section radius of curvature
    , @fR float -- Earth radius
    , @fz float -- Angular distance from the center of a spheroid
    , @fTemp float -- The temporal variable used in calculations
    , @Distance float -- Distance in meters
    , @Bearing float -- Bearing
    , @R2D float --  constant for transformation a radian in degrees
    , @a float -- The basic halfaxes
    , @b float -- Nonbasic halfaxes
    , @e2 float -- A square of ellipsoid eccentricity
    , @f float -- Alignment of ellipsoid


    SET @R2D = 57.295781
    SET @a = 6378137.0
    SET @b = 6356752.314245
    SET @e2 = 0.006739496742337
    SET @f = 0.003352810664747


    -- We calculate a difference between two longitudes and breadthes and it is received average breadth
    SET @fdLambda = radians(@StartLongitude - @FinalLongitude);
    SET @fdPhi = radians(@StartLatitude - @FinalLatitude);
    SET @fPhimean = radians((@StartLatitude + @FinalLatitude) / 2.0);

    -- We calculate meridian and cross-section radiuses of curvature of average breadth
    SET @fTemp = 1 - @e2 * (Power(Sin(@fPhimean), 2));
    SET @fRho = (@a * (1 - @e2)) / Power(@fTemp, 1.5);
    SET @fNu = @a / (Sqrt(1 - @e2 * (Sin(@fPhimean) * Sin(@fPhimean))));

    -- We calculate angular distance
    SET @fz =
        Sqrt(Power(Sin(@fdPhi / 2.0), 2) + Cos(radians(@FinalLatitude)) * Cos(radians(@StartLatitude)) *
        Power(Sin(@fdLambda / 2.0), 2));

    SET @fz = 2 * ASin(@fz);

    -- We calculate displacement
    SET @fAlpha = Cos(radians(@FinalLatitude)) * Sin(@fdLambda) * 1 / Sin(@fz);
    SET @fAlpha = ASin(@fAlpha);

    -- We calculate radius of the Earth
    SET @fR = (@fRho * @fNu) / ((@fRho * Power(Sin(@fAlpha), 2)) + (@fNu *
        Power(Cos(@fAlpha), 2)));

    -- Calculating displacement and distance
    SET @Distance = (@fz * @fR);
    if ((@StartLatitude < @FinalLatitude) and (@StartLongitude < @FinalLongitude))
        SET @Bearing = Abs(@fAlpha * @R2D)
    else if ((@StartLatitude < @FinalLatitude) and (@StartLongitude > @FinalLongitude))
        SET @Bearing = 360 - Abs(@fAlpha * @R2D)
    else if ((@StartLatitude > @FinalLatitude) and (@StartLongitude > @FinalLongitude))
        SET @Bearing = 180 + Abs(@fAlpha * @R2D)
    else if ((@StartLatitude > @FinalLatitude) and (@StartLongitude < @FinalLongitude))
        SET @Bearing = 180 - Abs(@fAlpha * @R2D);

        /*INSERT INTO @tbl (Distance, Bearing)
        SELECT @Distance, @Bearing*/
    RETURN @Distance
    END

Эта функция высчитывает дистанцию в километрах по радиусу круга или овала?