Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проблема с функцией, высчитывающей дистанцию по координатам / 7 сообщений из 7, страница 1 из 1
23.09.2015, 12:34
    #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
23.09.2015, 12:39
    #39059337
Lonepsycho
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с функцией, высчитывающей дистанцию по координатам
michaelpak,

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

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

так ST_Distance_Spheroid же.
и точки можно хранить сразу в геометриях postgis--а , а не в парах даблов/флоатов. [или встроенных point--ах postgresql] Чтобы меньше кастить потом. туда-- сюда.
...
Рейтинг: 0 / 0
29.09.2015, 19:22
    #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
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Проблема с функцией, высчитывающей дистанцию по координатам / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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