powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проблема с функцией, высчитывающей дистанцию по координатам
7 сообщений из 7, страница 1 из 1
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059327
michaelpak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Есть таблица:
Код: sql
1.
2.
3.
4.
5.
6.
  Column   |          Type           |                            Modifiers                             
-----------+-------------------------+------------------------------------------------------------------
 id        | integer                 | not null default nextval('support_taskaddress_id_seq'::regclass)
 task_id   | integer                 | not null
 longitude | double precision        | 
 latitude  | double precision        |


Написал функцию, которая бы высчитывала дистанцию по координатам пользователя и задания:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE FUNCTION distane (lat1 REAL, long1 REAL, lat2 REAL, long2 REAL) RETURNS REAL AS '
DECLARE 
	x REAL = 69.1 * (lat1 - lat2);
	y REAL = 69.1 * (long1 - long2) * cos (lat1 / 57.3);
BEGIN
	RETURN sqrt(x*x + y*y);
END;
' LANGUAGE plpgsql;


Делаю запрос:
Код: sql
1.
2.
3.
4.
5.
# SELECT distance(latitude, longitude, 68.0, 57.0) FROM support_taskaddress;
ERROR:  function distance(double precision, double precision, numeric, numeric) does not exist
LINE 1: SELECT distance(latitude, longitude, 68.0, 57.0) FROM suppor...
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.


Ладно, используем функцию CAST :
Код: sql
1.
2.
3.
4.
5.
6.
# SELECT distance(CAST (latitude AS REAL), CAST (longitude AS REAL), CAST (68 AS REAL), CAST (57 AS REAL)) FROM support_taskaddress;
ERROR:  column "lon2" does not exist
LINE 1: SELECT 69.1 * (lon2 - lon1) * cos(lat1 / 57.3)
                       ^
QUERY:  SELECT 69.1 * (lon2 - lon1) * cos(lat1 / 57.3)
CONTEXT:  PL/pgSQL function "distance" line 5 during statement block local variable initialization


Можете подсказать, в чем проблема?
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059337
Lonepsycho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michaelpak,

а имя создаваемой функции и используемой, вас не смущает?
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059340
drsm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michaelpak,

1) CREATE FUNCTION distane vs. # SELECT distance(
2) если что, то там должны быть лат лнг в радианах...
3) http://www.postgresql.org/docs/current/static/earthdistance.html
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059413
michaelpak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Lonepsycho, черт возьми, спасибо большое!
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059417
michaelpak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
drsm, в будующем я хочу использовать связку django+postgis, так что решил не разбираться в существующих функциях, а написать самому.
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39059430
qwwq
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michaelpakdrsm, в будующем я хочу использовать связку django+postgis, так что решил не разбираться в существующих функциях, а написать самому.

так ST_Distance_Spheroid же.
и точки можно хранить сразу в геометриях postgis--а , а не в парах даблов/флоатов. [или встроенных point--ах postgresql] Чтобы меньше кастить потом. туда-- сюда.
...
Рейтинг: 0 / 0
Проблема с функцией, высчитывающей дистанцию по координатам
    #39064613
Фотография Кроик Семён
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
michaelpak,

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

сорри за немецкие имена, перевод в комментариях

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
   
   -- перевод в доли градуса по формуле: 
   -- Длина или Широта = Градусы + Минуты/60 + Секунды/3600, где Градусы,Минуты,Секунды: целочисленные

   -- код тестировался на PL/SQL для Oracle 9i

   FUNCTION DistanceInMeter(LaengeA in float, -- долгота A  в градусах
                            BreiteA in float, -- широта A  в градусах
                            LaengeB in float, -- долгота B  в градусах
                            BreiteB in float) -- широта B  в градусах
   RETURN INTEGER 
      Result   integer;

      fPhimean float;
      fdLambda float;
      fdPhi    float;
      fAlpha   float;
      fRho     float;
      fNu      float;
      fR       float;
      fz       float;
      fTemp    float;

      D2R      float := 0.017453;
      a        float := 6378137.0;
      e2       float := 0.006739496742337;

   BEGIN
      if not((LaengeA is NULL) or (BreiteA is NULL) or (LaengeB is NULL) or (BreiteB is NULL)) then
         fdLambda := (LaengeA - LaengeB) * D2R;
         fdPhi := (BreiteA - BreiteB) * D2R;
         fPhimean := ((BreiteA + BreiteB) / 2.0) * D2R;

         fTemp := 1 - e2 * (Power(Sin(fPhimean), 2));
         fRho := (a * (1 - e2)) / Power(fTemp, 1.5);
         fNu := a / (Sqrt(1 - e2 * (Sin(fPhimean) * Sin(fPhimean))));

         fz :=
            Sqrt(Power(Sin(fdPhi / 2.0), 2) + Cos(BreiteB * D2R) * Cos(BreiteA * D2R) *
               Power(Sin(fdLambda / 2.0), 2));

         fz := 2 * ASin(fz);

         if fz=0 then
            Result:=0;
         else
            fAlpha := Cos(BreiteB * D2R) * Sin(fdLambda) * 1 / Sin(fz);
            fAlpha := ASin(fAlpha);

            fR := (fRho * fNu) / ((fRho * Power(Sin(fAlpha), 2)) + (fNu *
               Power(Cos(fAlpha), 2)));

            Result := (fz * fR);
         end if;
      else
         Result:=NULL;
      end if;

      return(Result);
   END DistanceInMeter;
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проблема с функцией, высчитывающей дистанцию по координатам
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]