在 Postgres 几何字段中存储圆
Store circles in Postgres geometry field
理想情况下应该是这样的,但是 WKT 没有圆圈类型。
ST_GeomFromText('CIRCLE(10 20, 10)',4326)
虽然圆形是几何类型中的listed,
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:这是我的 table 结构。目前我正在使用 longitude/latitude/radius,但我想使用 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)
);
Circle
是 postgresql 的原生版本,您可以在 manual 文档中看到。
Geometry
是与 PostGis
Extension 相关的类型,没有 CIRCLE
而是使用有很多点的多边形。
- 以
ST_
开头的函数也是 Postgis
函数并且仅适用于 Postgis
geometry
或 geography
数据类型
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;
GIST 索引使您可以高效地使用圆圈。如果这是您打算在此 table 中存储的唯一内容,那么您可以这样做:
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 ));
正如其他人所指出的,您不能将此 table 与不兼容的 GEOMETRY 类型混合使用。
为了利用上面的索引,您必须用类似的术语表达您的 WHERE 标准:circle( point( latitude, longitude ), radius )
或 '<( latitude, longitude ), radius >'::circle
并使用 GIST 知道的运算符......如下所列。我知道将圆的欧几里得形状投影到非欧几里得球形几何体上有局限性,但出于索引目的,它应该小心工作。
https://www.postgresql.org/docs/current/gist-builtin-opclasses.html
理想情况下应该是这样的,但是 WKT 没有圆圈类型。
ST_GeomFromText('CIRCLE(10 20, 10)',4326)
虽然圆形是几何类型中的listed,
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:这是我的 table 结构。目前我正在使用 longitude/latitude/radius,但我想使用 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)
);
Circle
是 postgresql 的原生版本,您可以在 manual 文档中看到。Geometry
是与PostGis
Extension 相关的类型,没有CIRCLE
而是使用有很多点的多边形。- 以
ST_
开头的函数也是Postgis
函数并且仅适用于Postgis
geometry
或geography
数据类型
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;
GIST 索引使您可以高效地使用圆圈。如果这是您打算在此 table 中存储的唯一内容,那么您可以这样做:
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 ));
正如其他人所指出的,您不能将此 table 与不兼容的 GEOMETRY 类型混合使用。
为了利用上面的索引,您必须用类似的术语表达您的 WHERE 标准:circle( point( latitude, longitude ), radius )
或 '<( latitude, longitude ), radius >'::circle
并使用 GIST 知道的运算符......如下所列。我知道将圆的欧几里得形状投影到非欧几里得球形几何体上有局限性,但出于索引目的,它应该小心工作。
https://www.postgresql.org/docs/current/gist-builtin-opclasses.html