2016-09-02 2 views
1

У меня есть таблица:Postgresql + PostGIS: найти запись по столбцам геометрии

CREATE TABLE main.address_list 
(
    id serial NOT NULL, 
    address_string text NOT NULL, 
    address_position geometry(Point,4326) 
    CONSTRAINT pk_address_list PRIMARY KEY (id) 
) 

Я хочу найти некоторые записи в этой таблице, используя address_position колонки:

select * 
     , public.ST_Y(al.address_position) latitude 
     , public.ST_X(al.address_position) longitude 
from address_list al 
where al.address_position = public.ST_SetSRID(public.ST_MakePoint(56.187339 --longitude$n 
                    , 57.964295 --latitude$n 
                   ), 4326) 

Но я получил следующее ошибка:

ERROR: operator is not unique: public.geometry = public.geometry 
LINE 5: where al.address_position = public.ST_SetSRID(public.ST_Make... 
           ^
HINT: Could not choose a best candidate operator. You might need to add explicit type casts. 

Как я могу получить явный тип приведения?

+0

SELECT *, ST_Y (adress_position) AS широты не работает? Вы пробовали что-нибудь еще, что работает? – Julo0sS

+0

Проверьте это: http://gis.stackexchange.com/questions/42970/how-to-get-coordinates-from-geometry-in-postgis и, кстати, вы действительно должны размещать свои «связанные с ГИС вопросы» в выделенном стеке gis .stackexchange.com – Julo0sS

ответ

2

Вы пытаетесь сравнить два geometries с оператором equals-to =. Это не поддерживается; вместо этого вы должны использовать некоторую функцию пространственных отношений. Вероятно, лучше всего использовать минимальное расстояние:

select * 
     , public.ST_Y(al.address_position) latitude 
     , public.ST_X(al.address_position) longitude 
from address_list al 
where public.ST_DWithin(al.address_position::geography 
         , public.ST_SetSRID(public.ST_MakePoint(56.187339 --longitude$n 
                  , 57.964295 --latitude$n 
             ), 4326)::geography 
         , 1.); -- maximum separation of 1m 

В качестве альтернативы, вы можете сравнить значения широты и долготы для равенства:

select * 
     , public.ST_Y(al.address_position) latitude 
     , public.ST_X(al.address_position) longitude 
from address_list al 
where public.ST_X(al.address_position) = 56.187339 --longitude$n 
    and public.ST_Y(al.address_position) = 57.964295; --latitude$n 

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

+0

Спасибо @Patrick за уведомление о том, что не поддерживается равным оператору для двух геометрий. Я думаю, что я мог бы использовать некоторую функцию для преобразования геометрии в WKT и сравнения этих значений. –

0

Я преобразовал столбец геометрии в WKT (хорошо известный текст) и сравните эти значения.

select * 
     , public.ST_Y(al.address_position) latitude 
     , public.ST_X(al.address_position) longitude 
     , public.ST_AsText(al.address_position) 
from address_list al 
where public.ST_AsText(al.address_position) = public.ST_AsText(public.ST_SetSRID(public.ST_MakePoint(56.187339 --longitude$n 
                            , 57.964295 --latitude$n 
                            ), 4326) 
                   ) 

И добавил индекс функции на колонке address_position

CREATE INDEX i_address_position_as_text 
    ON address_list 
    USING btree 
    (public.ST_AsText(address_position));