функция для postgis/postgresql

Trippal
Дата: 01.12.2014 22:36:34
добрый день уважаемые форумчане.
Вопрос такой, я не особо сведущ в построений функций. SQL нормально тяну, а вот с функциями беда просто.
Есть входная переменная - геометрия объекта.
есть две таблицы
буквально, не осложняя понимание:
t1 (id,geom,info1,info2,info3,uniq_id)
t2 (id, geom,uniq_id)

смысл в том, что создать такую функцию, которая будет понимать входную переменную (динамическую, т.е. она будет меняться) - в данном случае на кликании мышкой получаем геометрию t2.geom.
затем необходимо найти пересечение с t1 (полигон более меньшего размера) - с этим запросом проблем нет. делается для получения информации по объекту из таблицы t1 в таблицу t2. Т.е. t2 наследует данные от t1 по пересечению объектов.

SELECT t2.uniq_id,t2.geom
FROM t1,t2
WHERE public.st_intersects(t1.geom, t2.geom)

Затем - получаем info1,info2,info3 для t2 в одну ячейку кортежа.

Итак, возможно продублирую для адекватного объяснения.
Eсть две таблицы t1 и t2
Необходимо получить информацию по объекту в таблице t2, через пересекающего его объекта из t1, при условии, что объект в таблице t2 все время может меняться.

Понимаю, что задача не простая, но если есть хотя бы лоскуты для этой функции буду крайне признателен.
vyegorov
Дата: 02.12.2014 11:01:55
Trippal
добрый день уважаемые форумчане.
SELECT t2.uniq_id,t2.geom
FROM t1,t2
WHERE public.st_intersects(t1.geom, t2.geom)


Если у вас есть геометрия (как тип), то можно просто добавить значение в запрос как дополнительный предикат.
Также можно формировать геометрию из строки (если необходимо) через `ST_GeomFromText`.
Вот так:
SELECT t2.uniq_id,t2.geom
FROM t1,t2
WHERE st_intersects(t1.geom, t2.geom)
  AND st_intersects(t1.geom, ST_GeomFromText('POINT(x.xxx y.yyy)', 4326))
Trippal
Дата: 02.12.2014 13:54:27
о, спасибо, есть даже дополнение, буферная зоны точки клика в пересечении с t1, а затем c t2.
Но вот как это в функцию запихать, не понимаю...
vyegorov
Дата: 02.12.2014 15:46:28
Trippal,

Используйте функцию `ST_Buffer()` вокруг геометрий перед передачей их `ST_Intersects`.

Хотя, если вас интересует только факт нахождения в определенном отдалении, то используйте `ST_Dwithin(t1.geom, t2.geom, 125)`.
Если расстояние постоянно, то можно сделать функциональный GIST индекс по `ST_Expand(t1.geom, 125)`.
Trippal
Дата: 02.12.2014 16:01:50
vyegorov,

спасибо, это я и сделал, проблема в написании самой функции)
но все равно премного благодарен
vyegorov
Дата: 02.12.2014 17:33:15
Trippal,

Я рекомендую использовать PL/SQL для таких функций, т.к. функции на SQL-е прозрачны для планировщика и хорошо оптимизируются. Будем работать с SRF, т.е. функцию надо использовать во `FROM` части запроса.

CREATE OR REPLACE FUNCTION t2_onclick(in_click geometry, OUT uniq_id integer, OUT geom geometry) RETURNS SETOF record AS $t2_onclick$
    SELECT t2.uniq_id,t2.geom
      FROM t1
      JOIN t2 ON st_intersects(t1.geom, t2.geom)
    WHERE ST_DWithin(t1.geom, $1, 125);
$t2_onclick$ LANGUAGE sql;


Вызываем так:
SELECT * FROM t2_onclick(ST_GeomFromText('POINT(x.xxx y.yyy)', 4326)) s;


Возможно натыкал ошибок, проверяем.
Trippal
Дата: 02.12.2014 22:24:56
vyegorov
Trippal,

Я рекомендую использовать PL/SQL для таких функций, т.к. функции на SQL-е прозрачны для планировщика и хорошо оптимизируются. Будем работать с SRF, т.е. функцию надо использовать во `FROM` части запроса.

CREATE OR REPLACE FUNCTION t2_onclick(in_click geometry, OUT uniq_id integer, OUT geom geometry) RETURNS SETOF record AS $t2_onclick$
    SELECT t2.uniq_id,t2.geom
      FROM t1
      JOIN t2 ON st_intersects(t1.geom, t2.geom)
    WHERE ST_DWithin(t1.geom, $1, 125);
$t2_onclick$ LANGUAGE sql;


Вызываем так:
SELECT * FROM t2_onclick(ST_GeomFromText('POINT(x.xxx y.yyy)', 4326)) s;


Возможно натыкал ошибок, проверяем.


Спасибо огромное, есть повод задуматься, Вы мне очень помогли.