postgresql 纬度和经度的数据类型是什么?

hsgswve4  于 2023-02-15  发布在  PostgreSQL
关注(0)|答案(7)|浏览(1006)

我是PostgreSQL和PostGIS的新手。我想在PostgreSQL 9.1.1数据库表中存储纬度和经度值。我将计算两点之间的距离,通过使用这些位置值找到更近的点。
应该使用哪种数据类型表示纬度和经度?

icnyk63a

icnyk63a1#

您可以使用数据类型**point-组合(x,y),它可以是您的lat / long。2个float8内部编号。
或者将其设为两列,类型为
float(= float8double precision),每列8个字节。
如果不需要额外的精度,则为
real(= float4)。每个4字节。
如果需要绝对精度,甚至可以使用
numeric。每组4位2字节,外加3 - 8字节开销。
阅读关于numeric typesgeometric types的精细手册。
geometrygeography数据类型由附加模块
PostGIS**提供,在表中占用 * 一 * 列。每个点占用32个字节。其中有一些额外的开销,如SRID。这些类型存储(long/lat),而不是(lat/long)。
从此处开始阅读PostGIS手册。

epggiuax

epggiuax2#

在PostGIS中,具有纬度和经度的点具有地理数据类型。
要添加列:

alter table your_table add column geog geography;

要插入数据:

insert into your_table (geog) values ('SRID=4326;POINT(longitude latitude)');

4326是空间参考ID,表示数据以经度和纬度表示,与GPS中的数据相同。http://epsg.io/4326
顺序是经度,纬度--所以如果你把它画成Map,它就是(x,y)。
要查找最近点,首先需要创建空间索引:

create index on your_table using gist (geog);

然后请求,比如说,离给定点最近的5:

select * 
from your_table 
order by geog <-> 'SRID=4326;POINT(lon lat)' 
limit 5;
hrysbysz

hrysbysz3#

我强烈建议使用PostGis。它专门针对此类数据类型,并且具有现成的方法来计算点之间的距离以及其他GIS操作,您可能会发现这些操作在将来非常有用

n1bvdmb6

n1bvdmb64#

在PostGIS中,几何比地理(圆形地球模型)更受欢迎,因为它的计算更简单,因此更快。它也有许多可用的功能,但在很长的距离上不太准确。
将CSV long和lat字段导入到DECIMAL(10,6)列。6位数是10 cm的精度,对于大多数使用情况应该足够了。然后将导入的数据转换为正确的SRID
走错路了!

/* try what seems the obvious solution */
DROP TABLE IF EXISTS public.test_geom_bad;
-- Big Ben, London
SELECT ST_SetSRID(ST_MakePoint(-0.116773, 51.510357),4326) AS geom
INTO public.test_geom_bad;

正确的方法

/* add the necessary CAST to make it work */
DROP TABLE IF EXISTS public.test_geom_correct;
SELECT ST_SetSRID(ST_MakePoint(-0.116773, 51.510357),4326)::geometry(Geometry, 4326) AS geom
INTO public.test_geom_correct;

验证SRID不为零!

/* now observe the incorrect SRID 0 */
SELECT * FROM public.geometry_columns
WHERE f_table_name IN ('test_geom_bad','test_geom_correct');

使用WKT查看器验证long lat参数的顺序
SELECT ST_AsEWKT(geom) FROM public.test_geom_correct
然后将其编入索引以获得最佳性能

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
nfg76nw0

nfg76nw05#

如果你不需要PostGIS提供的所有功能,Postgres(现在)提供了一个名为earthdistance的扩展模块,它根据你对距离计算的精度要求使用pointcube数据类型。
然后,您可以使用earth_box()函数来查询(例如)某个位置特定距离内的点。

vybvopom

vybvopom6#

使用数据类型将经度和纬度存储在单个列中:

CREATE TABLE table_name (
    id integer NOT NULL,
    name text NOT NULL,
    location point NOT NULL,
    created_on timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
    CONSTRAINT table_name_pkey PRIMARY KEY (id)
)

在“位置”列上创建索引:

CREATE INDEX ON table_name USING GIST(location);

GiST索引能够优化“最近邻”搜索:

SELECT * FROM table_name ORDER BY location <-> point '(-74.013, 40.711)' LIMIT 10;

**注:**点的第一个元素是经度,第二个元素是纬度。

有关详细信息,请查看此查询运算符。

qnzebej0

qnzebej07#

完整性:您可以使用composite type列,该列可从PostgreSQL 11获得。
要创建列:

CREATE TYPE geo AS (lat float, long float);
ALTER TABLE your_table ADD COLUMN location geo;

要插入数据(选项):

-- with field names
INSERT INTO your_table (location.lat, location.long) VALUES (8.12345, -55.34567);

-- string syntax
INSERT INTO your_table (location) VALUES ('(8.12345, -55.34567)');

-- ROW() keyword
INSERT INTO your_table (location) VALUES (ROW(8.12345, -55.34567));

-- ROW() keyword is optional for multi-column composite types
INSERT INTO your_table (location) VALUES ((8.12345, -55.34567));

复合类型通常是不受欢迎的,因为它们就像"表中的表"。但在这种情况下,我认为它们提供了(轻微的)优势:

  • 您可以将地理位置编码在单个列中,如point,但还有一个额外的优点,即您可以根据所需的精度选择组件数据类型(realfloatnumeric)。
  • 你可以使用通常的"纬度,经度"坐标排序;当使用point作为地理位置值时,为了与PostgreSQL实践保持一致,您宁愿使用"long,lat",其中有几个函数期望:

"点被视为(经度,纬度),而不是相反,因为经度更接近于x轴和纬度的直观概念。"
(PostgreSQL 15手册,关于基于点的地球距离)

  • 能够在INSERT中引用字段名,避免格式为(lat,long)或(long,lat)时的任何混淆。
  • 不依赖于重量级的PostGIS,而earthdistance模块,特别是"基于点的地球距离"的操作符<@>,仍然可以用于执行邻近搜索。(您必须动态创建点,因为我们使用不同的数据类型,并将顺序颠倒为(long,lat))。

相关问题