纬度和经度的哪种数据类型?


154

我是PostgreSQL和PostGIS的新手。我想在PostgreSQL 9.1.1数据库表中存储纬度和经度值。我将计算两个点之间的距离,并使用此位置值找到更近的点。

经纬度应使用哪种数据类型?


4
如果您要做两个点(2D纬度/经度贴图),则应使用Geometry数据类型。如果您需要在距离计算中引入地球的高度或曲率,可以选择“地理”。
12

4
以下任何答案是否解决了您的问题?如果是这样,我鼓励您选择一个作为答案:)
Volte

Answers:


140

您可以使用数据类型point- (x,y)可以是经纬度的组合。占用16个字节:float8内部2个数字。

或使其成为两列类型float(= float8double precision)。每个8字节。
real(= float4)如果不需要额外的精度。每个4个字节。
甚至即使numeric您需要绝对精度。每组4位2字节,外加3-8字节开销。

阅读有关数字类型几何类型的精美手册。


geometrygeography数据类型由附加模块提供了PostGIS并占据一个在你的表列。每个点占用32个字节。那里有一些额外的开销,例如SRID。这些类型存储(long / lat),而不存储(lat / long)。

这里开始阅读PostGIS手册


5
我不建议使用float数据类型。这使得坐标计算非常复杂。您应该使用PostGIS和geography数据类型进行此类计算。
m13r 16/12/19

8
确实是一本很好的手册,不是吗?文档中出色的示例。
otocan '17

1
在尝试为原始长纬度解析geog时,存储长纬度和经度地理会更快吗?

1
@丹:取决于。请提出一个新问题并提供详细信息。您可以始终链接到此上下文。评论不是提出新问题的地方。
Erwin Brandstetter

39

在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

顺序为经度,纬度-因此,如果将其绘制为地图,则为(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;

1
澄清SRID 4326想要按此顺序的纬度经度。但是PostGIS对SRID 4326的解释要求按此顺序进行经度纬度。示例适用于PostGIS。 postgis.net/2013/08/18/tip_lon_lat
哈默德

25

我极力主张PostGis。它专用于这种数据类型,它具有开箱即用的方法来计算点之间的距离,以及将来可能会有用的其他GIS操作


5

如果您不需要PostGIS提供的所有功能,则Postgres(现在)提供了一个名为Earthdistance的扩展模块。它使用立方体根据距离计算的精度需求,数据类型。

现在,您可以使用earth_box函数-例如-查询某个位置特定距离内的点。


2

在PostGIS中,比起地理(圆形地球模型),几何学更受青睐,因为计算简单得多,因此速度更快。它还具有许多可用功能,但在很长的距离内精度较低。

将CSV导入到较长的纬度字段中DECIMAL(10,6)。6位数是10厘米精度,对于大多数使用情况应该足够了。

然后投射您导入的数据

SELECT 
    --ST_SetSRID(ST_Point(long, lat),4326) geom -- the wrong way because SRID not set in geometry_columns table
    ST_Point(long, lat)::geometry(Geometry, 4326) geom
INTO target_table
FROM source_table;

验证SRID不为零!

SELECT * FROM public.geometry_columns WHERE f_table_name = 'target_table';

使用WKT查看器和验证长纬度参数的顺序ST_AsEWKT(target_table.geom)

然后索引以获得最佳性能

CREATE INDEX idx_target_table_geom_gist
    ON target_table USING gist(geom);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.