use*_*404 124 postgresql types postgis latitude-longitude
我是PostgreSQL和PostGIS的新手.我想在PostgreSQL 9.1.1数据库表中存储纬度和经度值.我将计算两点之间的距离,通过使用此位置值找到更近的点.
我应该将哪种数据类型用于纬度和经度?
Erw*_*ter 123
您可以使用数据类型point
- 组合(x,y)
可以是您的纬度/经度.占用16个字节:float8
内部有2个数字.
或者使它成为两列类型float
(= float8
或double precision
).每个8个字节.
或real
(= float4
)如果不需要额外的精度.每个4个字节.
或者即使numeric
你需要绝对的精确度.每组4个数字2个字节,加上3-8个字节的开销.
该geometry
和geography
数据类型由附加模块提供了PostGIS并占据一个在你的表列.每个占用一个点的32个字节.还有一些像SRID那样的额外开销.这些类型存储(长/纬),而不是(纬度/长度).
Dar*_*ski 29
在PostGIS中,对于具有纬度和经度的点,存在地理数据类型.
要添加列:
alter table your_table add column geog geography;
Run Code Online (Sandbox Code Playgroud)
要插入数据:
insert into your_table (geog) values ('SRID=4326;POINT(longitude latitude)');
Run Code Online (Sandbox Code Playgroud)
4326是空间参考ID,它表示经度和纬度的数据,与GPS相同.更多关于它:http://epsg.io/4326
顺序是经度,纬度 - 所以如果你把它绘制成地图,它是(x,y).
要找到最近的点,首先需要创建空间索引:
create index on your_table using gist (geog);
Run Code Online (Sandbox Code Playgroud)
然后请求,例如,5最接近给定点:
select *
from your_table
order by geog <-> 'SRID=4326;POINT(lon lat)'
limit 5;
Run Code Online (Sandbox Code Playgroud)
如果您不需要 PostGIS 提供的所有功能,Postgres(现在)提供了一个名为earthdistance的扩展模块。它根据距离计算的精度需求使用点或立方体数据类型。
您现在可以使用earth_box函数来(例如)查询某个位置特定距离内的点。
在 PostGIS 中,几何优于地理(圆形地球模型),因为计算更简单,因此速度更快。它还具有更多可用功能,但在很长的距离内精度较低。
将您的 CSV 长和经纬度字段导入到DECIMAL(10,6)
列中。6 位数是 10 厘米的精度,对于大多数用例来说应该足够了。然后将导入的数据转换为正确的 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;
Run Code Online (Sandbox Code Playgroud)
正确的方法
/* 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;
Run Code Online (Sandbox Code Playgroud)
验证 SRID 不为零!
/* now observe the incorrect SRID 0 */
SELECT * FROM public.geometry_columns
WHERE f_table_name IN ('test_geom_bad','test_geom_correct');
Run Code Online (Sandbox Code Playgroud)
使用 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);
Run Code Online (Sandbox Code Playgroud)