Хранить круги в поле геометрии Postgres

В идеале было бы что-то вроде этого, но у WKT нет кругового типа.

ST_GeomFromText('CIRCLE(10 20, 10)',4326)

Хотя круговой тип перечислен среди геометрических типов,

circle <(x,y),r> (center point and radius)

Интересно, можно ли использовать тип круга непосредственно в sql:

update <table>
set the_geom = circle '((10, 20),10)'::geometry
where id = <id>;

Но там написано SQL Error [42846]: ERROR: cannot cast type circle to geometry.

Использование ST_Buffer для хранения кругов — это кладж, поэтому я не хочу его использовать.

Альтернативным решением может быть jsonb + geojson, но оно также не поддерживает круги.

UPD: Вот моя структура таблицы. В настоящее время я использую долготу/широту/радиус, но я хотел бы использовать либо geo_json, либо the_geom. Как GeoJSON и WKT могли не поддерживать круг?

CREATE SEQUENCE my_table_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE TABLE my_table (
    id INT NOT NULL,
    longitude NUMERIC(10, 7) DEFAULT NULL,
    latitude NUMERIC(10, 7) DEFAULT NULL,
    radius INT DEFAULT NULL,
    geo_json JSONB,
    the_geom Geometry DEFAULT NULL, PRIMARY KEY(id)
);

person karser    schedule 28.04.2017    source источник
comment
В чем проблема? Что вы пробовали? Какая у тебя ошибка?   -  person Juan Carlos Oropeza    schedule 28.04.2017
comment
comment
circle — это встроенный тип PostgreSQL, основанный на геометрии, а не на пространстве. Эти типы имеют мало общего с PostGIS.   -  person pozs    schedule 28.04.2017
comment
@JuanCarlosOropeza Я указал ошибку и добавил больше случаев.   -  person karser    schedule 28.04.2017
comment
@pozs верно, и мне интересно, можно ли сохранить круг в поле геометрии без использования WKT   -  person karser    schedule 28.04.2017
comment
@karser тип geometry взят из PostGIS. Который не поддерживает круги. Связанный вопрос содержит всю доступную информацию по этому вопросу.   -  person pozs    schedule 28.04.2017
comment
@JuanCarlosOropeza в вопросе, который вы приложили, они предлагают использовать ST_Buffer, который приближает круги к POLYGON, которые имеют много точек внутри, вместо того, чтобы просто хранить X, Y, радиус.   -  person karser    schedule 28.04.2017
comment
покажите нам свой оператор создания таблицы.   -  person Juan Carlos Oropeza    schedule 28.04.2017
comment
@JuanCarlosOropeza Пожалуйста, смотрите обновленный вопрос.   -  person karser    schedule 28.04.2017
comment
@pozs да, я вижу, это ясно сказано. фу   -  person karser    schedule 28.04.2017


Ответы (2)


  • Circle является родным для postgresql, как вы можете видеть в руководстве документация.
  • Geometry — это тип, связанный с PostGis Extension, и не имеет CIRCLE, но вместо этого использует полигоны с большим количеством точек.
  • Функции, начинающиеся с ST_, также являются функциями Postgis и работают только с типом данных Postgis geometry или geography.

ДЕМО SQL:

create table points ( p POINT not null); 
create table lines ( l LINE not null);
create table circles ( c CIRCLE not null);        

insert into points (p) values ( POINT(1.2, 123.1) );
insert into lines (l) values ( LINE(POINT(1.2, 123.1), POINT(-5, -123)) );
insert into circles (c) values ( CIRCLE(POINT(1.2, 123.1), 10) );

SELECT * FROM points;    
SELECT * FROM lines;    
SELECT * FROM circles;
person Juan Carlos Oropeza    schedule 28.04.2017
comment
Спасибо, что все разъяснили - person karser; 30.04.2017

Индекс GIST позволяет эффективно работать с кругами. Если это единственное, что вы собираетесь хранить в этой таблице, вы можете сделать это следующим образом:

CREATE TABLE my_table (
    id INT NOT NULL,
    longitude NUMERIC(10, 7) DEFAULT NULL,
    latitude NUMERIC(10, 7) DEFAULT NULL,
    radius INT DEFAULT NULL,
    geo_json JSONB
);
CREATE INDEX idx_my_table ON my_table USING GIST ( circle( point( latitude, longitude ), radius ));

Как указывали другие, вы не можете смешивать эту таблицу с типами GEOMETRY, которые несовместимы.

Чтобы использовать приведенный выше индекс, вы должны выразить свои критерии WHERE в аналогичных терминах: circle( point( latitude, longitude ), radius ) или '<( latitude, longitude ), radius >'::circle и использовать операторы, о которых знает GIST... которые перечислены ниже. Я знаю, что проецирование евклидовой формы круга на неевклидову сферическую геометрию имеет ограничения, но для целей индекса это должно работать нормально с осторожностью.

https://www.postgresql.org/docs/current/gist-builtin-opclasses.html

person Tel    schedule 27.03.2021