我是PostgreSQL和PostGIS的新手。我想在PostgreSQL 9.1.1数据库表中存储纬度和经度值。我将计算两点之间的距离,通过使用此位置值找到更近的点。
我应该将哪种数据类型用于纬度和经度?
答案 0 :(得分:115)
您可以使用数据类型point
- 组合(x,y)
,它可以是您的纬度/经度。占用16个字节:内部有2个float8
个数字。
或者将其设为两列float
(= float8
或double precision
)。每个8字节
或 real
(= float4
),如果不需要额外的精度。每个4个字节
如果你需要绝对的精确度,甚至是numeric
。每组4位数为2个字节,加上3 - 8个字节的开销。
阅读关于numeric types和geometric types的精美手册。
geometry
和geography
数据类型由附加模块 PostGIS 提供,并占用表格中的一个列。每个占用一个点的32个字节。还有一些像SRID那样的额外开销。这些类型存储(长/纬),而不是(纬度/纬度)。
开始阅读PostGIS manual here。
答案 1 :(得分:22)
我强烈支持PostGis。它特定于这种数据类型,它具有开箱即用的方法来计算点之间的距离,以及您将来可以发现有用的其他GIS操作
答案 2 :(得分:22)
在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;
答案 3 :(得分:4)
在PostGIS中,“几何”优于“地理”(圆形地球模型),因为计算简单得多,因此速度更快。它还具有许多可用功能,但在很长的距离内精度较低。
将CSV格式的长lat字段导入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)
验证long lat参数的顺序。
然后索引以获得最佳性能
CREATE INDEX idx_target_table_geom_gist
ON target_table USING gist(geom);
答案 4 :(得分:3)
如果不需要PostGIS提供的所有功能,则Postgres(如今)提供了一个名为earthdistance的扩展模块。根据您对距离计算的准确性要求,它使用point或cube数据类型。
现在,您可以使用 earth_box 函数-例如-查询某个位置特定距离内的点。
答案 5 :(得分:-1)
使用点数据类型将经度和纬度存储在单个列中:
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;
注意:点的第一个元素是经度,第二个元素是纬度。
有关更多信息,请检查此Query Operators。